| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 | #include "main.h"#include "common_config.h"#include "utility.h"#include "model_cfg.h"#include "digital_output.h"void soft_wdt(void *params);void init_task(void *params);void led_task(void *params);bool jump_to_app(uint32_t address);void (*pftarget)(void);bool boot_failed = false;int main(){    uint8_t load_mode;	uint8_t boot_try;	uint8_t fw_invalid = 0;        nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);        crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);        crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);    crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);    crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);    pwc_battery_powered_domain_access(TRUE);        system_clock_config();        delay_init();        // Флаг - нужно ли обновляться    load_mode = bpr_data_read(BACKUP_IAP_LOAD_MODE);        // Число попыток загрузки основного ПО    boot_try = bpr_data_read(BACKUP_IAP_BOOT_TRY);#if 0        //DBG printf("[IAP] load_mode: %u, boot_try: %u\r\n", load_mode, boot_try);    // Если есть попытки, то пытаемся загрузить FW.	// Используем ограниченное число попыток загрузить основное FW.    if (boot_try > 1)    {        boot_try--;        bpr_data_write(BACKUP_IAP_BOOT_TRY, boot_try);                if (!jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS))        {            // Флеш пустая. Нечего загружать            fw_invalid = 1;            boot_failed = false;            //DBG printf("FW empty! Bootloader starting...\n\r");        }    }    else if (boot_try == 1)    {        boot_failed = true;        //DBG printf("FW boot failed. Bootloader starting...\r\n");                load_mode = 1;        boot_try = 0;        bpr_data_write(BACKUP_IAP_LOAD_MODE, load_mode);        bpr_data_write(BACKUP_IAP_BOOT_TRY, boot_try);    }        if  ((load_mode == 0) && (!fw_invalid))    {        //DBG printf("Run main FW\r\n");        bpr_data_write(BACKUP_IAP_BOOT_TRY, BOOT_TRY);        //DBG printf("Go to main FW...\r\n");        jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS);    }#endif         // Модуль MDIO_88 должен поддерживать работу выходов при работе в IAP    if (get_mode_from_flash() == MODEL_MDIO_88)    {        crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE);        settings_load(&settings);        //settings_set_modbus_params(settings.com_settings.mb_port);        do_init();    }        uart_print_init(115200);        DBG printf("IAP starting...\r\n");            // -------------------------------------------------------------------------        // Мультиплексор        mux_gpio_init();    #if 0        // -------------------------------------------------------------------------    // Для теста. Сброс.    DBG printf("For test reset load_mode flag and jump to FW\r\n");    bpr_data_write(BACKUP_IAP_LOAD_MODE, 0);    jump_to_app(0x08021000); #endif        gpio_wdt_init();    gpio_mbaddr_init();    taskENTER_CRITICAL();              xTaskCreate(soft_wdt, "soft_wdt", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);            xTaskCreate(init_task, "init_task", 10*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);        xTaskCreate(led_task, "led_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);        taskEXIT_CRITICAL();        vTaskStartScheduler();    while (1) {}}// bool jump_to_app(uint32_t address){    uint32_t stkptr, jumpaddr;    stkptr = *(uint32_t *)address;    jumpaddr = *(uint32_t *)(address + sizeof(uint32_t));     //if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x20000000) == 0x20000000)     if  (*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS != 0xFFFFFFFF)     {        __set_MSP(stkptr);        pftarget = (void (*) (void))jumpaddr;        pftarget();    }    return false;}//void soft_wdt(void *params){    (void)params;        for (;;)    {        extern_wdt_togle(); // extern WDT        vTaskDelay(500);    }}//void init_task(void *params){    (void)params;        crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE);        init_settings();    settings_load(&settings);            mb_init();        for (;;)    {              vTaskDelay(500);    }}//void led_task(void *params){    for (;;) {        mux_led_proc();    }}//void USART1_IRQHandler(void){    char data = 0;          if (USART1->ctrl1_bit.rdbfien == SET)    {        if (usart_flag_get(USART1, USART_RDBF_FLAG) == SET)         {            data = usart_data_receive(USART1);        }    }  }
 |