/* USER CODE BEGIN Header */
/* you can remove the copyright */

/*
 *  Copyright 2020-2023 Yuntu Microelectronics co.,ltd
 *  All rights reserved.
 *
 *  YUNTU Confidential. This software is owned or controlled by YUNTU and may only be
 *  used strictly in accordance with the applicable license terms. By expressly
 *  accepting such terms or by downloading, installing, activating and/or otherwise
 *  using the software, you are agreeing that you have read, and that you agree to
 *  comply with and are bound by, such license terms. If you do not agree to be
 *  bound by the applicable license terms, then you may not retain, install,
 *  activate or otherwise use the software. The production use license in
 *  Section 2.3 is expressly granted for this software.
 *
 * @file main.c
 * @brief
 *
 */

/* USER CODE END Header */
#include "Mcal.h"
/* Includes ------------------------------------------------------------------*/

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "Fls_NvrDriver/Fls_Nvr.h"
#include "Platform_Types.h"
#include "Std_Types.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8 Fls_WriteData[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
uint8 Fls_ReadData[16] = {0};
uint32 Fls_TestCusKey = 0x4dff32;
boolean Fls_CurNvrEraseEn = FALSE;
boolean Fls_CurNvrFlsProtectEn = FALSE;
boolean Fls_CurNvrDebugDisEn = FALSE; 
boolean Fls_CurNvrDebugEn = FALSE;
boolean Fls_OptNvrWriteEn = FALSE;
boolean Fls_OptNvrReadEn = FALSE;
boolean Fls_HcuNvrWriteEn = FALSE;
boolean Fls_HcuNvrEraseEn = FALSE;
/* USER CODE END PV */

/* Private function declare --------------------------------------------------*/
/* USER CODE BEGIN PFDC */
/* USER CODE END PFDC */
static void Board_Init(void);

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */


/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
    /* USER CODE BEGIN 1 */
    Fls_Lld_ReturnType TestResult = FLASH_E_FAILED;
    Mcu_Init(&Mcu_Config);
    Mcu_InitClock(0);
#if (MCU_NO_PLL == STD_OFF)
    while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
    {
        /* Wait until PLL is locked */
    }
    Mcu_DistributePllClock();
