]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - common/s_record.c
1 // SPDX-License-Identifier: GPL-2.0+
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
10 static int hex1_bin (char c
);
11 static int hex2_bin (char *s
);
13 int srec_decode (char *input
, int *count
, ulong
*addr
, char *data
)
16 int v
; /* conversion buffer */
17 int srec_type
; /* S-Record type */
18 unsigned char chksum
; /* buffer for checksum */
22 /* skip anything before 'S', and the 'S' itself.
23 * Return error if not found
26 for (; *input
; ++input
) {
27 if (*input
== 'S') { /* skip 'S' */
32 if (*input
== '\0') { /* no more data? */
36 v
= *input
++; /* record type */
38 if ((*count
= hex2_bin(input
)) < 0) {
39 return (SREC_E_NOSREC
);
45 switch (v
) { /* record type */
47 case '0': /* start record */
48 srec_type
= SREC_START
; /* 2 byte addr field */
49 *count
-= 3; /* - checksum and addr */
52 srec_type
= SREC_DATA2
; /* 2 byte addr field */
53 *count
-= 3; /* - checksum and addr */
56 srec_type
= SREC_DATA3
; /* 3 byte addr field */
57 *count
-= 4; /* - checksum and addr */
59 case '3': /* data record with a */
60 srec_type
= SREC_DATA4
; /* 4 byte addr field */
61 *count
-= 5; /* - checksum and addr */
64 case '5': /* count record, addr field contains */
65 srec_type
= SREC_COUNT
; /* a 2 byte record counter */
66 *count
= 0; /* no data */
68 /*** case '6' -- not used ***/
69 case '7': /* end record with a */
70 srec_type
= SREC_END4
; /* 4 byte addr field */
71 *count
-= 5; /* - checksum and addr */
73 case '8': /* end record with a */
74 srec_type
= SREC_END3
; /* 3 byte addr field */
75 *count
-= 4; /* - checksum and addr */
77 case '9': /* end record with a */
78 srec_type
= SREC_END2
; /* 2 byte addr field */
79 *count
-= 3; /* - checksum and addr */
82 return (SREC_E_BADTYPE
);
85 /* read address field */
89 case '3': /* 4 byte addr field */
91 if ((v
= hex2_bin(input
)) < 0) {
92 return (SREC_E_NOSREC
);
98 case '2': /* 3 byte addr field */
100 if ((v
= hex2_bin(input
)) < 0) {
101 return (SREC_E_NOSREC
);
108 case '0': /* 2 byte addr field */
112 if ((v
= hex2_bin(input
)) < 0) {
113 return (SREC_E_NOSREC
);
120 if ((v
= hex2_bin(input
)) < 0) {
121 return (SREC_E_NOSREC
);
130 return (SREC_E_BADTYPE
);
133 /* convert data and calculate checksum */
134 for (i
=0; i
< *count
; ++i
) {
135 if ((v
= hex2_bin(input
)) < 0) {
136 return (SREC_E_NOSREC
);
143 /* read anc check checksum */
144 if ((v
= hex2_bin(input
)) < 0) {
145 return (SREC_E_NOSREC
);
148 if ((unsigned char)v
!= (unsigned char)~chksum
) {
149 return (SREC_E_BADCHKS
);
155 static int hex1_bin (char c
)
157 if (c
>= '0' && c
<= '9')
159 if (c
>= 'a' && c
<= 'f')
160 return (c
+ 10 - 'a');
161 if (c
>= 'A' && c
<= 'F')
162 return (c
+ 10 - 'A');
166 static int hex2_bin (char *s
)
170 if ((i
= hex1_bin(*s
++)) < 0) {
173 if ((j
= hex1_bin(*s
)) < 0) {