/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2022. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

/******************************************************************************
 * @version: V1.0.0  demo
 ******************************************************************************/

/*!
 * @file eflashOptionbyte.c
 *
 * @brief This file contains the user eflashOptionbyte function..
 *
 */
/* ===========================================  Includes  =========================================== */
#include "ac780x_eflash.h"
#include "ac780x_eflash_reg.h"
#include "stdbool.h"
#include "eflashOptionbyte.h"
#include "gpio.h"
#include "timer.h"

/* ============================================  Define  ============================================ */


/* ===========================================  Typedef  ============================================ */

/* ==========================================  Variables  =========================================== */
FLASHJobType g_FLASHJobType = FLASH_JOB_NULL;                                    /*！操作任务标志位 */
uint8_t ReadProtectStatus = 0U;                                                  /*! 读报护状态 */
uint32_t PflashPage_0_31_WProtectStatus = 0U;                                    /*！写保护状态 */
uint32_t PflashPage_32_63_WProtectStatus = 0U;                                   /*！写保护状态 */
uint32_t DflashBlock_0_31_WProtectStatus = 0U;                                   /*！写保护状态 */

/* ====================================  Functions declaration  ===================================== */

/* ======================================  Functions define  ======================================== */
/*!
 * @brief   FLASH_OptionByteInfoPrint_Job 选项字节信息打印
 *          打印选项字节信息
 * @param   none
 * @return  none
 */
static void FLASH_OptionByteInfoPrint_Job(void)
{
    ReadProtectStatus = EFLASH_GetReadProtectReg();                              /*！ 获取P-Flash&D-Flash 读保护状态 */
    if (ReadProtectStatus)
    {
        printf("P-Flash&D-Flash is in Read Protect!\r\n");
    }
    else
    {
        printf("P-Flash&D-Flash is not in Read Protect!\r\n");
    }
    PflashPage_0_31_WProtectStatus = EFLASH_GetWriteProReg0();                   /*！ 获取P-Flash Page 0~31写保护状态 */
    printf("P-Flash page 0~31: %08X\r\n", PflashPage_0_31_WProtectStatus);
    PflashPage_32_63_WProtectStatus = EFLASH_GetWriteProReg1();                  /*！ 获取P-Flash Page 32~63写保护状态 */
    printf("P-Flash page 32~63: %08X\r\n", PflashPage_32_63_WProtectStatus);
    DflashBlock_0_31_WProtectStatus = EFLASH_DFGetWriteProReg();                 /*！ 获取D-Flash Block 0~31写保护状态 */
    printf("D-Flash block 0~31: %08X\r\n", DflashBlock_0_31_WProtectStatus);
    printf("KEY: Disable or enable Write Protect\r\n");
    printf("NMI: Disable or enable Read Protect\r\n");
}


/*!
 * @brief   FLASH_SetReadProtect_Job 读保护设置
 *          对P-Flash&D-Flash进行读保护设置，如果原来无读保护，则设置读保护， 读保护复位后生效，
 *          如果原来使能了读保护，则取消读保护，取消读保护会立即清除整块芯片数据，在复位后取消读保护。
 * @param   none
 * @return  none
 */
static void FLASH_SetReadProtect_Job(void)
{
    EFLASH_UnlockCtrl();                                                        /*! Flash 控制器解锁 */
    if (ReadProtectStatus)
    {
        EFLASH_DisableReadProtection();
        printf("Disable Read Protect, chip erase after reset...\r\n");          /*! 取消读保护，复位后生效，但是芯片会被全片擦除（包括Code区域，谨慎使用）  */
    }
    else
    {
        EFLASH_EnableReadProtection();
        printf("Enable Read Protect...\r\n");                                   /*! 使能读报护，复位后生效后，无法通过调试器等工具读取Flash正确的数据会读到全0xAA */
    }
    EFLASH_LockCtrl();                                                          /*! Flash 控制器上锁 */
}


/*!
 * @brief   FLASH_SetWriteProtect_Job 写保护设置
 *          对P-Flash 的0~48页，D-Flash 0~15块的进行写保护设置，写保护设置复位后生效
 *          如果原来使能写保护，则取消写保护；如果原来无写保护，则使能写保护。
 * @param   none
 * @return  none
 */
