main.c 7.0 KB

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