IAP_YMODEM_ATY.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334
  1. /**
  2. * @file IAP_YMODEM_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of IAP with YMODEM for all embedded device
  20. *
  21. * @version
  22. * - 1_01_240911 > ATY
  23. * -# Preliminary version, first Release
  24. ********************************************************************************
  25. */
  26. #ifndef __IAP_YMODEM_ATY_C
  27. #define __IAP_YMODEM_ATY_C
  28. #include "IAP_YMODEM_ATY.h"
  29. /******************************* For user *************************************/
  30. uint8_t EmptyBuf[1] = {0};
  31. USBD_CDC_HandleTypeDef* hcdc;
  32. uint32_t PUT_IN_CDC_Receive_FS = 0;
  33. uint8_t ucdcRcvOverFlag = 1;
  34. uint32_t ucdcRcvLastTime = 0;
  35. uint8_t ucdcRcvBuffer[APP_RX_DATA_SIZE] = {0};
  36. uint32_t rcvDbg = 0;
  37. uint8_t temp_str[12] = {0};
  38. void All_Reset(void)
  39. {
  40. // Disable global interrupts
  41. __disable_irq();
  42. HAL_UART_DeInit(&Interface_UART);
  43. __HAL_RCC_USB_CLK_DISABLE();
  44. HAL_RCC_DeInit();
  45. HAL_DeInit();
  46. // Disable and reset SysTick timer
  47. SysTick->CTRL = 0;
  48. SysTick->LOAD = 0;
  49. SysTick->VAL = 0;
  50. // Optional: Disable and clear all NVIC interrupts
  51. for(int i = 0; i < 8; i++) {
  52. NVIC->ICER[i] = 0xFFFFFFFF; // Disable all interrupts
  53. NVIC->ICPR[i] = 0xFFFFFFFF; // Clear pending status
  54. }
  55. // Optional: Reset interrupt priority registers
  56. // for(int i = 0; i < 48; i++) {
  57. // NVIC->IP[i] = 0; // Set all priorities to default
  58. // }
  59. // Optional: Set vector table offset to App's address
  60. SCB->VTOR = APPLICATION_ADDRESS & 0x1FFFFF80;
  61. }
  62. void JumpToAppWithReset(void)
  63. {
  64. All_Reset();
  65. JumpToApp(APPLICATION_ADDRESS);
  66. }
  67. void Interface_Clean(void)
  68. {
  69. #ifndef IAP_YMODEM_ATY_USB
  70. __HAL_UART_FLUSH_DRREGISTER(&Interface_UART);
  71. #else
  72. PUT_IN_CDC_Receive_FS = 0;
  73. ucdcRcvOverFlag = 1;
  74. #endif
  75. }
  76. uint32_t timeoutCount = 0;
  77. uint32_t timeoutFinal = 100;
  78. HAL_StatusTypeDef Interface_Receive(uint8_t* bytes, uint16_t size, uint32_t timeout)
  79. {
  80. #ifndef IAP_YMODEM_ATY_USB
  81. HAL_StatusTypeDef state = HAL_UART_Receive(&Interface_UART, bytes, size, timeout);
  82. uint8_t length = (size > 12 ? 12 : size);
  83. memcpy(temp_str, bytes, length);
  84. return state;
  85. // return HAL_UART_Receive(&Interface_UART, bytes, size, timeout);
  86. #else
  87. hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  88. if(hcdc->RxLength > APP_RX_DATA_SIZE)
  89. return HAL_ERROR;
  90. timeoutCount = 0;
  91. timeoutFinal = timeout;
  92. while(PUT_IN_CDC_Receive_FS == 0){
  93. timeoutCount++;
  94. if(timeoutCount > timeoutFinal){
  95. timeoutCount = 0;
  96. USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  97. return HAL_TIMEOUT;
  98. }
  99. HAL_Delay(1);
  100. }
  101. if(ucdcRcvOverFlag == 0)
  102. {
  103. while(HAL_GetTick() - ucdcRcvLastTime < 200)
  104. {
  105. }
  106. ucdcRcvOverFlag = 1;
  107. }
  108. if(PUT_IN_CDC_Receive_FS > 0 && PUT_IN_CDC_Receive_FS <= APP_RX_DATA_SIZE){
  109. uint16_t copySize = (PUT_IN_CDC_Receive_FS > size) ? size : PUT_IN_CDC_Receive_FS;
  110. memcpy(bytes, ucdcRcvBuffer, copySize);
  111. PUT_IN_CDC_Receive_FS -= copySize;
  112. memcpy(ucdcRcvBuffer, ucdcRcvBuffer + copySize, PUT_IN_CDC_Receive_FS);
  113. // Interface_Clean();
  114. }
  115. return HAL_OK;
  116. #endif
  117. }
  118. HAL_StatusTypeDef Interface_Transmit(uint8_t* bytes, uint16_t size, uint32_t timeout)
  119. {
  120. #ifndef IAP_YMODEM_ATY_USB
  121. /* May be timeouted... */
  122. if(Interface_UART.gState == HAL_UART_STATE_TIMEOUT)
  123. {
  124. Interface_UART.gState = HAL_UART_STATE_READY;
  125. }
  126. return HAL_UART_Transmit(&Interface_UART, bytes, size, timeout);
  127. #else
  128. Interface_Clean();
  129. ucdcRcvOverFlag = 1;
  130. timeoutCount = 0;
  131. timeoutFinal = timeout;
  132. while(CDC_Transmit_FS(bytes, size) != HAL_OK){
  133. timeoutCount++;
  134. if(timeoutCount > timeoutFinal)
  135. return HAL_TIMEOUT;
  136. HAL_Delay(1);
  137. }
  138. return HAL_OK;
  139. #endif
  140. }
  141. /**
  142. * @brief Print a string on the HyperTerminal
  143. * @param p_string: The string to be printed
  144. * @retval None
  145. */
  146. HAL_StatusTypeDef Interface_PutString(uint8_t* p_string)
  147. {
  148. uint16_t length = 0;
  149. while(p_string[length] != '\0')
  150. {
  151. length++;
  152. }
  153. return Interface_Transmit(p_string, length, TX_TIMEOUT);
  154. }
  155. /**
  156. * @brief Transmit a byte to the HyperTerminal
  157. * @param param The byte to be sent
  158. * @retval send state
  159. */
  160. HAL_StatusTypeDef Interface_PutByte(uint8_t bytes)
  161. {
  162. return Interface_Transmit(&bytes, 1, TX_TIMEOUT);
  163. }
  164. uint32_t FlashProtection = 0;
  165. /**
  166. * @brief Download a file
  167. * @param None
  168. * @retval None
  169. */
  170. COM_StatusTypeDef Interface_Download(void)
  171. {
  172. uint8_t number[11] = {0};
  173. uint32_t size = 0;
  174. COM_StatusTypeDef result;
  175. Interface_PutString("\r\nWaiting for the file to be sent ... (press 'a' to abort)\r\n");
  176. result = Ymodem_Receive(&size);
  177. if(result == COM_OK)
  178. {
  179. Interface_PutString("\r\n\r\nProgramming Completed Successfully!\n\r--------------------------------\r\n Name: ");
  180. Interface_PutString(aFileName);
  181. Int2Str(number, size);
  182. Interface_PutString("\r\nSize: ");
  183. Interface_PutString(number);
  184. Interface_PutString(" Bytes\r\n");
  185. Interface_PutString("-------------------\r\n");
  186. }
  187. else if(result == COM_LIMIT)
  188. {
  189. Interface_PutString("\r\nThe image size is higher than the allowed space memory!\n\r");
  190. }
  191. else if(result == COM_DATA)
  192. {
  193. Interface_PutString("\r\nVerification failed!\n\r");
  194. }
  195. else if(result == COM_ABORT)
  196. {
  197. Interface_PutString("\r\nAborted by user.\n\r");
  198. }
  199. else
  200. {
  201. Interface_PutString("\r\nFailed to receive the file!\r\n");
  202. }
  203. return result;
  204. }
  205. /**
  206. * @brief Upload a file
  207. * @param None
  208. * @retval None
  209. */
  210. void Interface_Upload(void)
  211. {
  212. uint8_t status = 0;
  213. Interface_PutString("\r\n\r\nSelect receive file ... (press 'a' to abort)\r\n");
  214. while(1)
  215. {
  216. Interface_Receive(&status, 1, RX_TIMEOUT);
  217. if(status == CRC16)
  218. {
  219. /* Transmit the flash image through ymodem protocol */
  220. status = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (const uint8_t*)"UploadedFlashImage.bin", USER_FLASH_SIZE);
  221. if(status != 0)
  222. {
  223. if(status == COM_ABORT)
  224. Interface_PutString("\r\nAborted by user.\n\r");
  225. else
  226. Interface_PutString("\r\nError occurred while transmitting file\r\n");
  227. }
  228. else
  229. {
  230. Interface_PutString("\r\nFile uploaded successfully\r\n");
  231. }
  232. break;
  233. }
  234. else if(status == ABORT1 || status == ABORT2)
  235. {
  236. Interface_PutString("\r\nAborted by user.\n\r");
  237. break;
  238. }
  239. }
  240. }
  241. uint16_t errTimes = 0;
  242. uint8_t key = 0;
  243. /**
  244. * @brief Display the Main Menu on HyperTerminal
  245. * @param None
  246. * @retval None
  247. */
  248. void Main_Menu(void)
  249. {
  250. /* Initialise Flash */
  251. FLASH_If_Init();
  252. /* Test if any sector of Flash memory where user application will be loaded is write protected */
  253. FlashProtection = FLASH_If_GetWriteProtectionStatus();
  254. #ifdef IAP_YMODEM_ATY_DBG
  255. Interface_PutString("\r\n\r\n=================== Main Menu ============================\r\n\r\n");
  256. Interface_PutString(" Download image to the internal Flash ----------------- 1\r\n\r\n");
  257. Interface_PutString(" Upload image from the internal Flash ----------------- 2\r\n\r\n");
  258. Interface_PutString(" Execute the loaded application ----------------------- 3\r\n\r\n");
  259. if(FlashProtection != FLASHIF_PROTECTION_NONE)
  260. {
  261. Interface_PutString(" Disable the write protection ------------------------- 4\r\n\r\n");
  262. }
  263. else
  264. {
  265. Interface_PutString(" Enable the write protection -------------------------- 4\r\n\r\n");
  266. }
  267. Interface_PutString("==========================================================\r\n\r\n");
  268. #endif
  269. while(1)
  270. {
  271. /* Clean the input path */
  272. Interface_Clean();
  273. /* Receive key */
  274. uint16_t autoBootTime = 50000;
  275. Interface_Receive(&key, 1, autoBootTime);
  276. // if(key == 0)
  277. // key = 51;
  278. if(1){
  279. switch(key)
  280. {
  281. case '*':
  282. /* Upload user application from the Flash */
  283. Interface_Upload();
  284. break;
  285. case '2':
  286. /* Upload user application from the Flash */
  287. Interface_PutString("\r\nAuthorize wrong!\r\n\r\n");
  288. break;
  289. case '1':
  290. /* Download user application in the Flash */
  291. if(Interface_Download() != COM_OK)
  292. break;
  293. case '3':
  294. Interface_PutString("\r\nStart program execution......\r\n");
  295. JumpToAppWithReset();
  296. break;
  297. case '4':
  298. if(FlashProtection != FLASHIF_PROTECTION_NONE)
  299. {
  300. /* Disable the write protection */
  301. if(FLASH_If_WriteProtectionConfig(FLASHIF_WRP_DISABLE) == FLASHIF_OK)
  302. {
  303. Interface_PutString("Write protection disabled...\r\n");
  304. Interface_PutString("System will now restart...\r\n");
  305. /* Launch the option byte loading */
  306. HAL_FLASH_OB_Launch();
  307. }
  308. else
  309. {
  310. Interface_PutString("Error: Flash write un-protection failed...\r\n");
  311. }
  312. }
  313. else
  314. {
  315. if(FLASH_If_WriteProtectionConfig(FLASHIF_WRP_ENABLE) == FLASHIF_OK)
  316. {
  317. Interface_PutString("Write protection enabled...\r\n");
  318. Interface_PutString("System will now restart...\r\n");
  319. /* Launch the option byte loading */
  320. HAL_FLASH_OB_Launch();
  321. }
  322. else
  323. {
  324. Interface_PutString("Error: Flash write protection failed...\r\n");
  325. }
  326. }
  327. break;
  328. default:
  329. errTimes++;
  330. if(errTimes > 500){
  331. Interface_PutString("Start program execution for max err......\r\n\r\n");
  332. JumpToAppWithReset();
  333. }
  334. // Interface_PutString("Invalid Number ! ==> The number should be either 1, 2, 3 or 4\r\n");
  335. break;
  336. }
  337. }
  338. }
  339. }
  340. uint8_t sKey = 0;
  341. void Main_Cycle(void)
  342. {
  343. Interface_PutString("\r\n\r\nS to start\r\n\r\n");
  344. // Interface_Clean();
  345. while(1)
  346. {
  347. if(1)
  348. {
  349. // if(Interface_Receive(&sKey, 1, DOWNLOAD_TIMEOUT) != HAL_OK)
  350. // {
  351. // Interface_PutByte(CRC16);
  352. // }
  353. if(Interface_Receive(&sKey, 1, RX_TIMEOUT) == HAL_OK)
  354. {
  355. if(sKey == 'S')
  356. {
  357. Interface_Clean();
  358. Main_Menu();
  359. }
  360. else{
  361. Interface_Clean();
  362. }
  363. }
  364. else{
  365. Interface_Clean();
  366. }
  367. }
  368. /* Keep the user application running */
  369. else
  370. {
  371. JumpToAppWithReset();
  372. }
  373. }
  374. }
  375. /* ****************************************************************************/
  376. /* common *********************************************************************/
  377. /**
  378. * @brief Convert an Integer to a string
  379. * @param p_str: The string output pointer
  380. * @param intnum: The integer to be converted
  381. * @retval None
  382. */
  383. void Int2Str(uint8_t* p_str, uint32_t intnum)
  384. {
  385. uint32_t i, divider = 1000000000, pos = 0, status = 0;
  386. for(i = 0; i < 10; i++)
  387. {
  388. p_str[pos++] = (intnum / divider) + 48;
  389. intnum = intnum % divider;
  390. divider /= 10;
  391. if((p_str[pos - 1] == '0') & (status == 0))
  392. {
  393. pos = 0;
  394. }
  395. else
  396. {
  397. status++;
  398. }
  399. }
  400. }
  401. /**
  402. * @brief Convert a string to an integer
  403. * @param p_inputstr: The string to be converted
  404. * @param p_intnum: The integer value
  405. * @retval 1: Correct
  406. * 0: Error
  407. */
  408. uint32_t Str2Int(uint8_t* p_inputstr, uint32_t* p_intnum)
  409. {
  410. uint32_t i = 0, res = 0;
  411. uint32_t val = 0;
  412. if((p_inputstr[0] == '0') && ((p_inputstr[1] == 'x') || (p_inputstr[1] == 'X')))
  413. {
  414. i = 2;
  415. while((i < 11) && (p_inputstr[i] != '\0'))
  416. {
  417. if(ISVALIDHEX(p_inputstr[i]))
  418. {
  419. val = (val << 4) + CONVERTHEX(p_inputstr[i]);
  420. }
  421. else
  422. {
  423. /* Return 0, Invalid input */
  424. res = 0;
  425. break;
  426. }
  427. i++;
  428. }
  429. /* valid result */
  430. if(p_inputstr[i] == '\0')
  431. {
  432. *p_intnum = val;
  433. res = 1;
  434. }
  435. }
  436. else /* max 10-digit decimal input */
  437. {
  438. while((i < 11) && (res != 1))
  439. {
  440. if(p_inputstr[i] == '\0')
  441. {
  442. *p_intnum = val;
  443. /* return 1 */
  444. res = 1;
  445. }
  446. else if(((p_inputstr[i] == 'k') || (p_inputstr[i] == 'K')) && (i > 0))
  447. {
  448. val = val << 10;
  449. *p_intnum = val;
  450. res = 1;
  451. }
  452. else if(((p_inputstr[i] == 'm') || (p_inputstr[i] == 'M')) && (i > 0))
  453. {
  454. val = val << 20;
  455. *p_intnum = val;
  456. res = 1;
  457. }
  458. else if(ISVALIDDEC(p_inputstr[i]))
  459. {
  460. val = val * 10 + CONVERTDEC(p_inputstr[i]);
  461. }
  462. else
  463. {
  464. /* return 0, Invalid input */
  465. res = 0;
  466. break;
  467. }
  468. i++;
  469. }
  470. }
  471. return res;
  472. }
  473. /* ****************************************************************************/
  474. /* flash_if *******************************************************************/
  475. /**
  476. * @brief Unlocks Flash for write access
  477. * @param None
  478. * @retval None
  479. */
  480. void FLASH_If_Init(void)
  481. {
  482. /* Unlock the Program memory */
  483. HAL_FLASH_Unlock();
  484. /* Clear all FLASH flags */
  485. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  486. /* Unlock the Program memory */
  487. HAL_FLASH_Lock();
  488. }
  489. /**
  490. * @brief This function does an erase of all user flash area
  491. * @param start: start of user flash area
  492. * @retval FLASHIF_OK : user flash area successfully erased
  493. * FLASHIF_ERASEKO : error occurred
  494. */
  495. uint32_t FLASH_If_Erase(uint32_t start)
  496. {
  497. uint32_t NbrOfPages = 0;
  498. uint32_t PageError = 0;
  499. FLASH_EraseInitTypeDef pEraseInit;
  500. HAL_StatusTypeDef status = HAL_OK;
  501. /* Unlock the Flash to enable the flash control register access *************/
  502. HAL_FLASH_Unlock();
  503. /* Get the sector where start the user flash area */
  504. NbrOfPages = (USER_FLASH_END_ADDRESS - start) / FLASH_PAGE_SIZE;
  505. pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  506. pEraseInit.PageAddress = start;
  507. pEraseInit.Banks = FLASH_BANK_1;
  508. pEraseInit.NbPages = NbrOfPages;
  509. status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);
  510. /* Lock the Flash to disable the flash control register access (recommended
  511. to protect the FLASH memory against possible unwanted operation) *********/
  512. HAL_FLASH_Lock();
  513. if(status != HAL_OK)
  514. {
  515. /* Error occurred while page erase */
  516. return FLASHIF_ERASEKO;
  517. }
  518. return FLASHIF_OK;
  519. }
  520. /**
  521. * @brief This function writes a data buffer in flash (data are 32-bit aligned).
  522. * @note After writing data buffer, the flash content is checked.
  523. * @param destination: start address for target location
  524. * @param p_source: pointer on buffer with data to write
  525. * @param length: length of data buffer (unit is 32-bit word)
  526. * @retval uint32_t 0: Data successfully written to Flash memory
  527. * 1: Error occurred while writing data in Flash memory
  528. * 2: Written Data in flash memory is different from expected one
  529. */
  530. uint32_t FLASH_If_Write(uint32_t destination, uint32_t* p_source, uint32_t length)
  531. {
  532. uint32_t i = 0;
  533. /* Unlock the Flash to enable the flash control register access *************/
  534. HAL_FLASH_Unlock();
  535. for(i = 0; (i < length) && (destination <= (USER_FLASH_END_ADDRESS - 4)); i++)
  536. {
  537. /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
  538. be done by word */
  539. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, destination, *(uint32_t*)(p_source + i)) == HAL_OK)
  540. {
  541. /* Check the written value */
  542. if(*(uint32_t*)destination != *(uint32_t*)(p_source + i))
  543. {
  544. /* Flash content doesn't match SRAM content */
  545. return(FLASHIF_WRITINGCTRL_ERROR);
  546. }
  547. /* Increment FLASH destination address */
  548. destination += 4;
  549. }
  550. else
  551. {
  552. /* Error occurred while writing data in Flash memory */
  553. return (FLASHIF_WRITING_ERROR);
  554. }
  555. }
  556. /* Lock the Flash to disable the flash control register access (recommended
  557. to protect the FLASH memory against possible unwanted operation) *********/
  558. HAL_FLASH_Lock();
  559. return (FLASHIF_OK);
  560. }
  561. /**
  562. * @brief Returns the write protection status of application flash area.
  563. * @param None
  564. * @retval If a sector in application area is write-protected returned value is a combinaison
  565. of the possible values : FLASHIF_PROTECTION_WRPENABLED, FLASHIF_PROTECTION_PCROPENABLED, ...
  566. * If no sector is write-protected FLASHIF_PROTECTION_NONE is returned.
  567. */
  568. uint32_t FLASH_If_GetWriteProtectionStatus(void)
  569. {
  570. uint32_t ProtectedPAGE = FLASHIF_PROTECTION_NONE;
  571. FLASH_OBProgramInitTypeDef OptionsBytesStruct;
  572. /* Unlock the Flash to enable the flash control register access *************/
  573. HAL_FLASH_Unlock();
  574. /* Check if there are write protected sectors inside the user flash area ****/
  575. HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);
  576. /* Lock the Flash to disable the flash control register access (recommended
  577. to protect the FLASH memory against possible unwanted operation) *********/
  578. HAL_FLASH_Lock();
  579. /* Get pages already write protected ****************************************/
  580. ProtectedPAGE = ~(OptionsBytesStruct.WRPPage) & FLASH_PAGE_TO_BE_PROTECTED;
  581. /* Check if desired pages are already write protected ***********************/
  582. if(ProtectedPAGE != 0)
  583. {
  584. /* Some sectors inside the user flash area are write protected */
  585. return FLASHIF_PROTECTION_WRPENABLED;
  586. }
  587. else
  588. {
  589. /* No write protected sectors inside the user flash area */
  590. return FLASHIF_PROTECTION_NONE;
  591. }
  592. }
  593. /**
  594. * @brief Configure the write protection status of user flash area.
  595. * @param protectionstate : FLASHIF_WRP_DISABLE or FLASHIF_WRP_ENABLE the protection
  596. * @retval uint32_t FLASHIF_OK if change is applied.
  597. */
  598. uint32_t FLASH_If_WriteProtectionConfig(uint32_t protectionstate)
  599. {
  600. uint32_t ProtectedPAGE = 0x0;
  601. FLASH_OBProgramInitTypeDef config_new, config_old;
  602. HAL_StatusTypeDef result = HAL_OK;
  603. /* Get pages write protection status ****************************************/
  604. HAL_FLASHEx_OBGetConfig(&config_old);
  605. /* The parameter says whether we turn the protection on or off */
  606. config_new.WRPState = (protectionstate == FLASHIF_WRP_ENABLE ? OB_WRPSTATE_ENABLE : OB_WRPSTATE_DISABLE);
  607. /* We want to modify only the Write protection */
  608. config_new.OptionType = OPTIONBYTE_WRP;
  609. /* No read protection, keep BOR and reset settings */
  610. config_new.RDPLevel = OB_RDP_LEVEL_0;
  611. config_new.USERConfig = config_old.USERConfig;
  612. /* Get pages already write protected ****************************************/
  613. ProtectedPAGE = config_old.WRPPage | FLASH_PAGE_TO_BE_PROTECTED;
  614. /* Unlock the Flash to enable the flash control register access *************/
  615. HAL_FLASH_Unlock();
  616. /* Unlock the Options Bytes *************************************************/
  617. HAL_FLASH_OB_Unlock();
  618. /* Erase all the option Bytes ***********************************************/
  619. result = HAL_FLASHEx_OBErase();
  620. if(result == HAL_OK)
  621. {
  622. config_new.WRPPage = ProtectedPAGE;
  623. result = HAL_FLASHEx_OBProgram(&config_new);
  624. }
  625. return (result == HAL_OK ? FLASHIF_OK : FLASHIF_PROTECTION_ERRROR);
  626. }
  627. /* ****************************************************************************/
  628. /* ymodem *********************************************************************/
  629. #define CRC16_F /* activate the CRC16 integrity */
  630. /* @note ATTENTION - please keep this variable 32bit alligned */
  631. uint8_t aPacketData[PACKET_1K_SIZE + PACKET_DATA_INDEX + PACKET_TRAILER_SIZE];
  632. uint8_t aFileName[FILE_NAME_LENGTH];
  633. static void PrepareIntialPacket(uint8_t* p_data, const uint8_t* p_file_name, uint32_t length);
  634. static void PreparePacket(uint8_t* p_source, uint8_t* p_packet, uint8_t pkt_nr, uint32_t size_blk);
  635. static HAL_StatusTypeDef ReceivePacket(uint8_t* p_data, uint32_t* p_length, uint32_t timeout);
  636. uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte);
  637. uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size);
  638. uint8_t CalcChecksum(const uint8_t* p_data, uint32_t size);
  639. /**
  640. * @brief Receive a packet from sender
  641. * @param data
  642. * @param length
  643. * 0: end of transmission
  644. * 2: abort by sender
  645. * >0: packet length
  646. * @param timeout
  647. * @retval HAL_OK: normally return
  648. * HAL_BUSY: abort by user
  649. */
  650. uint8_t byteOne;
  651. static HAL_StatusTypeDef ReceivePacket(uint8_t* p_data, uint32_t* p_length, uint32_t timeout)
  652. {
  653. uint32_t crc;
  654. uint32_t packet_size = 0;
  655. HAL_StatusTypeDef status;
  656. *p_length = 0;
  657. // todo
  658. status = Interface_Receive(&byteOne, 1, timeout);
  659. if(status == HAL_OK)
  660. {
  661. switch(byteOne)
  662. {
  663. case SOH:
  664. packet_size = PACKET_SIZE;
  665. break;
  666. case STX:
  667. packet_size = PACKET_1K_SIZE;
  668. break;
  669. case EOT:
  670. break;
  671. case CA:
  672. // todo
  673. if((Interface_Receive(&byteOne, 1, timeout) == HAL_OK) && (byteOne == CA))
  674. {
  675. packet_size = 2;
  676. }
  677. else
  678. {
  679. status = HAL_ERROR;
  680. }
  681. break;
  682. case ABORT1:
  683. case ABORT2:
  684. status = HAL_BUSY;
  685. break;
  686. default:
  687. status = HAL_ERROR;
  688. break;
  689. }
  690. *p_data = byteOne;
  691. if(packet_size >= PACKET_SIZE)
  692. {
  693. status = Interface_Receive(&p_data[PACKET_NUMBER_INDEX], packet_size + PACKET_OVERHEAD_SIZE, timeout);
  694. /* Simple packet sanity check */
  695. if(status == HAL_OK)
  696. {
  697. if(p_data[PACKET_NUMBER_INDEX] != ((p_data[PACKET_CNUMBER_INDEX]) ^ NEGATIVE_BYTE))
  698. {
  699. packet_size = 0;
  700. status = HAL_ERROR;
  701. }
  702. else
  703. {
  704. /* Check packet CRC */
  705. crc = p_data[packet_size + PACKET_DATA_INDEX] << 8;
  706. crc += p_data[packet_size + PACKET_DATA_INDEX + 1];
  707. if(Cal_CRC16(&p_data[PACKET_DATA_INDEX], packet_size) != crc)
  708. {
  709. packet_size = 0;
  710. status = HAL_ERROR;
  711. }
  712. }
  713. }
  714. else
  715. {
  716. packet_size = 0;
  717. }
  718. }
  719. }
  720. *p_length = packet_size;
  721. return status;
  722. }
  723. /**
  724. * @brief Prepare the first block
  725. * @param p_data: output buffer
  726. * @param p_file_name: name of the file to be sent
  727. * @param length: length of the file to be sent in bytes
  728. * @retval None
  729. */
  730. uint8_t astring[10];
  731. static void PrepareIntialPacket(uint8_t* p_data, const uint8_t* p_file_name, uint32_t length)
  732. {
  733. uint32_t i, j = 0;
  734. // uint8_t astring[10];
  735. /* first 3 bytes are constant */
  736. p_data[PACKET_START_INDEX] = SOH;
  737. p_data[PACKET_NUMBER_INDEX] = 0x00;
  738. p_data[PACKET_CNUMBER_INDEX] = 0xff;
  739. /* Filename written */
  740. for(i = 0; (p_file_name[i] != '\0') && (i < FILE_NAME_LENGTH); i++)
  741. {
  742. p_data[i + PACKET_DATA_INDEX] = p_file_name[i];
  743. }
  744. p_data[i + PACKET_DATA_INDEX] = 0x00;
  745. /* file size written */
  746. Int2Str(astring, length);
  747. i = i + PACKET_DATA_INDEX + 1;
  748. while(astring[j] != '\0')
  749. {
  750. p_data[i++] = astring[j++];
  751. }
  752. /* padding with zeros */
  753. for(j = i; j < PACKET_SIZE + PACKET_DATA_INDEX; j++)
  754. {
  755. p_data[j] = 0;
  756. }
  757. }
  758. /**
  759. * @brief Prepare the data packet
  760. * @param p_source: pointer to the data to be sent
  761. * @param p_packet: pointer to the output buffer
  762. * @param pkt_nr: number of the packet
  763. * @param size_blk: length of the block to be sent in bytes
  764. * @retval None
  765. */
  766. static void PreparePacket(uint8_t* p_source, uint8_t* p_packet, uint8_t pkt_nr, uint32_t size_blk)
  767. {
  768. uint8_t* p_record;
  769. uint32_t i, size, packet_size;
  770. /* Make first three packet */
  771. packet_size = size_blk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE;
  772. size = size_blk < packet_size ? size_blk : packet_size;
  773. if(packet_size == PACKET_1K_SIZE)
  774. {
  775. p_packet[PACKET_START_INDEX] = STX;
  776. }
  777. else
  778. {
  779. p_packet[PACKET_START_INDEX] = SOH;
  780. }
  781. p_packet[PACKET_NUMBER_INDEX] = pkt_nr;
  782. p_packet[PACKET_CNUMBER_INDEX] = (~pkt_nr);
  783. p_record = p_source;
  784. /* Filename packet has valid data */
  785. for(i = PACKET_DATA_INDEX; i < size + PACKET_DATA_INDEX; i++)
  786. {
  787. p_packet[i] = *p_record++;
  788. }
  789. if(size <= packet_size)
  790. {
  791. for(i = size + PACKET_DATA_INDEX; i < packet_size + PACKET_DATA_INDEX; i++)
  792. {
  793. p_packet[i] = 0x1A; /* EOF (0x1A) or 0x00 */
  794. }
  795. }
  796. }
  797. /**
  798. * @brief Update CRC16 for input byte
  799. * @param crc_in input value
  800. * @param input byte
  801. * @retval None
  802. */
  803. uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte)
  804. {
  805. uint32_t crc = crc_in;
  806. uint32_t in = byte | 0x100;
  807. do
  808. {
  809. crc <<= 1;
  810. in <<= 1;
  811. if(in & 0x100)
  812. ++crc;
  813. if(crc & 0x10000)
  814. crc ^= 0x1021;
  815. }
  816. while(!(in & 0x10000));
  817. return crc & 0xffffu;
  818. }
  819. /**
  820. * @brief Cal CRC16 for YModem Packet
  821. * @param data
  822. * @param length
  823. * @retval None
  824. */
  825. uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size)
  826. {
  827. uint32_t crc = 0;
  828. const uint8_t* dataEnd = p_data + size;
  829. while(p_data < dataEnd)
  830. crc = UpdateCRC16(crc, *p_data++);
  831. crc = UpdateCRC16(crc, 0);
  832. crc = UpdateCRC16(crc, 0);
  833. return crc & 0xffffu;
  834. }
  835. /**
  836. * @brief Calculate Check sum for YModem Packet
  837. * @param p_data Pointer to input data
  838. * @param size length of input data
  839. * @retval uint8_t checksum value
  840. */
  841. uint8_t CalcChecksum(const uint8_t* p_data, uint32_t size)
  842. {
  843. uint32_t sum = 0;
  844. const uint8_t* p_data_end = p_data + size;
  845. while(p_data < p_data_end)
  846. {
  847. sum += *p_data++;
  848. }
  849. return (sum & 0xffu);
  850. }
  851. /* Public functions ---------------------------------------------------------*/
  852. /**
  853. * @brief Receive a file using the ymodem protocol with CRC16.
  854. * @param p_size The size of the file.
  855. * @retval COM_StatusTypeDef result of reception/programming
  856. */
  857. COM_StatusTypeDef Ymodem_Receive(uint32_t* p_size)
  858. {
  859. uint32_t i, packet_length, session_done = 0, file_done, errors = 0, session_begin = 0;
  860. uint32_t flashdestination, ramsource, filesize;
  861. uint8_t* file_ptr;
  862. uint8_t file_size[FILE_SIZE_LENGTH], tmp, packets_received;
  863. COM_StatusTypeDef result = COM_OK;
  864. /* Initialize flashdestination variable */
  865. flashdestination = APPLICATION_ADDRESS;
  866. while((session_done == 0) && (result == COM_OK))
  867. {
  868. packets_received = 0;
  869. file_done = 0;
  870. while((file_done == 0) && (result == COM_OK))
  871. {
  872. switch(ReceivePacket(aPacketData, &packet_length, DOWNLOAD_TIMEOUT))
  873. {
  874. case HAL_OK:
  875. errors = 0;
  876. switch(packet_length)
  877. {
  878. case 2:
  879. /* Abort by sender */
  880. Interface_PutByte(ACK);
  881. result = COM_ABORT;
  882. break;
  883. case 0:
  884. /* End of transmission */
  885. Interface_PutByte(ACK);
  886. file_done = 1;
  887. break;
  888. default:
  889. /* Normal packet */
  890. if(aPacketData[PACKET_NUMBER_INDEX] != packets_received)
  891. {
  892. Interface_PutByte(NAK);
  893. }
  894. else
  895. {
  896. if(packets_received == 0)
  897. {
  898. /* File name packet */
  899. if(aPacketData[PACKET_DATA_INDEX] != 0)
  900. {
  901. /* File name extraction */
  902. i = 0;
  903. file_ptr = aPacketData + PACKET_DATA_INDEX;
  904. while((*file_ptr != 0) && (i < FILE_NAME_LENGTH))
  905. {
  906. aFileName[i++] = *file_ptr++;
  907. }
  908. /* File size extraction */
  909. aFileName[i++] = '\0';
  910. i = 0;
  911. file_ptr++;
  912. while((*file_ptr != ' ') && (i < FILE_SIZE_LENGTH))
  913. {
  914. file_size[i++] = *file_ptr++;
  915. }
  916. file_size[i++] = '\0';
  917. Str2Int(file_size, &filesize);
  918. /* Test the size of the image to be sent */
  919. /* Image size is greater than Flash size */
  920. if(*p_size > (USER_FLASH_SIZE + 1))
  921. {
  922. /* End session */
  923. tmp = CA;
  924. Interface_Transmit(&tmp, 1, NAK_TIMEOUT);
  925. Interface_Transmit(&tmp, 1, NAK_TIMEOUT);
  926. result = COM_LIMIT;
  927. }
  928. /* erase user application area */
  929. FLASH_If_Erase(APPLICATION_ADDRESS);
  930. *p_size = filesize;
  931. Interface_PutByte(ACK);
  932. Interface_PutByte(CRC16);
  933. }
  934. /* File header packet is empty, end session */
  935. else
  936. {
  937. Interface_PutByte(ACK);
  938. file_done = 1;
  939. session_done = 1;
  940. break;
  941. }
  942. }
  943. else /* Data packet */
  944. {
  945. ramsource = (uint32_t)&aPacketData[PACKET_DATA_INDEX];
  946. /* Write received data in Flash */
  947. if(FLASH_If_Write(flashdestination, (uint32_t*)ramsource, packet_length / 4) == FLASHIF_OK)
  948. {
  949. flashdestination += packet_length;
  950. Interface_PutByte(ACK);
  951. }
  952. else /* An error occurred while writing to Flash memory */
  953. {
  954. /* End session */
  955. Interface_PutByte(CA);
  956. Interface_PutByte(CA);
  957. result = COM_DATA;
  958. }
  959. }
  960. packets_received++;
  961. session_begin = 1;
  962. }
  963. break;
  964. }
  965. break;
  966. case HAL_BUSY: /* Abort actually */
  967. Interface_PutByte(CA);
  968. Interface_PutByte(CA);
  969. result = COM_ABORT;
  970. break;
  971. default:
  972. if(session_begin > 0)
  973. {
  974. errors++;
  975. }
  976. if(errors > MAX_ERRORS)
  977. {
  978. /* Abort communication */
  979. Interface_PutByte(CA);
  980. Interface_PutByte(CA);
  981. }
  982. else
  983. {
  984. Interface_PutByte(CRC16); /* Ask for a packet */
  985. }
  986. break;
  987. }
  988. }
  989. }
  990. return result;
  991. }
  992. /**
  993. * @brief Transmit a file using the ymodem protocol
  994. * @param p_buf: Address of the first byte
  995. * @param p_file_name: Name of the file sent
  996. * @param file_size: Size of the transmission
  997. * @retval COM_StatusTypeDef result of the communication
  998. */
  999. COM_StatusTypeDef Ymodem_Transmit(uint8_t* p_buf, const uint8_t* p_file_name, uint32_t file_size)
  1000. {
  1001. uint32_t errors = 0, ack_recpt = 0, size = 0, pkt_size;
  1002. uint8_t* p_buf_int;
  1003. COM_StatusTypeDef result = COM_OK;
  1004. uint32_t blk_number = 1;
  1005. uint8_t a_rx_ctrl[2];
  1006. uint8_t i;
  1007. #ifdef CRC16_F
  1008. uint32_t temp_crc;
  1009. #else /* CRC16_F */
  1010. uint8_t temp_chksum;
  1011. #endif /* CRC16_F */
  1012. /* Prepare first block - header */
  1013. PrepareIntialPacket(aPacketData, p_file_name, file_size);
  1014. while((!ack_recpt) && (result == COM_OK))
  1015. {
  1016. /* Send Packet */
  1017. Interface_Transmit(&aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
  1018. /* Send CRC or Check Sum based on CRC16_F */
  1019. #ifdef CRC16_F
  1020. temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
  1021. Interface_PutByte(temp_crc >> 8);
  1022. Interface_PutByte(temp_crc & 0xFF);
  1023. #else /* CRC16_F */
  1024. temp_chksum = CalcChecksum(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
  1025. Interface_PutByte(temp_chksum);
  1026. #endif /* CRC16_F */
  1027. /* Wait for Ack and 'C' */
  1028. if(Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
  1029. {
  1030. if(a_rx_ctrl[0] == ACK)
  1031. {
  1032. ack_recpt = 1;
  1033. }
  1034. else if(a_rx_ctrl[0] == CA)
  1035. {
  1036. if((Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
  1037. {
  1038. HAL_Delay(2);
  1039. Interface_Clean();
  1040. result = COM_ABORT;
  1041. }
  1042. }
  1043. else if(a_rx_ctrl[0] == ABORT1 || a_rx_ctrl[0] == ABORT2)
  1044. {
  1045. result = COM_ABORT;
  1046. }
  1047. }
  1048. else
  1049. {
  1050. errors++;
  1051. }
  1052. if(errors >= MAX_ERRORS)
  1053. {
  1054. result = COM_ERROR;
  1055. }
  1056. }
  1057. p_buf_int = p_buf;
  1058. size = file_size;
  1059. /* Here 1024 bytes length is used to send the packets */
  1060. while((size) && (result == COM_OK))
  1061. {
  1062. /* Prepare next packet */
  1063. PreparePacket(p_buf_int, aPacketData, blk_number, size);
  1064. ack_recpt = 0;
  1065. a_rx_ctrl[0] = 0;
  1066. errors = 0;
  1067. /* Resend packet if NAK for few times else end of communication */
  1068. while((!ack_recpt) && (result == COM_OK))
  1069. {
  1070. /* Send next packet */
  1071. if(size >= PACKET_1K_SIZE)
  1072. {
  1073. pkt_size = PACKET_1K_SIZE;
  1074. }
  1075. else
  1076. {
  1077. pkt_size = PACKET_SIZE;
  1078. }
  1079. Interface_Transmit(&aPacketData[PACKET_START_INDEX], pkt_size + PACKET_HEADER_SIZE, NAK_TIMEOUT);
  1080. /* Send CRC or Check Sum based on CRC16_F */
  1081. #ifdef CRC16_F
  1082. temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], pkt_size);
  1083. Interface_PutByte(temp_crc >> 8);
  1084. Interface_PutByte(temp_crc & 0xFF);
  1085. #else /* CRC16_F */
  1086. temp_chksum = CalcChecksum(&aPacketData[PACKET_DATA_INDEX], pkt_size);
  1087. Interface_PutByte(temp_chksum);
  1088. #endif /* CRC16_F */
  1089. /* Wait for Ack */
  1090. if((Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == ACK))
  1091. {
  1092. ack_recpt = 1;
  1093. if(size > pkt_size)
  1094. {
  1095. p_buf_int += pkt_size;
  1096. size -= pkt_size;
  1097. if(blk_number == (USER_FLASH_SIZE / PACKET_1K_SIZE))
  1098. {
  1099. result = COM_LIMIT; /* boundary error */
  1100. }
  1101. else
  1102. {
  1103. blk_number++;
  1104. }
  1105. }
  1106. else
  1107. {
  1108. p_buf_int += pkt_size;
  1109. size = 0;
  1110. }
  1111. }
  1112. else
  1113. {
  1114. errors++;
  1115. }
  1116. /* Resend packet if NAK for a count of 10 else end of communication */
  1117. if(errors >= MAX_ERRORS)
  1118. {
  1119. result = COM_ERROR;//
  1120. }
  1121. }
  1122. }
  1123. /* Sending End Of Transmission char */
  1124. ack_recpt = 0;
  1125. a_rx_ctrl[0] = 0x00;
  1126. errors = 0;
  1127. while((!ack_recpt) && (result == COM_OK))
  1128. {
  1129. Interface_PutByte(EOT);
  1130. /* Wait for Ack */
  1131. if(Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
  1132. {
  1133. if(a_rx_ctrl[0] == ACK)
  1134. {
  1135. ack_recpt = 1;
  1136. }
  1137. else if(a_rx_ctrl[0] == CA)
  1138. {
  1139. if((Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
  1140. {
  1141. HAL_Delay(2);
  1142. Interface_Clean();
  1143. result = COM_ABORT;
  1144. }
  1145. }
  1146. }
  1147. else
  1148. {
  1149. errors++;
  1150. }
  1151. if(errors >= MAX_ERRORS)
  1152. {
  1153. result = COM_ERROR;
  1154. }
  1155. }
  1156. /* Empty packet sent - some terminal emulators need this to close session */
  1157. if(result == COM_OK)
  1158. {
  1159. /* Preparing an empty packet */
  1160. aPacketData[PACKET_START_INDEX] = SOH;
  1161. aPacketData[PACKET_NUMBER_INDEX] = 0;
  1162. aPacketData[PACKET_CNUMBER_INDEX] = 0xFF;
  1163. for(i = PACKET_DATA_INDEX; i < (PACKET_SIZE + PACKET_DATA_INDEX); i++)
  1164. {
  1165. aPacketData[i] = 0x00;
  1166. }
  1167. /* Send Packet */
  1168. Interface_Transmit(&aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
  1169. /* Send CRC or Check Sum based on CRC16_F */
  1170. #ifdef CRC16_F
  1171. temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
  1172. Interface_PutByte(temp_crc >> 8);
  1173. Interface_PutByte(temp_crc & 0xFF);
  1174. #else /* CRC16_F */
  1175. temp_chksum = CalcChecksum(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
  1176. Interface_PutByte(temp_chksum);
  1177. #endif /* CRC16_F */
  1178. /* Wait for Ack and 'C' */
  1179. if(Interface_Receive(&a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
  1180. {
  1181. if(a_rx_ctrl[0] == CA)
  1182. {
  1183. HAL_Delay(2);
  1184. Interface_Clean();
  1185. result = COM_ABORT;
  1186. }
  1187. }
  1188. }
  1189. return result; /* file transmitted successfully */
  1190. }
  1191. #endif /* __IAP_YMODEM_ATY_C */
  1192. /******************************** End Of File *********************************/