
#include "t1001.h"
#include "system.h"

#if !(defined(OMW_BLE_ONLY_V0)) // && !defined(OMW_HAS_SCH))
// volatile uint8_t  g_is_in_critical;
volatile uint8_t  g_is_in_irq_flag;
#endif

int main(void);

void ram_init(void);
void SystemInit (void);
void Default_Handler(void);

void SoftIrq_Handler        (void) __attribute__ ((weak, alias("Default_Handler")));
void ExtIrq_Handler         (void) __attribute__ ((weak, alias("Default_Handler")));
void SysTick_Handler        (void) __attribute__ ((weak, alias("Default_Handler")));

void WDT_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void Interrupt1_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
//extern void RADIO_DMA_Handler     (void);
void RADIO_DMA_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void RADIO_TICK_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void Interrupt4_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void Interrupt5_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void Interrupt6_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void Interrupt7_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));

void UART0_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void UART1_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void SPIM0_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void SPIM1_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void I2C0_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void Interrupt13_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void SPIS0_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void USB_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void GPIO_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void QDEC_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void AES_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void CAPTURE_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void CLKCAL_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));

void RTC_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void SDMA_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void Interrupt23_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));

void TIMER0_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void TIMER1_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void TIMER2_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void TIMER3_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void TIMER4_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void TIMER5_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void TIMER6_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void TIMER7_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));

#ifndef OMW_USE_STATIC_IRQ_TBL
#define MAX_IRQ_ID  TIMER7_IRQn

VECTOR_TABLE_Type __VECTOR_TABLE[MAX_IRQ_ID + 1] __attribute__((aligned(64)));

#define ADD_IRQ_HANDLE(irq_id, handle)    __VECTOR_TABLE[irq_id] = handle
static void irq_handle_init()
{
    ADD_IRQ_HANDLE(RADIO_DMA_IRQn, RADIO_DMA_Handler);
    ADD_IRQ_HANDLE(RADIO_TICK_IRQn, RADIO_TICK_Handler);
    ADD_IRQ_HANDLE(UART1_IRQn, UART1_Handler);
    ADD_IRQ_HANDLE(RTC_IRQn, RTC_Handler);
	ADD_IRQ_HANDLE(TIMER1_IRQn, TIMER1_Handler);
	ADD_IRQ_HANDLE(TIMER7_IRQn, TIMER7_Handler);
}
#else
//MAX 48
VECTOR_TABLE_Type __VECTOR_TABLE[] __attribute__((aligned(64))) =
{
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    SoftIrq_Handler,                          /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    SysTick_Handler,                          /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    ExtIrq_Handler,                           /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */
    0,                                        /*     Reserved */

    /* Interrupts */
    WDT_Handler,                                /*   0 Interrupt 0 */
    Interrupt1_Handler,                         /*   1 Interrupt 1 */
    RADIO_DMA_Handler,                          /*   2 Interrupt 2 */
    RADIO_TICK_Handler,                         /*   3 Interrupt 3 */
    Interrupt4_Handler,                         /*   4 Interrupt 4 */
    Interrupt5_Handler,                         /*   5 Interrupt 5 */
    Interrupt6_Handler,                         /*   6 Interrupt 6 */
    Interrupt7_Handler,                         /*   7 Interrupt 7 */
    UART0_Handler,                              /*   8 Interrupt 8 */
    UART1_Handler,                              /*   9 Interrupt 9 */
    SPIM0_Handler,                              /*   10 Interrupt 10 */
    SPIM1_Handler,                              /*   11 Interrupt 11 */
    I2C0_Handler,                               /*   12 Interrupt 12 */
    Interrupt13_Handler,                        /*   13 Interrupt 13 */
    SPIS0_Handler,                              /*   14 Interrupt 14 */
    USB_Handler,                                /*   15 Interrupt 15 */
    GPIO_Handler,                               /*   16 Interrupt 16 */
    QDEC_Handler,                               /*   17 Interrupt 17 */
    AES_Handler,                                /*   18 Interrupt 18 */
    CAPTURE_Handler,                            /*   19 Interrupt 19 */
    CLKCAL_Handler,                             /*   20 Interrupt 20 */
    RTC_Handler,                                /*   21 Interrupt 21 */
    SDMA_Handler,                               /*   22 Interrupt 22 */
    Interrupt23_Handler,                        /*   23 Interrupt 23 */
    TIMER0_Handler,                             /*   24 Interrupt 24 */
    TIMER1_Handler,                             /*   25 Interrupt 25 */
    TIMER2_Handler,                             /*   26 Interrupt 26 */
    TIMER3_Handler,                             /*   27 Interrupt 27 */
    TIMER4_Handler,                             /*   28 Interrupt 28 */
    TIMER5_Handler,                             /*   29 Interrupt 29 */
    TIMER6_Handler,                             /*   30 Interrupt 30 */
    TIMER7_Handler,                             /*   31 Interrupt 31 */
};
#endif

void clic_init()
{
    int i;
    CLIC->CLICCFG = (((CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos) << CLIC_CLICCFG_NLBIT_Pos);

    for (i = 0; i < 48; i++) {
        CLIC->CLICINT[i].IP = 1;
        CLIC->CLICINT[i].IE = 0;
        CLIC->CLICINT[i].ATTR = 1; /* use vector interrupt */
    }

    #ifndef OMW_USE_STATIC_IRQ_TBL
    irq_handle_init();
    #endif
}

void sys_entry()
{
    ram_init();

    clic_init();

    SystemInit();

    GLOBAL_INT_START();

    main();
}

void Default_Handler(void)
{
    GLOBAL_INT_STOP();

    while(1);
}

void
omw_hw_chk_and_en_irq(void)
{
    //work round: for irq issue
    uint32_t result;
    result = __get_MSTATUS();

    if ((result & INTE_EN) == 0){
        __enable_irq();
    }
}

// uint32_t
// omw_hw_enter_critical(void)
// {
//     uint32_t rlt = ENTER_CRITICAL_SECTION();
//     g_is_in_critical++;
//     return rlt;
// }

// void
// omw_hw_exit_critical(uint32_t ctx)
// {
//     g_is_in_critical--;
//     if ((ctx & INTE_EN) != 0){
//         EXIT_CRITICAL_SECTION(ctx);
//     }
//     //work round: first layer, and not in irq context
//     else if (g_is_in_critical == 0 && 0 == g_is_in_irq_flag){
//         __enable_irq();
//     }
// }