libsigrokdecode: decoding SOP*'s from 3 k-codes; text output.
Allow detailed decoding of SOP, SOP', SOP", SOP'_Debug, SOP"_Debug.
Allow decoding SOP*, Cable Reset, Hard Reset from 3 valid k-codes,
(instead of all 4), which is specified in the USB PD spec.
Allow text output without running PulseView.
Signed-off-by: Dawei Li <daweili@google.com>
BUG=chrome-os-partner:42703
TEST=BEGIN
The following command will output the pd packets in text format:
sigrok-cli -i test.sr -P usb_pd_bmc:cc=CC1,usb_pd_packet -A usb_pd_packet=text
Change CC1 to CC2, if that is the case.
END
Change-Id: I18ca145b9be5c28770b3ab7c42c2783008dc8754
Reviewed-on: https://chromium-review.googlesource.com/289249
Commit-Ready: Sheng-liang Song <ssl@chromium.org>
Tested-by: Dawei Li <daweili@google.com>
Reviewed-by: Sheng-liang Song <ssl@chromium.org>
diff --git a/decoders/usb_pd_bmc/pd.py b/decoders/usb_pd_bmc/pd.py
index 67356f9..f0f6e23 100644
--- a/decoders/usb_pd_bmc/pd.py
+++ b/decoders/usb_pd_bmc/pd.py
@@ -64,6 +64,7 @@
self.edges = []
self.half_one = False
self.start_one = 0
+ self.tstamp = 0
def metadata(self, key, value):
if key == srd.SRD_CONF_SAMPLERATE:
@@ -118,7 +119,7 @@
self.edges.append(self.previous)
# Export the packet
self.putx([0, ['BMC %d' % (self.seq),'PD']])
- self.putp({'BITS': self.packet, 'EDGES':self.edges})
+ self.putp({'TIMESTAMP':tstamp, 'BITS': self.packet, 'EDGES':self.edges})
#self.putb((1, bytes(self.packet))
# Reset for next packet
self.startsample = self.samplenum
@@ -149,4 +150,3 @@
self.edges.append(self.previous)
self.half_one = False
self.previous = self.samplenum
-
diff --git a/decoders/usb_pd_packet/pd.py b/decoders/usb_pd_packet/pd.py
index 5eb7af2..c1c0fdf 100644
--- a/decoders/usb_pd_packet/pd.py
+++ b/decoders/usb_pd_packet/pd.py
@@ -95,6 +95,17 @@
SYNC_CODES=[SYNC1, SYNC2, SYNC3]
HRST_CODES=[RST1, RST1, RST1, RST2]
+# different SOPs: SOP, SOP', SOP", SOP'_Debug, SOP"_Debug
+SOP = [SYNC1, SYNC1, SYNC1, SYNC2, "SOP" ]
+SOPP = [SYNC1, SYNC1, SYNC3, SYNC3, "SOP'"]
+SOPPP = [SYNC1, SYNC3, SYNC1, SYNC3, 'SOP"']
+SOPPDebug = [SYNC1, RST2, RST2, SYNC3, "SOP'_Debug"]
+SOPPPDebug = [SYNC1, RST2, SYNC3, SYNC2, 'SOP"_Debug']
+START_OF_PACKETS = [SOP, SOPP, SOPPP, SOPPDebug, SOPPPDebug]
+
+CableReset = [ RST1, SYNC1, RST1, SYNC3, "Cable Reset"]
+HardReset = [ RST1, RST1, RST1, RST2, "Hard Reset" ]
+
SYM_NAME = [
['0x0', '0'],
['0x1', '1'],
@@ -366,18 +377,40 @@
hi = self.get_short()
return lo | (hi << 16)
+ def is_hard_reset(self, sym_array):
+ first = 1 if sym_array[0]==HardReset[0] else 0
+ second = 1 if sym_array[1]==HardReset[1] else 0
+ third = 1 if sym_array[2]==HardReset[2] else 0
+ fourth = 1 if sym_array[3]==HardReset[3] else 0
+ return first + second + third + fourth >= 3
+
+ def is_cable_reset(self, sym_array):
+ first = 1 if sym_array[0]==CableReset[0] else 0
+ second = 1 if sym_array[1]==CableReset[1] else 0
+ third = 1 if sym_array[2]==CableReset[2] else 0
+ fourth = 1 if sym_array[3]==CableReset[3] else 0
+ return first + second + third + fourth >= 3
+
+ def get_start_of_packet(self, sym_array):
+ for i in range(5):
+ first = 1 if sym_array[0]==START_OF_PACKETS[i][0] else 0
+ second = 1 if sym_array[1]==START_OF_PACKETS[i][1] else 0
+ third = 1 if sym_array[2]==START_OF_PACKETS[i][2] else 0
+ fourth = 1 if sym_array[3]==START_OF_PACKETS[i][3] else 0
+ if first + second + third + fourth >= 3:
+ return START_OF_PACKETS[i][4]
+ else:
+ return None
+
def scan_eop(self):
for i in range(len(self.bits) - 19):
- k = [self.get_sym(i, rec=False), self.get_sym(i+5, rec=False), self.get_sym(i+10, rec=False), self.get_sym(i+15, rec=False)]
- syncs = 0
- hreset = HRST_CODES[:]
- for sym in k:
- if sym in SYNC_CODES:
- syncs += 1
- if sym == hreset[0]:
- del hreset[0]
+ k = [self.get_sym(i, rec=False), self.get_sym(i+5, rec=False),
+ self.get_sym(i+10, rec=False), self.get_sym(i+15, rec=False)]
+ hard_reset = self.is_hard_reset(k)
+ cable_reset = self.is_cable_reset(k)
+ start_of_packet = self.get_start_of_packet(k)
# We have an interesting symbol sequence
- if len(hreset) == 0 or syncs >= 4: #TODO 3 symbols
+ if hard_reset or cable_reset or start_of_packet!=None:
# annotate the preamble
self.putx(0, i, [1, ['Preamble', '...']])
# annotate each symbol
@@ -385,14 +418,13 @@
self.rec_sym(i+5, k[1])
self.rec_sym(i+10, k[2])
self.rec_sym(i+15, k[3])
- # we have the 4 HardReset symbols
- if len(hreset) == 0:
- # annote the HardReset
- self.putx(i, i+20, [2, ['HardReset', 'HRST']])
+ if hard_reset:
self.text += "HRST"
return HARD_RESET
- # 3 valid SYNC-x codes : SOP*
- self.putx(i, i+20, [2, ['SOP*', 'SOP']])
+ elif cable_reset:
+ self.putx(i, i+20, [2, [CableReset[4], 'CRST']])
+ else:
+ self.putx(i, i+20, [2, [start_of_packet, 'S']])
return i+20
self.putx(0, len(self.bits), [1, ['Junk???', 'XXX']])
self.text += "Junk???"
@@ -402,6 +434,7 @@
def __init__(self, **kwargs):
self.samplerate = None
self.idx = 0
+ self.packet_seq = 0
def metadata(self, key, value):
if key == srd.SRD_CONF_SAMPLERATE:
@@ -422,19 +455,18 @@
print(traceback.format_exc())
def decode_(self, ss, es, data):
+ self.tstamp = data['TIMESTAMP']
self.bits = data['BITS']
self.edges = data['EDGES']
self.data = []
self.idx = 0
+ self.samplenum = 0
if len(self.edges) < 50:
return # Not a real PD packet
- # TODO:Samplerate metadata not passed to stacked decoder : HARDCODING
- self.samplerate = 2400000
- t0_time = self.edges[0]/self.samplerate
- dt_us = (self.edges[-1] - self.edges[0])/(self.samplerate/1000000.0)
- self.text = "%5.6f (%4d): " % (t0_time, dt_us)
+ self.packet_seq += 1
+ self.text = "#%d (%8.6fms): " % (self.packet_seq, self.tstamp*1000)
self.idx = self.scan_eop()
if self.idx < 0:
@@ -466,6 +498,5 @@
self.putx(self.idx-5, self.idx, [6, ['EOP', 'E']])
else:
self.putwarn("No EOP","EOP!")
-
# Full text trace
self.putx(0, self.idx, [12, [self.text, 'TXT']])