IAP_YMODEM_ATY.c 41 KB

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