r4857 - developers/werner/ahrt/host/tmc/lib

werner at docs.openmoko.org werner at docs.openmoko.org
Mon Dec 8 13:23:17 CET 2008


Author: werner
Date: 2008-12-08 13:23:16 +0100 (Mon, 08 Dec 2008)
New Revision: 4857

Modified:
   developers/werner/ahrt/host/tmc/lib/crc.py
   developers/werner/ahrt/host/tmc/lib/decode.py
   developers/werner/ahrt/host/tmc/lib/dxplore.py
   developers/werner/ahrt/host/tmc/lib/phosphor.py
   developers/werner/ahrt/host/tmc/lib/scope.py
   developers/werner/ahrt/host/tmc/lib/wave.py
Log:
Highlights:

- added basic USB decoding, a contribution from a non-Openmoko project

Details:

- lib/scope.py, lib/wave.py, lib/phosphor.py: use  hasattr(obj, "__iter__")
  instead of  isinstance(obj, list)
- lib/crc.py: added USB's CRC5
- lib/dxplore.py: split decoding into a pre-decode phase where the bits are
  collected and the actual decode phase. This facilitates the construction of
  multi-channel decoders.
- lib/decode.py: added decoding of the USB NRZI bitstream, bit-stuffing, and
  packet header and content (transfers are not yet decoded)



Modified: developers/werner/ahrt/host/tmc/lib/crc.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/crc.py	2008-12-08 10:18:26 UTC (rev 4856)
+++ developers/werner/ahrt/host/tmc/lib/crc.py	2008-12-08 12:23:16 UTC (rev 4857)
@@ -46,6 +46,8 @@
       0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
       0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 )
 
+    # Table for CRC-16 (polynomial x^16 + x^15 + x^2 + 1)
+
     crc16_syndrome = (
       0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
       0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
@@ -80,6 +82,28 @@
       0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
       0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 )
 
+    #
+    # USB CRC5 (x^4 + x^3)
+    #
+    # According to http://www.usb.org/developers/whitepapers/crcdes.pdf
+    #
+    # To obtain the USB CRC5, crc = crc5(0x1f, data, 11) ^ 0x1f
+    #
+
+    def crc5(self, crc, value, bits):
+	#
+	# polynomial is 0x05 reversed, then shifted one position to the left
+	# original 00101
+	# reverse  10100
+	# shift   101000
+	#
+	poly = 0x28
+	for b in range(0, bits):
+	    if ((value >> b) & 1) != (crc & 1):
+		crc ^= poly
+	    crc >>= 1
+	return crc & 0x1f
+	
     def crc7(self, crc, bytes):
 	for b in bytes:
 	    crc = self.crc7_syndrome[(crc << 1) ^ b]

Modified: developers/werner/ahrt/host/tmc/lib/decode.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/decode.py	2008-12-08 10:18:26 UTC (rev 4856)
+++ developers/werner/ahrt/host/tmc/lib/decode.py	2008-12-08 12:23:16 UTC (rev 4857)
@@ -31,6 +31,9 @@
 g_crc = tmc.crc.crc()
 
 
+d_table = {}
+
+
 def d_bits(bits):
     s = ""
     for b in bits:
@@ -327,6 +330,248 @@
     return s
 
 
