1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <sys/time.h>
5
6 #include "s-record.h"
7
8
9 #define S0 0x5330
10 #define S1 0x5331
11 #define S2 0x5332
12 #define S3 0x5333
13
14
show_performance(struct timeval * start,struct timeval * end,int size)15 static void show_performance(struct timeval *start, struct timeval *end, int size)
16 {
17 double ssec = start->tv_sec + start->tv_usec / 1000000.0;
18 double esec = end->tv_sec + end->tv_usec / 1000000.0;
19 double bytes = (double)size;
20 double bsec = bytes / (esec - ssec);
21
22 printf("Time used: %.2lf seconds ==> ", esec - ssec);
23 if (bsec / 1000000 > 1.0)
24 printf("%.3lf MB/s\n", bsec/1000000);
25 else if (bsec / 1000 > 1.0)
26 printf("%.3lf kB/s\n", bsec/1000);
27 else
28 printf("%.3lf B/s\n", bsec);
29 }
30
digit_to_val(char * digit)31 static unsigned char digit_to_val(char *digit)
32 {
33 if (*digit <= 0x39)
34 return *digit - 0x30;
35 else if (*digit <= 70)
36 return *digit - 55;
37
38 return *digit - 87;
39 }
40
char_to_val(char * str)41 static unsigned char char_to_val(char *str)
42 {
43 return digit_to_val(&str[0]) << 4 | digit_to_val(&str[1]);
44 }
45
str_to_char(char * str,unsigned char * buf,int length)46 static void str_to_char(char *str, unsigned char *buf, int length)
47 {
48 int i;
49
50 for (i = 0; i < length/2; i++, str += 2, buf++)
51 *buf = (unsigned char)char_to_val(str);
52 }
53
s_record_to_bin(char * file_buffer,unsigned char * flash_buffer,int file_size,int flash_size)54 int s_record_to_bin(char *file_buffer, unsigned char *flash_buffer,
55 int file_size, int flash_size)
56 {
57 unsigned char *flash = flash_buffer;
58 char *sline = file_buffer;
59 struct timeval start, end;
60 int left_to_convert = file_size;
61 int bin_size = 0;
62 int newline = 0;
63 char *is_dos;
64
65 /* Check for dos format CR/LN */
66 is_dos = strstr(sline + 2, "S") - 2;
67 if (*is_dos == 0x0d)
68 newline = 2;
69 else
70 newline = 1;
71
72 printf("Convert %u bytes of S-record data to binary flash format\n", file_size);
73 gettimeofday(&start, NULL);
74 while (left_to_convert) {
75 unsigned short stype = (sline[0] << 8) | sline[1];
76 unsigned char num_of_char = 2 + char_to_val(&sline[2]);
77 int sline_length = 2*num_of_char + newline;
78 int payload_size;
79 char *next = sline + sline_length;
80 char *data;
81 unsigned int offset;
82
83 switch (stype) {
84 case S0:
85 data = sline + 8;
86 payload_size = sline_length - 11;
87 goto next_line;
88 case S3:
89 data = sline + 12;
90 payload_size = sline_length - 14 - newline;
91 offset = (char_to_val(sline + 4) << 24 |
92 char_to_val(sline + 6) << 16 |
93 char_to_val(sline + 8) << 8 |
94 char_to_val(sline + 10));
95 break;
96 default:
97 printf("%c%c line is not supported\n",
98 char_to_val(&sline[0]), char_to_val(&sline[2]));
99 return -1;
100 }
101
102 if (offset + payload_size > flash_size) {
103 printf("S-record try to write outside flash area!\n");
104 return -1;
105 }
106
107 /* Copy Sx data to binary buffer */
108 str_to_char(data, &flash[offset], payload_size);
109
110 next_line:
111 bin_size += payload_size / 2;
112 sline = next;
113 left_to_convert -= sline_length;
114 }
115
116 gettimeofday(&end, NULL);
117 show_performance(&start, &end, file_size);
118
119 return bin_size;
120 }
121