/** ****************************************************************************** * @file IAP_Main/Src/menu.c * @author MCD Application Team * @version 1.0.0 * @date 8-April-2015 * @brief This file provides the software which contains the main menu routine. * The main menu gives the options of: * - downloading a new binary file, * - uploading internal flash memory, * - executing the binary file already loaded * - configuring the write protection of the Flash sectors where the * user loads his binary file. ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2015 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /** @addtogroup STM32F1xx_IAP * @{ */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "common.h" #include "flash_if.h" #include "menu.h" #include "ymodem.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ pFunction JumpToApplication; uint32_t JumpAddress; uint32_t FlashProtection = 0; uint8_t aFileName[FILE_NAME_LENGTH]; extern uint8_t is_watchdog; /* Private function prototypes -----------------------------------------------*/ void SerialDownload(void); void SerialUpload(uint32_t addr, const uint8_t *filename, uint32_t size); /* Private functions ---------------------------------------------------------*/ /** * @brief Download a file via serial port * @param None * @retval None */ void SerialDownload(void) { uint32_t size = 0; COM_StatusTypeDef result; Serial_PutString("Waiting for file ... (press 'a' to abort)\n\r"); result = Ymodem_Receive( &size ); HAL_Delay(500); if (result == COM_OK) { dev_info.fireware_size = size; dev_info_save(); Serial_PutString("\n\r Programming completed.\r\n Name: "); Serial_PutString(aFileName); Int2Str(number_str, size); Serial_PutString("\n\r Size: "); Serial_PutString(number_str); Serial_PutString(" Bytes\r\n"); Serial_PutString("\r\n"); } else if (result == COM_LIMIT) { Serial_PutString("\n\rImage size too large!\n\r"); } else if (result == COM_DATA) { Serial_PutString("\n\rVerification failed!\n\r"); } else if (result == COM_ABORT) { Serial_PutString("\r\n\nAborted by user.\n\r"); } else { Serial_PutString("\n\rFailed to receive!\n\r"); } } /** * @brief Upload a file via serial port. * @param addr - 读取位置 filename - 文件名 size - 读取大小 * @retval None */ void SerialUpload(uint32_t addr, const uint8_t *filename, uint32_t size) { uint8_t status = 0; Serial_PutString("Upload ymodem ...\r\n"); HAL_UART_Receive(UartHandle, &status, 1, RX_TIMEOUT); if ( status == CRC16) { /* Transmit the flash image through ymodem protocol */ if (INTERNAL_FLASH_TYPE == flash_type) status = Ymodem_Transmit((uint8_t*)addr, filename, size); else status = Ymodem_Transmit((uint8_t*)addr, filename, size); if (status != 0) { Serial_PutString("\n\rError occurred.\n\r"); } else { Serial_PutString("\n\rUploaded successfully.\n\r"); } } } /* 开始执行应用程序. */ void start_app(void) { Serial_PutString("\r\nStart program ...\r\n\n"); __set_PRIMASK(1); /* execute the new program */ JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); /* Jump to user application */ JumpToApplication = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); JumpToApplication(); } /* 捕获id输入. */ static COM_StatusTypeDef _serial_input_type(void) { uint8_t key = 0; uint8_t i = 0; uint8_t buf[TYPE_STR_LEN] = {0}; for(i = 0; i < TYPE_STR_LEN - 1; i++) { HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); buf[i] = key; if (!ISVALIDHEX(key)) goto _ID_SET_ERR; if (0 == i) dev_info.type_m = CONVERTHEX(key) << 4; else if(1 == i) dev_info.type_m += CONVERTHEX(key); else if (2 == i) dev_info.type_s = CONVERTHEX(key) << 4; else if(3 == i) dev_info.type_s += CONVERTHEX(key); } HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); Serial_PutString(buf); return COM_OK; _ID_SET_ERR: Serial_PutString(buf); Serial_PutString("\r\n Type error. Ex: 0101\r\n"); return COM_ERROR; } /* 捕获mac输入. */ static COM_StatusTypeDef _serial_input_mac(uint8_t *mac) { uint8_t key = 0; uint8_t i = 0; uint8_t buf[MAC_STR_LEN] = {0}; for(i = 0; i < MAC_STR_LEN - 1; i++) { HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); buf[i] = key; /* 判断是不是':'的位置 */ if (i % MAC_STR_BYTE_LEN != MAC_STR_SEQ_BIT) { if (!ISVALIDHEX(key)) goto _MAC_SET_ERR; if (MAC_STR_HIGH_BIT == (i % MAC_STR_BYTE_LEN)) mac[i / MAC_STR_BYTE_LEN] = CONVERTHEX(key) << 4; else mac[i / MAC_STR_BYTE_LEN] += CONVERTHEX(key); } else if (key != ':') goto _MAC_SET_ERR; } HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); Serial_PutString(buf); return COM_OK; _MAC_SET_ERR: Serial_PutString(buf); Serial_PutString("\r\n Mac error. Ex: 00:23:56:89:bc:ef\r\n"); return COM_ERROR; } /* 捕获ip输入. */ static COM_StatusTypeDef _serial_input_ip(uint8_t *ip) { uint8_t key = 0; uint8_t i = 0; uint8_t buf[IP_STR_LEN] = {0}; uint8_t ip_index = 0; uint8_t num_str_index = 0; uint16_t val = 0; for (i = 0; i < IP_STR_LEN - 1; i++) { HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); if ('\r' == key || '\n' == key) { if (ip_index != 3 || val > 0xFF) goto _IP_SET_ERR; ip[ip_index] = val; Serial_PutString(buf); break; } else if('.' == key) { buf[i] = key; if (ip_index > 2 || val > 0xFF) goto _IP_SET_ERR; ip[ip_index++] = val; val = 0; num_str_index = 0; } else if(ISVALIDDEC(key)) { buf[i] = key; if (num_str_index++ > 2) goto _IP_SET_ERR; val = val * 10 + CONVERTDEC(key); } else { buf[i] = key; goto _IP_SET_ERR; } } return COM_OK; _IP_SET_ERR: Serial_PutString(buf); Serial_PutString("\r\n Ip error. Ex: 192.168.0.10\r\n"); return COM_ERROR; } /* 捕获 port 输入. */ static COM_StatusTypeDef _serial_input_port(uint16_t *port) { uint8_t key = 0; uint8_t i = 0; uint8_t buf[PORT_STR_LEN] = {0}; uint16_t val = 0; for (i = 0; i < PORT_STR_LEN - 1; i++) { HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); if ('\r' == key || '\n' == key) { Serial_PutString(buf); break; } else if(ISVALIDDEC(key)) { buf[i] = key; val = val * 10 + CONVERTDEC(key); } else { buf[i] = key; goto _IP_SET_ERR; } } *port = val; return COM_OK; _IP_SET_ERR: Serial_PutString(buf); Serial_PutString("\r\n Port error. Ex: 12345\r\n"); return COM_ERROR; } /* 捕获 port 输入. */ static COM_StatusTypeDef _serial_input_id(uint32_t *id) { uint8_t key = 0; uint8_t i = 0; uint8_t buf[ID_STR_LEN] = {0}; uint32_t val = 0; for (i = 0; i < ID_STR_LEN - 1; i++) { HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); if (ISVALIDHEX(key)) { buf[i] = key; val <<= 4; val |= CONVERTHEX(key); } else { buf[i] = key; goto _IP_SET_ERR; } } *id = val; HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); Serial_PutString(buf); return COM_OK; _IP_SET_ERR: Serial_PutString(buf); Serial_PutString("\r\n Id error. Ex: ABCD1234\r\n"); return COM_ERROR; } /* 配置网络参数. */ static void _dev_info_set(void) { do { Serial_PutString("Device type: "); } while(_serial_input_type() != COM_OK); do { Serial_PutString("\r\nDevice id: "); } while(_serial_input_id((uint32_t*)&dev_info.id) != COM_OK); do { Serial_PutString("\r\nMac: "); } while(_serial_input_mac(dev_info.mac) != COM_OK); do { Serial_PutString("\r\nIp: "); } while(_serial_input_ip(dev_info.ip) != COM_OK); do { Serial_PutString("\r\nMask: "); } while(_serial_input_ip(dev_info.ip_mask) != COM_OK); do { Serial_PutString("\r\nGateway: "); } while(_serial_input_ip(dev_info.ip_gw) != COM_OK); do { Serial_PutString("\r\nWireless server ip: "); } while(_serial_input_ip(dev_info.wireless_server_ip) != COM_OK); do { Serial_PutString("\r\nWireless server port: "); } while(_serial_input_port(&dev_info.wireless_server_port) != COM_OK); Serial_PutString("\r\n"); dev_info_save(); } /* 强制启动app. */ void force_start_app(void) { if (dev_info.magic != INIT_DONE_MAGIC) { dev_info.magic = INIT_DONE_MAGIC; dev_info_save(); } start_app(); } /** * @brief Display the Main Menu on HyperTerminal * @param None * @retval None */ void Main_Menu(void) { uint8_t key = 0; while (1) { Serial_PutString("\r\n1-Download image\r\n"); Serial_PutString("2-Upload IAP\r\n"); Serial_PutString("3-Upload image(I)\r\n"); Serial_PutString("4-Upload image(S)\r\n"); Serial_PutString("5-Upload config\r\n"); Serial_PutString("6-Upload device info\r\n"); Serial_PutString("7-Upload log\r\n"); Serial_PutString("8-Set device info\r\n"); Serial_PutString("!-Erase config data\r\n"); Serial_PutString("F-Force Run image\r\n"); Serial_PutString("R-Reset\r\n"); /* Clean the input path */ __HAL_UART_FLUSH_DRREGISTER(UartHandle); /* Receive key */ watchdog_refresh(); key = 'f'; HAL_UART_Abort(UartHandle); HAL_UART_Receive(UartHandle, &key, 1, 60000); watchdog_refresh(); switch (key) { case '1' : /* Download user application in the Flash */ SerialDownload(); break; case '2' : /* Upload IAP from the internal Flash */ flash_type = INTERNAL_FLASH_TYPE; SerialUpload(IAP_ADDRESS, IAP_NAME, APPLICATION_ADDRESS - IAP_ADDRESS); break; case '3' : /* Upload user application from the internal Flash */ flash_type = INTERNAL_FLASH_TYPE; SerialUpload(APPLICATION_ADDRESS, IMG_NAME, dev_info.fireware_size); break; case '4' : /* Upload user application from the spi Flash */ flash_type = SPI_FLASH_TYPE; SerialUpload(TFTP_APP_ADDRESS, SPI_IMG_NAME, dev_info.spi_fireware_size); break; case '5' : /* Upload config from the spi Flash */ flash_type = SPI_FLASH_TYPE; SerialUpload(CONFIG_ADDRESS, CONFIG_NAME, RECORD_ADDRESS - CONFIG_ADDRESS); break; case '6' : /* Upload device info from the spi Flash */ flash_type = SPI_FLASH_TYPE; SerialUpload(INFO_ADDRESS, INFO_NAME, TFTP_APP_ADDRESS - INFO_ADDRESS); break; case '7' : /* Upload log from the spi Flash */ break; case '8' : _dev_info_set(); break; case 'f' : case 'F' : force_start_app(); break; case 'r' : case 'R' : HAL_NVIC_SystemReset(); break; case '!' : Serial_PutString("\n\rAre you sure erase config data(y/n):"); HAL_UART_Receive(UartHandle, &key, 1, RX_TIMEOUT); if ('y' == key) { Serial_PutString("y\r\n"); spi_flash_erase_chip(); Serial_PutString("\n\rErase config data completed in spi flash!!!\r\n"); dev_info_init(); } break; default: Serial_PutString("Invalid input.\r\n"); break; } } } /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/