/* 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
 ******************************************************************************/

  /*!
 *例程说明：
 *例程6， eep.lib 使用 ，包括eep 初始化， 读， 写操作
 */
/* ===========================================  Includes  =========================================== */

#include "debugout_ac7840x.h"
#include "clock_config.h"
#include "eep_drv.h"
#include "gpio.h"

/* ============================================  Define  ============================================ */
#define USER_EEP_SIZE            (1024U)
#define USER_EEP_RAMBASEADDR     (0x2000D000U)
#define USER_EEP_FLASHBASEADDR   (0x01000000U)
#define USER_EEP_PAGESIZE        (0x800U)
#define USER_EEP_MINPROBYTE      (0x08U)

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

/* ==========================================  Variables  =========================================== */

/*!
 * @brief EEPCallback
 *
 * @param[in]  none
 *
 * @return none
 */
void EEPCallback(void)
{
    // 此回调函数在EEP.lib 进行group切换时进行调用
    printf("Do Callback...\r\n");
}



const Eep_Hal_ConfigType eep_config = {
    .EepSize          = USER_EEP_SIZE,           /*!< EEP空间大小 (byte) */
    .EepRamBaseAddr   = USER_EEP_RAMBASEADDR,    /*!< EEP使用的RAM基地址 , 如果使用了CSE 模块， 不可以将EEP使用的RAM基地址 设置为0x14000000U  */
    .EepFlashBaseAddr = USER_EEP_FLASHBASEADDR,  /*!< EEP使用的FLASH基地址 */
    .FlashPageSize    = USER_EEP_PAGESIZE,       /*!< FLASH页大小(byte) */
    .FlashMinProByte  = USER_EEP_MINPROBYTE,     /*!< FLASH最小编程字节 */
    .IcType           = EEP_HAL_AC78406,         /*!< 芯片型号 */
    .CallbackType     = EEPCallback,             /*!< 回调函数 */
};

/*
    注意：
    1. 用户需要保证EEP使用的RAM空间不可被其他程序使用；
    2. 如果使用了CSE模块，禁止使用0x1400_0000U做为EEP的RAM基地址；
    3. 如果使用eepRamBaseAddr为0x1400_0000U, 请注意FlexRAM需要做SRAM使用， 注意FLASH_PART的EPART位；
    4. EEP的每一项操作，初始化， 读，写和擦除都需要判断返回值以确定是否操作成功；
*/
/* ====================================  Functions declaration  ===================================== */

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

/*!
 * @brief main
 *
 * @param[in]  none
 *
 * @return none
 */
