main.c 7.0 KB

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