main.c 4.4 KB

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