X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=decoders%2Fjtag%2Fjtag.py;h=4e27ce8477cdb09d48214f7143e81b093efbccce;hb=2dc6d41c64a8235308e61b4f9b509c7fecb2b502;hp=828cbef52f68d8439ec1a8d3f24c91f388531929;hpb=557a143d8018ac5b25b0cdde99415433e3663f62;p=libsigrokdecode.git diff --git a/decoders/jtag/jtag.py b/decoders/jtag/jtag.py index 828cbef..4e27ce8 100644 --- a/decoders/jtag/jtag.py +++ b/decoders/jtag/jtag.py @@ -26,8 +26,8 @@ class Decoder(srd.Decoder): api_version = 1 id = 'jtag' name = 'JTAG' - longname = 'Joint Test Action Group' - desc = 'TODO.' + longname = 'Joint Test Action Group (IEEE 1149.1)' + desc = 'Protocol for testing, debugging, and flashing ICs.' license = 'gplv2+' inputs = ['logic'] outputs = ['jtag'] @@ -36,17 +36,22 @@ class Decoder(srd.Decoder): {'id': 'tdo', 'name': 'TDO', 'desc': 'Test data output'}, {'id': 'tck', 'name': 'TCK', 'desc': 'Test clock'}, {'id': 'tms', 'name': 'TMS', 'desc': 'Test mode select'}, - {'id': 'trst', 'name': 'TRST', 'desc': 'Test reset'}, ] - optional_probes = [] # TODO? SRST? + optional_probes = [ + {'id': 'trst', 'name': 'TRST#', 'desc': 'Test reset'}, + {'id': 'srst', 'name': 'SRST#', 'desc': 'System reset'}, + {'id': 'rtck', 'name': 'RTCK', 'desc': 'Return clock signal'}, + ] options = {} annotations = [ - ['ASCII', 'TODO: description'], + ['Text', 'Human-readable text'], ] def __init__(self, **kwargs): - self.state = 'TEST-LOGIC-RESET' - self.oldpins = (-1, -1, -1, -1, -1) + # self.state = 'TEST-LOGIC-RESET' + self.state = 'RUN-TEST/IDLE' + self.oldstate = None + self.oldpins = (-1, -1, -1, -1) self.oldtck = -1 self.bits_tdi = [] self.bits_tdo = [] @@ -59,6 +64,8 @@ class Decoder(srd.Decoder): pass def advance_state_machine(self, tms): + self.oldstate = self.state + # Intro "tree" if self.state == 'TEST-LOGIC-RESET': self.state = 'TEST-LOGIC-RESET' if (tms) else 'RUN-TEST/IDLE' @@ -100,35 +107,45 @@ class Decoder(srd.Decoder): else: raise Exception('Invalid state: %s' % self.state) - def handle_rising_tck_edge(self, tdi, tdo, tck, tms, trst): - # In SHIFT-DR/SHIFT-IR (on rising TCK edges) we collect TDI values. - if self.state in ('SHIFT-DR', 'SHIFT-IR'): - self.bits_tdi.append(tdi) - - # Output all TDI bits. - elif self.state in ('EXIT1-DR', 'EXIT1-IR'): - s = self.state[-2:] + ' TDI: ' + ''.join(map(str, self.bits_tdi)) - s += ', ' + str(len(self.bits_tdi)) + ' bits' - self.put(self.ss, self.es, self.out_ann, [0, [s]]) - self.bits_tdi = [] - + def handle_rising_tck_edge(self, tdi, tdo, tck, tms): # Rising TCK edges always advance the state machine. self.advance_state_machine(tms) # Output the state we just switched to. self.put(self.ss, self.es, self.out_ann, [0, ['New state: %s' % self.state]]) + self.put(self.ss, self.es, self.out_proto, + ['NEW STATE', self.state]) + + # If we went from SHIFT-IR to SHIFT-IR, or SHIFT-DR to SHIFT-DR, + # collect the current TDI/TDO values (upon rising TCK edge). + if self.state.startswith('SHIFT-') and self.oldstate == self.state: + self.bits_tdi.insert(0, tdi) + self.bits_tdo.insert(0, tdo) + # TODO: ANN/PROTO output. + # self.put(self.ss, self.es, self.out_ann, + # [0, ['TDI add: ' + str(tdi)]]) + # self.put(self.ss, self.es, self.out_ann, + # [0, ['TDO add: ' + str(tdo)]]) + + # Output all TDI/TDO bits if we just switched from SHIFT-* to EXIT1-*. + if self.oldstate.startswith('SHIFT-') and \ + self.state.startswith('EXIT1-'): + + t = self.state[-2:] + ' TDI' + b = ''.join(map(str, self.bits_tdi)) + h = ' (0x%x' % int('0b' + b, 2) + ')' + s = t + ': ' + b + h + ', ' + str(len(self.bits_tdi)) + ' bits' + self.put(self.ss, self.es, self.out_ann, [0, [s]]) + self.put(self.ss, self.es, self.out_proto, [t, b]) + self.bits_tdi = [] - def handle_falling_tck_edge(self, tdi, tdo, tck, tms, trst): - # In SHIFT-DR/SHIFT-IR (on falling TCK edges) we collect TDO values. - if self.state in ('SHIFT-DR', 'SHIFT-IR'): - self.bits_tdo.append(tdo) - - # Output all TDO bits. - if self.state in ('EXIT1-DR', 'EXIT1-IR'): - s = self.state[-2:] + ' TDO: ' + ''.join(map(str, self.bits_tdo)) - s += ', ' + str(len(self.bits_tdo)) + ' bits' + t = self.state[-2:] + ' TDO' + b = ''.join(map(str, self.bits_tdo)) + h = ' (0x%x' % int('0b' + b, 2) + ')' + s = t + ': ' + b + h + ', ' + str(len(self.bits_tdo)) + ' bits' self.put(self.ss, self.es, self.out_ann, [0, [s]]) + self.put(self.ss, self.es, self.out_proto, [t, b]) self.bits_tdo = [] def decode(self, ss, es, data): @@ -142,8 +159,8 @@ class Decoder(srd.Decoder): self.oldpins = pins # Get individual pin values into local variables. - # TODO: Handle optional pins. - (tdi, tdo, tck, tms, trst) = pins + # Unused probes will have a value of > 1. + (tdi, tdo, tck, tms, trst, srst, rtck) = pins # We only care about TCK edges (either rising or falling). if (self.oldtck == tck): @@ -152,10 +169,12 @@ class Decoder(srd.Decoder): # Store start/end sample for later usage. self.ss, self.es = ss, es + # self.put(self.ss, self.es, self.out_ann, + # [0, ['tdi:%s, tdo:%s, tck:%s, tms:%s' \ + # % (tdi, tdo, tck, tms)]]) + if (self.oldtck == 0 and tck == 1): - self.handle_rising_tck_edge(tdi, tdo, tck, tms, trst) - elif (self.oldtck == 1 and tck == 0): - self.handle_falling_tck_edge(tdi, tdo, tck, tms, trst) + self.handle_rising_tck_edge(tdi, tdo, tck, tms) self.oldtck = tck