mirror of
https://github.com/No-Chicken/Power-Pico.git
synced 2026-04-03 13:02:36 +08:00
移动文件夹
This commit is contained in:
346
software/bootloader/Ymodem/common.c
Normal file
346
software/bootloader/Ymodem/common.c
Normal file
@@ -0,0 +1,346 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/src/common.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the common functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_IAP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "common.h"
|
||||
#include "usbd_cdc_if.h"
|
||||
#include "usbd_core.h" // ??????????????
|
||||
#include "usb_device.h" // ?????? hUsbDeviceFS
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
// ?? usbd_cdc_if.c ????
|
||||
extern uint8_t USB_RxBuffer[];
|
||||
extern volatile uint16_t USB_RxHead;
|
||||
extern volatile uint16_t USB_RxTail;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Convert an Integer to a string
|
||||
* @param str: The string
|
||||
* @param intnum: The integer to be converted
|
||||
* @retval None
|
||||
*/
|
||||
void Int2Str(uint8_t* str, int32_t intnum)
|
||||
{
|
||||
uint32_t i, Div = 1000000000, j = 0, Status = 0;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
str[j++] = (intnum / Div) + 48;
|
||||
|
||||
intnum = intnum % Div;
|
||||
Div /= 10;
|
||||
if ((str[j-1] == '0') & (Status == 0))
|
||||
{
|
||||
j = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a string to an integer
|
||||
* @param inputstr: The string to be converted
|
||||
* @param intnum: The integer value
|
||||
* @retval 1: Correct
|
||||
* 0: Error
|
||||
*/
|
||||
uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum)
|
||||
{
|
||||
uint32_t i = 0, res = 0;
|
||||
uint32_t val = 0;
|
||||
|
||||
if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X'))
|
||||
{
|
||||
if (inputstr[2] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (i = 2; i < 11; i++)
|
||||
{
|
||||
if (inputstr[i] == '\0')
|
||||
{
|
||||
*intnum = val;
|
||||
/* return 1; */
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
if (ISVALIDHEX(inputstr[i]))
|
||||
{
|
||||
val = (val << 4) + CONVERTHEX(inputstr[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return 0, Invalid input */
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Over 8 digit hex --invalid */
|
||||
if (i >= 11)
|
||||
{
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
else /* max 10-digit decimal input */
|
||||
{
|
||||
for (i = 0;i < 11;i++)
|
||||
{
|
||||
if (inputstr[i] == '\0')
|
||||
{
|
||||
*intnum = val;
|
||||
/* return 1 */
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0))
|
||||
{
|
||||
val = val << 10;
|
||||
*intnum = val;
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0))
|
||||
{
|
||||
val = val << 20;
|
||||
*intnum = val;
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
else if (ISVALIDDEC(inputstr[i]))
|
||||
{
|
||||
val = val * 10 + CONVERTDEC(inputstr[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* return 0, Invalid input */
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Over 10 digit decimal --invalid */
|
||||
if (i >= 11)
|
||||
{
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an integer from the USB VCP
|
||||
* @param num: The integer
|
||||
* @retval 1: Correct
|
||||
* 0: Error
|
||||
*/
|
||||
uint32_t GetIntegerInput(int32_t * num)
|
||||
{
|
||||
uint8_t inputstr[16];
|
||||
|
||||
while (1)
|
||||
{
|
||||
GetInputString(inputstr);
|
||||
if (inputstr[0] == '\0') continue;
|
||||
if ((inputstr[0] == 'a' || inputstr[0] == 'A') && inputstr[1] == '\0')
|
||||
{
|
||||
USB_PutString("User Cancelled \r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Str2Int(inputstr, num) == 0)
|
||||
{
|
||||
USB_PutString("Error, Input again: \r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test to see if a key has been pressed on the USB VCP
|
||||
* @param key: The key pressed
|
||||
* @retval 1: A key was received
|
||||
* 0: No key was received
|
||||
*/
|
||||
uint32_t USB_KeyPressed(uint8_t *key)
|
||||
{
|
||||
// Check if there is data in the USB receive ring buffer
|
||||
if (USB_RxHead != USB_RxTail)
|
||||
{
|
||||
*key = USB_RxBuffer[USB_RxTail];
|
||||
USB_RxTail = (USB_RxTail + 1) % 2048; // APP_RX_DATA_SIZE
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a key from the USB VCP
|
||||
* @param None
|
||||
* @retval The Key Pressed
|
||||
*/
|
||||
uint8_t GetKey(void)
|
||||
{
|
||||
uint8_t key = 0;
|
||||
|
||||
/* Waiting for user input */
|
||||
while (1)
|
||||
{
|
||||
if (USB_KeyPressed((uint8_t*)&key)) break;
|
||||
}
|
||||
return key;
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint8_t USB_GetChar(uint8_t *c, uint32_t timeout)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (USB_RxHead != USB_RxTail)
|
||||
{
|
||||
*c = USB_RxBuffer[USB_RxTail];
|
||||
USB_RxTail = (USB_RxTail + 1) % RING_BUFFER_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((HAL_GetTick() - tickstart) > timeout)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a char to the USB VCP
|
||||
* @param c: The char to be sent
|
||||
* @retval None
|
||||
*/
|
||||
void USB_PutChar(uint8_t c)
|
||||
{
|
||||
static uint8_t temp_buf;
|
||||
|
||||
if (hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED) return;
|
||||
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
|
||||
while (hcdc->TxState != 0) {}
|
||||
|
||||
temp_buf = c;
|
||||
CDC_Transmit_FS(&temp_buf, 1);
|
||||
}
|
||||
|
||||
void USB_PutString(char *s)
|
||||
{
|
||||
if (hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t len = strlen(s);
|
||||
while (CDC_Transmit_FS((uint8_t*)s, len) == USBD_BUSY)
|
||||
{
|
||||
if (hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Input string from the HyperTerminal
|
||||
* @param buffP: The input string
|
||||
* @retval None
|
||||
*/
|
||||
void GetInputString (uint8_t * buffP)
|
||||
{
|
||||
uint32_t bytes_read = 0;
|
||||
uint8_t c = 0;
|
||||
do
|
||||
{
|
||||
c = GetKey();
|
||||
if (c == '\r')
|
||||
break;
|
||||
if (c == '\b') /* Backspace */
|
||||
{
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
USB_PutString("\b \b");
|
||||
bytes_read --;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (bytes_read >= CMD_STRING_SIZE )
|
||||
{
|
||||
USB_PutString("Command string size overflow\r\n");
|
||||
bytes_read = 0;
|
||||
continue;
|
||||
}
|
||||
if (c >= 0x20 && c <= 0x7E)
|
||||
{
|
||||
buffP[bytes_read++] = c;
|
||||
USB_PutChar(c);
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
USB_PutString(("\n\r"));
|
||||
buffP[bytes_read] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates the CRC32 of a given memory area.
|
||||
* @param start_address: Start address of the data
|
||||
* @param size: Size of the data in bytes
|
||||
* @retval Calculated CRC32 value
|
||||
*/
|
||||
uint32_t Calculate_CRC32(uint32_t start_address, uint32_t size)
|
||||
{
|
||||
// ??CRC????
|
||||
__HAL_RCC_CRC_CLK_ENABLE();
|
||||
CRC_HandleTypeDef CrcHandle;
|
||||
CrcHandle.Instance = CRC;
|
||||
HAL_CRC_Init(&CrcHandle);
|
||||
|
||||
return HAL_CRC_Calculate(&CrcHandle, (uint32_t*)start_address, size / 4);
|
||||
}
|
||||
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE******/
|
||||
76
software/bootloader/Ymodem/common.h
Normal file
76
software/bootloader/Ymodem/common.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/inc/common.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the headers of the common functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __COMMON_H
|
||||
#define __COMMON_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Constants used by Serial Command Line Mode */
|
||||
#define CMD_STRING_SIZE 128
|
||||
|
||||
/* Common routines */
|
||||
#define IS_AF(c) ((c >= 'A') && (c <= 'F'))
|
||||
#define IS_af(c) ((c >= 'a') && (c <= 'f'))
|
||||
#define IS_09(c) ((c >= '0') && (c <= '9'))
|
||||
#define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c)
|
||||
#define ISVALIDDEC(c) IS_09(c)
|
||||
#define CONVERTDEC(c) (c - '0')
|
||||
|
||||
#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10))
|
||||
#define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))
|
||||
|
||||
#define USBPutString(x) USB_PutString((uint8_t*)(x))
|
||||
|
||||
// 定义升级信息结构体
|
||||
typedef struct {
|
||||
uint32_t magic_word; // 魔法字,如 0xDEADBEEF,用于标识此结构体有效
|
||||
uint32_t upgrade_status; // 升级状态标志
|
||||
uint32_t new_app_size; // 新APP的固件大小
|
||||
uint32_t new_app_crc32; // 新APP的CRC32校验和
|
||||
} UpgradeInfo_t;
|
||||
|
||||
// 定义升级状态
|
||||
#define UPGRADE_STATUS_NONE 0xFFFFFFFF
|
||||
#define UPGRADE_STATUS_START 0xABCD1234
|
||||
#define UPGRADE_STATUS_COMPLETE 0x5A5A5A5A
|
||||
#define MAGIC_WORD 0xDEADBEEF
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void Int2Str(uint8_t* str,int32_t intnum);
|
||||
uint32_t Str2Int(uint8_t *inputstr,int32_t *intnum);
|
||||
uint32_t GetIntegerInput(int32_t * num);
|
||||
uint32_t USB_KeyPressed(uint8_t *key);
|
||||
uint8_t GetKey(void);
|
||||
void USB_PutChar(uint8_t c);
|
||||
void USB_PutString(char *s);
|
||||
void GetInputString(uint8_t * buffP);
|
||||
uint32_t Calculate_CRC32(uint32_t start_address, uint32_t size);
|
||||
|
||||
#endif /* __COMMON_H */
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE******/
|
||||
299
software/bootloader/Ymodem/flash_if.c
Normal file
299
software/bootloader/Ymodem/flash_if.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/src/flash_if.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the memory related operation functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_IAP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "flash_if.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static uint32_t GetSector(uint32_t Address);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Unlocks Flash for write access
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_If_Init(void)
|
||||
{
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
/* Clear pending flags (if any) */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
|
||||
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief This function does an erase of all user flash area
|
||||
* @param StartSector: start of user flash area
|
||||
* @retval 0: user flash area successfully erased
|
||||
* 1: error occurred
|
||||
*/
|
||||
uint32_t FLASH_If_Erase(uint32_t StartSector)
|
||||
{
|
||||
uint32_t UserStartSector;
|
||||
uint32_t SectorError;
|
||||
FLASH_EraseInitTypeDef pEraseInit;
|
||||
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
UserStartSector = GetSector(APPLICATION_ADDRESS);
|
||||
|
||||
pEraseInit.TypeErase = TYPEERASE_SECTORS;
|
||||
pEraseInit.Sector = UserStartSector;
|
||||
pEraseInit.NbSectors = GetSector(USER_FLASH_END_ADDRESS)-UserStartSector+1 ;
|
||||
pEraseInit.VoltageRange = VOLTAGE_RANGE_3;
|
||||
|
||||
if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK)
|
||||
{
|
||||
/* Error occurred while page erase */
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function erase one sector
|
||||
* @param StartSector: start of user flash area
|
||||
* @retval 0: user flash area successfully erased
|
||||
* 1: error occurred
|
||||
*/
|
||||
uint32_t FLASH_If_Erase_One_Sector(uint32_t StartSector)
|
||||
{
|
||||
uint32_t SectorError;
|
||||
FLASH_EraseInitTypeDef pEraseInit;
|
||||
|
||||
pEraseInit.TypeErase = TYPEERASE_SECTORS;
|
||||
pEraseInit.Sector = StartSector;
|
||||
pEraseInit.NbSectors = 1 ;
|
||||
pEraseInit.VoltageRange = VOLTAGE_RANGE_3;
|
||||
|
||||
if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK)
|
||||
{
|
||||
/* Error occurred while page erase */
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes a data buffer in flash (data are 32-bit aligned).
|
||||
* @note After writing data buffer, the flash content is checked.
|
||||
* @param FlashAddress: start address for writing data buffer
|
||||
* @param Data: pointer on data buffer
|
||||
* @param DataLength: length of data buffer (unit is 32-bit word)
|
||||
* @retval 0: Data successfully written to Flash memory
|
||||
* 1: Error occurred while writing data in Flash memory
|
||||
* 2: Written Data in flash memory is different from expected one
|
||||
*/
|
||||
uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint32_t DataLength)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++)
|
||||
{
|
||||
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
|
||||
be done by word */
|
||||
FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data+i));
|
||||
/* Check the written value */
|
||||
if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i))
|
||||
{
|
||||
/* Flash content doesn't match SRAM content */
|
||||
return(2);
|
||||
}
|
||||
/* Increment FLASH destination address */
|
||||
*FlashAddress += 4;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the write protection status of user flash area.
|
||||
* @param None
|
||||
* @retval 0: No write protected sectors inside the user flash area
|
||||
* 1: Some sectors inside the user flash area are write protected
|
||||
*/
|
||||
uint16_t FLASH_If_GetWriteProtectionStatus(void)
|
||||
{
|
||||
uint32_t UserStartSector = FLASH_SECTOR_1;
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
UserStartSector = GetSector(APPLICATION_ADDRESS);
|
||||
|
||||
/* Check if there are write protected sectors inside the user flash area */
|
||||
if ((*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS) >> (UserStartSector/8)) == (0xFFF >> (UserStartSector/8)))
|
||||
{ /* No write protected sectors inside the user flash area */
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ /* Some sectors inside the user flash area are write protected */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the write protection of user flash area.
|
||||
* @param None
|
||||
* @retval 1: Write Protection successfully disabled
|
||||
* 2: Error: Flash write unprotection failed
|
||||
*/
|
||||
uint32_t FLASH_If_DisableWriteProtection(void)
|
||||
{
|
||||
__IO uint32_t UserStartSector = FLASH_SECTOR_1, UserWrpSectors = OB_WRP_SECTOR_1;
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
UserStartSector = GetSector(APPLICATION_ADDRESS);
|
||||
|
||||
/* Mark all sectors inside the user flash area as non protected */
|
||||
UserWrpSectors = 0xFFF-((1 << (UserStartSector/8))-1);
|
||||
|
||||
/* Unlock the Option Bytes */
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
/* Disable the write protection for all sectors inside the user flash area */
|
||||
FLASH_OB_DisableWRP(UserWrpSectors, FLASH_BANK_1);
|
||||
|
||||
/* Start the Option Bytes programming process. */
|
||||
if (HAL_FLASH_OB_Launch( ) != HAL_OK)
|
||||
{
|
||||
/* Error: Flash write unprotection failed */
|
||||
return (2);
|
||||
}
|
||||
|
||||
/* Write Protection successfully disabled */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the sector of a given address
|
||||
* @param Address: Flash address
|
||||
* @retval The sector of a given address
|
||||
*/
|
||||
|
||||
static uint32_t GetSector(uint32_t Address)
|
||||
{
|
||||
uint32_t sector = 0;
|
||||
|
||||
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
|
||||
{
|
||||
sector = FLASH_SECTOR_0;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
|
||||
{
|
||||
sector = FLASH_SECTOR_1;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
|
||||
{
|
||||
sector = FLASH_SECTOR_2;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
|
||||
{
|
||||
sector = FLASH_SECTOR_3;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
|
||||
{
|
||||
sector = FLASH_SECTOR_4;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
|
||||
{
|
||||
sector = FLASH_SECTOR_5;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
|
||||
{
|
||||
sector = FLASH_SECTOR_6;
|
||||
}
|
||||
else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_7))*/
|
||||
{
|
||||
sector = FLASH_SECTOR_7;
|
||||
}
|
||||
// else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_7;
|
||||
// }
|
||||
// else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_8;
|
||||
// }
|
||||
// else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_9;
|
||||
// }
|
||||
// else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_10;
|
||||
// }
|
||||
// else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
|
||||
// {
|
||||
// sector = FLASH_SECTOR_11;
|
||||
// }
|
||||
return sector;
|
||||
}
|
||||
|
||||
|
||||
HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_WRP_SECTOR(WRPSector));
|
||||
assert_param(IS_FLASH_BANK(Banks));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(50000);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
*(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void FLASH_ProgramWord(uint32_t Address, uint32_t Data)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_ADDRESS(Address));
|
||||
|
||||
/* If the previous operation is completed, proceed to program the new data */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
|
||||
FLASH->CR |= FLASH_PSIZE_WORD;
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
|
||||
*(__IO uint32_t*)Address = Data;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
75
software/bootloader/Ymodem/flash_if.h
Normal file
75
software/bootloader/Ymodem/flash_if.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/inc/flash_if.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the headers of the flash_if functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __FLASH_IF_H
|
||||
#define __FLASH_IF_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx.h"
|
||||
#include "main.h"
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Base address of the Flash sectors */
|
||||
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbyte */
|
||||
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbyte */
|
||||
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbyte */
|
||||
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbyte */
|
||||
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbyte */
|
||||
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbyte */
|
||||
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbyte */
|
||||
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbyte */
|
||||
// #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbyte */
|
||||
// #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbyte */
|
||||
// #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbyte */
|
||||
// #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbyte */
|
||||
|
||||
/* End of the Flash address */
|
||||
#define USER_FLASH_END_ADDRESS 0x0807FFFF
|
||||
/* Define the user application size */
|
||||
#define USER_FLASH_SIZE (USER_FLASH_END_ADDRESS - APPLICATION_ADDRESS + 1)
|
||||
|
||||
/* Define the address from where user application will be loaded.
|
||||
Note: the 1st sector 0x08000000-0x0800FFFF is reserved for the IAP code */
|
||||
#define APPLICATION_ADDRESS ADDR_FLASH_SECTOR_4
|
||||
|
||||
/* Sector 3 (16KB) 被保留用作升级校验区 */
|
||||
#define UPGRADE_INFO_SECTOR_ADDR ADDR_FLASH_SECTOR_3
|
||||
#define UPGRADE_INFO_SECTOR_NUM FLASH_SECTOR_3
|
||||
#define UPGRADE_INFO_ADDRESS UPGRADE_INFO_SECTOR_ADDR
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void FLASH_If_Init(void);
|
||||
uint32_t FLASH_If_Erase(uint32_t StartSector);
|
||||
uint32_t FLASH_If_Erase_One_Sector(uint32_t StartSector);
|
||||
uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data, uint32_t DataLength);
|
||||
uint16_t FLASH_If_GetWriteProtectionStatus(void);
|
||||
uint32_t FLASH_If_DisableWriteProtection(void);
|
||||
|
||||
//
|
||||
void FLASH_ProgramWord(uint32_t Address, uint32_t Data);
|
||||
HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks);
|
||||
|
||||
#endif /* __FLASH_IF_H */
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE******/
|
||||
302
software/bootloader/Ymodem/menu.c
Normal file
302
software/bootloader/Ymodem/menu.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/src/menu.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @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
|
||||
* - disabling the write protection of the Flash sectors where the
|
||||
* user loads his binary file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_IAP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "common.h"
|
||||
#include "flash_if.h"
|
||||
#include "menu.h"
|
||||
#include "ymodem.h"
|
||||
#include "string.h"
|
||||
#include "usb_device.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
pFunction Jump_To_Application;
|
||||
uint32_t JumpAddress;
|
||||
__IO uint32_t FlashProtection = 0;
|
||||
uint8_t tab_1024[1024] =
|
||||
{
|
||||
0
|
||||
};
|
||||
uint8_t FileName[FILE_NAME_LENGTH];
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void USB_Download(void);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Writes the UpgradeInfo structure to the dedicated Flash sector.
|
||||
* @param info: pointer to the UpgradeInfo_t structure
|
||||
* @retval None
|
||||
*/
|
||||
static void Write_Upgrade_Info(UpgradeInfo_t* info)
|
||||
{
|
||||
// 1. 擦除专门用于校验的 Sector 3
|
||||
FLASH_If_Erase_One_Sector(UPGRADE_INFO_SECTOR_NUM);
|
||||
// 2. 写入升级信息
|
||||
uint32_t flash_address = UPGRADE_INFO_ADDRESS;
|
||||
FLASH_If_Write((__IO uint32_t*)&flash_address, (uint32_t*)info, sizeof(UpgradeInfo_t) / 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the UpgradeInfo structure from the dedicated Flash sector.
|
||||
* @param info: pointer to the UpgradeInfo_t structure to be filled
|
||||
* @retval None
|
||||
*/
|
||||
static void Read_Upgrade_Info(UpgradeInfo_t* info)
|
||||
{
|
||||
memcpy(info, (void*)UPGRADE_INFO_ADDRESS, sizeof(UpgradeInfo_t));
|
||||
}
|
||||
|
||||
// Int-to-Hex函数
|
||||
static void Int2Hex(uint8_t* str, uint32_t intnum)
|
||||
{
|
||||
const char hex_chars[] = "0123456789ABCDEF";
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
str[7 - i] = hex_chars[intnum & 0x0F];
|
||||
intnum >>= 4;
|
||||
}
|
||||
str[8] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Download a file via serial port
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Download(void)
|
||||
{
|
||||
UpgradeInfo_t received_info;
|
||||
uint8_t Number[10] = " ";
|
||||
int32_t file_size = 0;
|
||||
|
||||
// user operation
|
||||
// 1. 接收元数据
|
||||
USB_PutString("Waiting for the file to be sent ... (press 'a' to abort)\n\r");
|
||||
// 2. 擦除整个APP区域
|
||||
USB_PutString("Erasing Application Area...\r\n");
|
||||
if (FLASH_If_Erase(APPLICATION_ADDRESS) != 0)
|
||||
{
|
||||
USB_PutString("Error: Failed to erase application area!\r\n");
|
||||
return;
|
||||
}
|
||||
USB_PutString("Erase Complete.\r\n");
|
||||
/* Waiting for file sent */
|
||||
USB_PutString("Starting Ymodem Receive\n\r");
|
||||
file_size = Ymodem_Receive(&tab_1024[0]);
|
||||
if (file_size > 0)
|
||||
{
|
||||
|
||||
USB_PutString("\n\n\r File reception complete. Verifying...\n\r");
|
||||
// 4. 最终校验
|
||||
// 理想情况下,这里应该有一个从上位机获取的CRC32值进行对比, 此处不对比
|
||||
uint32_t calculated_crc = Calculate_CRC32(APPLICATION_ADDRESS, file_size);
|
||||
|
||||
// 5. 写入校验信息到Flash末尾
|
||||
received_info.magic_word = MAGIC_WORD;
|
||||
received_info.upgrade_status = UPGRADE_STATUS_COMPLETE; // 标记为升级完成
|
||||
received_info.new_app_size = file_size;
|
||||
received_info.new_app_crc32 = calculated_crc;
|
||||
Write_Upgrade_Info(&received_info);
|
||||
USB_PutString("Verification and Flag Set successful!\r\n");
|
||||
USB_PutString("--------------------------------\r\n Name: ");
|
||||
USB_PutString(FileName);
|
||||
Int2Str(Number, file_size);
|
||||
USB_PutString("\n\r Size: ");
|
||||
USB_PutString(Number);
|
||||
USB_PutString(" Bytes\r\n");
|
||||
USB_PutString(" CRC32: 0x");
|
||||
uint8_t calculated_crc_str[9];
|
||||
Int2Hex(calculated_crc_str, calculated_crc);
|
||||
USB_PutString(calculated_crc_str);
|
||||
USB_PutString("\r\n-------------------\n");
|
||||
USB_PutString("Please reboot the device.\r\n");
|
||||
}
|
||||
else /* An error occurred while writing to Flash memory */
|
||||
{
|
||||
FLASH_If_Erase_One_Sector(UPGRADE_INFO_SECTOR_NUM); // 擦除升级校验区,避免误跳转
|
||||
USB_PutString("\n\rUpgrade failed!\r\n");
|
||||
if (file_size == -1)
|
||||
{
|
||||
USB_PutString("\n\n\rThe image size is higher than the allowed space memory!\n\r");
|
||||
}
|
||||
else if (file_size == -2)
|
||||
{
|
||||
USB_PutString("\n\n\rVerification failed!\n\r");
|
||||
}
|
||||
else if (file_size == -3)
|
||||
{
|
||||
USB_PutString("\r\n\nAborted by user.\n\r");
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_PutString("\n\rFailed to receive the file!\n\r");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display the Main Menu on HyperTerminal
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void Main_Menu(void)
|
||||
{
|
||||
uint8_t key = 0;
|
||||
|
||||
USB_PutString("\r\n======================================================================");
|
||||
USB_PutString("\r\n= (C) COPYRIGHT 2011 STMicroelectronics =");
|
||||
USB_PutString("\r\n= =");
|
||||
USB_PutString("\r\n= STM32F4xx In-Application Programming Application (Version 1.0.0) =");
|
||||
USB_PutString("\r\n= =");
|
||||
USB_PutString("\r\n= By MCD Application Team =");
|
||||
USB_PutString("\r\n======================================================================");
|
||||
USB_PutString("\r\n\r\n");
|
||||
|
||||
/* Test if any sector of Flash memory where user application will be loaded is write protected */
|
||||
if (FLASH_If_GetWriteProtectionStatus() == 0)
|
||||
{
|
||||
FlashProtection = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FlashProtection = 0;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
USB_PutString("\r\n================== Main Menu ============================\r\n\n");
|
||||
USB_PutString(" Download Image To the STM32F4xx Internal Flash ------- 1\r\n\n");
|
||||
USB_PutString(" Upload Image From the STM32F4xx Internal Flash ------- 2\r\n\n");
|
||||
USB_PutString(" Execute The New Program ------------------------------ 3\r\n\n");
|
||||
|
||||
if(FlashProtection != 0)
|
||||
{
|
||||
USB_PutString(" Disable the write protection ------------------------- 4\r\n\n");
|
||||
}
|
||||
|
||||
USB_PutString("==========================================================\r\n\n");
|
||||
|
||||
/* Receive key */
|
||||
key = GetKey();
|
||||
|
||||
if (key == 0x31)
|
||||
{
|
||||
/* Download user application in the Flash */
|
||||
USB_Download();
|
||||
}
|
||||
else if (key == 0x32)
|
||||
{
|
||||
/* Upload user application from the Flash */
|
||||
// USB_Upload();
|
||||
USB_PutString("This function is disabled! Please Use 1\r");
|
||||
}
|
||||
else if (key == 0x33) /* execute the new program */
|
||||
{
|
||||
USB_PutString("Start to execute the user application...\r\n");
|
||||
HAL_Delay(1000);
|
||||
jump_to_app();
|
||||
}
|
||||
else if ((key == 0x34) && (FlashProtection == 1))
|
||||
{
|
||||
/* Disable the write protection */
|
||||
switch (FLASH_If_DisableWriteProtection())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
USB_PutString("Write Protection disabled...\r\n");
|
||||
FlashProtection = 0;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
USB_PutString("Error: Flash write unprotection failed...\r\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FlashProtection == 0)
|
||||
{
|
||||
USB_PutString("Invalid Number ! ==> The number should be either 1, 2 or 3\r");
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_PutString("Invalid Number ! ==> The number should be either 1, 2, 3 or 4\r");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Public functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Jumps to the user application loaded in the Flash memory.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void jump_to_app(void)
|
||||
{
|
||||
USER_USB_DEVICE_DeInit();
|
||||
// 给予PC足够的时间来识别设备断开
|
||||
HAL_Delay(500);
|
||||
HAL_RCC_DeInit();
|
||||
HAL_DeInit();
|
||||
//user code here
|
||||
SysTick->CTRL = 0X00;//禁止SysTick
|
||||
SysTick->LOAD = 0;
|
||||
SysTick->VAL = 0;
|
||||
__disable_irq();
|
||||
|
||||
//set JumpAddress
|
||||
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
|
||||
/* Jump to user application */
|
||||
Jump_To_Application = (pFunction) JumpAddress;
|
||||
/* Initialize user application's Stack Pointer */
|
||||
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
|
||||
Jump_To_Application();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE******/
|
||||
41
software/bootloader/Ymodem/menu.h
Normal file
41
software/bootloader/Ymodem/menu.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/inc/menu.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the headers of the menu functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MENU_H
|
||||
#define __MENU_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "flash_if.h"
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
typedef void (*pFunction)(void);
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void Main_Menu(void);
|
||||
void jump_to_app(void);
|
||||
|
||||
#endif /* __MENU_H */
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE******/
|
||||
671
software/bootloader/Ymodem/ymodem.c
Normal file
671
software/bootloader/Ymodem/ymodem.c
Normal file
@@ -0,0 +1,671 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/src/ymodem.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the software functions related to the ymodem
|
||||
* protocol.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "flash_if.h"
|
||||
#include "common.h"
|
||||
#include "ymodem.h"
|
||||
#include "string.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
extern uint8_t FileName[];
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Receive byte from sender
|
||||
* @param c: Character
|
||||
* @param timeout: Timeout
|
||||
* @retval 0: Byte received
|
||||
* -1: Timeout
|
||||
*/
|
||||
static int32_t Receive_Byte (uint8_t *c, uint32_t timeout)
|
||||
{
|
||||
while (timeout-- > 0)
|
||||
{
|
||||
if (USB_KeyPressed(c) == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a byte
|
||||
* @param c: Character
|
||||
* @retval 0: Byte sent
|
||||
*/
|
||||
static uint32_t Send_Byte (uint8_t c)
|
||||
{
|
||||
USB_PutChar(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a packet from sender
|
||||
* @param data
|
||||
* @param length
|
||||
* @param timeout
|
||||
* 0: end of transmission
|
||||
* -1: abort by sender
|
||||
* >0: packet length
|
||||
* @retval 0: normally return
|
||||
* -1: timeout or packet error
|
||||
* 1: abort by user
|
||||
*/
|
||||
static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout)
|
||||
{
|
||||
uint16_t i, packet_size;
|
||||
uint8_t c;
|
||||
*length = 0;
|
||||
if (Receive_Byte(&c, timeout) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
switch (c)
|
||||
{
|
||||
case SOH:
|
||||
packet_size = PACKET_SIZE;
|
||||
break;
|
||||
case STX:
|
||||
packet_size = PACKET_1K_SIZE;
|
||||
break;
|
||||
case EOT:
|
||||
return 0;
|
||||
case CA:
|
||||
if ((Receive_Byte(&c, timeout) == 0) && (c == CA))
|
||||
{
|
||||
*length = -1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
case ABORT1:
|
||||
case ABORT2:
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
*data = c;
|
||||
for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)
|
||||
{
|
||||
if (Receive_Byte(data + i, timeout) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
*length = packet_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive a file using the ymodem protocol.
|
||||
* @param buf: Address of the first byte.
|
||||
* @retval The size of the file.
|
||||
*/
|
||||
int32_t Ymodem_Receive (uint8_t *buf)
|
||||
{
|
||||
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
|
||||
int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;
|
||||
uint32_t flashdestination, ramsource;
|
||||
|
||||
/* Initialize flashdestination variable */
|
||||
flashdestination = APPLICATION_ADDRESS;
|
||||
|
||||
for (session_done = 0, errors = 0, session_begin = 0; ;)
|
||||
{
|
||||
for (packets_received = 0, file_done = 0, buf_ptr = buf; ;)
|
||||
{
|
||||
switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))
|
||||
{
|
||||
case 0:
|
||||
errors = 0;
|
||||
switch (packet_length)
|
||||
{
|
||||
/* Abort by sender */
|
||||
case - 1:
|
||||
Send_Byte(ACK);
|
||||
return 0;
|
||||
/* End of transmission */
|
||||
case 0:
|
||||
Send_Byte(ACK);
|
||||
file_done = 1;
|
||||
break;
|
||||
/* Normal packet */
|
||||
default:
|
||||
if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
|
||||
{
|
||||
Send_Byte(NAK);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (packets_received == 0)
|
||||
{
|
||||
/* Filename packet */
|
||||
if (packet_data[PACKET_HEADER] != 0)
|
||||
{
|
||||
/* Filename packet has valid data */
|
||||
for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
|
||||
{
|
||||
FileName[i++] = *file_ptr++;
|
||||
}
|
||||
FileName[i++] = '\0';
|
||||
for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);)
|
||||
{
|
||||
file_size[i++] = *file_ptr++;
|
||||
}
|
||||
file_size[i++] = '\0';
|
||||
Str2Int(file_size, &size);
|
||||
|
||||
/* Test the size of the image to be sent */
|
||||
/* Image size is greater than Flash size */
|
||||
if (size > (USER_FLASH_SIZE + 1))
|
||||
{
|
||||
/* End session */
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return -1;
|
||||
}
|
||||
/* erase user application area */
|
||||
FLASH_If_Erase(APPLICATION_ADDRESS);
|
||||
Send_Byte(ACK);
|
||||
Send_Byte(CRC16);
|
||||
}
|
||||
/* Filename packet is empty, end session */
|
||||
else
|
||||
{
|
||||
Send_Byte(ACK);
|
||||
file_done = 1;
|
||||
session_done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Data packet */
|
||||
else
|
||||
{
|
||||
memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
|
||||
ramsource = (uint32_t)buf;
|
||||
|
||||
/* Write received data in Flash */
|
||||
if (FLASH_If_Write(&flashdestination, (uint32_t*) ramsource, (uint16_t) packet_length/4) == 0)
|
||||
{
|
||||
Send_Byte(ACK);
|
||||
}
|
||||
else /* An error occurred while writing to Flash memory */
|
||||
{
|
||||
/* End session */
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
packets_received ++;
|
||||
session_begin = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return -3;
|
||||
default:
|
||||
if (session_begin > 0)
|
||||
{
|
||||
errors ++;
|
||||
}
|
||||
if (errors > MAX_ERRORS)
|
||||
{
|
||||
Send_Byte(CA);
|
||||
Send_Byte(CA);
|
||||
return 0;
|
||||
}
|
||||
Send_Byte(CRC16);
|
||||
break;
|
||||
}
|
||||
if (file_done != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (session_done != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (int32_t)size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check response using the ymodem protocol
|
||||
* @param buf: Address of the first byte
|
||||
* @retval The size of the file
|
||||
*/
|
||||
int32_t Ymodem_CheckResponse(uint8_t c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare the first block
|
||||
* @param timeout
|
||||
* 0: end of transmission
|
||||
* @retval None
|
||||
*/
|
||||
void Ymodem_PrepareIntialPacket(uint8_t *data, const uint8_t* fileName, uint32_t *length)
|
||||
{
|
||||
uint16_t i, j;
|
||||
uint8_t file_ptr[10];
|
||||
|
||||
/* Make first three packet */
|
||||
data[0] = SOH;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0xff;
|
||||
|
||||
/* Filename packet has valid data */
|
||||
for (i = 0; (fileName[i] != '\0') && (i < FILE_NAME_LENGTH);i++)
|
||||
{
|
||||
data[i + PACKET_HEADER] = fileName[i];
|
||||
}
|
||||
|
||||
data[i + PACKET_HEADER] = 0x00;
|
||||
|
||||
Int2Str (file_ptr, *length);
|
||||
for (j =0, i = i + PACKET_HEADER + 1; file_ptr[j] != '\0' ; )
|
||||
{
|
||||
data[i++] = file_ptr[j++];
|
||||
}
|
||||
|
||||
for (j = i; j < PACKET_SIZE + PACKET_HEADER; j++)
|
||||
{
|
||||
data[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare the data packet
|
||||
* @param timeout
|
||||
* 0: end of transmission
|
||||
* @retval None
|
||||
*/
|
||||
void Ymodem_PreparePacket(uint8_t *SourceBuf, uint8_t *data, uint8_t pktNo, uint32_t sizeBlk)
|
||||
{
|
||||
uint16_t i, size, packetSize;
|
||||
uint8_t* file_ptr;
|
||||
|
||||
/* Make first three packet */
|
||||
packetSize = sizeBlk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE;
|
||||
size = sizeBlk < packetSize ? sizeBlk :packetSize;
|
||||
if (packetSize == PACKET_1K_SIZE)
|
||||
{
|
||||
data[0] = STX;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[0] = SOH;
|
||||
}
|
||||
data[1] = pktNo;
|
||||
data[2] = (~pktNo);
|
||||
file_ptr = SourceBuf;
|
||||
|
||||
/* Filename packet has valid data */
|
||||
for (i = PACKET_HEADER; i < size + PACKET_HEADER;i++)
|
||||
{
|
||||
data[i] = *file_ptr++;
|
||||
}
|
||||
if ( size <= packetSize)
|
||||
{
|
||||
for (i = size + PACKET_HEADER; i < packetSize + PACKET_HEADER; i++)
|
||||
{
|
||||
data[i] = 0x1A; /* EOF (0x1A) or 0x00 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update CRC16 for input byte
|
||||
* @param CRC input value
|
||||
* @param input byte
|
||||
* @retval None
|
||||
*/
|
||||
uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte)
|
||||
{
|
||||
uint32_t crc = crcIn;
|
||||
uint32_t in = byte | 0x100;
|
||||
|
||||
do
|
||||
{
|
||||
crc <<= 1;
|
||||
in <<= 1;
|
||||
if(in & 0x100)
|
||||
++crc;
|
||||
if(crc & 0x10000)
|
||||
crc ^= 0x1021;
|
||||
}
|
||||
|
||||
while(!(in & 0x10000));
|
||||
|
||||
return crc & 0xffffu;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Cal CRC16 for YModem Packet
|
||||
* @param data
|
||||
* @param length
|
||||
* @retval None
|
||||
*/
|
||||
uint16_t Cal_CRC16(const uint8_t* data, uint32_t size)
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
const uint8_t* dataEnd = data+size;
|
||||
|
||||
while(data < dataEnd)
|
||||
crc = UpdateCRC16(crc, *data++);
|
||||
|
||||
crc = UpdateCRC16(crc, 0);
|
||||
crc = UpdateCRC16(crc, 0);
|
||||
|
||||
return crc&0xffffu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cal Check sum for YModem Packet
|
||||
* @param data
|
||||
* @param length
|
||||
* @retval None
|
||||
*/
|
||||
uint8_t CalChecksum(const uint8_t* data, uint32_t size)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
const uint8_t* dataEnd = data+size;
|
||||
|
||||
while(data < dataEnd )
|
||||
sum += *data++;
|
||||
|
||||
return (sum & 0xffu);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmit a data packet using the ymodem protocol
|
||||
* @param data
|
||||
* @param length
|
||||
* @retval None
|
||||
*/
|
||||
void Ymodem_SendPacket(uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint16_t i;
|
||||
i = 0;
|
||||
while (i < length)
|
||||
{
|
||||
Send_Byte(data[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmit a file using the ymodem protocol
|
||||
* @param buf: Address of the first byte
|
||||
* @retval The size of the file
|
||||
*/
|
||||
uint8_t Ymodem_Transmit (uint8_t *buf, const uint8_t* sendFileName, uint32_t sizeFile)
|
||||
{
|
||||
|
||||
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
|
||||
uint8_t filename[FILE_NAME_LENGTH];
|
||||
uint8_t *buf_ptr, tempCheckSum;
|
||||
uint16_t tempCRC;
|
||||
uint16_t blkNumber;
|
||||
uint8_t receivedC[2], CRC16_F = 0, i;
|
||||
uint32_t errors, ackReceived, size = 0, pktSize;
|
||||
|
||||
errors = 0;
|
||||
ackReceived = 0;
|
||||
for (i = 0; i < (FILE_NAME_LENGTH - 1); i++)
|
||||
{
|
||||
filename[i] = sendFileName[i];
|
||||
}
|
||||
CRC16_F = 1;
|
||||
|
||||
/* Prepare first block */
|
||||
Ymodem_PrepareIntialPacket(&packet_data[0], filename, &sizeFile);
|
||||
|
||||
do
|
||||
{
|
||||
/* Send Packet */
|
||||
Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
|
||||
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
if (CRC16_F)
|
||||
{
|
||||
tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);
|
||||
Send_Byte(tempCRC >> 8);
|
||||
Send_Byte(tempCRC & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE);
|
||||
Send_Byte(tempCheckSum);
|
||||
}
|
||||
|
||||
/* Wait for Ack and 'C' */
|
||||
if (Receive_Byte(&receivedC[0], 10000) == 0)
|
||||
{
|
||||
if (receivedC[0] == ACK)
|
||||
{
|
||||
/* Packet transferred correctly */
|
||||
ackReceived = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
buf_ptr = buf;
|
||||
size = sizeFile;
|
||||
blkNumber = 0x01;
|
||||
/* Here 1024 bytes package is used to send the packets */
|
||||
|
||||
|
||||
/* Resend packet if NAK for a count of 10 else end of communication */
|
||||
while (size)
|
||||
{
|
||||
/* Prepare next packet */
|
||||
Ymodem_PreparePacket(buf_ptr, &packet_data[0], blkNumber, size);
|
||||
ackReceived = 0;
|
||||
receivedC[0]= 0;
|
||||
errors = 0;
|
||||
do
|
||||
{
|
||||
/* Send next packet */
|
||||
if (size >= PACKET_1K_SIZE)
|
||||
{
|
||||
pktSize = PACKET_1K_SIZE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
pktSize = PACKET_SIZE;
|
||||
}
|
||||
Ymodem_SendPacket(packet_data, pktSize + PACKET_HEADER);
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
if (CRC16_F)
|
||||
{
|
||||
tempCRC = Cal_CRC16(&packet_data[3], pktSize);
|
||||
Send_Byte(tempCRC >> 8);
|
||||
Send_Byte(tempCRC & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempCheckSum = CalChecksum (&packet_data[3], pktSize);
|
||||
Send_Byte(tempCheckSum);
|
||||
}
|
||||
|
||||
/* Wait for Ack */
|
||||
if ((Receive_Byte(&receivedC[0], 100000) == 0) && (receivedC[0] == ACK))
|
||||
{
|
||||
ackReceived = 1;
|
||||
if (size > pktSize)
|
||||
{
|
||||
buf_ptr += pktSize;
|
||||
size -= pktSize;
|
||||
if (blkNumber == (USER_FLASH_SIZE/1024))
|
||||
{
|
||||
return 0xFF; /* error */
|
||||
}
|
||||
else
|
||||
{
|
||||
blkNumber++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_ptr += pktSize;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while(!ackReceived && (errors < 0x0A));
|
||||
/* Resend packet if NAK for a count of 10 else end of communication */
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
}
|
||||
ackReceived = 0;
|
||||
receivedC[0] = 0x00;
|
||||
errors = 0;
|
||||
do
|
||||
{
|
||||
Send_Byte(EOT);
|
||||
/* Send (EOT); */
|
||||
/* Wait for Ack */
|
||||
if ((Receive_Byte(&receivedC[0], 10000) == 0) && receivedC[0] == ACK)
|
||||
{
|
||||
ackReceived = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* Last packet preparation */
|
||||
ackReceived = 0;
|
||||
receivedC[0] = 0x00;
|
||||
errors = 0;
|
||||
|
||||
packet_data[0] = SOH;
|
||||
packet_data[1] = 0;
|
||||
packet_data [2] = 0xFF;
|
||||
|
||||
for (i = PACKET_HEADER; i < (PACKET_SIZE + PACKET_HEADER); i++)
|
||||
{
|
||||
packet_data [i] = 0x00;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* Send Packet */
|
||||
Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
|
||||
|
||||
/* Send CRC or Check Sum based on CRC16_F */
|
||||
tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);
|
||||
Send_Byte(tempCRC >> 8);
|
||||
Send_Byte(tempCRC & 0xFF);
|
||||
|
||||
/* Wait for Ack and 'C' */
|
||||
if (Receive_Byte(&receivedC[0], 10000) == 0)
|
||||
{
|
||||
if (receivedC[0] == ACK)
|
||||
{
|
||||
/* Packet transferred correctly */
|
||||
ackReceived = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
|
||||
/* Resend packet if NAK for a count of 10 else end of communication */
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Send_Byte(EOT);
|
||||
/* Send (EOT); */
|
||||
/* Wait for Ack */
|
||||
if ((Receive_Byte(&receivedC[0], 10000) == 0) && receivedC[0] == ACK)
|
||||
{
|
||||
ackReceived = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors++;
|
||||
}
|
||||
}while (!ackReceived && (errors < 0x0A));
|
||||
|
||||
if (errors >= 0x0A)
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
return 0; /* file transmitted successfully */
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
64
software/bootloader/Ymodem/ymodem.h
Normal file
64
software/bootloader/Ymodem/ymodem.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/inc/ymodem.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the software function headers of the ymodem.c
|
||||
* file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "stdint.h"
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __YMODEM_H_
|
||||
#define __YMODEM_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#define PACKET_SEQNO_INDEX (1)
|
||||
#define PACKET_SEQNO_COMP_INDEX (2)
|
||||
|
||||
#define PACKET_HEADER (3)
|
||||
#define PACKET_TRAILER (2)
|
||||
#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER)
|
||||
#define PACKET_SIZE (128)
|
||||
#define PACKET_1K_SIZE (1024)
|
||||
|
||||
#define FILE_NAME_LENGTH (256)
|
||||
#define FILE_SIZE_LENGTH (16)
|
||||
|
||||
#define SOH (0x01) /* start of 128-byte data packet */
|
||||
#define STX (0x02) /* start of 1024-byte data packet */
|
||||
#define EOT (0x04) /* end of transmission */
|
||||
#define ACK (0x06) /* acknowledge */
|
||||
#define NAK (0x15) /* negative acknowledge */
|
||||
#define CA (0x18) /* two of these in succession aborts transfer */
|
||||
#define CRC16 (0x43) /* 'C' == 0x43, request 16-bit CRC */
|
||||
|
||||
#define ABORT1 (0x41) /* 'A' == 0x41, abort by user */
|
||||
#define ABORT2 (0x61) /* 'a' == 0x61, abort by user */
|
||||
|
||||
#define NAK_TIMEOUT (0x100000)
|
||||
#define MAX_ERRORS (5)
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
int32_t Ymodem_Receive (uint8_t *);
|
||||
uint8_t Ymodem_Transmit (uint8_t *,const uint8_t* , uint32_t );
|
||||
|
||||
#endif /* __YMODEM_H_ */
|
||||
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
Reference in New Issue
Block a user