| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371 |
- /**
- * @file IAP_YMODEM_ATY.c
- *
- * @param Project DEVICE_GENERAL_ATY_LIB
- *
- * @author ATY
- *
- * @copyright
- * - Copyright 2017 - 2023 MZ-ATY
- * - This code follows:
- * - MZ-ATY Various Contents Joint Statement -
- * <a href="https://mengze.top/MZ-ATY_VCJS">
- * https://mengze.top/MZ-ATY_VCJS</a>
- * - CC 4.0 BY-NC-SA -
- * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
- * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
- * - Your use will be deemed to have accepted the terms of this statement.
- *
- * @brief Familiar functions of IAP with YMODEM for all embedded device
- *
- * @version
- * - 1_01_240911 > ATY
- * -# Preliminary version, first Release
- * - 1_01_250701 > ATY
- * -# real fix to lib type
- * - 1_01_250704 > ATY
- * -# finish uart and ucdc IAP whole test
- ********************************************************************************
- */
- #ifndef __IAP_YMODEM_ATY_C
- #define __IAP_YMODEM_ATY_C
- #include "IAP_YMODEM_ATY.h"
- /******************************* For user *************************************/
- uint8_t EmptyBuf[1] = {0};
- #ifdef IAP_YMODEM_ATY_USB
- USBD_CDC_HandleTypeDef* hcdc;
- uint32_t ucdcRcvLength = 0;
- uint8_t ucdcRcvOverFlag = 1;
- uint32_t ucdcRcvLastTime = 0;
- uint8_t ucdcRcvBuffer[APP_RX_DATA_SIZE] = {0};
- #endif
- void All_Reset(void)
- {
- // Disable global interrupts
- __disable_irq();
- // Deinnit peripherals
- HAL_UART_DeInit(&Interface_UART);
- __HAL_RCC_USB_CLK_DISABLE();
- HAL_RCC_DeInit();
- HAL_DeInit();
- // Disable and reset SysTick timer
- SysTick->CTRL = 0;
- SysTick->LOAD = 0;
- SysTick->VAL = 0;
- // Optional: Disable and clear all NVIC interrupts
- for(int i = 0; i < 8; i++) {
- NVIC->ICER[i] = 0xFFFFFFFF; // Disable all interrupts
- NVIC->ICPR[i] = 0xFFFFFFFF; // Clear pending status
- }
- // Optional: Reset interrupt priority registers
- // for(int i = 0; i < 48; i++) {
- // NVIC->IP[i] = 0; // Set all priorities to default
- // }
- // Optional: Set vector table offset to App's address
- SCB->VTOR = APPLICATION_ADDRESS & 0x1FFFFF80;
- }
- void JumpToAppWithReset(void)
- {
- All_Reset();
- JumpToApp(APPLICATION_ADDRESS);
- }
- void Interface_Clean(void)
- {
- #ifndef IAP_YMODEM_ATY_USB
- #warning "NOT IAP_YMODEM_ATY_USB"
- __HAL_UART_FLUSH_DRREGISTER(&Interface_UART);
- #else
- #warning "IAP_YMODEM_ATY_USB"
- ucdcRcvLength = 0;
- ucdcRcvOverFlag = 1;
- #endif
- }
- #ifdef IAP_YMODEM_ATY_USB
- void PUT_IN_CDC_Receive_FS(uint8_t* Buf, uint32_t* Len)
- {
- if(ucdcRcvOverFlag == 1){ // new start
- ucdcRcvOverFlag = 0;
- ucdcRcvLength = *Len;
- memcpy(ucdcRcvBuffer, Buf, *Len);
- if(*Len < 64){
- ucdcRcvOverFlag = 1;
- }
- else{
- ucdcRcvLastTime = HAL_GetTick();
- }
- }
- else{ // pending to before
- memcpy(ucdcRcvBuffer + ucdcRcvLength, Buf, *Len);
- ucdcRcvLength += *Len;
- if(*Len < 64){
- ucdcRcvOverFlag = 1;
- }
- else{
- ucdcRcvLastTime = HAL_GetTick();
- }
- }
- // USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
- // USBD_CDC_ReceivePacket(&hUsbDeviceFS);
- // return (USBD_OK);
- }
- #endif
- uint32_t timeoutCount = 0;
- uint32_t timeoutFinal = 100;
- HAL_StatusTypeDef Interface_Receive(uint8_t* bytes, uint16_t size, uint32_t timeout)
- {
- #ifndef IAP_YMODEM_ATY_USB
- HAL_StatusTypeDef state = HAL_UART_Receive(&Interface_UART, bytes, size, timeout);
- return state;
- // return HAL_UART_Receive(&Interface_UART, bytes, size, timeout);
- #else
- hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
- if(hcdc->RxLength > APP_RX_DATA_SIZE)
- return HAL_ERROR;
- timeoutCount = 0;
- timeoutFinal = timeout;
- while(ucdcRcvLength == 0){
- timeoutCount++;
- if(timeoutCount > timeoutFinal){
- timeoutCount = 0;
- USBD_CDC_ReceivePacket(&hUsbDeviceFS);
- return HAL_TIMEOUT;
- }
- HAL_Delay(1);
- }
- if(ucdcRcvOverFlag == 0)
- {
- while(HAL_GetTick() - ucdcRcvLastTime < 200)
- {
- }
- ucdcRcvOverFlag = 1;
- }
- if(ucdcRcvLength > 0 && ucdcRcvLength <= APP_RX_DATA_SIZE){
- uint16_t copySize = (ucdcRcvLength > size) ? size : ucdcRcvLength;
- memcpy(bytes, ucdcRcvBuffer, copySize);
- ucdcRcvLength -= copySize;
- memcpy(ucdcRcvBuffer, ucdcRcvBuffer + copySize, ucdcRcvLength);
- }
- return HAL_OK;
- #endif
- }
- HAL_StatusTypeDef Interface_Transmit(uint8_t* bytes, uint16_t size, uint32_t timeout)
- {
- #ifndef IAP_YMODEM_ATY_USB
- /* May be timeouted... */
- if(Interface_UART.gState == HAL_UART_STATE_TIMEOUT)
- {
- Interface_UART.gState = HAL_UART_STATE_READY;
- }
- return HAL_UART_Transmit(&Interface_UART, bytes, size, timeout);
- #else
- Interface_Clean();
- ucdcRcvOverFlag = 1;
- timeoutCount = 0;
- timeoutFinal = timeout;
- while(CDC_Transmit_FS(bytes, size) != HAL_OK){
- timeoutCount++;
- if(timeoutCount > timeoutFinal)
- return HAL_TIMEOUT;
- HAL_Delay(1);
- }
- return HAL_OK;
- #endif
- }
- /**
- * @brief Display the Main Menu on HyperTerminal
- */
- void Main_Menu(void)
- {
- uint8_t key = 0;
- uint16_t errTimes = 0;
- uint32_t FlashProtection = 0;
- /* Initialise Flash */
- FLASH_If_Init();
- /* Test if any sector of Flash memory where user application will be loaded is write protected */
- FlashProtection = FLASH_If_GetWriteProtectionStatus();
- Interface_PutString("\r\n\r\n=================== Main Menu ============================\r\n\r\n");
- Interface_PutString(" Download image to the internal Flash ----------------- 1\r\n\r\n");
- Interface_PutString(" Upload image from the internal Flash ----------------- 2\r\n\r\n");
- Interface_PutString(" Execute the loaded application ----------------------- 3\r\n\r\n");
- if(FlashProtection != FLASHIF_PROTECTION_NONE)
- {
- Interface_PutString(" Disable the write protection ------------------------- 4\r\n\r\n");
- }
- else
- {
- Interface_PutString(" Enable the write protection -------------------------- 4\r\n\r\n");
- }
- Interface_PutString("==========================================================\r\n\r\n");
- while(1)
- {
- /* Clean the input path */
- Interface_Clean();
- /* Receive key */
- Interface_Receive(&key, 1, IAP_3_TIME);
- /* Auto jump to app */
- if(key == 0)
- key = 51;
- switch(key)
- {
- case '*':
- /* Upload user application from the Flash */
- Interface_Upload();
- break;
- case '2':
- /* Upload user application from the Flash */
- Interface_PutString("\r\nAuthorize wrong!\r\n\r\n");
- break;
- case '1':
- /* Download user application in the Flash */
- if(Interface_Download() != COM_OK)
- break;
- case '3':
- Interface_PutString("\r\nStart program execution...\r\n");
- JumpToAppWithReset();
- break;
- case '4':
- if(FlashProtection != FLASHIF_PROTECTION_NONE)
- {
- /* Disable the write protection */
- if(FLASH_If_WriteProtectionConfig(FLASHIF_WRP_DISABLE) == FLASHIF_OK)
- {
- Interface_PutString("Write protection disabled...\r\n");
- Interface_PutString("System will now restart...\r\n");
- /* Launch the option byte loading */
- HAL_FLASH_OB_Launch();
- }
- else
- {
- Interface_PutString("Error: Flash write un-protection failed...\r\n");
- }
- }
- else
- {
- if(FLASH_If_WriteProtectionConfig(FLASHIF_WRP_ENABLE) == FLASHIF_OK)
- {
- Interface_PutString("Write protection enabled...\r\n");
- Interface_PutString("System will now restart...\r\n");
- /* Launch the option byte loading */
- HAL_FLASH_OB_Launch();
- }
- else
- {
- Interface_PutString("Error: Flash write protection failed...\r\n");
- }
- }
- break;
- default:
- errTimes++;
- if(errTimes > 500){
- Interface_PutString("Start program execution for max err...\r\n\r\n");
- JumpToAppWithReset();
- }
- // Interface_PutString("Invalid Number ! ==> The number should be either 1, 2, 3 or 4\r\n");
- break;
- }
- key = 0;
- }
- }
- #include "rtc.h"
- void Main_Cycle(void)
- {
- uint8_t sKey[2] = {0};
- HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 101);
- HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, 250);
- HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, 705);
- Interface_PutString("\r\n\r\nS to start\r\n\r\n");
- while(1)
- {
- #ifdef IAP_YMODEM_ATY_USB
- if(hcdc->RxLength > 1024){
- uint8_t t[1] = {0};
- Interface_Receive(t, 1, 10);
- continue;
- }
- #endif
- if(1)
- {
- if(Interface_Receive(sKey, 2, IAP_S_TIME) == HAL_OK)
- {
- if(sKey[0] == 'S')
- {
- uint8_t verStr[] = "BLA_V_1_01_250705\r\n";
- Interface_Transmit(verStr, sizeof(verStr), 100);
- if(sKey[1] == '3'){
- Interface_Clean();
- Interface_PutString("\r\nStart program execution...\r\n");
- JumpToAppWithReset();
- }
-
- else if(sKey[1] == '1'){
- Interface_Clean();
- if(Interface_Download() != COM_OK){
- Interface_PutString("\r\nStart program execution...\r\n");
- JumpToAppWithReset();
- }
- }
- else{
- Interface_Clean();
- Main_Menu();
- }
- }
- else{
- Interface_Clean();
- }
- }
- else{
- Interface_Clean();
- Main_Menu();
- }
- }
- /* Keep the user application running */
- else
- {
- JumpToAppWithReset();
- }
- }
- }
- /* ****************************************************************************/
- /* interface realize **********************************************************/
- /**
- * @brief Print a string on the HyperTerminal
- * @param p_string: The string to be printed
- * @retval send state
- */
- HAL_StatusTypeDef Interface_PutString(uint8_t* p_string)
- {
- #ifdef IAP_YMODEM_ATY_DBG
- uint16_t length = 0;
- while(p_string[length] != '\0')
- {
- length++;
- }
- return Interface_Transmit(p_string, length, TX_TIMEOUT);
- #else
- return Interface_Transmit("", 0, TX_TIMEOUT);;
- #endif
- }
- /**
- * @brief Transmit a byte to the HyperTerminal
- * @param bytes The byte to be sent
- * @retval send state
- */
- HAL_StatusTypeDef Interface_PutByte(uint8_t bytes)
- {
- return Interface_Transmit(&bytes, 1, TX_TIMEOUT);
- }
- /**
- * @brief Download a file
- * @retval download state
- */
- COM_StatusTypeDef Interface_Download(void)
- {
- uint8_t number[11] = {0};
- uint32_t size = 0;
- COM_StatusTypeDef result;
- Interface_PutString("\r\nWaiting for the file to be sent... (press 'a' to abort)\r\n");
- result = Ymodem_Receive(&size);
- if(result == COM_OK)
- {
- Interface_PutString("\r\n\r\nProgramming Completed Successfully!\n\r--------------------------------\r\n Name: ");
- Interface_PutString(aFileName);
- Int2Str(number, size);
- Interface_PutString("\r\nSize: ");
- Interface_PutString(number);
- Interface_PutString(" Bytes\r\n");
- Interface_PutString("-------------------\r\n");
- }
- else if(result == COM_LIMIT)
- {
- Interface_PutString("\r\nThe image size is higher than the allowed space memory!\n\r");
- }
- else if(result == COM_DATA)
- {
- Interface_PutString("\r\nVerification failed!\n\r");
- }
- else if(result == COM_ABORT)
- {
- Interface_PutString("\r\nAborted by user.\n\r");
- }
- else
- {
- Interface_PutString("\r\nFailed to receive the file!\r\n");
- }
- return result;
- }
- /**
- * @brief Upload a file
- */
- void Interface_Upload(void)
- {
- uint8_t status = 0;
- Interface_PutString("\r\n\r\nSelect receive file... (press 'a' to abort)\r\n");
- while(1)
- {
- Interface_Receive(&status, 1, RX_TIMEOUT);
- if(status == CRC16)
- {
- /* Transmit the flash image through ymodem protocol */
- status = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (const uint8_t*)"UploadedFlashImage.bin", USER_FLASH_SIZE);
- if(status != 0)
- {
- if(status == COM_ABORT)
- Interface_PutString("\r\nAborted by user.\n\r");
- else
- Interface_PutString("\r\nError occurred while transmitting file\r\n");
- }
- else
- {
- Interface_PutString("\r\nFile uploaded successfully\r\n");
- }
- break;
- }
- else if(status == ABORT1 || status == ABORT2)
- {
- Interface_PutString("\r\nAborted by user.\n\r");
- break;
- }
- }
- }
- /* common *********************************************************************/
- /**
- * @brief Convert an Integer to a string
- * @param p_str: The string output pointer
- * @param intnum: The integer to be converted
- */
- void Int2Str(uint8_t* p_str, uint32_t intnum)
- {
- uint32_t i, divider = 1000000000, pos = 0, status = 0;
- for(i = 0; i < 10; i++)
- {
- p_str[pos++] = (intnum / divider) + 48;
- intnum = intnum % divider;
- divider /= 10;
- if((p_str[pos - 1] == '0') & (status == 0))
- {
- pos = 0;
- }
- else
- {
- status++;
- }
- }
- }
- /**
- * @brief Convert a string to an integer
- * @param p_inputstr: The string to be converted
- * @param p_intnum: The integer value
- * @retval 1: Correct
- * 0: Error
- */
- uint32_t Str2Int(uint8_t* p_inputstr, uint32_t* p_intnum)
- {
- uint32_t i = 0, res = 0;
- uint32_t val = 0;
- if((p_inputstr[0] == '0') && ((p_inputstr[1] == 'x') || (p_inputstr[1] == 'X')))
- {
- i = 2;
- while((i < 11) && (p_inputstr[i] != '\0'))
- {
- if(ISVALIDHEX(p_inputstr[i]))
- {
- val = (val << 4) + CONVERTHEX(p_inputstr[i]);
- }
- else
- {
- /* Return 0, Invalid input */
- res = 0;
- break;
- }
- i++;
- }
- /* valid result */
- if(p_inputstr[i] == '\0')
- {
- *p_intnum = val;
- res = 1;
- }
- }
- else /* max 10-digit decimal input */
- {
- while((i < 11) && (res != 1))
- {
- if(p_inputstr[i] == '\0')
- {
- *p_intnum = val;
- /* return 1 correct */
- res = 1;
- }
- else if(((p_inputstr[i] == 'k') || (p_inputstr[i] == 'K')) && (i > 0))
- {
- val = val << 10;
- *p_intnum = val;
- res = 1;
- }
- else if(((p_inputstr[i] == 'm') || (p_inputstr[i] == 'M')) && (i > 0))
- {
- val = val << 20;
- *p_intnum = val;
- res = 1;
- }
- else if(ISVALIDDEC(p_inputstr[i]))
- {
- val = val * 10 + CONVERTDEC(p_inputstr[i]);
- }
- else
- {
- /* return 0, Invalid input */
- res = 0;
- break;
- }
- i++;
- }
- }
- return res;
- }
- /* flash_if *******************************************************************/
- /**
- * @brief Unlocks Flash for write access
- */
- void FLASH_If_Init(void)
- {
- /* Unlock the Program memory */
- HAL_FLASH_Unlock();
- /* Clear all FLASH flags */
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
- /* Unlock the Program memory */
- HAL_FLASH_Lock();
- }
- /**
- * @brief This function does an erase of all user flash area
- * @param start: start of user flash area
- * @retval FLASHIF_OK : user flash area successfully erased
- * FLASHIF_ERASEKO : error occurred
- */
- uint32_t FLASH_If_Erase(uint32_t start)
- {
- uint32_t NbrOfPages = 0;
- uint32_t PageError = 0;
- FLASH_EraseInitTypeDef pEraseInit;
- HAL_StatusTypeDef status = HAL_OK;
- /* Unlock the Flash to enable the flash control register access */
- HAL_FLASH_Unlock();
- /* Get the sector where start the user flash area */
- NbrOfPages = (USER_FLASH_END_ADDRESS - start) / FLASH_PAGE_SIZE;
- pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
- pEraseInit.PageAddress = start;
- pEraseInit.Banks = FLASH_BANK_1;
- pEraseInit.NbPages = NbrOfPages;
- status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) */
- HAL_FLASH_Lock();
- if(status != HAL_OK)
- {
- /* Error occurred while page erase */
- return FLASHIF_ERASEKO;
- }
- return FLASHIF_OK;
- }
- /**
- * @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 destination: start address for target location
- * @param p_source: pointer on buffer with data to write
- * @param length: length of data buffer (unit is 32-bit word)
- * @retval uint32_t 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(uint32_t destination, uint32_t* p_source, uint32_t length)
- {
- uint32_t i = 0;
- /* Unlock the Flash to enable the flash control register access */
- HAL_FLASH_Unlock();
- for(i = 0; (i < length) && (destination <= (USER_FLASH_END_ADDRESS - 4)); i++)
- {
- /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
- be done by word */
- if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, destination, *(uint32_t*)(p_source + i)) == HAL_OK)
- {
- /* Check the written value */
- if(*(uint32_t*)destination != *(uint32_t*)(p_source + i))
- {
- /* Flash content doesn't match SRAM content */
- return(FLASHIF_WRITINGCTRL_ERROR);
- }
- /* Increment FLASH destination address */
- destination += 4;
- }
- else
- {
- /* Error occurred while writing data in Flash memory */
- return (FLASHIF_WRITING_ERROR);
- }
- }
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) */
- HAL_FLASH_Lock();
- return (FLASHIF_OK);
- }
- /**
- * @brief Returns the write protection status of application flash area.
- * @retval If a sector in application area is write-protected returned value is a combinaison
- of the possible values : FLASHIF_PROTECTION_WRPENABLED, FLASHIF_PROTECTION_PCROPENABLED, ...
- * If no sector is write-protected FLASHIF_PROTECTION_NONE is returned.
- */
- uint32_t FLASH_If_GetWriteProtectionStatus(void)
- {
- uint32_t ProtectedPAGE = FLASHIF_PROTECTION_NONE;
- FLASH_OBProgramInitTypeDef OptionsBytesStruct;
- /* Unlock the Flash to enable the flash control register access */
- HAL_FLASH_Unlock();
- /* Check if there are write protected sectors inside the user flash area */
- HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) */
- HAL_FLASH_Lock();
- /* Get pages already write protected */
- ProtectedPAGE = ~(OptionsBytesStruct.WRPPage) & FLASH_PAGE_TO_BE_PROTECTED;
- /* Check if desired pages are already write protected */
- if(ProtectedPAGE != 0)
- {
- /* Some sectors inside the user flash area are write protected */
- return FLASHIF_PROTECTION_WRPENABLED;
- }
- else
- {
- /* No write protected sectors inside the user flash area */
- return FLASHIF_PROTECTION_NONE;
- }
- }
- /**
- * @brief Configure the write protection status of user flash area.
- * @param protectionstate : FLASHIF_WRP_DISABLE or FLASHIF_WRP_ENABLE the protection
- * @retval uint32_t FLASHIF_OK if change is applied.
- */
- uint32_t FLASH_If_WriteProtectionConfig(uint32_t protectionstate)
- {
- uint32_t ProtectedPAGE = 0x0;
- FLASH_OBProgramInitTypeDef config_new, config_old;
- HAL_StatusTypeDef result = HAL_OK;
- /* Get pages write protection status */
- HAL_FLASHEx_OBGetConfig(&config_old);
- /* The parameter says whether we turn the protection on or off */
- config_new.WRPState = (protectionstate == FLASHIF_WRP_ENABLE ? OB_WRPSTATE_ENABLE : OB_WRPSTATE_DISABLE);
- /* We want to modify only the Write protection */
- config_new.OptionType = OPTIONBYTE_WRP;
- /* No read protection, keep BOR and reset settings */
- config_new.RDPLevel = OB_RDP_LEVEL_0;
- config_new.USERConfig = config_old.USERConfig;
- /* Get pages already write protected */
- ProtectedPAGE = config_old.WRPPage | FLASH_PAGE_TO_BE_PROTECTED;
- /* Unlock the Flash to enable the flash control register access */
- HAL_FLASH_Unlock();
- /* Unlock the Options Bytes */
- HAL_FLASH_OB_Unlock();
- /* Erase all the option Bytes */
- result = HAL_FLASHEx_OBErase();
- if(result == HAL_OK)
- {
- config_new.WRPPage = ProtectedPAGE;
- result = HAL_FLASHEx_OBProgram(&config_new);
- }
- return (result == HAL_OK ? FLASHIF_OK : FLASHIF_PROTECTION_ERRROR);
- }
- /* ymodem *********************************************************************/
- /* activate the CRC16 integrity */
- #define CRC16_F
- /* ATTENTION - please keep this variable 32bit alligned */
- uint8_t aPacketData[PACKET_1K_SIZE + PACKET_DATA_INDEX + PACKET_TRAILER_SIZE];
- uint8_t aFileName[FILE_NAME_LENGTH];
- /**
- * @brief Receive a packet from sender
- * @param data
- * @param length
- * 0: end of transmission
- * 2: abort by sender
- * >0: packet length
- * @param timeout
- * @retval HAL_OK: normally return
- * HAL_BUSY: abort by user
- */
- static HAL_StatusTypeDef ReceivePacket(uint8_t* p_data, uint32_t* p_length, uint32_t timeout)
- {
- uint32_t crc;
- uint32_t packet_size = 0;
- HAL_StatusTypeDef status;
- uint8_t byteOne;
- *p_length = 0;
- status = Interface_Receive(&byteOne, 1, timeout);
- if(status == HAL_OK)
- {
- switch(byteOne)
- {
- case SOH:
- packet_size = PACKET_SIZE;
- break;
- case STX:
- packet_size = PACKET_1K_SIZE;
- break;
- case EOT:
- break;
- case CA:
- if((Interface_Receive(&byteOne, 1, timeout) == HAL_OK) && (byteOne == CA))
- {
- packet_size = 2;
- }
- else
- {
- status = HAL_ERROR;
- }
- break;
- case ABORT1:
- case ABORT2:
- status = HAL_BUSY;
- break;
- default:
- status = HAL_ERROR;
- break;
- }
- *p_data = byteOne;
- if(packet_size >= PACKET_SIZE)
- {
- status = Interface_Receive(&p_data[PACKET_NUMBER_INDEX], packet_size + PACKET_OVERHEAD_SIZE, timeout);
- /* Simple packet sanity check */
- if(status == HAL_OK)
- {
- if(p_data[PACKET_NUMBER_INDEX] != ((p_data[PACKET_CNUMBER_INDEX]) ^ NEGATIVE_BYTE))
- {
- packet_size = 0;
- status = HAL_ERROR;
- }
- else
- {
- /* Check packet CRC */
- crc = p_data[packet_size + PACKET_DATA_INDEX] << 8;
- crc += p_data[packet_size + PACKET_DATA_INDEX + 1];
- if(Cal_CRC16(&p_data[PACKET_DATA_INDEX], packet_size) != crc)
- {
- packet_size = 0;
- status = HAL_ERROR;
- }
- }
- }
- else
- {
- packet_size = 0;
- }
- }
- }
- *p_length = packet_size;
- return status;
- }
- /**
- * @brief Prepare the first block
- * @param p_data: output buffer
- * @param p_file_name: name of the file to be sent
- * @param length: length of the file to be sent in bytes
- */
- static void PrepareIntialPacket(uint8_t* p_data, const uint8_t* p_file_name, uint32_t length)
- {
- uint32_t i, j = 0;
- uint8_t astring[10];
- /* first 3 bytes are constant */
- p_data[PACKET_START_INDEX] = SOH;
- p_data[PACKET_NUMBER_INDEX] = 0x00;
- p_data[PACKET_CNUMBER_INDEX] = 0xff;
- /* Filename written */
- for(i = 0; (p_file_name[i] != '\0') && (i < FILE_NAME_LENGTH); i++)
- {
- p_data[i + PACKET_DATA_INDEX] = p_file_name[i];
- }
- p_data[i + PACKET_DATA_INDEX] = 0x00;
- /* file size written */
- Int2Str(astring, length);
- i = i + PACKET_DATA_INDEX + 1;
- while(astring[j] != '\0')
- {
- p_data[i++] = astring[j++];
- }
- /* padding with zeros */
- for(j = i; j < PACKET_SIZE + PACKET_DATA_INDEX; j++)
- {
- p_data[j] = 0;
- }
- }
- /**
- * @brief Prepare the data packet
- * @param p_source: pointer to the data to be sent
- * @param p_packet: pointer to the output buffer
- * @param pkt_nr: number of the packet
- * @param size_blk: length of the block to be sent in bytes
- */
- static void PreparePacket(uint8_t* p_source, uint8_t* p_packet, uint8_t pkt_nr, uint32_t size_blk)
- {
- uint8_t* p_record;
- uint32_t i, size, packet_size;
- /* Make first three packet */
- packet_size = size_blk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE;
- size = size_blk < packet_size ? size_blk : packet_size;
- if(packet_size == PACKET_1K_SIZE)
- {
- p_packet[PACKET_START_INDEX] = STX;
- }
- else
- {
- p_packet[PACKET_START_INDEX] = SOH;
- }
- p_packet[PACKET_NUMBER_INDEX] = pkt_nr;
- p_packet[PACKET_CNUMBER_INDEX] = (~pkt_nr);
- p_record = p_source;
- /* Filename packet has valid data */
- for(i = PACKET_DATA_INDEX; i < size + PACKET_DATA_INDEX; i++)
- {
- p_packet[i] = *p_record++;
- }
- if(size <= packet_size)
- {
- for(i = size + PACKET_DATA_INDEX; i < packet_size + PACKET_DATA_INDEX; i++)
- {
- p_packet[i] = 0x1A; /* EOF (0x1A) or 0x00 */
- }
- }
- }
- /**
- * @brief Update CRC16 for input byte
- * @param crc_in input value
- * @param input byte
- */
- uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte)
- {
- uint32_t crc = crc_in;
- 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
- */
- uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size)
- {
- uint32_t crc = 0;
- const uint8_t* dataEnd = p_data + size;
- while(p_data < dataEnd)
- crc = UpdateCRC16(crc, *p_data++);
- crc = UpdateCRC16(crc, 0);
- crc = UpdateCRC16(crc, 0);
- return crc & 0xffffu;
- }
- /**
- * @brief Calculate Check sum for YModem Packet
- * @param p_data Pointer to input data
- * @param size length of input data
- * @retval uint8_t checksum value
- */
- uint8_t CalcChecksum(const uint8_t* p_data, uint32_t size)
- {
- uint32_t sum = 0;
- const uint8_t* p_data_end = p_data + size;
- while(p_data < p_data_end)
- {
- sum += *p_data++;
- }
- return (sum & 0xffu);
- }
- /* Public functions ---------------------------------------------------------*/
- /**
- * @brief Receive a file using the ymodem protocol with CRC16.
- * @param p_size The size of the file.
- * @retval COM_StatusTypeDef result of reception/programming
- */
- COM_StatusTypeDef Ymodem_Receive(uint32_t* p_size)
- {
- uint32_t i, packet_length, session_done = 0, file_done, errors = 0, session_begin = 0;
- uint32_t flashdestination, ramsource, filesize;
- uint8_t* file_ptr;
- uint8_t file_size[FILE_SIZE_LENGTH], tmp, packets_received;
- COM_StatusTypeDef result = COM_OK;
- /* Initialize flashdestination variable */
- flashdestination = APPLICATION_ADDRESS;
- while((session_done == 0) && (result == COM_OK))
- {
- packets_received = 0;
- file_done = 0;
- while((file_done == 0) && (result == COM_OK))
- {
- switch(ReceivePacket(aPacketData, &packet_length, DOWNLOAD_TIMEOUT))
- {
- case HAL_OK:
- errors = 0;
- switch(packet_length)
- {
- case 2:
- /* Abort by sender */
- Interface_PutByte(ACK);
- result = COM_ABORT;
- break;
- case 0:
- /* End of transmission */
- Interface_PutByte(ACK);
- file_done = 1;
- break;
- default:
- /* Normal packet */
- if(aPacketData[PACKET_NUMBER_INDEX] != packets_received)
- {
- Interface_PutByte(NAK);
- }
- else
- {
- if(packets_received == 0)
- {
- /* File name packet */
- if(aPacketData[PACKET_DATA_INDEX] != 0)
- {
- /* File name extraction */
- i = 0;
- file_ptr = aPacketData + PACKET_DATA_INDEX;
- while((*file_ptr != 0) && (i < FILE_NAME_LENGTH))
- {
- aFileName[i++] = *file_ptr++;
- }
- /* File size extraction */
- aFileName[i++] = '\0';
- i = 0;
- file_ptr++;
- while((*file_ptr != ' ') && (i < FILE_SIZE_LENGTH))
- {
- file_size[i++] = *file_ptr++;
- }
- file_size[i++] = '\0';
- Str2Int(file_size, &filesize);
- /* Test the size of the image to be sent */
- /* Image size is greater than Flash size */
- if(*p_size > (USER_FLASH_SIZE + 1))
- {
- /* End session */
- tmp = CA;
- Interface_Transmit(&tmp, 1, NAK_TIMEOUT);
- Interface_Transmit(&tmp, 1, NAK_TIMEOUT);
- result = COM_LIMIT;
- }
- /* Erase user application area */
- FLASH_If_Erase(APPLICATION_ADDRESS);
- *p_size = filesize;
- Interface_PutByte(ACK);
- Interface_PutByte(CRC16);
- }
- /* File header packet is empty, end session */
- else
- {
- Interface_PutByte(ACK);
- file_done = 1;
- session_done = 1;
- break;
- }
- }
- else /* Data packet */
- {
- ramsource = (uint32_t)&aPacketData[PACKET_DATA_INDEX];
- /* Write received data in Flash */
- if(FLASH_If_Write(flashdestination, (uint32_t*)ramsource, packet_length / 4) == FLASHIF_OK)
- {
- flashdestination += packet_length;
- Interface_PutByte(ACK);
- }
- else /* An error occurred while writing to Flash memory */
- {
- /* End session */
- Interface_PutByte(CA);
- Interface_PutByte(CA);
- result = COM_DATA;
- }
- }
- packets_received++;
- session_begin = 1;
- }
- break;
- }
- break;
- case HAL_BUSY: /* Abort actually */
- Interface_PutByte(CA);
- Interface_PutByte(CA);
- result = COM_ABORT;
- break;
- default:
- if(session_begin > 0)
- {
- errors++;
- }
- if(errors > MAX_ERRORS)
- {
- /* Abort communication */
- Interface_PutByte(CA);
- Interface_PutByte(CA);
- }
- else
- {
- /* Ask for a packet */
- Interface_PutByte(CRC16);
- }
- break;
- }
- }
- }
- return result;
- }
- /**
- * @brief Transmit a file using the ymodem protocol
- * @param p_buf: Address of the first byte
- * @param p_file_name: Name of the file sent
- * @param file_size: Size of the transmission
- * @retval COM_StatusTypeDef result of the communication
- */
- COM_StatusTypeDef Ymodem_Transmit(uint8_t* p_buf, const uint8_t* p_file_name, uint32_t file_size)
- {
- uint32_t errors = 0, ack_recpt = 0, size = 0, pkt_size;
- uint8_t* p_buf_int;
- COM_StatusTypeDef result = COM_OK;
- uint32_t blk_number = 1;
- uint8_t a_rx_ctrl[2];
- uint8_t i;
- #ifdef CRC16_F
- uint32_t temp_crc;
- #else /* CRC16_F */
- uint8_t temp_chksum;
- #endif /* CRC16_F */
- /* Prepare first block - header */
- PrepareIntialPacket(aPacketData, p_file_name, file_size);
- while((!ack_recpt) && (result == COM_OK))
- {
- /* Send Packet */
- Interface_Transmit(&aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
- /* Send CRC or Check Sum based on CRC16_F */
- #ifdef CRC16_F
- temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Interface_PutByte(temp_crc >> 8);
- Interface_PutByte(temp_crc & 0xFF);
- #else /* CRC16_F */
- temp_chksum = CalcChecksum(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Interface_PutByte(temp_chksum);
- #endif /* CRC16_F */
- /* Wait for Ack and 'C' */
- if(Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
- {
- if(a_rx_ctrl[0] == ACK)
- {
- ack_recpt = 1;
- }
- else if(a_rx_ctrl[0] == CA)
- {
- if((Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
- {
- HAL_Delay(2);
- Interface_Clean();
- result = COM_ABORT;
- }
- }
- else if(a_rx_ctrl[0] == ABORT1 || a_rx_ctrl[0] == ABORT2)
- {
- result = COM_ABORT;
- }
- }
- else
- {
- errors++;
- }
- if(errors >= MAX_ERRORS)
- {
- result = COM_ERROR;
- }
- }
- p_buf_int = p_buf;
- size = file_size;
- /* Here 1024 bytes length is used to send the packets */
- while((size) && (result == COM_OK))
- {
- /* Prepare next packet */
- PreparePacket(p_buf_int, aPacketData, blk_number, size);
- ack_recpt = 0;
- a_rx_ctrl[0] = 0;
- errors = 0;
- /* Resend packet if NAK for few times else end of communication */
- while((!ack_recpt) && (result == COM_OK))
- {
- /* Send next packet */
- if(size >= PACKET_1K_SIZE)
- {
- pkt_size = PACKET_1K_SIZE;
- }
- else
- {
- pkt_size = PACKET_SIZE;
- }
- Interface_Transmit(&aPacketData[PACKET_START_INDEX], pkt_size + PACKET_HEADER_SIZE, NAK_TIMEOUT);
- /* Send CRC or Check Sum based on CRC16_F */
- #ifdef CRC16_F
- temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], pkt_size);
- Interface_PutByte(temp_crc >> 8);
- Interface_PutByte(temp_crc & 0xFF);
- #else /* CRC16_F */
- temp_chksum = CalcChecksum(&aPacketData[PACKET_DATA_INDEX], pkt_size);
- Interface_PutByte(temp_chksum);
- #endif /* CRC16_F */
- /* Wait for Ack */
- if((Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == ACK))
- {
- ack_recpt = 1;
- if(size > pkt_size)
- {
- p_buf_int += pkt_size;
- size -= pkt_size;
- if(blk_number == (USER_FLASH_SIZE / PACKET_1K_SIZE))
- {
- result = COM_LIMIT; /* boundary error */
- }
- else
- {
- blk_number++;
- }
- }
- else
- {
- p_buf_int += pkt_size;
- size = 0;
- }
- }
- else
- {
- errors++;
- }
- /* Resend packet if NAK for a count of 10 else end of communication */
- if(errors >= MAX_ERRORS)
- {
- result = COM_ERROR;
- }
- }
- }
- /* Sending End Of Transmission char */
- ack_recpt = 0;
- a_rx_ctrl[0] = 0x00;
- errors = 0;
- while((!ack_recpt) && (result == COM_OK))
- {
- Interface_PutByte(EOT);
- /* Wait for Ack */
- if(Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
- {
- if(a_rx_ctrl[0] == ACK)
- {
- ack_recpt = 1;
- }
- else if(a_rx_ctrl[0] == CA)
- {
- if((Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
- {
- HAL_Delay(2);
- Interface_Clean();
- result = COM_ABORT;
- }
- }
- }
- else
- {
- errors++;
- }
- if(errors >= MAX_ERRORS)
- {
- result = COM_ERROR;
- }
- }
- /* Empty packet sent - some terminal emulators need this to close session */
- if(result == COM_OK)
- {
- /* Preparing an empty packet */
- aPacketData[PACKET_START_INDEX] = SOH;
- aPacketData[PACKET_NUMBER_INDEX] = 0;
- aPacketData[PACKET_CNUMBER_INDEX] = 0xFF;
- for(i = PACKET_DATA_INDEX; i < (PACKET_SIZE + PACKET_DATA_INDEX); i++)
- {
- aPacketData[i] = 0x00;
- }
- /* Send Packet */
- Interface_Transmit(&aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
- /* Send CRC or Check Sum based on CRC16_F */
- #ifdef CRC16_F
- temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Interface_PutByte(temp_crc >> 8);
- Interface_PutByte(temp_crc & 0xFF);
- #else /* CRC16_F */
- temp_chksum = CalcChecksum(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
- Interface_PutByte(temp_chksum);
- #endif /* CRC16_F */
- /* Wait for Ack and 'C' */
- if(Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
- {
- if(a_rx_ctrl[0] == CA)
- {
- HAL_Delay(2);
- Interface_Clean();
- result = COM_ABORT;
- }
- }
- }
- return result; /* File transmitted successfully */
- }
- #endif /* __IAP_YMODEM_ATY_C */
- /******************************** End Of File *********************************/
|