| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 | 
							- #include "stm32f4xx.h"
 
- #include "common_config.h"
 
- #include "conf.h"
 
- #include "main.h"
 
- #include "led.h"
 
- #include "systick.h"
 
- #include "usart.h"
 
- #include "httpserver.h"
 
- #include "flash_if.h"
 
- #include "settings_api.h"
 
- #include "gpio_io.h"
 
- #include "gpio.h"
 
- #include "crc.h"
 
- #include "wdg.h"
 
- #include "tinystdio.h"
 
- #include "time.h"
 
- #include "string.h"
 
- #include "stm32f4x7_eth.h"
 
- #include "netconf.h"
 
- #include "rng.h"
 
- #ifdef SD_ENABLE
 
- #include "SD_Card/sdio_sd.h"
 
- #include "FATFS/ff.h"
 
- #include "FATFS/diskio.h"
 
- #endif
 
- #ifdef LCD_ENABLE
 
- #include "lcd.h"
 
- #endif
 
- #ifdef SLAVEBRD_ENABLE
 
- #include "stm32sprog.h"
 
- #endif
 
- #ifdef FTP_ENABLE
 
- #include "spi_flash.h"
 
- #endif
 
- /* Секция размещения СRC прошивки */
 
- #if defined ( __GNUC__ )
 
- uint32_t crc __attribute__ ((section (".crc"))) = 0xAABBCCDD;
 
- #endif
 
- #define FW_FILE_NAME    MAIN_FW_NAME
 
- /*
 
-  * Bootloader verification key section.
 
-  * Use "openssl rand -hex 8" to generate new key.
 
-  * */
 
- uint64_t bootkey __attribute__ ((section (".bootkey"))) = 0x92dc73b8fef3b041;
 
- bool IAPviaETH = false;
 
- bool fDoneReset = false;
 
- bool fUpload = false;
 
- bool fInvalidFw = false;
 
- bool fBootFailed = false;
 
- volatile uint32_t resetCounter = 0;
 
- bool UpdateTimeoutFlag = false;
 
- #ifdef SD_ENABLE
 
- extern FATFS    fs;
 
- extern FIL      fil_obj;
 
- #endif
 
- /* this variable is used to create a time reference incremented by 10ms */
 
- __IO uint32_t LocalTime = 0;
 
- pFunction Jump_To_App;
 
- uint32_t JumpAdd;
 
- /**
 
-   * @brief  Общая структура настроек
 
-   */
 
- extern SETTINGS_t sSettings;
 
- void UpdateTimeout_Handler(void);
 
- #ifdef SD_ENABLE
 
- bool mmc_mount(void)
 
- {
 
-     if (disk_initialize(0) != RES_OK) return false;
 
-     if (f_mount(&fs, "0:", 1) != FR_OK) return false;
 
-     return true;
 
- }
 
- #endif
 
- bool CheckFWIsValid(void)
 