+def usb_field(raw, bits):
+    bit = 0
+    got = 0
+    byte = 0
+    while bit != len(raw):
+	if raw[bit] == "S":
+	    bit += 1
+	    continue
+	if raw[bit] == "X":
+	    return None
+	elif raw[bit]:
+	    byte |= 1 << got
+	got += 1
+	bit += 1
+	if got == bits:
+	    del raw[0:bit]
+	    return byte
+    return None
+
+
+def usb_token(raw):
+    addr = usb_field(raw, 7)
+    if addr is None:
+	return ""
+    s = "%d" % addr
+
+    ep = usb_field(raw, 4)
+    if ep is None:
+	return s
+    s += "/%d" % ep
+
+    expect = g_crc.crc5(0x1f, ep << 7 | addr, 11) ^ 0x1f
+
+    crc = usb_field(raw, 5)
+    if crc is None:
+	return s
+
+    if crc == expect and len(raw) == 0:
+	return s
+
+    s += ",CRC%02X" % crc
+    if crc != expect:
+	s += "/%02X" % expect
+
+    return s
+
+
+def usb_sof(raw):
+    frame = usb_field(raw, 11)
+    if frame is None:
+	return ""
+    s = "%03X" % frame
+
+    expect = g_crc.crc5(frame, 11) ^ 0x1f
+
+    crc = usb_field(raw, 5)
+    if crc is None:
+	return s
+
+    if crc == expect and len(raw) == 0:
+	return s
+
+    s += ",CRC%02X" % crc
+    if crc != expect:
+	s += "/%02X" % expect
+
+    return s
+
+
+def usb_data(raw):
+    bytes = []
+    while True:
+	byte = usb_field(raw, 8)
+	if byte is None:
+	    break
+	bytes.append(byte)
+
+    s = ""
+    if len(bytes) < 2:
+	crc = None
+    else:
+	crc = (bytes[-2], bytes[-1])
+	del bytes[-1]
+	del bytes[-1]
+	expect = g_crc.crc16(0xffff, bytes) ^ 0xffff
+
+    for b in bytes:
+	if s:
+	    s += "."
+	else:
+	    s += ":"
+	s += "%02X" % b
+
+    if crc is None:
+	return s
+
+    crc = crc[0] | crc[1] << 8
+    if crc == expect and len(raw) == 0:
+	return s
+
+    if s:
+	s += ","
+    else:
+	s += ":"
+    s += "CRC%04X" % crc
+    if crc != expect:
+	s += "/%04X" % expect
+
+    return s
+
+
+def usb_handshake(raw):
+    return ""
+
+
+def usb_packet(raw):
+    sync = usb_field(raw, 8)
+    if sync is None:
+	return ""
+    if sync != 0x80:
+	return "%02X?" % sync
+
+    pid = usb_field(raw, 8)
+    if pid is None:
+	return "SYNC"
+
+    if pid == 0xe1:
+	return "OUT"+usb_token(raw)
+    if pid == 0x69:
+	return "IN"+usb_token(raw)
+    if pid == 0xa5:
+	return "SOF"+usb_sof(raw)
+    if pid == 0x2d:
+	return "SETUP"+usb_token(raw)
+
+    if pid == 0xc3:
+	return "DATA0"+usb_data(raw)
+    if pid == 0x4b:
+	return "DATA1"+usb_data(raw)
+    if pid == 0x87:
+	return "DATA2"+usb_data(raw)
+    if pid == 0x0f:
+	return "MDATA"+usb_data(raw)
+
+    if pid == 0xd2:
+	return "ACK"
+    if pid == 0x5a:
+	return "NAK"
+    if pid == 0x1e:
+	return "STALL"
+
+    # we don't decode NYET and special packets
+
+    return "SYNC"
+
+
+def d_usb(bits):
+    if bits[0]:
+	s = "~"
+    else:
+	s = ""
+
+    while len(bits) and bits[0]:
+	del bits[0]
+
+    raw = []
+    last = 1
+    ones = 0
+    for b in bits:
+	if b == "X":
+	    raw.append("X")
+	elif b == last:
+	    raw.append(1)
+	    ones += 1
+	else:
+	    if ones == 6:
+		raw.append("S")
+	    else:
+		raw.append(0)
+	    ones = 0
+	last = b
+
+    s += usb_packet(raw)
+
+    if len(raw):
+	s += "|"
+	for b in raw:
+	    s += str(b)
+
+    return s
+
+
+def d_usb_dp(bits):
+    if d_usb_dm not in d_table:
+	return d_usb(bits)
+
+    dp = bits
+    dm = d_table[d_usb_dm]
+    s = ""
+
+    packet = []
+    while len(dp):
+	if dp[0] == "X" or dm[0] == "X":
+	    packet.append("X")
+	elif not dp[0] and not dm[0]:
+	    if len(packet):
+		s += "["+d_usb(packet)+"]"
+	    packet = []
+	elif dp[0] and dm[0]:
+	    if len(packet):
+		s += "["+d_usb(packet)+"+"
+	    packet = []
+	    s += "SE1"
+	else:
+	    packet.append(dp[0])
+	del dp[0]
+	del dm[0]
+
+    if len(packet):
+	s += "["+d_usb(packet)+"+"
+
+    return s
+
+
+def d_usb_dm(bits):
+    if d_usb_dp in d_table:
+	return ""
+    inverted = []
+    for b in bits:
+	if b == "X":
+	    inverted.append(b)
+	else:
+	    inverted.append(1-b)
+    return d_usb(inverted)
+
+
+def d_set_table(table):
+    global d_table
+
+    d_table = table
+
+
 decoders = [
     #  0123456789abcdef -- maximum length is 16 characters
     ( "LSB->MSB",		d_byte_lsb ),
@@ -335,4 +580,6 @@
     ( "SDIO RESP (SD)",		d_sdio_resp_sd ),
     ( "SDIO RESP (SPI)",	d_sdio_resp_spi ),
     ( "SDIO R5 (SPI)",		d_sdio_r5_spi ),
+    ( "USB D+",			d_usb_dp ),
+    ( "USB D-",			d_usb_dm ),
 ]

