| Linduino 1.3.0 Linear Technology Arduino-Compatible Demonstration Board

hex_file_parser.cpp
Go to the documentation of this file.
1 /*!
2
3 Copyright 2018(c) Analog Devices, Inc.
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the
14 distribution.
15 - Neither the name of Analog Devices, Inc. nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
18 - The use of this software may or may not infringe the patent rights
19 of one or more patent holders. This license does not release you
20 from the requirement that you obtain separate licenses from these
21 patent holders to use this software.
22 - Use of the software either in source or binary form, must be run
23 on or directly connected to an Analog Devices Inc. component.
24
25 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
26 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
27 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
29 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
31 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 /*! @file
38 @ingroup LTPSM_InFlightUpdate
39 Library File
40 */
41
42 #include "hex_file_parser.h"
43 #include "nvm_data_helpers.h"
44
45 #define DEBUG_PARSE_DATA 0
46 #define PARSE_DATA_LEN 64
47
48 uint8_t ascii_to_hex(uint8_t ascii)
49 {
50 return 0;
51 }
52
53 uint8_t filter_terminations(uint8_t (*get_data)(void))
54 {
55 uint8_t c = '\0';
56
57 c = get_data();
58 while (c == '\n' || c == '\r')
59 c = get_data();
60 return c;
61 }
62
63 uint8_t detect_colons(uint8_t (*get_data)(void))
64 {
65 uint8_t c;
66
67 c = get_data();
68 if (c == ':')
69 {
70 Serial.print(".");
71 }
72 return c;
73 }
74
75 static uint8_t parse_data[PARSE_DATA_LEN];
76 static uint16_t parse_data_length = 0;
77 static uint16_t parse_data_position = 0;
78
79 void reset_parse_hex()
80 {
81 parse_data_length = 0;
82 parse_data_position = 0;
83 }
84
85 /*
86 * Parse a list of hex file bytes returning a list of ltc record bytes
87 *
88 * in_data: Function to get one line of data to parse.
89 * return: One byte of data
90 *
91 * Notes: CRC is ignored. No error processing; original data must be correct.
92 * Copies char input data so that it can be const, and frees when done.
93 * It is best to use const input so that memory usage is only temporary.
94 */
95 uint8_t parse_hex(uint8_t (*get_data)(void))
96 {
97 uint8_t start_code;
98 uint16_t byte_count;
99 uint16_t record_type;
100 // uint32_t address;
101 // uint16_t crc;
102 uint16_t i;
103 char data[5];
104
105 if (parse_data_position == parse_data_length)
106 {
107 // Get colon
108 start_code = 0x00;
109 while (start_code != ':')
110 start_code = get_data();
111
112 data[0] = get_data();
113 data[1] = get_data();
114 data[2] = '\0';
115 byte_count = httoi(data);
116 #if (DEBUG_PARSE_DATA)
117 Serial.print(F("Cnt: "));
118 Serial.println(byte_count, HEX);
119 #endif
120 if (byte_count > PARSE_DATA_LEN)
121 Serial.println(F("Parse_data size too samll"));
122
123 // Serial.print(F("data size ")); Serial.println(byte_count, DEC);
124
125 data[0] = get_data();
126 data[1] = get_data();
127 data[2] = get_data();
128 data[3] = get_data();
129 data[4] = '\0';
130 #if (DEBUG_PARSE_DATA)
131 int address = httoi(data);
132 Serial.print(F("Addr: "));
133 Serial.println(address, HEX);
134 #endif
135
136 data[0] = get_data();
137 data[1] = get_data();
138 data[2] = '\0';
139 record_type = httoi(data);
140 #if (DEBUG_PARSE_DATA)
141 Serial.print(F("Rec: "));
142 Serial.println(record_type, HEX);
143 #endif
144 if (record_type == 0)
145 {
146 for (i = 0; i < byte_count; i++)
147 {
148 data[0] = get_data();
149 data[1] = get_data();
150 data[2] = '\0';
151 parse_data[i] = httoi(data);
152 #if (DEBUG_PARSE_DATA)
153 Serial.print(F("Parse: "));
154 Serial.print(data[0], HEX);
155 Serial.print(F(" "));
156 Serial.print(data[1], HEX);
157 Serial.print(F(" "));
158 Serial.println(parse_data[i], HEX);
159 #endif
160 }
161
162 data[0] = get_data();
163 data[1] = get_data();
164 data[2] = '\0';
165 #if (DEBUG_PARSE_DATA)
166 int crc = httoi(data);
167 Serial.print(F("Crc: "));
168 Serial.println(crc, HEX);
169 #endif
170 parse_data_position = 0;
171 parse_data_length = byte_count;
172 }
173 else if (record_type == 1) // Make termination record
174 {
175 parse_data[0] = 4;
176 parse_data[1] = 0;
177 parse_data[2] = 0x22;
178 parse_data[3] = 0;
179 parse_data_position = 0;
180 parse_data_length = 4;
181 }
182 }
183 #if (DEBUG_PARSE_DATA)
184 Serial.print(F("Byte "));
185 Serial.println(parse_data[parse_data_position], HEX);
186 #endif
187 return parse_data[parse_data_position++];
188 }
189
190 uint16_t parse_records(uint8_t *in_data, uint16_t in_length, tRecordHeaderLengthAndType **out_records)
191 {
192 uint16_t in_position;
193 uint16_t out_position;
194 tRecordHeaderLengthAndType *record;
195
196 in_position = 0;
197 out_position = 0;
198
199 while (1)
200 {
201 record = (tRecordHeaderLengthAndType *) &in_data[in_position];
202 *(out_records+out_position) = record;
203 in_position += (*out_records[out_position]).Length;
204 out_position += 1;
205
206 if (in_position >= in_length)
207 break;
208 }
209
210 return out_position;
211 }
212
213 pRecordHeaderLengthAndType parse_record(uint8_t (*get_data)(void))
214 {
215 uint32_t header;
216 uint16_t size;
217 uint16_t pos;
218 pRecordHeaderLengthAndType record;
219
220 header = (uint32_t)get_data() << 0 | (uint32_t)get_data() << 8 | (uint32_t)get_data() << 16 | (uint32_t)get_data() << 24;
221
222 record = (pRecordHeaderLengthAndType) &header;
223 size = record->Length;
224
225 if (size > getMaxRecordSize())
226 {
227 Serial.println(F("record_data size too samll"));
228 Serial.print(F("requires "));
229 Serial.print(size, DEC);
230 Serial.print(F(" has "));
231 Serial.println(getMaxRecordSize());
232 Serial.print(F("Record Type 0x"));
233 Serial.println(record->RecordType, HEX);
234 }
235
236 // Serial.print(F("Record size ")); Serial.println(size, DEC);
237
238 uint8_t *record_data = getRecordData();
239
240 record_data[0] = (header >> 0) & 0xFF;
241 record_data[1] = (header >> 8) & 0xFF;
242 record_data[2] = (header >> 16) & 0xFF;
243 record_data[3] = (header >> 24) & 0xFF;
244
245 if (size <= getMaxRecordSize())
246 {
247 for (pos = 0; pos < size - 4; pos++)
248 record_data[pos + 4] = get_data();
249 }
250 record = (pRecordHeaderLengthAndType) record_data;
251
252 return record;
253 }
254
255 pRecordHeaderLengthAndType print_record(pRecordHeaderLengthAndType (*get_record)(void))
256 {
257 pRecordHeaderLengthAndType record = get_record();
258
259 switch (record->RecordType)
260 {
261 case 0x01:
262 Serial.println(F("processWriteByteOptionalPEC(t_RECORD_PMBUS_WRITE_BYTE*);"));
263 break;
264 case 0x02:
265 Serial.println(F("processWriteWordOptionalPEC(t_RECORD_PMBUS_WRITE_WORD*);"));
266 break;
267 case 0x04:
268 Serial.println(F("processReadByteExpectOptionalPEC(t_RECORD_PMBUS_READ_BYTE_EXPECT*);"));
269 break;
270 case 0x05:
271 Serial.println(F("processReadWordExpectOptionalPEC(t_RECORD_PMBUS_READ_WORD_EXPECT*);"));
272 break;
273 case 0x09:
274 Serial.println(F("bufferNVMData(t_RECORD_NVM_DATA*);"));
275 break;
276 case 0x0A:
277 Serial.println(F("processReadByteLoopMaskOptionalPEC(t_RECORD_PMBUS_READ_BYTE_LOOP_MASK*);"));
278 break;
279 case 0x0B:
280 Serial.println(F("processReadWordLoopMaskOptionalPEC(t_RECORD_PMBUS_READ_WORD_LOOP_MASK*);"));
281 break;
282 case 0x0C:
283 Serial.println(F("processPollReadByteUntilAckNoPEC(t_RECORD_PMBUS_POLL_READ_BYTE_UNTIL_ACK*);"));
284 break;
285 case 0x0D:
286 Serial.println(F("processDelayMs(t_RECORD_DELAY_MS*);"));
287 break;
288 case 0x0E:
289 Serial.println(F("processSendByteOptionalPEC(t_RECORD_PMBUS_SEND_BYTE*);"));
290 break;
291 case 0x0F:
292 Serial.println(F("processWriteByteNoPEC(t_RECORD_PMBUS_WRITE_BYTE_NOPEC*);"));
293 break;
294 case 0x10:
295 Serial.println(F("processWriteWordNoPEC(t_RECORD_PMBUS_WRITE_WORD_NOPEC*);"));
296 break;
297 case 0x12:
298 Serial.println(F("processReadByteExpectNoPEC(t_RECORD_PMBUS_READ_BYTE_EXPECT_NOPEC*);"));
299 break;
300 case 0x13:
301 Serial.println(F("processReadWordExpectNoPEC(t_RECORD_PMBUS_READ_WORD_EXPECT_NOPEC*);"));
302 break;
303 case 0x15:
304 Serial.println(F("processReadByteLoopMaskNoPEC(t_RECORD_PMBUS_READ_BYTE_LOOP_MASK_NOPEC*);"));
305 break;
306 case 0x16:
307 Serial.println(F("processReadWordLoopMaskNoPEC(t_RECORD_PMBUS_READ_WORD_LOOP_MASK_NOPEC*);"));
308 break;
309 case 0x17:
310 Serial.println(F("processSendByteNoPEC(t_RECORD_PMBUS_SEND_BYTE_NOPEC*);"));
311 break;
312 case 0x18:
313 Serial.println(F("processEvent(t_RECORD_EVENT*);"));
314 break;
315 case 0x19:
316 Serial.println(F("processReadByteExpectMaskNoPEC(t_RECORD_PMBUS_READ_BYTE_EXPECT_MASK_NOPEC*);"));
317 break;
318 case 0x1A:
319 Serial.println(F("processReadWordExpectMaskNoPEC(t_RECORD_PMBUS_READ_WORD_EXPECT_MASK_NOPEC*);"));
320 break;
321 case 0x1B:
322 Serial.println(F("processVariableMetaData(t_RECORD_VARIABLE_META_DATA*);"));
323 break;
324 case 0x1C:
325 Serial.println(F("modifyWordNoPEC(t_RECORD_PMBUS_MODIFY_WORD_NO_PEC*);"));
326 break;
327 case 0x1D:
328 Serial.println(F("modifyByteNoPEC(t_RECORD_PMBUS_MODIFY_BYTE_NO_PEC*);"));
329 break;
330 case 0x1E:
331 Serial.println(F("writeNvmData(t_RECORD_NVM_DATA*);"));
332 break;
333 case 0x1F:
334 Serial.println(F("read_then_verifyNvmData(t_RECORD_NVM_DATA*);"));
335 break;
336 case 0x20:
337 Serial.println(F("modifyByteOptionalPEC(t_RECORD_PMBUS_MODIFY_BYTE*);"));
338 break;
339 case 0x21:
340 Serial.println(F("modifyWordOptionalPEC(t_RECORD_PMBUS_MODIFY_WORD*);"));
341 break;
342 default :
343 Serial.print(F("Unknown Record Type "));
344 Serial.println(record->RecordType, HEX);
345 break;
346 }
347
348 return record;
349 }
tRecordHeader::Length
uint16_t Length
Definition: record_type_basic_definitions.h:54
pRecordHeaderLengthAndType
struct tRecordHeader * pRecordHeaderLengthAndType
detect_colons
uint8_t detect_colons(uint8_t(*get_data)(void))
Definition: hex_file_parser.cpp:63
parse_record
pRecordHeaderLengthAndType parse_record(uint8_t(*get_data)(void))
Definition: hex_file_parser.cpp:213
parse_records
uint16_t parse_records(uint8_t *in_data, uint16_t in_length, tRecordHeaderLengthAndType **out_records)
Definition: hex_file_parser.cpp:190
nvm_data_helpers.h
Copyright 2018(c) Analog Devices, Inc.
PARSE_DATA_LEN
#define PARSE_DATA_LEN
Definition: hex_file_parser.cpp:46
tRecordHeader::RecordType
uint16_t RecordType
Definition: record_type_basic_definitions.h:55
reset_parse_hex
void reset_parse_hex()
Definition: hex_file_parser.cpp:79
parse_hex
uint8_t parse_hex(uint8_t(*get_data)(void))
Definition: hex_file_parser.cpp:95
address
static uint8_t address
Definition: DC2091A.ino:83
data
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
pos
static int16_t pos
Definition: Precision_Voltage_Source.ino:73
get_record
pRecordHeaderLengthAndType get_record(void)
Definition: nvm.cpp:85
parse_data
static uint8_t parse_data[PARSE_DATA_LEN]
Definition: hex_file_parser.cpp:75
getRecordData
uint8_t * getRecordData()
Definition: nvm_data_helpers.cpp:56
getMaxRecordSize
int getMaxRecordSize()
Definition: nvm_data_helpers.cpp:51
hex_file_parser.h
Copyright 2018(c) Analog Devices, Inc.
parse_data_length
static uint16_t parse_data_length
Definition: hex_file_parser.cpp:76
ascii_to_hex
uint8_t ascii_to_hex(uint8_t ascii)
Definition: hex_file_parser.cpp:48
filter_terminations
uint8_t filter_terminations(uint8_t(*get_data)(void))
Definition: hex_file_parser.cpp:53
httoi
uint16_t httoi(char *value)
Definition: conversions.cpp:48
record_data
static uint8_t record_data[MAX_RECORD_SIZE]
Definition: nvm_data_helpers.cpp:45
tRecordHeader
Basic Record Type Definitions.
Definition: record_type_basic_definitions.h:52
i
static int i
Definition: DC2430A.ino:184
print_record
pRecordHeaderLengthAndType print_record(pRecordHeaderLengthAndType(*get_record)(void))
Definition: hex_file_parser.cpp:255
parse_data_position
static uint16_t parse_data_position
Definition: hex_file_parser.cpp:77