void EepTest(void)
{
    static uint8_t offset =0;                               /*!< 偏移值 ， 每操作一次写入， 偏移值+1 */
    uint8_t readWriteBuff = 0;                              /*!< 写入数据      */
    uint16_t i = 0;                                         /*!< 计数值        */
    Eep_Hal_StatusType res = EEP_HAL_SUCCESS;               /*!< EEP操作返回值 */

    InitDebug();                                            /*!< 串口初始化    */
    GPIO_LedInit();                                         /*!< LED初始化     */
    GPIO_KeyInit();                                         /*!< KEY初始化     */

    res = Eep_Hal_Init(&eep_config);                        /*!< 初始化EEP， 每次复位都需要执行一次EEP_Init, EEP_Init只初始化算法所需变量，不会擦除空间 */
    if(EEP_HAL_SUCCESS != res)                              /*!< 判断初始化是否成功 */
    {
        printf("LINE[%d] : ERROR_CODE[%02X] EEP Init fail...\r\n", __LINE__, res);
    }
    
    res = Eep_Hal_Read(0x00U, &readWriteBuff, 1u);          /*!< 读取首次擦除标志位， 判断是否完成首次擦除， 为0xAA为已完成首次擦除， 非0xAA为未完成首次擦除 */
    if(EEP_HAL_SUCCESS != res)                              /*!< 判断读取是否成功 */
    {
        printf("LINE[%d] : ERROR_CODE[%02X] Read frist erase flag fail...\r\n", __LINE__, res);
    }
    
    /*!<
            1. 首次使用EEP 需要调用EEP_Erase 的机制是为了保证在首次使用的时候，用于模拟EEP 的Flash 空间是全空的，不会有其他数据对模拟EEP算法
               造成干扰， 如果用户有其他方法保证首次使用EEP时，用于模拟EEP的 Flash空间是空的，也可以不使用此种机制; 
            2. 使用0地址存放首次擦除标志，地址可由用户决定， 不一定都使用0地址。
            3. 调用EEP_Erase 会把所有数据清空， 慎重使用。
    */
    if(0xAA == readWriteBuff)
    {
                                                            /*!< 非首次使用， 不需要进行擦除，擦除操作会将eep空间全部擦除，会造成数据丢失，请慎重使用 */
    }
    else
    {
        printf("Frist use, Erase EEP...\r\n");
        res = Eep_Hal_Erase();                              /*!< 首次使用， 建议把用于模拟的flash 空间全部擦除 */
        if(EEP_HAL_SUCCESS != res)
        {
            printf("LINE[%d] : ERROR_CODE[%02X] Erase EEP fail...\r\n", __LINE__, res);
        }
        readWriteBuff = 0xAA;                               /*!< 首次使用标志位不是0xAA, 说明是首次使用， 建议执行一次EEP_Erase, 如LINE139 */
        res = Eep_Hal_Write(0x00U, &readWriteBuff, 1u);     /*!< 擦除后，写入完成首次擦除标志位至EEP 0x00位置上 */
        if(EEP_HAL_SUCCESS != res)
        {
            printf("LINE[%d] : ERROR_CODE[%02X] Write frist erase flag fail...\r\n", __LINE__, res);
        }

    }
    printf("K3 Write , K4 Read...\r\n");

    while(1)
    {
        /*********************************** 写操作 *******************************************/
        if(Get_Key3Value())                                 /*!< 按下K3, 向EEP 写入数据， 注意写入地址不能超过 eepSize */
        {
            printf("Write Task start...\r\n");
            for(i=1; i< 1024; i++)
            {
                readWriteBuff = i + offset;
                res = Eep_Hal_Write(i, &readWriteBuff, 1u); /*!< 向1~1023地址， 写入数据, 0x00位置为首次使用标志位， 勿使用 */
                if(EEP_HAL_SUCCESS != res)
                {
                    printf("LINE[%d] : ERROR_CODE[%02X] Write data[%d] fail...\r\n", __LINE__, res, i);
                }
            }
            offset ++;                                      /*!< 每写一次， 偏移值+1 */
            printf("Write Task end! \r\n");
        }
        
        
        /*********************************** 读操作 *******************************************/
        if(Get_Key4Value())                                 /*!< 按下K4， 读取EEP数据 */
        {
            printf("Read Task start...\r\n");
            res = Eep_Hal_Read(0, &readWriteBuff, 1u);      /*!< 读取0地址的数据，0地址存储首次使用标志位 */
            if(EEP_HAL_SUCCESS != res)
            {
                 printf("LINE[%d] : ERROR_CODE[%02X] Read data[%d] fail...\r\n", __LINE__, res, i);
            }
            else 
            {
                 printf(" FristUseFlag is %02X ", readWriteBuff);
            }
            for(i=1; i< 1024; i++)
            {
                 readWriteBuff = i;
                 res = Eep_Hal_Read(i, &readWriteBuff, 1u);  /*!< 读取1~1023地址的数据*/
                 if(EEP_HAL_SUCCESS != res)
                 {
                     printf("LINE[%d] : ERROR_CODE[%02X] Read data[%d] fail...\r\n", __LINE__, res, i);
                 }
                 else 
                 {
                    printf(" Addr[%04X] , Data[%02X]\r\n ", i, readWriteBuff);
                 }
            }
            printf("\r\nRead Task end!\r\n");
        }

        /*********************************** RGB闪烁 *******************************************/
        RGB_Toggle();                                     
    }

}

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