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 
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;
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;
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 
256 {
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 }
struct tRecordHeader * pRecordHeaderLengthAndType
uint8_t detect_colons(uint8_t(*get_data)(void))
pRecordHeaderLengthAndType parse_record(uint8_t(*get_data)(void))
uint16_t parse_records(uint8_t *in_data, uint16_t in_length, tRecordHeaderLengthAndType **out_records)
Copyright 2018(c) Analog Devices, Inc.
#define PARSE_DATA_LEN
void reset_parse_hex()
uint8_t parse_hex(uint8_t(*get_data)(void))
static uint8_t address
Definition: DC2091A.ino:83
union LT_union_int32_4bytes data
Definition: DC2094A.ino:138
static int16_t pos
pRecordHeaderLengthAndType get_record(void)
Definition: nvm.cpp:85
static uint8_t parse_data[PARSE_DATA_LEN]
uint8_t * getRecordData()
int getMaxRecordSize()
Copyright 2018(c) Analog Devices, Inc.
static uint16_t parse_data_length
uint8_t ascii_to_hex(uint8_t ascii)
uint8_t filter_terminations(uint8_t(*get_data)(void))
uint16_t httoi(char *value)
Definition: conversions.cpp:48
static uint8_t record_data[MAX_RECORD_SIZE]
Basic Record Type Definitions.
static int i
Definition: DC2430A.ino:184
pRecordHeaderLengthAndType print_record(pRecordHeaderLengthAndType(*get_record)(void))
static uint16_t parse_data_position