Modified: developers/werner/ahrt/host/tmc/lib/dxplore.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/dxplore.py	2008-12-08 10:18:26 UTC (rev 4856)
+++ developers/werner/ahrt/host/tmc/lib/dxplore.py	2008-12-08 12:23:16 UTC (rev 4857)
@@ -148,6 +148,12 @@
 	self.main.w.tag_raise("d_bg_"+self.tag)
 	self.main.w.tag_raise("d_fg_"+self.tag)
 
+    def pre_decode(self, selected, bits):
+	global d_table
+
+	if not selected:
+	    d_table[self.decoder] = bits
+
     def decode(self, selected, bits):
 	y = self.y(0)
 	x0 = self.x(self.main.decode_from)
@@ -706,12 +712,17 @@
 	self.decode()
 
     def decode(self):
+	global d_table
+
 	self.meas_start.show(self.cur.pos-self.decode_from)
 	if self.cur.pos < self.decode_from:
 	    return
 	x0 = self.ch[0].x(self.decode_from)
 	x1 = self.ch[0].x(self.cur.pos+1)
 	self.w.coords("selection", x0, 0, x1, self.yres)
+
+	d_table = {}
+	by_ch = {}
 	for ch in self.ch:
 	    bits = []
 	    i = self.decode_from
@@ -723,8 +734,14 @@
 		    else:
 			bits.append("X")
 		i += 1
-	    ch.decode(ch is self.selected, bits)
+	    by_ch[ch] = bits
+	    ch.pre_decode(ch is self.selected, bits)
 
+	d_set_table(d_table)
+
+	for ch in self.ch:
+	    ch.decode(ch is self.selected, by_ch[ch])
+
     def end_decode(self):
 	for ch in self.ch:
 	    ch.end_decode()

Modified: developers/werner/ahrt/host/tmc/lib/phosphor.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/phosphor.py	2008-12-08 10:18:26 UTC (rev 4856)
+++ developers/werner/ahrt/host/tmc/lib/phosphor.py	2008-12-08 12:23:16 UTC (rev 4857)
@@ -156,7 +156,7 @@
     def pnm(self, px = 1, py = 1, colors = None, normalize = norm_linear):
 	if colors is None:
 	    fn = self.color_default
-	elif isinstance(colors, list):
+	elif hasattr(colors, "__iter__"):
 	    fn = lambda v: colors[min(len(colors)-1, int(v*len(colors)))]
 	else:
 	    fn = colors

Modified: developers/werner/ahrt/host/tmc/lib/scope.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/scope.py	2008-12-08 10:18:26 UTC (rev 4856)
+++ developers/werner/ahrt/host/tmc/lib/scope.py	2008-12-08 12:23:16 UTC (rev 4857)
@@ -381,7 +381,7 @@
 	return rigol_to_ppm(self.query(":LCD:DATA?"))
 
     def wave(self, channels, start = None, end = None, step = None):
-	if not isinstance(channels, list):
+	if not hasattr(channels, "__iter__"):
 	    return self.wave([channels], start, end, step)[0]
 	la = None
 	res = waves()

Modified: developers/werner/ahrt/host/tmc/lib/wave.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/wave.py	2008-12-08 10:18:26 UTC (rev 4856)
+++ developers/werner/ahrt/host/tmc/lib/wave.py	2008-12-08 12:23:16 UTC (rev 4857)
@@ -97,7 +97,7 @@
 	f.close()
 
     def get(self, t):
-	if isinstance(t, list):
+	if hasattr(t, "__iter__"):
 	    res = []
 	    for v in t:
 		res.append(self.get_one(v))




More information about the commitlog mailing list