/******************************************************************************
 * @file     main.c
 * @brief    Main program body
 * @version  V4.0.0
 * @date     30-July-2026
 *
 * @note
 * Copyright (C) 2022 Spintrol Electronic Technology (Shanghai) Co., Ltd.. All rights reserved.
 *
 * @attention
 * THIS SOFTWARE JUST PROVIDES CUSTOMERS WITH CODING INFORMATION REGARDING
 * THEIR PRODUCTS, WHICH AIMS AT SAVING TIME FOR THEM. SPINTROL SHALL NOT BE
 * LIABLE FOR THE USE OF THE SOFTWARE. SPINTROL DOES NOT GUARANTEE THE
 * CORRECTNESS OF THIS SOFTWARE AND RESERVES THE RIGHT TO MODIFY THE SOFTWARE
 * WITHOUT NOTIFICATION.
 *
 ******************************************************************************/

#include<stdio.h>

#if defined(SPC1158)
#include "spc1158.h"
#elif defined(SPD1148)
#include "spd1148.h"
#elif defined(SPD1178)
#include "spd1178.h"
#elif defined(SPD1188)
#include "spd1188.h"
#elif defined(SPD1163)
#include "spd1163.h"
#else
#include "spc1168.h"
#endif

#if defined(SPC1158)
#define                         OffsetADDRInFlash                      0xC000
#else
#define                         OffsetADDRInFlash                      0x10000
#endif

#if defined ( __CC_ARM )
#define                         _RAM_FUNC_
#else
#define                         _RAM_FUNC_                              __ramfunc
#endif

#define                         FlashBaseADDR                          0x10000000
#define                         OperationADDR                          (FlashBaseADDR + OffsetADDRInFlash)
#define                         VectorTableLoadAddr                    0x10000000
#define                         TimerPeriodCount                        1 //1ms
#define                         VECTOR_NUM                              79u        

uint32_t u32VectorCnt = 0;
static uint32_t u32Count = 0;
volatile uint32_t u32aRAMVector[VECTOR_NUM] __attribute__((aligned(0x400))) = {0};

/*************************************************************************************************************************
*
* @brief      This demo show how to setup a project to write/erase flash, which may be break-in by interrupt.
*
*************************************************************************************************************************/

int main()
{
    ErrorStatus es;

    FLASH_WALLOW();

#if defined(SPC1158)
    FLASH_SetTiming(100000000);

    CLOCK_InitWithRCO(100000000UL);
#else
    FLASH_SetTiming(200000000);

    CLOCK_InitWithRCO(200000000UL);
#endif

    Delay_Init();

    /*
     * Init the UART
     *
     * 1.Set the GPIO34/35 as UART FUNC
     *
     * 2.Enable the UART CLK
     *
     * 3.Set the rest para
     */
    GPIO_SetPinChannel(GPIO_34, GPIO34_UART_TXD);
    GPIO_SetPinChannel(GPIO_35, GPIO35_UART_RXD);
    CLOCK_EnableModule(UART_MODULE);
    UART_Init(UART, 38400);

    printf("test .....\n");
    /* Copy vector table to RAM */
    for(u32VectorCnt = 0; u32VectorCnt < VECTOR_NUM; u32VectorCnt++)
    {
        u32aRAMVector[u32VectorCnt] = *((volatile uint32_t *)(VectorTableLoadAddr + u32VectorCnt * 4));
    }
    /* Redirection the Vector Address */

    SCB->VTOR = (uint32_t)u32aRAMVector;
    printf("Exception vector table Addr is : %x\n", SCB->VTOR);

    /* Open Global INT for TIMER1 */
    NVIC_EnableIRQ(TIMER1_IRQn);
    
    /* Init TIMER1 */
    TIMER_Init(TIMER1, TimerPeriodCount);

    while(1)
    {
        printf("Erase Start (Round %d)...\n", u32Count);
        /* When Erase Flash, XIP Will be Closed, In order to make MCU Fetch Instruction
           Normally, we Must Put Flash Driver Code into RAM in .icf file*/
        es = FLASH_EraseSector(OperationADDR);
        if (es == ERROR)
        {
            printf("flash erase fail\n");
            return 0;
        }

        u32Count++;
        printf("Erase End...\n");
    }
}

/* If the project is IAR Project, use '__ramfunc' direction letting the func running
    in ram address region. But '__ramfunc' is not usefully in KEIL project, So we must
    use .sct file to put 'main.o' in ram region for KEIL project. */
_RAM_FUNC_ void TIMER1_IRQHandler(void)
{
    /* When Erase Flash, XIP Will be Closed, At that moment, If TIMER1 Interrupt
      Happened, MCU will go to Fetch TIMER Driver Code,So we Must Put TIMER Driver
      Code into RAM in .icf file*/
    /* Clear the INT */
    TIMER_ClearInt(TIMER1);
}