- {
 
- 	if (((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000 &&
 
-         *(__IO uint32_t *)USER_FLASH_CRC_ADDRESS != 0xFFFFFFFF) {
 
-         return true;
 
-     }
 
-     printf("\r\nFW empty. Started bootloader\r\n");
 
-     return false;
 
- }
 
- #ifdef FTP_ENABLE
 
- void  spi_flash_update(void)
 
- {
 
-   printf("ftp: trying to update the firmware from the SPI flash\r\n");
 
-   const uint32_t spif_firmware_offset = SPI_FLASH_SECTOR_SIZE * FIRMWARE_UPDATE_SECTOR_OFFSET;
 
-   uint32_t fw_begin;
 
-   spi_flash_init();
 
-   spi_flash_read(spif_firmware_offset, &fw_begin, 4, 0);
 
-   const uint32_t crc_offset = USER_FLASH_CRC_ADDRESS - USER_FLASH_FIRST_PAGE_ADDRESS;
 
-   uint32_t expected_crc;
 
-   spi_flash_read(spif_firmware_offset + crc_offset, &expected_crc, 4, 0);
 
-   bool present_firmware = (fw_begin != 0xFFFFFFFF) || (expected_crc != 0xFFFFFFFF);
 
-   if (!present_firmware) {
 
-     printf("ftp: no firmware-like data is present on the SPI flash\r\n");
 
-     return;
 
-   }
 
-   // check CRC
 
-   CRC->CR = 1;
 
-   for (uint32_t offset = 0; offset < crc_offset; offset += 4) {
 
-     uint32_t data;
 
-     spi_flash_read(spif_firmware_offset + offset, &data, sizeof(data), 0);
 
-     CRC->DR = data;
 
-   }
 
-   uint32_t calculated_crc = CRC->DR;
 
-   if (expected_crc != calculated_crc) {
 
-     printf("ftp: calculated CRC (%lx) doesn't match the expected CRC (%lx)!\r\n", calculated_crc, expected_crc);
 
-     return;
 
-   }
 
-   printf("ftp: writing the stm32 flash\r\n");
 
-   FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS);
 
-   FLASH_If_Init(); // unlock it again
 
-   uint8_t buf[1024];
 
-   for (uint32_t offset = 0; offset < MAIN_FW_SIZE; offset += sizeof(buf)) {
 
-     spi_flash_read(spif_firmware_offset + offset, buf, sizeof(buf), 0);
 
-     uint8_t *addr = USER_FLASH_FIRST_PAGE_ADDRESS + offset;
 
-     FLASH_If_Write(&addr, buf, sizeof(buf) / 4);
 
-   }
 
-   printf("ftp: erasing the SPI flash\r\n");
 
-   for (int sec = 0; sec < FIRMWARE_UPDATE_SECTOR_COUNT; ++sec) {
 
-     spi_flash_erase_sector(SPI_FLASH_SECTOR_SIZE * (FIRMWARE_UPDATE_SECTOR_OFFSET + sec), 0);
 
-   }
 
-   printf("ftp: update successful, rebooting...\r\n");
 
-   SET_FWUPDATED_FLAG();
 
-   CLEAR_FWINVALID_FLAG();
 
-   RTC_WriteBackupRegister(RTC_BKP_DR1, 0); // loadMode
 
-   NVIC_SystemReset();
 
- }
 
- #endif // FTP_ENABLE
 
- void main(void)
 
- {
 
-   	uint8_t bootTry;
 
-   	uint8_t loadMode;
 
-     gpio_init();
 
-     WDG_Init();
 
-     InitUSART();
 
- #ifdef PRINTF_STDLIB
 
-     setvbuf(stdin, NULL, _IONBF, 0);
 
-     setvbuf(stdout, NULL, _IONBF, 0);
 
-     setvbuf(stderr, NULL, _IONBF, 0);
 
- #endif
 
-   /* Enable PWR peripheral clock */
 
-   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
 
-   /* Allow access to BKP Domain */
 
-   PWR_BackupAccessCmd(ENABLE);
 
-   /* Включаем тактирование модуля CRC */
 
-   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
 
-   
 
-   /* Проверка флага, определяющего состояние устройства. */
 
-   /* Флаг установлен - работает Bootloader               */
 
-   /* Флаг сброшен - запускается основная программа       */
 
-   SETTINGS_Load();
 
-   
 
-   /* Проверка флага bootTry. Если флаг установлен, значит произошел сбой в 
 
-      основной прошивке. Нужно загружать bootloader и ждать обновления ПО */
 
-   loadMode = RTC_ReadBackupRegister(RTC_BKP_DR1);
 
-   bootTry = RTC_ReadBackupRegister(RTC_BKP_DR2);
 
-   fInvalidFw = RTC_ReadBackupRegister(RTC_BKP_DR7);
 
-   printf("\r\nloadMode: %d\r\nbootTry: %d\r\n", loadMode, bootTry);
 
-   printf("fInvalidFw: %s\r\n", fInvalidFw ? "true" : "false");
 
-   
 
-   if (bootTry > 1) {
 
-       bootTry--;
 
-       RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
 
-       /* Check if valid stack address (RAM address) then jump to user application */
 
-       if (CheckFWIsValid()) {
 
-           CLEAR_FWINVALID_FLAG();
 
-           /* Jump to user application */
 
-           JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
 
-           Jump_To_App = (pFunction) JumpAdd;
 
-           /* Initialize user application's Stack Pointer */
 
-           __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
 
-           Jump_To_App();
 
-       } else {
 
-           /* Флеш пустая, нечего загружать, висим в аварийном режиме */
 
-           SET_FWINVALID_FLAG();
 
-       }
 
-   } else if (bootTry == 1) {
 
-       fBootFailed = 1;
 
-       printf("\r\nFW boot failed. Started bootloader\r\n");
 
-       bootTry = 0;
 
-       loadMode = 1;
 
-       RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
 
-       RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
 
-   }
 
-   /* Флаг не установлен прыгаем на основную программу */
 
-   if (loadMode == 0) {
 
-       printf("Run main FW\r\n");
 
-       //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS) = 0x%X\r\n", *(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS);
 
-       //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4) = 0x%X\r\n", *(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4));
 
-       /* Set bootTry flag every time to ensure that
 
-         * IAP will starts again if FW is corrupted */
 
-       bootTry = BOOT_TRY;
 
-       RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
 
-       /* Check if valid stack address (RAM address) then jump to user application */
 
-       if (CheckFWIsValid()) {
 
-           CLEAR_FWINVALID_FLAG();
 
-           /* Jump to user application */
 
-           JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
 
-           Jump_To_App = (pFunction) JumpAdd;
 
-           /* Initialize user application's Stack Pointer */
 
-           __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
 
-           Jump_To_App();
 
-       }
 
-   }
 
-   
 
-   /* Загружается Bootloader... */
 
-   
 
-   SysTick_Config(168000);//120000
 
-   LED_Init();
 
-   LED_On(LED_INIT_ERR);
 
-   PRINT_USART("\n\rBootloader starting...   \n\r");
 
- #ifdef LCD_ENABLE
 
-     LCD_Init();
 
-     LCD_PrintAligned(1, alignCENTER, "Обновление ПО");
 
- #endif
 
-   /* Random number generator */
 
-   RNG_Init();
 
-   ETH_BSP_Config();
 
-   LwIP_Init();
 
-   IAP_httpd_init();
 
-   CRC_Init();
 
-   //Если нажата DEF начинаем обновление с sd
 
-   if (IO_BtnDefaultPressed()) {
 
- #ifdef SD_ENABLE
 
-       IAPviaETH = false;
 
-       timer_AddFunction(500, &LED_Blinky_Red);
 
-       SD_NVIC_Init();
 
- #endif
 
-   } else {
 
-       IAPviaETH = true;
 
-       timer_AddFunction(500, &LED_Blinky_Red);
 
-   }
 
-   
 
-   /* Check if valid stack address (RAM address) */
 
-   if (((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000 && !fInvalidFw) {
 
- #if UPDATE_TIMEOUT != 0
 
-       timer_AddFunction(1000, &UpdateTimeout_Handler);
 
- #endif
 
-   } else {
 
-       update_timeout = 0;
 
-       /* Флеш пустая, нечего загружать, висим в аварийном режиме */
 
-       SET_FWINVALID_FLAG();
 
- #ifdef LCD_ENABLE
 
-       LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
 
-       LCD_PrintAligned(7, alignCENTER, "Ошибка ПО");
 
- #endif
 
-   }
 
-   if (fBootFailed) {
 
- #ifdef LCD_ENABLE
 
-       LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
 
-       LCD_ClearRow(7);
 
- #endif
 
-   }
 
- #ifdef FTP_ENABLE
 
-   spi_flash_update();
 
- #endif // FTP_ENABLE
 
-   while (1)
 
-   {
 
-       timer_Main();
 
-       if (IAPviaETH) { // Обновление по ETH
 
-           /* Handle received packets and periodic timers for LwIP */
 
-           LwIP_Periodic_Handle(0);
 
-           if (fDoneReset) {
 
-               resetCounter++;
 
-               if (resetCounter > 400000) {
 
-                   loadMode = 0;
 
-                   bootTry = BOOT_TRY;
 
-                   RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
 
-                   RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
 
-                   SET_FWUPDATED_FLAG();
 
-                   CLEAR_FWINVALID_FLAG();
 
- #ifdef SLAVEBRD_ENABLE
 
-                   /* Reboot daughter board */
 
-                   stmReboot();
 
- #endif
 
-                   /* Self reboot */
 
-                   NVIC_SystemReset();
 
-               }
 
-           }
 
-       } else {
 
- #ifdef SD_ENABLE
 
-           // Обновление с SD
 
-           // Пробуем смонтировать SD
 
-           if (mmc_mount()) {
 
-               // Пробуем открыть файл с именем FW_FILE_NAME
 
-               timer_Stop(&LED_Blinky_Yellow);
 
-               LED_Off(RED1_INT);
 
-               LED_Off(GREEN_INT);
 
-               if (f_open(&fil_obj, FW_FILE_NAME, FA_READ | FA_OPEN_EXISTING) == FR_OK) {  // открываем файл
 
-                   LED_On(GREEN_INT);
 
-                   if (startFlashing() < 0) {
 
-                       Error_Handler();
 
-                   }
 
-                   f_close(&fil_obj);
 
-                   // CRC посчитанная при сборке и записанная в последине 4 байта прошивки
 
-                   // Должна сойтись с CRC посчитанной на контроллере
 
-                   if (CRC_Read() == CRC_Calculate()) {
 
-                       loadMode = 0;
 
-                       bootTry = BOOT_TRY;
 
-                       RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
 
-                       RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
 
- #ifdef SLAVEBRD_ENABLE
 
-                       /* Reboot daughter board */
 
-                       stmReboot();
 
- #endif
 
-                       /* Self reboot */
 
-                       NVIC_SystemReset();
 
-                   } else {
 
-                       Error_Handler();
 
-                   }
 
-               } else { // Файл не найден
 
-                   LED_On(RED1_INT);
 
-               }
 
-           }
 
- #endif
 
-       }
 
-       //Если нажата DEF переходим в основную прошивку
 
-       if (IO_BtnDefaultPressed() || UpdateTimeoutFlag) {
 
-           if (!fUpload && ((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) != 0xFFFFFFFF)) {
 
-               printf("\r\nUpdate timeout... Return to main FW\r\n");
 
-               loadMode = 0;
 
-               bootTry = BOOT_TRY;
 
-               RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
 
-               RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
 
- #ifdef SLAVEBRD_ENABLE
 
-               /* Reboot daughter board */
 
-               stmReboot();
 
- #endif
 
-               /* Self reboot */
 
-               NVIC_SystemReset();
 
-           }
 
-       }
 
-   }
 
- }
 
- /**
 
-   * @brief  Updates the system local time
 
-   * @param  None
 
-   * @retval None
 
-   */
 
- void Time_Update(void)
 
- {
 
-   LocalTime += SYSTEMTICK_PERIOD_MS;
 
- }
 
- /**
 
-   * @brief
 
-   */
 
- u32_t sys_now(void) {
 
-     return LocalTime;
 
- }
 
- /**
 
-   * @brief  Error handler
 
-   * @param  None
 
-   * @retval None
 
-   */
 
- void Error_Handler(void) {
 
-   LED_Off(LED_INIT_ERR);
 
-   LED_Off(LED_INIT_OK);
 
-   timer_AddFunction(500, &LED_Blinky_Red);
 
-   while (1)
 
-   {
 
-     timer_Main();
 
-   }
 
- }
 
- /**
 
-   * @brief
 
-   */
 
- void UpdateTimeout_Handler(void)
 
- {
 
-     if ((fUpload) || (fInvalidFw) || (fDoneReset)) {
 
-         return;
 
-     }
 
-     if (update_timeout == 0) {
 
-         UpdateTimeoutFlag = true;
 
-     } else {
 
- #ifdef LCD_ENABLE
 
-         static char lcdbuf[32] = {0};
 
-         sprintf(lcdbuf, "Ожидание (%d) ", update_timeout);
 
-         LCD_ClearRow(7);
 
-         LCD_PrintAligned(7, alignCENTER, lcdbuf);
 
- #endif
 
-         update_timeout--;
 
-     }
 
- }
 
 
  |