/**
  ******************************************************************************
  * @file    BAKR/Bakr_Data/main.c
  * @author  IOT Development Team
  * @version V1.0.0
  * @date    10-January-2020
  * @brief   Main program body.
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "apm32f10x.h"
#include "platform_config.h"

/** @addtogroup APM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup BAKR_Bakr_Data
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#if defined APM32_MINI || defined APM32_DISCOVERY
#define BAKR_DR_NUMBER              10
#else
#define BAKR_DR_NUMBER              42
#endif /* APM32_MINI or APM32_DISCOVERY */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
#if defined APM32_MINI || defined APM32_DISCOVERY
uint16_t BAKRDataReg[BAKR_DR_NUMBER] =
{
    BAKR_DATA1, BAKR_DATA2, BAKR_DATA3, BAKR_DATA4, BAKR_DATA5,
    BAKR_DATA6, BAKR_DATA7, BAKR_DATA8, BAKR_DATA9, BAKR_DATA10
};
#else
uint16_t BAKRDataReg[BAKR_DR_NUMBER] =
{
    BAKR_DR1 , BAKR_DR2 , BAKR_DR3 , BAKR_DR4 ,  BAKR_DR5 , BAKR_DR6 , BAKR_DR7 , BAKR_DR8 ,
    BAKR_DR9 , BAKR_DR10, BAKR_DR11, BAKR_DR12, BAKR_DR13, BAKR_DR14, BAKR_DR15, BAKR_DR16,
    BAKR_DR17, BAKR_DR18, BAKR_DR19, BAKR_DR20, BAKR_DR21, BAKR_DR22, BAKR_DR23, BAKR_DR24,
    BAKR_DR25, BAKR_DR26, BAKR_DR27, BAKR_DR28, BAKR_DR29, BAKR_DR30, BAKR_DR31, BAKR_DR32,
    BAKR_DR33, BAKR_DR34, BAKR_DR35, BAKR_DR36, BAKR_DR37, BAKR_DR38, BAKR_DR39, BAKR_DR40,
    BAKR_DR41, BAKR_DR42
};
#endif /* APM32_MINI or APM32_DISCOVERY */

/* Private function prototypes -----------------------------------------------*/
void WriteToBakrReg(uint16_t FirstBakrData);
uint8_t CheckBakrReg(uint16_t FirstBakrData);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief   Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
    /*!< At this stage the microcontroller clock setting is already configured,
         this is done through SystemInit() function which is called from startup
         file (startup_apm32f10x_xx.s) before to branch to application main.
         To reconfigure the default setting of SystemInit() function, refer to
         system_apm32f10x.c file
       */
#if defined (APM32_MINI)
    /* Initialize Leds mounted on APM32-MINI board */
    APM_MINI_LEDInit(LED2);
    APM_MINI_LEDInit(LED3);
#elif defined(APM32_DISCOVERY)
    /* Initialize Leds mounted on APM32-DISCOVERY board */
    APM_DISCOVERY_LEDInit(LED2);
    APM_DISCOVERY_LEDInit(LED3);
#endif
    /* Enable PMU and BAKR clock */
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU | RCM_APB1_PERIPH_BAKR);

    /* Enable write access to BAKR domain */
    PMU_EnableBakrAccess();

    /* Clear Tamper pin Event(TE) pending flag */
    BAKR_ClearFlag();

    /* Check if the Power On Reset flag is set */
    if (RCM_ReadFlag(RCM_FLAG_PMURST) != RESET)
    {
        /* Clear reset flags */
        RCM_ClearFlag();

        /* Check if Bakr data registers are programmed */
        if (CheckBakrReg(0x3210) == 0x00)
        {
            /* Bakr data registers values are correct */
            /* Turn on LED3 */
#if defined (APM32_MINI)
            APM_MINI_LEDOn(LED3);
#elif defined(APM32_DISCOVERY)
            APM_DISCOVERY_LEDOn(LED3);
#endif
        }
        else
        {
            /* Bakr data registers values are not correct or they are not yet
               programmed (when the first time the program is executed) */

            /* Write data to Bakr data registers */
            WriteToBakrReg(0x3210);

            /* Turn on LED2 */
#if defined (APM32_MINI)
            APM_MINI_LEDOn(LED2);
#elif defined(APM32_DISCOVERY)
            APM_DISCOVERY_LEDOn(LED2);
#endif
        }
    }

    while (1)
    {
    }
}

/**
  * @brief  Writes data Bakr DRx registers.
  * @param  FirstBakrData: data to be written to Bakr data registers.
  * @retval None
  */
void WriteToBakrReg(uint16_t FirstBakrData)
{
    uint32_t index = 0;

    for (index = 0; index < BAKR_DR_NUMBER; index++)
    {
        BAKE_SetBakrRegister(BAKRDataReg[index], FirstBakrData + (index * 0x5A));
    }
}

/**
  * @brief  Checks if the Bakr DRx registers values are correct or not.
  * @param  FirstBakrData: data to be compared with Bakr data registers.
  * @retval
  *          - 0: All Bakr DRx registers values are correct
  *          - Value different from 0: Number of the first Bakr register
  *            which value is not correct
  */
uint8_t CheckBakrReg(uint16_t FirstBakrData)
{
    uint32_t index = 0;

    for (index = 0; index < BAKR_DR_NUMBER; index++)
    {
        if (BAKR_GetBakrRegister(BAKRDataReg[index]) != (FirstBakrData + (index * 0x5A)))
        {
            return (index + 1);
        }
    }

    return 0;
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

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

#endif

/**
  * @}
  */

/**
  * @}
  */
