#include "stm32f4xx.h"
#include "wdg.h"
#include "FreeRTOS.h"
#include "task.h"
#include "common_config.h"
#include "settings_api.h"
#include "cJSON.h"

#include "gpio.h"

#include "main.h"
#include "init_task.h"
#include "log.h"

#include "spi_flash.h"


static cJSON_Hooks cjson_hooks = {
    pvPortMalloc,
    vPortFree
};

// crude libc compatibility
int __errno;

/* Размещение стека FreeRTOS в CCRAM */
#if defined ( __ICCARM__ )
#pragma location = ".sram"
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".mb1text")));
/* Секция размещения СRC прошивки */
uint32_t crc __attribute__ ((section (".crc"))) = 0xAABBCCDD;
/* Секция размещения HW ревизии платы */
char hw_rev[HW_REV_LEN] __attribute__ ((section (".hw_rev"))) = HW_REV;
#endif


void vApplicationTickHook(void)
{
}

int main()
{
    TIM_Cmd(TIM13, DISABLE);
    TIM_ClearITPendingBit(TIM13, TIM_IT_Update);

    __disable_irq();
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x20000);
    NVIC_SetPriorityGrouping(0);
    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
    __enable_irq();

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);

    /* Clear flash error flags if were set */
    FLASH_ClearFlag(FLASH_FLAG_PGPERR);
    FLASH_ClearFlag(FLASH_FLAG_PGSERR);

#ifndef DEBUG
    if (FLASH_OB_GetRDP() != SET) {
        FLASH_Unlock();                           // this line is critical!
        FLASH_OB_Unlock();
        FLASH_OB_RDPConfig(OB_RDP_Level_1);
        FLASH_OB_Launch();                        // Option Bytes programming
        FLASH_OB_Lock();
        FLASH_Lock();
    }
#endif

    cJSON_InitHooks(&cjson_hooks);

    gpio_init();

    WDG_Init();

    spi_flash_init();
    //log_init(false);
    //log_test();
    //spi_flash_test();
    //  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    init_settings();

    xTaskCreate( InitTask, "InitTask", 1000, NULL, tskIDLE_PRIORITY, NULL);
  //  xTaskCreate( InitTask, "InitTask", 6000, NULL, tskIDLE_PRIORITY, NULL);

    vTaskStartScheduler();

    return 0;
    /*while(1)
    {

    }*/

}