IAP_YMODEM_ATY.c 41 KB

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