main.c 5.0 KB

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