+ self.bits = []
+ self.packet = []
+ self.packet_summary = ''
+ self.ss = self.es = None
+ self.ss_packet = self.es_packet = None
+ self.state = 'WAIT FOR SOP'
+
+ def putpb(self, data):
+ self.put(self.ss, self.es, self.out_python, data)
+
+ def putb(self, data):
+ self.put(self.ss, self.es, self.out_ann, data)
+
+ def putpp(self, data):
+ self.put(self.ss_packet, self.es_packet, self.out_python, data)
+
+ def putp(self, data):
+ self.put(self.ss_packet, self.es_packet, self.out_ann, data)
+
+ def start(self):
+ self.out_python = self.register(srd.OUTPUT_PYTHON)
+ self.out_ann = self.register(srd.OUTPUT_ANN)
+
+ def handle_packet(self):
+ packet = ''
+ for (bit, ss, es) in self.bits:
+ packet += bit
+
+ # Bits[0:7]: SYNC
+ sync = packet[:7 + 1]
+ self.ss, self.es = self.bits[0][1], self.bits[7][2]
+ # The SYNC pattern for low-speed/full-speed is KJKJKJKK (00000001).
+ if sync != '00000001':
+ self.putpb(['SYNC ERROR', sync])
+ self.putb([1, ['SYNC ERROR: %s' % sync, 'SYNC ERR: %s' % sync,
+ 'SYNC ERR', 'SE', 'S']])
+ else:
+ self.putpb(['SYNC', sync])
+ self.putb([0, ['SYNC: %s' % sync, 'SYNC', 'S']])
+ self.packet.append(sync)
+
+ # Bits[8:15]: PID
+ pid = packet[8:15 + 1]
+ pidname = pids.get(pid, (pid, ''))[0]
+ self.ss, self.es = self.bits[8][1], self.bits[15][2]
+ self.putpb(['PID', pidname])
+ self.putb([2, ['PID: %s' % pidname, pidname, pidname[0]]])
+ self.packet.append(pid)
+ self.packet_summary += pidname
+
+ if pidname in ('OUT', 'IN', 'SOF', 'SETUP', 'PRE', 'PING'):
+ if pidname == 'SOF':
+ # Bits[16:26]: Framenum
+ framenum = bitstr_to_num(packet[16:26 + 1])
+ self.ss, self.es = self.bits[16][1], self.bits[26][2]
+ self.putpb(['FRAMENUM', framenum])
+ self.putb([3, ['Frame: %d' % framenum, 'Frame', 'Fr', 'F']])
+ self.packet.append(framenum)
+ self.packet_summary += ' %d' % framenum
+ else:
+ # Bits[16:22]: Addr
+ addr = bitstr_to_num(packet[16:22 + 1])
+ self.ss, self.es = self.bits[16][1], self.bits[22][2]
+ self.putpb(['ADDR', addr])
+ self.putb([4, ['Address: %d' % addr, 'Addr: %d' % addr,
+ 'Addr', 'A']])
+ self.packet.append(addr)
+ self.packet_summary += ' ADDR %d' % addr
+
+ # Bits[23:26]: EP
+ ep = bitstr_to_num(packet[23:26 + 1])
+ self.ss, self.es = self.bits[23][1], self.bits[26][2]
+ self.putpb(['EP', ep])
+ self.putb([5, ['Endpoint: %d' % ep, 'EP: %d' % ep, 'EP', 'E']])
+ self.packet.append(ep)
+ self.packet_summary += ' EP %d' % ep
+
+ # Bits[27:31]: CRC5
+ crc5 = bitstr_to_num(packet[27:31 + 1])
+ self.ss, self.es = self.bits[27][1], self.bits[31][2]
+ self.putpb(['CRC5', crc5])
+ self.putb([6, ['CRC5: 0x%02X' % crc5, 'CRC5', 'C']])
+ self.packet.append(crc5)
+ elif pidname in ('DATA0', 'DATA1', 'DATA2', 'MDATA'):
+ # Bits[16:packetlen-16]: Data
+ data = packet[16:-16]
+ # TODO: len(data) must be a multiple of 8.
+ databytes = []
+ self.packet_summary += ' ['
+ for i in range(0, len(data), 8):
+ db = bitstr_to_num(data[i:i + 8])
+ self.ss, self.es = self.bits[16 + i][1], self.bits[23 + i][2]
+ self.putpb(['DATABYTE', db])
+ self.putb([8, ['Databyte: %02X' % db, 'Data: %02X' % db,
+ 'DB: %02X' % db, '%02X' % db]])
+ databytes.append(db)
+ self.packet_summary += ' %02X' % db
+ data = data[8:]
+ self.packet_summary += ' ]'
+
+ # Convenience Python output (no annotation) for all bytes together.
+ self.ss, self.es = self.bits[16][1], self.bits[-16][2]
+ self.putpb(['DATABYTES', databytes])
+ self.packet.append(databytes)
+
+ # Bits[packetlen-16:packetlen]: CRC16
+ crc16 = bitstr_to_num(packet[-16:])
+ self.ss, self.es = self.bits[-16][1], self.bits[-1][2]
+ self.putpb(['CRC16', crc16])
+ self.putb([9, ['CRC16: 0x%04X' % crc16, 'CRC16', 'C']])
+ self.packet.append(crc16)
+ elif pidname in ('ACK', 'NAK', 'STALL', 'NYET', 'ERR'):
+ pass # Nothing to do, these only have SYNC+PID+EOP fields.
+ else:
+ pass # TODO: Handle 'SPLIT' and possibly 'Reserved' packets.