main.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #include "stm32f4xx.h"
  2. #include "common_config.h"
  3. #include "main.h"
  4. #include "led.h"
  5. #include "systick.h"
  6. #include "usart.h"
  7. #include "httpserver.h"
  8. #include "flash_if.h"
  9. #include "settings_api.h"
  10. #include "gpio_io.h"
  11. #include "crc.h"
  12. #include "wdg.h"
  13. #include "tinystdio.h"
  14. #include "time.h"
  15. #include "string.h"
  16. #include "stm32f4x7_eth.h"
  17. #include "netconf.h"
  18. #define FW_FILE_NAME "stm32prs.bin"
  19. bool IAPviaETH = false;
  20. uint8_t fDoneReset = 0;
  21. uint8_t fErrorReset = 0;
  22. uint8_t fUpload = 0;
  23. uint8_t fInvalidFw = 0;
  24. uint8_t fBootFailed = 0;
  25. uint32_t resetCounter = 0;
  26. bool UpdateTimeoutFlag = false;
  27. /* this variable is used to create a time reference incremented by 10ms */
  28. __IO uint32_t LocalTime = 0;
  29. pFunction Jump_To_App;
  30. uint32_t JumpAdd;
  31. /**
  32. * @brief Общая структура настроек
  33. */
  34. extern SETTINGS_t sSettings;
  35. void UpdateTimeout_Handler(void);
  36. void main(void)
  37. {
  38. uint8_t bootTry;
  39. uint8_t loadMode;
  40. WDG_Init();
  41. IO_Init();
  42. InitUSART();
  43. /* Enable PWR peripheral clock */
  44. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  45. /* Allow access to BKP Domain */
  46. PWR_BackupAccessCmd(ENABLE);
  47. /* Включаем тактирование модуля CRC */
  48. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  49. /* Проверка флага, определяющего состояние устройства. */
  50. /* Флаг установлен - работает Bootloader */
  51. /* Флаг сброшен - запускается основная программа */
  52. SETTINGS_Load();
  53. /* Проверка флага bootTry. Если флаг установлен, значит произошел сбой в
  54. основной прошивке. Нужно загружать bootloader и ждать обновления ПО */
  55. /* TODO remove if tested */
  56. //bootTry = sSettings.bootParams.bootTry;
  57. loadMode = RTC_ReadBackupRegister(RTC_BKP_DR1);
  58. bootTry = RTC_ReadBackupRegister(RTC_BKP_DR2);
  59. printf("loadMode: %d\r\nbootTry: %d\r\n", loadMode, bootTry);
  60. if (bootTry > 1)
  61. {
  62. bootTry--;
  63. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  64. /* Check if valid stack address (RAM address) then jump to user application */
  65. if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
  66. {
  67. JumpAdd = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  68. Jump_To_App = (pFunction) JumpAdd;
  69. __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
  70. Jump_To_App();
  71. }
  72. else {
  73. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  74. fInvalidFw = 1;
  75. PRINT_USART("\n\rFW empty. Started bootloader\n\r");
  76. }
  77. }
  78. else if (bootTry == 1)
  79. {
  80. fBootFailed = 1;
  81. PRINT_USART("\n\rFW boot failed. Started bootloader\n\r");
  82. bootTry = 0;
  83. loadMode = 1;
  84. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  85. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  86. }
  87. /* Флаг не установлен прыгаем на основную программу */
  88. if (loadMode == 0)
  89. {
  90. printf("Run main FW\n\r");
  91. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS) = 0x%X\n\r", *(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS);
  92. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4) = 0x%X\n\r", *(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4));
  93. /* Set bootTry flag every time to ensure that
  94. * IAP will starts again if FW is corrupted */
  95. bootTry = BOOT_TRY;
  96. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  97. /* Check if valid stack address (RAM address) then jump to user application */
  98. if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
  99. {
  100. /* Jump to user application */
  101. JumpAdd = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  102. Jump_To_App = (pFunction) JumpAdd;
  103. /* Initialize user application's Stack Pointer */
  104. __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
  105. Jump_To_App();
  106. }
  107. }
  108. /* Загружается Bootloader... */
  109. SysTick_Config(120000);
  110. LED_Init();
  111. PRINT_USART("\n\rBootloader starting... \n\r");
  112. LED_On(RED_STATUS);
  113. ETH_BSP_Config();
  114. LwIP_Init();
  115. IAP_httpd_init();
  116. CRC_Init();
  117. //Если нажата DEF начинаем обновление с sd
  118. if (IO_BtnDefaultPressed())
  119. {
  120. // IAPviaETH = false;
  121. // timer_AddFunction(500, &LED_Blinky_Yellow);
  122. // SD_NVIC_Init();
  123. } else {
  124. IAPviaETH = true;
  125. timer_AddFunction(500, &LED_Blinky_Green);
  126. }
  127. /* Check if valid stack address (RAM address) */
  128. if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000) {
  129. timer_AddFunction(1000, &UpdateTimeout_Handler);
  130. }
  131. else {
  132. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  133. fInvalidFw = 1;
  134. }
  135. while (1)
  136. {
  137. timer_Main();
  138. if (IAPviaETH) { // Обновление по ETH
  139. /* check if any packet received */
  140. if (ETH_CheckFrameReceived())
  141. {
  142. /* process received ethernet packet */
  143. LwIP_Pkt_Handle();
  144. }
  145. /* handle periodic timers for LwIP */
  146. LwIP_Periodic_Handle(LocalTime);
  147. if (fDoneReset)
  148. {
  149. resetCounter++;
  150. if (resetCounter > 100000)
  151. {
  152. loadMode = 0;
  153. bootTry = BOOT_TRY;
  154. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  155. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  156. /* Set FW update flag */
  157. RTC_WriteBackupRegister(RTC_BKP_DR3, 1);
  158. NVIC_SystemReset();
  159. }
  160. }
  161. if (fErrorReset)
  162. {
  163. resetCounter++;
  164. if (resetCounter > 100000) {
  165. NVIC_SystemReset();
  166. }
  167. }
  168. }
  169. //Если нажата DEF переходим в основную прошивку
  170. if (IO_BtnDefaultPressed() || UpdateTimeoutFlag)
  171. {
  172. if (!fUpload && ((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) != 0xFFFFFFFF)) {
  173. PRINT_USART("\n\rUpdate timeout... Return to main FW\n\r");
  174. loadMode = 0;
  175. bootTry = BOOT_TRY;
  176. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  177. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  178. NVIC_SystemReset();
  179. }
  180. }
  181. }
  182. }
  183. /**
  184. * @brief Updates the system local time
  185. * @param None
  186. * @retval None
  187. */
  188. void Time_Update(void)
  189. {
  190. LocalTime += SYSTEMTICK_PERIOD_MS;
  191. }
  192. /**
  193. * @brief
  194. */
  195. u32_t sys_now(void) {
  196. return LocalTime;
  197. }
  198. /**
  199. * @brief Error handler
  200. * @param None
  201. * @retval None
  202. */
  203. void Error_Handler(void) {
  204. LED_Off(RED_STATUS);
  205. LED_Off(GREEN_STATUS);
  206. timer_AddFunction(500, &LED_Blinky_Red);
  207. while (1)
  208. {
  209. timer_Main();
  210. }
  211. }
  212. /**
  213. * @brief
  214. */
  215. void UpdateTimeout_Handler(void)
  216. {
  217. static char lcdbuf[32] = {0};
  218. static uint8_t time = UPDATE_TIMEOUT;
  219. if ((fUpload) || (fInvalidFw)) return;
  220. if (time == 0) {
  221. UpdateTimeoutFlag = true;
  222. }
  223. else {
  224. time--;
  225. }
  226. }