/*********************************************************
*Copyright (C), 2017, Shanghai Eastsoft Microelectronics Co., Ltd.
 * @文件名:  main.c
 * @作  者:  AE Team
 * @版  本:  V1.00
 * @日  期:  2022/07/25
 * @描  述:  依次进行单字编程，多字编程及擦除操作
             任一操作失败则点亮LED1持续4S，操作结束则LED1将亮0.5秒灭0.5秒
 * @note
 *          Change Logs:
 *          Date            Author          Notes
 *          25 July 2022    AE Team         change license to Apache-2.0
 *
 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **********************************************************************************
 */


#include "main.h"

int main(void)
{
    uint32_t data = 0x12345678;
    uint8_t  dataArr[8] = {0x33, 0x81, 0x12, 0x1A, 0x2F, 0x7C, 0x32, 0x33};
    uint32_t dataArrRef[2] = {0x1A128133, 0x33327C2F};
    uint32_t u32buf = 0;
    uint32_t u32Arr[8];

    HRC_Config(Enable, SCU_HRC_48M, Enable);
    SystemInit();
    DeviceClockAllEnable();
    User_SysTickInit();

    LightInit(LED1_PIN);

    /* 页擦除 */
    IAP_FLASH_Unlock();     /* 解锁FLASH */
    IAP_Code_PageErase(CODE_START_ADDR, ~CODE_START_ADDR);

    if (1 == check_empty((uint32_t *) CODE_START_ADDR, 512))
    {
        LightOff(LED1_PIN);
    }
    else
    {
        LightOn(LED1_PIN);
    }

    Delay_100us(40000);
    LightOff(LED1_PIN);

    /* 单字编程 */
    IAP_Code_WordProgram(CODE_START_ADDR, ~CODE_START_ADDR, data);
    IAPRead(&u32buf, CODE_START_ADDR, 1);

    if (data == u32buf)
    {
        LightOff(LED1_PIN);
    }
    else
    {
        LightOn(LED1_PIN);
    }

    Delay_100us(40000);
    LightOff(LED1_PIN);

    /* 页擦除 */
    IAP_Code_PageErase(CODE_START_ADDR, ~CODE_START_ADDR);

    if (1 == check_empty((uint32_t *) CODE_START_ADDR, 512))
    {
        LightOff(LED1_PIN);
    }
    else
    {
        LightOn(LED1_PIN);
    }

    Delay_100us(40000);
    LightOff(LED1_PIN);

    /* 多字编程 */
    IAP_Code_PageProgram(CODE_START_ADDR, ~CODE_START_ADDR, dataArr, 8, 0);
    IAP_FLASH_Lock();       /* 锁定FLASH */
    IAPRead(u32Arr, CODE_START_ADDR, 2);

    if ((u32Arr[0] == dataArrRef[0]) && (u32Arr[1] == dataArrRef[1]))
    {
        LightOff(LED1_PIN);
    }
    else
    {
        LightOn(LED1_PIN);
    }

    Delay_100us(40000);
    LightOff(LED1_PIN);

    /* 页擦除 */
    IAP_FLASH_Unlock();     /* 解锁FLASH */
    IAP_Code_PageErase(CODE_START_ADDR, ~CODE_START_ADDR);
    IAP_FLASH_Lock();       /* 锁定FLASH */

    if (1 == check_empty((uint32_t *) CODE_START_ADDR, 512))
    {
        LightOff(LED1_PIN);
    }
    else
    {
        LightOn(LED1_PIN);
    }

    Delay_100us(40000);
    LightOff(LED1_PIN);

    while (1)
    {
        Delay_100us(5000);
        LightOn(LED1_PIN);
        Delay_100us(5000);
        LightOff(LED1_PIN);
    }
}

/***************************************************************
 函数名：uint8_t check_empty(uint32_t *data_ptr, uint32_t len)
 描  述：检查指定FLASH区域是否为空
 输入值：data_ptr-FLASH地址
         len-要查空的字节长度
 输出值：无
 返回值：0-非空
         1-空
         2-参数错误
***************************************************************/
uint8_t check_empty(uint32_t *data_ptr, uint32_t len)
{
    uint32_t  i;

    if ((((uint32_t)data_ptr) % 4 != 0) || (len % 4 != 0))
    {
        return 2;
    }

    for (i = 0; i < len; i += 4)
    {
        if (*(data_ptr++) != 0xFFFFFFFF)
        {
            break;
        }
    }

    if (i < len)
        return 0;
    else
        return 1;
}


/*************************END OF FILE**********************/
