/* 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) 2024. 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: V3.1.0  AC7840x  Demo
 ******************************************************************************/

/* ===========================================  Includes  =========================================== */
#include "flashOptionByte_sample.h"
#include "flash_drv.h"
#include "gpio.h"
#include "osif.h"

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

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

/* ==========================================  Variables  =========================================== */
flash_config_t Flash_Config;

const flash_user_config_t Flash_InitConfig = 
{
    .pFlashBase = 0x00000000U,                  /*!< Pflash 起始地址 */
    .pFlashSize = 0x100000U,                    /*!< Pflash 大小 */
    .dFlashBase = 0x01000000U,                  /*!< Dflash 起始地址 */
    .flexRAMBase = 0x14000000U,                 /*!< FlexRAM 起始地 */
    .callback = NULL,                           /*!< 回调 */
};
/* ====================================  Functions declaration  ===================================== */

/* ======================================  Functions define  ======================================== */

/*!<
* @brief Flash OptionByte 操作， 包括Dflash操作和Pflash操作
*
* @param[in] none
* @return none
*/
void FlashOptionByteTest(void)
{
    uint32_t PflashWriteProtectStatus = 0U;            /*!< Pflash 写保护状态，32位，每一位代表一块32KB区域 */
    uint8_t DflashWriteProtectStatus = 0U;             /*!< Dflash 写保护状态，8位，每一位代表一块16KB区域 */
    uint8_t WriteProtectSet[5] = {0};                  /*!< flash 写保护设置 */
    uint8_t ReadProtectSet[1] = {0};                   /*!< Read 写保护设置 */
    uint8_t SecurityStatus = 0U;                       /*!< 读报护等安全信息标识符 */
    status_t ret = STATUS_SUCCESS;                     /*!< 操作状态返回值 */

    GPIO_LedInit();                                    /*!< LED IO初始化 */
    GPIO_KeyInit();                                    /*!< KEY IO 初始化 */
    FLASH_DRV_Init(&Flash_InitConfig, &Flash_Config);  /*!< Flash 模块初始化 */


    FLASH_DRV_GetPFlashProtection(&PflashWriteProtectStatus);                     /*!< 获取Pflash 写保护状态 */
    FLASH_DRV_GetDFlashProtection(&Flash_Config, &DflashWriteProtectStatus);      /*!< 获取Dflash 写保护状态 */
    FLASH_DRV_GetSecurityState(&SecurityStatus);                                  /*!< 返回值: 01 无读保护， 02 读保护且有Backdoor, 04 读报护且无Backdoor */
    printf("Pflash WriteProtect Status: %08X\r\n", PflashWriteProtectStatus);
    printf("Dflash WriteProtect Status: %08X\r\n", DflashWriteProtectStatus);
    printf("Flash ReadProtect Status: %08X\r\n", SecurityStatus);
    
    printf("==*******************************************==\r\n");
    printf("==   Key3: enable/disable Write protect...   ==\r\n");
    printf("==   Key4: enable/disable Read protect...    ==\r\n");
    printf("==*******************************************==\r\n");

    while(1)
    {
        if(1U == Get_Key3Value())         
        {
            if(0xFFFFFFFFU == PflashWriteProtectStatus )
            {
                WriteProtectSet[0] = 0x00U;                                       /*!< 设置Pflash (0~8)*32KB 区域写保护 ,  每一位代表32KB flash空间，1代表无写保护， 0代表写保护 */
                WriteProtectSet[1] = 0x00U;                                       /*!< 设置Pflash (9~16) *32KB 区域写保护, 每一位代表32KB flash空间，1代表无写保护， 0代表写保护 */
                WriteProtectSet[2] = 0x00U;                                       /*!< 设置Pflash (17~24)*32KB 区域写保护, 每一位代表32KB flash空间，1代表无写保护， 0代表写保护 */
                WriteProtectSet[3] = 0xFFU;                                       /*!< 设置Pflash (24~32)*32KB 区域写保护, 每一位代表32KB flash空间，1代表无写保护， 0代表写保护 */
                WriteProtectSet[4] = 0x00U;                                       /*!< 设置Dflash (0~8)*16KB 区域, 每一位代表16KB flash空间，1代表无写保护， 0代表写保换 */
                printf("Pflash 0~ 24*32KB set Write Protect， Dflash 0~8*16KB set Write Protect， reset and take effect...\r\n");
                FLASH_DRV_UnlockCtrl();                                           /*!< Unlock Flash */
                FLASH_DRV_SetWriteProtection(&Flash_Config, WriteProtectSet, 5);  /*!< 设置相应区域写保护，复位生效 */
                FLASH_DRV_LockCtrl();                                             /*!< lock Flash */
                
            }
            else
            {
                FLASH_DRV_UnlockCtrl();                                           /*!< Unlock Flash */
                FLASH_DRV_EraseWriteProtection(&Flash_Config);                    /*!< 取消所有Flash的写保护 */
                printf("Disable Write Protect， reset and take effect...");
                FLASH_DRV_LockCtrl();                                             /*!< lock Flash */
            }

        }
        if(1U == Get_Key4Value())
        {
            if(0x01U == SecurityStatus)
            {
                if(0 == ((FLASH->STAT & FLASH_STAT_RAMRDY_Msk) >> FLASH_STAT_RAMRDY_Pos))  /*!< 如果需要在存在CSE情况下使能读保护，修改此判断条件即可，需慎重使用 */
                {
                    /*!< 检查程序中是否存在CSE 分区， 存在CSE分区的情况下Code无法解除读保护，请慎重使用 */
                    printf("FlexRAM is use for CSE, can not enable read protect...\r\n ");
                }
                else 
                {
                    FLASH_DRV_UnlockCtrl();                                          /*!< Unlock Flash */
                    ReadProtectSet[0] = 0xFCU;                                       /*!< 读保护配置码 */
                    FLASH_DRV_SetSecurity(&Flash_Config, ReadProtectSet, 1);         /*!< 使能读保护 */
                    FLASH_DRV_LockCtrl();                                            /*!< lock Flash */
                    printf("Set Read Protect， reset and take effect...\r\n");
                }
            }
            else 
            {
                printf("Disable Read Protect, Will erase all chip...\r\n");
                FLASH_DRV_UnlockCtrl();                                              /*!< Unlock Flash */
                ret = FLASH_DRV_EraseAllBlock(&Flash_Config);                        /*!< 全片擦除，取消读保护 ,芯片会变成空片 */
                if(ret != STATUS_SUCCESS)
                {
                    printf("[%d]ERROR: Erase allblock failure...\r\n", __LINE__);    /*!< 全片擦除异常， 请检查是否存在CSE分区的情况 */
                }
                FLASH_DRV_LockCtrl();                                                /*!< lock Flash */
            }
        }
    };
}


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


