• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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