#include "main.h"
#include "serial.h"


static inline void rcc_init(void)
{
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB |RCC_AHBPeriph_EFLS, ENABLE);

   RCC_APB0PeriphClockCmd(RCC_APB0Periph_USART1, ENABLE);

}

static void jump2app(void)
{
    static uint32_t func;
    uint32_t stack = *(uint32_t *)APP_ADDR;
    func = *(uint32_t *)(APP_ADDR + 4);

    SysTick->CTRL = 0; // disable systick irq
    printf("j app ...\n");

    __set_MSP(stack); // init stack pointer
    ((void(*)()) func)();
    while (true);
}

void Systic_notirq(uint32_t ticks)
{
    SysTick->LOAD = (uint32_t)(ticks - 1UL);
    SysTick->VAL = 0UL;
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; 
}

int main(void)
{
    SetSysClock();
    rcc_init();
    printf("bl start ...\n");
    load_conf(); 
    serial_init();
    Systic_notirq(84000);



    csa.keep_bl = *(uint32_t *)BL_ARGS == 0xcdcd0001 | !app_valid();
    printf("bl %x %X\n", (uint16_t)csa.conf_from, *(uint32_t *)BL_ARGS);

    while (true)
    {
        if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)
        {
            systick++;
            Systic_notirq(84000);
        }
        
        serial_task();
        if (!csa.keep_bl && get_systick() > 500)
            jump2app();

        if (csa.do_reboot){
            NVIC_SystemReset();
        }

        if (csa.save_conf)
        {
            csa.save_conf = false;
            save_conf();
        }
    }
}


#if defined(__GNUC__) // make gcc happy
int _write(int file, char *data, int len)
{
    return len;
}
int _read(int file, char *ptr, int len)
{
    return len;
}
int _close(int file)
{
    return -1;
}
int _fstat(int file, void *st)
{
    return -1;
}
int _isatty(int file)
{
    return 1;
}
int _lseek(int file, int ptr, int dir)
{
    return 0;
}
#endif