#endif
    /* USER CODE END 1 */ 
    Board_Init();
    /* USER CODE BEGIN 2 */
    /*Operate the sector FlsConf_FlsConfigSet_DFLASH_0,the step is as follows:
    *step I  :erase the sector,
    *step II :write Fls_WriteData to the sector 0 to 7 byte,
    *step III:read the sector 0 to 7 byte to Fls_ReadData,and check the data,
    *step IV :compare the data in flash,
    *step V  :if the Fls_WriteData and Fls_ReadData are equal,then the test is pass and erase the sector.
    *step VI :verify the Flash blank or not
    */

    /*step I :erase CusNvr*/
    if(TRUE == Fls_CurNvrEraseEn)
    {
        TestResult = Fls_EraseCusNvr(0x4dff32);
        while(FLASH_E_OK != TestResult)
        {
            __asm("NOP");
        }

        Fls_CurNvrEraseEn = FALSE;
    }


    TestResult = Fls_ReadCusNvr(0x10013810, Fls_ReadData, 16,Fls_TestCusKey);

    while(FLASH_E_OK != TestResult)
    {
        __asm("NOP");
    }

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {

        /*Test the fls protect register init value*/
        if(TRUE == Fls_CurNvrFlsProtectEn)
        {
            /*Clear the register init value in customer nvr*/
            TestResult = Fls_EraseCusNvr(0x4dff32);
            while(FLASH_E_OK != TestResult)
            {
                __asm("NOP");
            }
            /*Write the customer nvr,the FLASH_ADDR_PROT[0] initial to 0x00000000,FLASH_ADDR_PROT[1] initial to 0xFFFFFFFF after reset,
            so the PFLASH0 can't be write and erase after reset */

            *((uint32 *)&Fls_WriteData[0]) = 0x00000000;
            *((uint32 *)&Fls_WriteData[4]) = 0x5A5A5A5A;
            TestResult = Fls_WriteCusNvr(0x10013810, Fls_WriteData, 8,0x4dff32);
            while(FLASH_E_OK != TestResult)
            {
                __asm("NOP");
            }

            *((uint32 *)&Fls_WriteData[0]) = 0xFFFFFFFF;
            *((uint32 *)&Fls_WriteData[4]) = 0x5A5A5A5A;
            TestResult = Fls_WriteCusNvr(0x10013818, Fls_WriteData, 8,0x4dff32);
            while(FLASH_E_OK != TestResult)
            {
                __asm("NOP");
            }

            Fls_ReadCusNvr(0x10013810, Fls_ReadData, 16,0x4dff32);

            Fls_CurNvrFlsProtectEn = FALSE;
        }


        /*Test the debug enable and disable*/
        if((STD_LOW == Dio_ReadChannel(DioConf_DioChannel_SW1))&&(FALSE == Fls_CurNvrDebugEn))
        {
            Fls_CurNvrDebugDisEn = TRUE;
        }

        if((STD_LOW == Dio_ReadChannel(DioConf_DioChannel_SW2))&&(FALSE == Fls_CurNvrDebugDisEn))
        {
            Fls_CurNvrDebugEn = TRUE;
        }

        /*Disable Jlink or SWD debug when SW1 is pressed*/
        if(TRUE == Fls_CurNvrDebugDisEn)
        {
            *((uint32 *)&Fls_WriteData[0]) = 0x5A5A5A5A;
            *((uint32 *)&Fls_WriteData[4]) = 0x5A5A5A5A;
            TestResult = Fls_WriteCusNvr(0x10013808, Fls_WriteData, 8,0x4dff32);

            if(FLASH_E_OK == TestResult)
            {
                /*test code nothing to do*/
            }
            else 
            {
                /*test code nothing to do*/
            }
            Fls_CurNvrDebugDisEn = FALSE;
        }

        /*Enable Jlink or SWD debug when SW2 is pressed*/
        if(TRUE == Fls_CurNvrDebugEn)
        {
            TestResult = Fls_EraseCusNvr(0x4dff32);
            if(FLASH_E_OK == TestResult)
            {
                /*After erase the cus nvr for enable debug, you need to rewrite 
                the customer key and fls protect reg initial value if needed*/

                /*test code nothing to do*/
            }
            else 
            {
                /*test code nothing to do*/
            }
            Fls_CurNvrDebugEn = FALSE;
        }

        /*Write opt nvr, please note that opt nvr can only be written once*/
        if(TRUE == Fls_OptNvrWriteEn)
        {
            *((uint32 *)&Fls_WriteData[0]) = 0x5A5A5A5A;
            *((uint32 *)&Fls_WriteData[4]) = 0x5A5A5A5A;
            (void)Fls_WriteOptNvr(0x10003A00, Fls_WriteData,8);    
            Fls_OptNvrWriteEn = FALSE;
        }

        /*Read opt nvr*/
        if(TRUE == Fls_OptNvrReadEn)
        {
            Fls_ReadOptNvr(0x10003A00, Fls_ReadData, 8);
            Fls_OptNvrReadEn = FALSE;
        }

        /*Write and erase HCU nvr test , the Hcu nvr can't be read by AHB, so after write or erase ,
        the data can only be verified by load key to HCU. It's not verified in this demo.*/
        if(TRUE == Fls_HcuNvrEraseEn)
        {
            TestResult = Fls_EraseHcuNvr(0x10003800, 0x200, 0x4dff32);

            if(FLASH_E_OK == TestResult)
            {
                /*test code nothing to do*/
            }
            else 
            {
                /*test code nothing to do*/
                while(1)
                {
                    __asm("NOP");
                }
            }
            Fls_HcuNvrEraseEn = FALSE;
        }

        if(TRUE == Fls_HcuNvrWriteEn)
        {
            *((uint32 *)&Fls_WriteData[0]) = 0x01020304;
            *((uint32 *)&Fls_WriteData[4]) = 0x05060708;
            *((uint32 *)&Fls_WriteData[8]) = 0x01020304;
            *((uint32 *)&Fls_WriteData[12]) = 0x05060708;
            TestResult = Fls_WriteHcuNvr(0x10003800, Fls_WriteData, 16);
            if(FLASH_E_OK == TestResult)
            {
                /*test code nothing to do*/
            }
            else 
            {
                /*test code nothing to do*/
                while(1)
                {
                    __asm("NOP");
                }
            }
            Fls_HcuNvrWriteEn = FALSE;
        }

        
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

static void Board_Init(void)
{
    Port_Init(&Port_Config);
    Fls_Init(&Fls_Config);
}

/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
