main.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "main.h"
  2. #include "common_config.h"
  3. void soft_wdt(void *params);
  4. void init_task(void *params);
  5. void led_task(void *params);
  6. bool jump_to_app(uint32_t address);
  7. void (*pftarget)(void);
  8. bool boot_failed = false;
  9. int main()
  10. {
  11. uint8_t load_mode;
  12. uint8_t boot_try;
  13. uint8_t fw_invalid = 0;
  14. nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  15. crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  16. crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  17. crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
  18. crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
  19. crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
  20. crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  21. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
  22. crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
  23. pwc_battery_powered_domain_access(TRUE);
  24. system_clock_config();
  25. delay_init();
  26. uart_print_init(115200);
  27. // Флаг - нужно ли обновляться
  28. load_mode = bpr_data_read(BACKUP_IAP_LOAD_MODE);
  29. // Число попыток загрузки основного ПО
  30. boot_try = bpr_data_read(BACKUP_IAP_BOOT_TRY);
  31. DBG printf("[IAP] load_mode: %u, boot_try: %u\r\n", load_mode, boot_try);
  32. // Если есть попытки, то пытаемся загрузить FW.
  33. // Используем ограниченное число попыток загрузить основное FW.
  34. if (boot_try > 1)
  35. {
  36. boot_try--;
  37. bpr_data_write(BACKUP_IAP_BOOT_TRY, boot_try);
  38. if (!jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS))
  39. {
  40. // Флеш пустая. Нечего загружать
  41. fw_invalid = 1;
  42. boot_failed = false;
  43. DBG printf("FW empty! Bootloader starting...\n\r");
  44. }
  45. }
  46. else if (boot_try == 1)
  47. {
  48. boot_failed = true;
  49. DBG printf("FW boot failed. Bootloader starting...\r\n");
  50. load_mode = 1;
  51. boot_try = 0;
  52. bpr_data_write(BACKUP_IAP_LOAD_MODE, load_mode);
  53. bpr_data_write(BACKUP_IAP_BOOT_TRY, boot_try);
  54. }
  55. if ((load_mode == 0) && (!fw_invalid))
  56. {
  57. DBG printf("Run main FW\r\n");
  58. bpr_data_write(BACKUP_IAP_BOOT_TRY, BOOT_TRY);
  59. DBG printf("Go to main FW...\r\n");
  60. jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS);
  61. }
  62. DBG printf("IAP starting...\r\n");
  63. // -------------------------------------------------------------------------- //
  64. // Мультиплексор
  65. mux_gpio_init();
  66. #if 0
  67. // -------------------------------------------------------------------------
  68. // Для теста. Сброс.
  69. DBG printf("For test reset load_mode flag and jump to FW\r\n");
  70. bpr_data_write(BACKUP_IAP_LOAD_MODE, 0);
  71. jump_to_app(0x08021000);
  72. #endif
  73. gpio_wdt_init();
  74. gpio_mbaddr_init();
  75. taskENTER_CRITICAL();
  76. xTaskCreate(soft_wdt, "soft_wdt", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
  77. xTaskCreate(init_task, "init_task", 10*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
  78. xTaskCreate(led_task, "led_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
  79. taskEXIT_CRITICAL();
  80. vTaskStartScheduler();
  81. while (1) {}
  82. }
  83. //
  84. bool jump_to_app(uint32_t address)
  85. {
  86. uint32_t stkptr, jumpaddr;
  87. stkptr = *(uint32_t *)address;
  88. jumpaddr = *(uint32_t *)(address + sizeof(uint32_t));
  89. //if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x20000000) == 0x20000000)
  90. if (*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS != 0xFFFFFFFF)
  91. {
  92. __set_MSP(stkptr);
  93. pftarget = (void (*) (void))jumpaddr;
  94. pftarget();
  95. }
  96. return false;
  97. }
  98. //
  99. void soft_wdt(void *params)
  100. {
  101. (void)params;
  102. for (;;)
  103. {
  104. extern_wdt_togle(); // extern WDT
  105. vTaskDelay(500);
  106. }
  107. }
  108. //
  109. void init_task(void *params)
  110. {
  111. (void)params;
  112. crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE);
  113. init_settings();
  114. settings_load(&settings);
  115. mb_init();
  116. for (;;)
  117. {
  118. vTaskDelay(500);
  119. }
  120. }
  121. //
  122. void led_task(void *params)
  123. {
  124. for (;;) {
  125. mux_led_proc();
  126. }
  127. }
  128. //
  129. void USART1_IRQHandler(void)
  130. {
  131. char data = 0;
  132. if (USART1->ctrl1_bit.rdbfien == SET)
  133. {
  134. if (usart_flag_get(USART1, USART_RDBF_FLAG) == SET)
  135. {
  136. data = usart_data_receive(USART1);
  137. }
  138. }
  139. }