static void FLASH_SetWriteProtect_Job(void)
{
    uint32_t PflashWriteProtectArray[2] = {0};                                    /*! 每一位代表P-Flash 的1个page, PflashWriteProtectArray[0]为0~31page,PflashWriteProtectArray[1] 为32~64page */
    uint32_t DflashWriteProtectArray[1] = {0};
    if (0x00 == PflashPage_0_31_WProtectStatus)                                   /*! 获取0~31 page 写保护设置 */
    {
        PflashWriteProtectArray[0] = 0xFFFFFFFFU;                                 /*! 0~31 Page 全写保护 */
        printf("P-Flash page 0~31 enable write protect\r\n");
    }
    else
    {
        PflashWriteProtectArray[0] = 0x00U;                                       /*! 0~31 Page 全取消写保护 */
        printf("P-Flash page 0~31 disable write protect\r\n");
    }

    if (0x00 == PflashPage_32_63_WProtectStatus)                                  /*! 获取31~64 page 写保护设置 */
    {
        PflashWriteProtectArray[1] = 0x0000FFFFU;                                 /*! 32~48 Page 全写保护 */
        printf("P-Flash page 32~63 enable write protect\r\n");
    }
    else
    {
        PflashWriteProtectArray[1] = 0x00U;                                       /*！32~64 Page 全取消写保护 */
        printf("P-Flash page 32~63 disable write protect\r\n");
    }

    EFLASH_UnlockCtrl();                                                          /*! Flash 控制器解锁 */
    EFLASH_SetWriteProtection(PflashWriteProtectArray);                           /*! 写保护配置写入， 复位后配置生效 */
    if (0x00 == DflashBlock_0_31_WProtectStatus)
    {
        DflashWriteProtectArray[0] = 0x0000FFFFU;                                 /*！每1位代表1个block，此位置1代表此block使能写保护 */
        EFLASH_DFSetWriteProtection(DflashWriteProtectArray);                     /*! D-Flash的0~15 Block 写保护设置*/
    }
    else
    {
        DflashWriteProtectArray[0] = 0U;                                          /*！每1位代表1个block，此位置1代表此block使能写保护 */
        EFLASH_DFSetWriteProtection(DflashWriteProtectArray);                     /*! D-Flash 全取消写保护 */
    }
    EFLASH_LockCtrl();                                                            /*!  Flash 控制器上锁 */
    printf("Write Protect set done, please reset mcu...\r\n");
}

/*!
 * @brief   eflash_OptionByte_Test
 *          按下KEY1 进行写保护配置
 *          按下NMI，进行读报护配置
 *          读写保护均需要复位生效，其中读报护不可在debug模式下设置
 *          烧录程序后，芯片需要断电才会清楚debug信息，不断电直接设置读报护，复位后芯片会halt，需要断电才可恢复
 * @param   none
 * @return  none
 */
void eflash_OptionByte_Test(void)
{
    GPIO_LedInit();                                     /*！ LED 初始化 */
    GPIO_KeyInit();                                     /*！ KEY 初始化 */
    TIMER_PrdInit();                                    /*！ TIMER 初始化 */
    FLASH_OptionByteInfoPrint_Job();                    /*！ 打印选项字节信息*/

    while (1)
    {
        GPIO_ScanKeyInput();                            /*！按键扫描 */
        switch (g_FLASHJobType)                         /*！任务查询 */
        {
        case FLASH_JOB_WRITE_PROTECT_SET:               /*！写保护设置 */
            FLASH_SetWriteProtect_Job();                /*！如果设置了写保护，则取消写保护；如果没有设置写保护，则设置写保护 */
            g_FLASHJobType = FLASH_JOB_NULL;            /*！标志转换 */
            break;

        case FLASH_JOB_READ_PROTECT_SET:                /*！读保护设置 */
            FLASH_SetReadProtect_Job();                 /*！如果设置了读报护，则取消了读保护；如果没有设置读报护，则设置读报护 */
            g_FLASHJobType = FLASH_JOB_NULL;            /*！标志转换 */
            break;

        case FLASH_JOB_NULL:                            /*！空闲状态 */
            GPIO_ToggleLedPrd();                        /*！LED闪烁 */
            break;

        default:
            g_FLASHJobType = FLASH_JOB_NULL;
            break;
        }

    }
}

/* =============================================  EOF  ============================================== */
