/**
 * @file        main.c
 *
 * @brief       Main program body
 *
 * @version     V1.0.0
 *
 * @date        2024-08-01
 *
 * @attention
 *
 *  Copyright (C) 2024-2025 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

/* Includes ***************************************************************/
#include "main.h"

/* Private includes *******************************************************/
#include "apm32f4xx_device_cfg.h"
#include "log.h"

/* Private macro **********************************************************/
#define FLASH_USER_ADDR     ((uint32_t)0x08010000U)

#define FLASH_WRITE_DATA
//#define FLASH_ENABLE_WRITE_PROTECTION
#define FLASH_DISABLE_WRITE_PROTECTION

/* Private typedef ********************************************************/

/* Private variables ******************************************************/
static const char* tag = "main";

uint32_t data          = 0x89ABCDEF;

/* Private function prototypes ********************************************/

/* External variables *****************************************************/

/* External functions *****************************************************/

/**
 * @brief   Main program
 *
 * @param   None
 *
 * @retval  None
 */
int main(void)
{
    uint32_t pageError = 0U;

    FLASH_OBProgramInitTypeDef OB_InitStruct = {0};
    FLASH_EraseInitTypeDef Erase_InitStruct = {0};

    /* Device configuration */
    DAL_DeviceConfig();

    /* Unlock the Flash */
    DAL_FLASH_Unlock();

    DAL_FLASHEx_OBGetConfig(&OB_InitStruct);

#ifdef FLASH_ENABLE_WRITE_PROTECTION
    if (OB_InitStruct.WRPPage != ~(OB_WRP_PAGES64TO67))
    {
        DAL_FLASHEx_OBErase();
        OB_InitStruct.OptionType = OPTIONBYTE_WRP;
        OB_InitStruct.WRPState = OB_WRPSTATE_ENABLE;
        OB_InitStruct.WRPPage = OB_WRP_PAGES64TO67;
        OB_InitStruct.Banks = FLASH_BANK_1;
        if(DAL_FLASHEx_OBProgram(&OB_InitStruct) != DAL_OK)
        {
            return -1;
        }
        DAL_FLASH_OB_Launch();
    }
#elif defined FLASH_DISABLE_WRITE_PROTECTION
    if (OB_InitStruct.WRPPage == ~(OB_WRP_PAGES64TO67))
    {
        DAL_FLASHEx_OBErase();
        OB_InitStruct.OptionType = OPTIONBYTE_WRP;
        OB_InitStruct.WRPState = OB_WRPSTATE_DISABLE;
        OB_InitStruct.WRPPage = OB_WRP_PAGES64TO67;
        OB_InitStruct.Banks = FLASH_BANK_1;
        if(DAL_FLASHEx_OBProgram(&OB_InitStruct) != DAL_OK)
        {
            return -1;
        }
        DAL_FLASH_OB_Launch();
    }
#endif

    DAL_FLASH_OB_Lock();

#ifdef FLASH_WRITE_DATA
    /* Erase page */
    Erase_InitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    Erase_InitStruct.PageAddress = FLASH_USER_ADDR;
    Erase_InitStruct.NbPages     = 1U;
    if(DAL_FLASHEx_Erase(&Erase_InitStruct, &pageError) != DAL_OK)
    {
        BOARD_LED_On(LED3);
        LOGI(tag, "Erase fail!\r\n");
        Error_Handler();
    }
    else
    {
        LOGI(tag, "Erase success!\r\n");
    }

    if (DAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_USER_ADDR, data) != DAL_OK)
    {
        LOGI(tag, "Program fail!\r\n");
        BOARD_LED_On(LED3);
        Error_Handler();
    }
    else
    {
        LOGI(tag, "Program success!\r\n");
    }

    if (*(volatile uint32_t*)FLASH_USER_ADDR == data)
    {
        LOGI(tag, "Compare success!\r\n");
        BOARD_LED_On(LED2);
    }
    else
    {
        LOGI(tag, "Compare fail!\r\n");
    }
#endif

    /* Lock the Flash to */
    DAL_FLASH_Lock();

    /* Infinite loop */
    while (1)
    {
    }
}
