class Parser(object): """ Parser class currently for LT devices ISP hexfile It convertes the encoded instruction in the hexfile into CSV. As a result we can use the CSV to program the device Attributes ---------- record_length : hex Defines the length of the record in half word record_type : byte Linear Technologies defined record types address : byte Address to write to PM device command : byte TBD data : byte TBD """ lt_record_type = {"PMBUS_WRITE_BYTE": 0x01, "PMBUS_WRITE_WORD": 0x02, "PMBUS_WRITE_BLOCK": 0x03, "PMBUS_READ_BYTE_EXPECT": 0x04, "PMBUS_READ_WORD_EXPECT": 0x05, "PMBUS_READ_BLOCK_EXPECT": 0x06, "DEVICE_ADDRESS": 0x07, "PACKING_CODE": 0x08, "NVM_DATA": 0x09, "PMBUS_READ_BYTE_LOOP_MASK": 0x0A, "PMBUS_READ_WORD_LOOP_MASK": 0x0B, "PMBUS_POLL_UNTIL_ACK_NOPEC": 0x0C, "DELAY_MS": 0x0D, "PMBUS_SEND_BYTE": 0x0E, "PMBUS_WRITE_BYTE_NOPEC": 0x0F, "PMBUS_WRITE_WORD_NOPEC": 0x10, "PMBUS_WRITE_BLOCK_NOPEC": 0x11, "PMBUS_READ_BYTE_EXPECT_NOPEC": 0x12, "PMBUS_READ_WORD_EXPECT_NOPEC": 0x13, "PMBUS_READ_BLOCK_EXPECT_NOPEC": 0x14, "PMBUS_READ_BYTE_LOOP_MASK_NOPEC": 0x15, "PMBUS_READ_WORD_LOOP_MASK_NOPEC": 0x16, "PMBUS_SEND_BYTE_NOPEC": 0x17, "EVENT": 0x18, "PMBUS_READ_BYTE_EXPECT_MASK_NOPEC": 0x19, "PMBUS_READ_WORD_EXPECT_MASK_NOPEC": 0x1A, "VARIABLE_META_DATA": 0x1B, "MODIFY_WORD_NOPEC": 0x1C, "MODIFY_BYTE_NOPEC": 0x1D, "PMBUS_WRITE_EE_DATA": 0x1E, "PMBUS_READ_AND_VERIFY_EE_DATA": 0x1F, "PMBUS_MODIFY_BYTE": 0x20, "PMBUS_MODIFY_WORD": 0x21 } lt_record_event = {"BEFORE_BEGIN": 0x00, "BEFORE_INSYSTEM_PROGRAMMING_BEGIN": 0x10, "SYSTEM_BEFORE_PROGRAMMING": 0x01, "INSYSTEM_CHIP_BEFORE_PROGRAM": 0x11, "SYSTEM_BEFORE_VERIFY": 0x02, "INSYSTEM_CHIP_BEFORE_VERIFY": 0x12, "INSYSTEM_CHIP_AFTER_VERIFY": 0x13, "SYSTEM_AFTER_VERIFY": 0x04, "AFTER_DONE": 0x03} def __init__(self, hexfile): """ Constructor """ self.hf = IntelHex(hexfile) self.record_length = None self.record_type = None self.address = None self.command = None self.data = None self.payload = [] def _get_lt_record_type(self, position): """ Interpret what is in the hexfile """ i = position # Get the number of bytes for the defined record self.record_length = struct.unpack('<H', struct.pack('2B', self.hf[i], self.hf[i+1]))[0] # Record self.record_type = struct.unpack('<H', struct.pack('2B', self.hf[i+2], self.hf[i+3]))[0] # When there is an event inform us if self.record_type == self.lt_record_type["EVENT"]: print "Event triggered" self._get_lt_payload(i) #for n in self.lt_record_event is self.data elif self.record_type == self.lt_record_type["PMBUS_WRITE_BYTE"]: self._get_lt_payloadheader(i) self._get_lt_payload(i) self.payload.append([self.address, self.command, self.data]) elif self.record_type == self.lt_record_type["PMBUS_WRITE_BYTE_NOPEC"]: self._get_lt_payloadheader(i) self._get_lt_payload(i) self.payload.append([self.address, self.command, self.data]) elif self.record_type == self.lt_record_type["PMBUS_WRITE_WORD"]: self._get_lt_payloadheader(i) self._get_lt_payload(i) self.payload.append([self.address, self.command, self.data]) elif self.record_type == self.lt_record_type["PMBUS_WRITE_WORD_NOPEC"]: self._get_lt_payloadheader(i) self._get_lt_payload(i) self.payload.append([self.address, self.command, self.data]) elif self.record_type == self.lt_record_type["PMBUS_READ_BYTE_LOOP_MASK"]: self._get_lt_payloadheader(i) self._get_lt_payload(i) self.payload.append([self.address, self.command, self.data]) elif self.record_type == self.lt_record_type["NVM_DATA"]: self._get_lt_payloadheader(i) self._get_lt_payload(i) self.payload.append([self.address, self.command, self.data]) return self.record_length def _get_lt_payloadheader(self, position): """ Extract payloadheader """ # Assume LT record and payload header need to byte each i = position + 4 self.address = struct.unpack('<H', struct.pack('2B', self.hf[i], self.hf[i+1]))[0] # Find how much we need to parse self.command = struct.unpack('B', struct.pack('B', self.hf[i+2]))[0] def _get_lt_payload(self, position): """ Extract payload Parameters ---------- position : int position in hexfile """ i = position + 7 if self.record_type == self.lt_record_type["EVENT"]: i = position +4 print "Position %d" % i self.data = struct.unpack('<H', struct.pack('2B', self.hf[i+1], self.hf[i+2]))[0] print "Data %d" % self.data elif self.record_type == self.lt_record_type["PMBUS_WRITE_BYTE"]: self.data = struct.unpack('B', struct.pack('B', self.hf[i+1]))[0] elif self.record_type == self.lt_record_type["PMBUS_WRITE_BYTE_NOPEC"]: self.data = struct.unpack('B', struct.pack('B', self.hf[i]))[0] elif self.record_type == self.lt_record_type["PMBUS_WRITE_WORD"]: self.data = struct.unpack('<H', struct.pack('2B', self.hf[i+1], self.hf[i+2]))[0] elif self.record_type == self.lt_record_type["PMBUS_WRITE_WORD_NOPEC"]: self.data = struct.unpack('<H', struct.pack('2B', self.hf[i], self.hf[i+1]))[0] elif self.record_type == self.lt_record_type["PMBUS_READ_BYTE_LOOP_MASK"]: self.data = struct.unpack('<H', struct.pack('2B', self.hf[i+1], self.hf[i+2]))[0] def parse(self, hexfile="ltctest.isphex"): """ Parse the hexfile, yo Parameters ---------- hexfile : str hexfile which should be parsed """ i = 0 while i < self.hf.__len__(): i += self._get_lt_record_type(i) print i print self.payload