1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
22
23
32
33
34
35
40
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
78
81
83
93
94
97
100
101
102
103
104
105
106
107
108
127
131
132
133
134
135
136
137
144
145
146
147
148
149
150
151
152
153
154
155
159
160
161
162
163
164
165
169
170
171
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
197
201
202
203
204
205
206
210
217
218
219
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
271
272
273
274
275
276
280
281
282
283
284
285
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
319
324
325
326
330
331
332
333
334
335
336
337
338
339
340
344
345
346
347
348
349
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
381
382
399
400
401
402
403
404
405
410
426
427
428
429
430
431
432
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
466
467
469
470
471
472
488
492
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
518
522
523
524
525
526
527
530
531
533
534
535
536
558
562
563
564
568
569
570
571
572
573
574
575
576
577
578
579
580
596
600
601
605
606
607
608
609
610
611
612
613
614
618
619
620
621
622
623
624
627
628
630
631
632
633
642
643
644
645
646
647
650
651
/* ... */
/* ... */
#include "flash_if.h"
#include "common.h"
#include "ymodem.h"
#include "string.h"
#include "main.h"
#include "menu.h"
6 includes
Includes
#define CRC16_F
__IO uint32_t flashdestination;
uint8_t aPacketData[PACKET_1K_SIZE + PACKET_DATA_INDEX + PACKET_TRAILER_SIZE];
Private variables
static void PrepareIntialPacket(uint8_t *p_data, const uint8_t *p_file_name, uint32_t length);
static void PreparePacket(uint8_t *p_source, uint8_t *p_packet, uint8_t pkt_nr, uint32_t size_blk);
static HAL_StatusTypeDef ReceivePacket(uint8_t *p_data, uint32_t *p_length, uint32_t timeout);
uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte);
uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size);
uint8_t CalcChecksum(const uint8_t *p_data, uint32_t size);
Private function prototypes
/* ... */
static HAL_StatusTypeDef ReceivePacket(uint8_t *p_data, uint32_t *p_length, uint32_t timeout)
{
uint32_t crc;
uint32_t packet_size = 0;
HAL_StatusTypeDef status;
uint8_t char1;
*p_length = 0;
status = HAL_UART_Receive(&UartHandle, &char1, 1, timeout);
if (status == HAL_OK)
{
switch (char1)
{
case SOH:
packet_size = PACKET_SIZE;
break;case SOH:
case STX:
packet_size = PACKET_1K_SIZE;
break;case STX:
case EOT:
break;case EOT:
case CA:
if ((HAL_UART_Receive(&UartHandle, &char1, 1, timeout) == HAL_OK) && (char1 == CA))
{
packet_size = 2;
}if ((HAL_UART_Receive(&UartHandle, &char1, 1, timeout) == HAL_OK) && (char1 == CA)) { ... }
else
{
status = HAL_ERROR;
}else { ... }
break;case CA:
case ABORT1:
case ABORT2:
status = HAL_BUSY;
break;case ABORT2:
default:
status = HAL_ERROR;
break;default
}switch (char1) { ... }
*p_data = char1;
if (packet_size >= PACKET_SIZE )
{
status = HAL_UART_Receive(&UartHandle, &p_data[PACKET_NUMBER_INDEX], packet_size + PACKET_OVERHEAD_SIZE, timeout);
if (status == HAL_OK )
{
if (p_data[PACKET_NUMBER_INDEX] != ((p_data[PACKET_CNUMBER_INDEX]) ^ NEGATIVE_BYTE))
{
packet_size = 0;
status = HAL_ERROR;
}if (p_data[PACKET_NUMBER_INDEX] != ((p_data[PACKET_CNUMBER_INDEX]) ^ NEGATIVE_BYTE)) { ... }
else
{
crc = p_data[ packet_size + PACKET_DATA_INDEX ] << 8;
crc += p_data[ packet_size + PACKET_DATA_INDEX + 1 ];
if (Cal_CRC16(&p_data[PACKET_DATA_INDEX], packet_size) != crc )
{
packet_size = 0;
status = HAL_ERROR;
}if (Cal_CRC16(&p_data[PACKET_DATA_INDEX], packet_size) != crc) { ... }
}else { ... }
}if (status == HAL_OK) { ... }
else
{
packet_size = 0;
}else { ... }
}if (packet_size >= PACKET_SIZE) { ... }
}if (status == HAL_OK) { ... }
*p_length = packet_size;
return status;
}{ ... }
/* ... */
static void PrepareIntialPacket(uint8_t *p_data, const uint8_t *p_file_name, uint32_t length)
{
uint32_t i, j = 0;
uint8_t astring[10];
p_data[PACKET_START_INDEX] = SOH;
p_data[PACKET_NUMBER_INDEX] = 0x00;
p_data[PACKET_CNUMBER_INDEX] = 0xff;
for (i = 0; (p_file_name[i] != '\0') && (i < FILE_NAME_LENGTH); i++)
{
p_data[i + PACKET_DATA_INDEX] = p_file_name[i];
}for (i = 0; (p_file_name[i] != '\0') && (i < FILE_NAME_LENGTH); i++) { ... }
p_data[i + PACKET_DATA_INDEX] = 0x00;
Int2Str (astring, length);
i = i + PACKET_DATA_INDEX + 1;
while (astring[j] != '\0')
{
p_data[i++] = astring[j++];
}while (astring[j] != '\0') { ... }
for (j = i; j < PACKET_SIZE + PACKET_DATA_INDEX; j++)
{
p_data[j] = 0;
}for (j = i; j < PACKET_SIZE + PACKET_DATA_INDEX; j++) { ... }
}{ ... }
/* ... */
static void PreparePacket(uint8_t *p_source, uint8_t *p_packet, uint8_t pkt_nr, uint32_t size_blk)
{
uint8_t *p_record;
uint32_t i, size, packet_size;
packet_size = size_blk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE;
size = size_blk < packet_size ? size_blk : packet_size;
if (packet_size == PACKET_1K_SIZE)
{
p_packet[PACKET_START_INDEX] = STX;
}if (packet_size == PACKET_1K_SIZE) { ... }
else
{
p_packet[PACKET_START_INDEX] = SOH;
}else { ... }
p_packet[PACKET_NUMBER_INDEX] = pkt_nr;
p_packet[PACKET_CNUMBER_INDEX] = (~pkt_nr);
p_record = p_source;
for (i = PACKET_DATA_INDEX; i < size + PACKET_DATA_INDEX;i++)
{
p_packet[i] = *p_record++;
}for (i = PACKET_DATA_INDEX; i < size + PACKET_DATA_INDEX;i++) { ... }
if ( size <= packet_size)
{
for (i = size + PACKET_DATA_INDEX; i < packet_size + PACKET_DATA_INDEX; i++)
{
p_packet[i] = 0x1A;
}for (i = size + PACKET_DATA_INDEX; i < packet_size + PACKET_DATA_INDEX; i++) { ... }
}if (size <= packet_size) { ... }
}{ ... }
/* ... */
uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte)
{
uint32_t crc = crc_in;
uint32_t in = byte | 0x100;
do
{
crc <<= 1;
in <<= 1;
if(in & 0x100)
++crc;
if(crc & 0x10000)
crc ^= 0x1021;
...}
while(!(in & 0x10000));
return crc & 0xffffu;
}{ ... }
/* ... */
uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size)
{
uint32_t crc = 0;
const uint8_t* dataEnd = p_data+size;
while(p_data < dataEnd)
crc = UpdateCRC16(crc, *p_data++);
crc = UpdateCRC16(crc, 0);
crc = UpdateCRC16(crc, 0);
return crc&0xffffu;
}{ ... }
/* ... */
uint8_t CalcChecksum(const uint8_t *p_data, uint32_t size)
{
uint32_t sum = 0;
const uint8_t *p_data_end = p_data + size;
while (p_data < p_data_end )
{
sum += *p_data++;
}while (p_data < p_data_end) { ... }
return (sum & 0xffu);
}{ ... }
Private functions
/* ... */
COM_StatusTypeDef Ymodem_Receive ( uint32_t *p_size )
{
uint32_t i, packet_length, session_done = 0, file_done, errors = 0, session_begin = 0;
uint32_t ramsource, filesize, packets_received;
uint8_t *file_ptr;
uint8_t file_size[FILE_SIZE_LENGTH], tmp;
COM_StatusTypeDef result = COM_OK;
flashdestination = APPLICATION_ADDRESS;
while ((session_done == 0) && (result == COM_OK))
{
packets_received = 0;
file_done = 0;
while ((file_done == 0) && (result == COM_OK))
{
switch (ReceivePacket(aPacketData, &packet_length, DOWNLOAD_TIMEOUT))
{
case HAL_OK:
errors = 0;
switch (packet_length)
{
case 2:
Serial_PutByte(ACK);
result = COM_ABORT;
break;case 2:
case 0:
Serial_PutByte(ACK);
file_done = 1;
break;case 0:
default:
if (aPacketData[PACKET_NUMBER_INDEX] != (uint8_t)packets_received)
{
Serial_PutByte(NAK);
}if (aPacketData[PACKET_NUMBER_INDEX] != (uint8_t)packets_received) { ... }
else
{
if (packets_received == 0)
{
if (aPacketData[PACKET_DATA_INDEX] != 0)
{
i = 0;
file_ptr = aPacketData + PACKET_DATA_INDEX;
while ( (*file_ptr != 0) && (i < FILE_NAME_LENGTH))
{
aFileName[i++] = *file_ptr++;
}while ((*file_ptr != 0) && (i < FILE_NAME_LENGTH)) { ... }
aFileName[i++] = '\0';
i = 0;
file_ptr ++;
while ( (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH))
{
file_size[i++] = *file_ptr++;
}while ((*file_ptr != ' ') && (i < FILE_SIZE_LENGTH)) { ... }
file_size[i++] = '\0';
Str2Int(file_size, &filesize);
if (*p_size > (USER_FLASH_SIZE + 1))
{
tmp = CA;
HAL_UART_Transmit(&UartHandle, &tmp, 1, NAK_TIMEOUT);
HAL_UART_Transmit(&UartHandle, &tmp, 1, NAK_TIMEOUT);
result = COM_LIMIT;
}if (*p_size > (USER_FLASH_SIZE + 1)) { ... }
FLASH_If_Erase(APPLICATION_ADDRESS);
*p_size = filesize;
Serial_PutByte(ACK);
Serial_PutByte(CRC16);
}if (aPacketData[PACKET_DATA_INDEX] != 0) { ... }
else
{
Serial_PutByte(ACK);
file_done = 1;
session_done = 1;
break;
}else { ... }
}if (packets_received == 0) { ... }
else
{
ramsource = (uint32_t) & aPacketData[PACKET_DATA_INDEX];
if (FLASH_If_Write(flashdestination, (uint32_t*) ramsource, packet_length/4) == FLASHIF_OK)
{
flashdestination += packet_length;
Serial_PutByte(ACK);
}if (FLASH_If_Write(flashdestination, (uint32_t*) ramsource, packet_length/4) == FLASHIF_OK) { ... }
else
{
Serial_PutByte(CA);
Serial_PutByte(CA);
result = COM_DATA;
}else { ... }
}else { ... }
packets_received ++;
session_begin = 1;
}else { ... }
break;default
}switch (packet_length) { ... }
break;case HAL_OK:
case HAL_BUSY:
Serial_PutByte(CA);
Serial_PutByte(CA);
result = COM_ABORT;
break;case HAL_BUSY:
default:
if (session_begin > 0)
{
errors ++;
}if (session_begin > 0) { ... }
if (errors > MAX_ERRORS)
{
Serial_PutByte(CA);
Serial_PutByte(CA);
}if (errors > MAX_ERRORS) { ... }
else
{
Serial_PutByte(CRC16);
}else { ... }
break;default
}switch (ReceivePacket(aPacketData, &packet_length, DOWNLOAD_TIMEOUT)) { ... }
}while ((file_done == 0) && (result == COM_OK)) { ... }
}while ((session_done == 0) && (result == COM_OK)) { ... }
return result;
}{ ... }
/* ... */
COM_StatusTypeDef Ymodem_Transmit (uint8_t *p_buf, const uint8_t *p_file_name, uint32_t file_size)
{
uint32_t errors = 0, ack_recpt = 0, size = 0, pkt_size;
uint8_t *p_buf_int;
COM_StatusTypeDef result = COM_OK;
uint32_t blk_number = 1;
uint8_t a_rx_ctrl[2];
uint8_t i;
#ifdef CRC16_F
uint32_t temp_crc;
#else
uint8_t temp_chksum;
#endif
PrepareIntialPacket(aPacketData, p_file_name, file_size);
while (( !ack_recpt ) && ( result == COM_OK ))
{
HAL_UART_Transmit(&UartHandle, &aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
#ifdef CRC16_F
temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
Serial_PutByte(temp_crc >> 8);
Serial_PutByte(temp_crc & 0xFF);/* ... */
#else
temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
Serial_PutByte(temp_chksum);/* ... */
#endif
if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
{
if (a_rx_ctrl[0] == ACK)
{
ack_recpt = 1;
}if (a_rx_ctrl[0] == ACK) { ... }
else if (a_rx_ctrl[0] == CA)
{
if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
{
HAL_Delay( 2 );
__HAL_UART_FLUSH_DRREGISTER(&UartHandle);
result = COM_ABORT;
}if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA)) { ... }
}else if (a_rx_ctrl[0] == CA) { ... }
}if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) { ... }
else
{
errors++;
}else { ... }
if (errors >= MAX_ERRORS)
{
result = COM_ERROR;
}if (errors >= MAX_ERRORS) { ... }
}while (( !ack_recpt ) && ( result == COM_OK )) { ... }
p_buf_int = p_buf;
size = file_size;
while ((size) && (result == COM_OK ))
{
PreparePacket(p_buf_int, aPacketData, blk_number, size);
ack_recpt = 0;
a_rx_ctrl[0] = 0;
errors = 0;
while (( !ack_recpt ) && ( result == COM_OK ))
{
if (size >= PACKET_1K_SIZE)
{
pkt_size = PACKET_1K_SIZE;
}if (size >= PACKET_1K_SIZE) { ... }
else
{
pkt_size = PACKET_SIZE;
}else { ... }
HAL_UART_Transmit(&UartHandle, &aPacketData[PACKET_START_INDEX], pkt_size + PACKET_HEADER_SIZE, NAK_TIMEOUT);
#ifdef CRC16_F
temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], pkt_size);
Serial_PutByte(temp_crc >> 8);
Serial_PutByte(temp_crc & 0xFF);/* ... */
#else
temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], pkt_size);
Serial_PutByte(temp_chksum);/* ... */
#endif
if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == ACK))
{
ack_recpt = 1;
if (size > pkt_size)
{
p_buf_int += pkt_size;
size -= pkt_size;
if (blk_number == (USER_FLASH_SIZE / PACKET_1K_SIZE))
{
result = COM_LIMIT;
}if (blk_number == (USER_FLASH_SIZE / PACKET_1K_SIZE)) { ... }
else
{
blk_number++;
}else { ... }
}if (size > pkt_size) { ... }
else
{
p_buf_int += pkt_size;
size = 0;
}else { ... }
}if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == ACK)) { ... }
else
{
errors++;
}else { ... }
if (errors >= MAX_ERRORS)
{
result = COM_ERROR;
}if (errors >= MAX_ERRORS) { ... }
}while (( !ack_recpt ) && ( result == COM_OK )) { ... }
}while ((size) && (result == COM_OK )) { ... }
ack_recpt = 0;
a_rx_ctrl[0] = 0x00;
errors = 0;
while (( !ack_recpt ) && ( result == COM_OK ))
{
Serial_PutByte(EOT);
if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
{
if (a_rx_ctrl[0] == ACK)
{
ack_recpt = 1;
}if (a_rx_ctrl[0] == ACK) { ... }
else if (a_rx_ctrl[0] == CA)
{
if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA))
{
HAL_Delay( 2 );
__HAL_UART_FLUSH_DRREGISTER(&UartHandle);
result = COM_ABORT;
}if ((HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) && (a_rx_ctrl[0] == CA)) { ... }
}else if (a_rx_ctrl[0] == CA) { ... }
}if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) { ... }
else
{
errors++;
}else { ... }
if (errors >= MAX_ERRORS)
{
result = COM_ERROR;
}if (errors >= MAX_ERRORS) { ... }
}while (( !ack_recpt ) && ( result == COM_OK )) { ... }
if ( result == COM_OK )
{
aPacketData[PACKET_START_INDEX] = SOH;
aPacketData[PACKET_NUMBER_INDEX] = 0;
aPacketData[PACKET_CNUMBER_INDEX] = 0xFF;
for (i = PACKET_DATA_INDEX; i < (PACKET_SIZE + PACKET_DATA_INDEX); i++)
{
aPacketData [i] = 0x00;
}for (i = PACKET_DATA_INDEX; i < (PACKET_SIZE + PACKET_DATA_INDEX); i++) { ... }
HAL_UART_Transmit(&UartHandle, &aPacketData[PACKET_START_INDEX], PACKET_SIZE + PACKET_HEADER_SIZE, NAK_TIMEOUT);
#ifdef CRC16_F
temp_crc = Cal_CRC16(&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
Serial_PutByte(temp_crc >> 8);
Serial_PutByte(temp_crc & 0xFF);/* ... */
#else
temp_chksum = CalcChecksum (&aPacketData[PACKET_DATA_INDEX], PACKET_SIZE);
Serial_PutByte(temp_chksum);/* ... */
#endif
if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK)
{
if (a_rx_ctrl[0] == CA)
{
HAL_Delay( 2 );
__HAL_UART_FLUSH_DRREGISTER(&UartHandle);
result = COM_ABORT;
}if (a_rx_ctrl[0] == CA) { ... }
}if (HAL_UART_Receive(&UartHandle, &a_rx_ctrl[0], 1, NAK_TIMEOUT) == HAL_OK) { ... }
}if (result == COM_OK) { ... }
return result;
}{ ... }
/* ... */
Public functions