IAP_YMODEM_ATY.c 41 KB

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