summaryrefslogtreecommitdiff
path: root/decoders
diff options
context:
space:
mode:
authorKongou Hikari <hikari@iloli.bid>2019-12-05 18:37:05 +0800
committerUwe Hermann <uwe@hermann-uwe.de>2020-01-09 00:14:55 +0100
commite349cbe9c80b772d5b96c94d24719b2cb49e0c4f (patch)
tree6c928ed0bc304adfc92c92b0456097075a653f3f /decoders
parente88f63751affb679a894ed2c81e1b750aa70fd61 (diff)
downloadlibsigrokdecode-e349cbe9c80b772d5b96c94d24719b2cb49e0c4f.tar.gz
libsigrokdecode-e349cbe9c80b772d5b96c94d24719b2cb49e0c4f.zip
cjtag: Add cJTAG OSCAN1 decoder.
[Note: This is a commit from Kongou Hikari ("diodep" on GitHub) that was "rebased" by Uwe Hermann on top of the current libsigrokdecode mainline JTAG decoder. There are various reasons for this, including avoiding non-mainline or outdated decoder changes, as well as making it easily visible what the changes vs. the current JTAG decoder are, in case we later need to apply some changes to both decoders or in case both decoders might be merged later on. Minor cosmetic and naming changes were also squashed in (no functional changes, though).]
Diffstat (limited to 'decoders')
-rw-r--r--decoders/cjtag/__init__.py6
-rw-r--r--decoders/cjtag/pd.py107
2 files changed, 107 insertions, 6 deletions
diff --git a/decoders/cjtag/__init__.py b/decoders/cjtag/__init__.py
index 51bb629..168d4d6 100644
--- a/decoders/cjtag/__init__.py
+++ b/decoders/cjtag/__init__.py
@@ -25,6 +25,12 @@ and flashing various digital ICs.
Details:
https://en.wikipedia.org/wiki/Joint_Test_Action_Group
http://focus.ti.com/lit/an/ssya002c/ssya002c.pdf
+
+This decoder handles a tiny part of IEEE 1149.7, the CJTAG OSCAN1 format.
+ZBS is currently not supported.
+
+Details:
+http://developers-club.com/posts/237885/
'''
from .pd import Decoder
diff --git a/decoders/cjtag/pd.py b/decoders/cjtag/pd.py
index 2bbe9a4..a5c398e 100644
--- a/decoders/cjtag/pd.py
+++ b/decoders/cjtag/pd.py
@@ -2,6 +2,8 @@
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2012-2015 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2019 Zhiyuan Wan <dv.xw@qq.com>
+## Copyright (C) 2019 Kongou Hikari <hikari@iloli.bid>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@@ -55,9 +57,9 @@ jtag_states = [
class Decoder(srd.Decoder):
api_version = 3
- id = 'jtag'
- name = 'JTAG'
- longname = 'Joint Test Action Group (IEEE 1149.1)'
+ id = 'cjtag'
+ name = 'cJTAG'
+ longname = 'Compact Joint Test Action Group (IEEE 1149.7)'
desc = 'Protocol for testing, debugging, and flashing ICs.'
license = 'gplv2+'
inputs = ['logic']
@@ -79,12 +81,16 @@ class Decoder(srd.Decoder):
('bit-tdo', 'Bit (TDO)'),
('bitstring-tdi', 'Bitstring (TDI)'),
('bitstring-tdo', 'Bitstring (TDO)'),
+ ('bit-tms', 'Bit (TMS)'),
+ ('state-tapc', 'TAPC state'),
)
annotation_rows = (
('bits-tdi', 'Bits (TDI)', (16,)),
('bits-tdo', 'Bits (TDO)', (17,)),
('bitstrings-tdi', 'Bitstrings (TDI)', (18,)),
('bitstrings-tdo', 'Bitstrings (TDO)', (19,)),
+ ('bit-tms', 'Bit (TMS)', (20,)),
+ ('state-tapc', 'TAPC state', (21,)),
('states', 'States', tuple(range(15 + 1))),
)
@@ -94,6 +100,13 @@ class Decoder(srd.Decoder):
def reset(self):
# self.state = 'TEST-LOGIC-RESET'
self.state = 'RUN-TEST/IDLE'
+ self.cjtagstate = '4-WIRE'
+ self.oldcjtagstate = None
+ self.escape_edges = 0
+ self.oaclen = 0
+ self.oldtms = 0
+ self.oacp = 0
+ self.oscan1cycle = 0
self.oldstate = None
self.bits_tdi = []
self.bits_tdo = []
@@ -124,6 +137,41 @@ class Decoder(srd.Decoder):
def advance_state_machine(self, tms):
self.oldstate = self.state
+ if self.cjtagstate.startswith('CJTAG-'):
+ self.oacp = self.oacp + 1
+ if (self.oacp > 4 and self.oaclen == 12):
+ self.cjtagstate = 'CJTAG-EC'
+
+ if (self.oacp == 8 and tms == 0):
+ self.oaclen = 36
+ if (self.oacp > 8 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-SPARE'
+ if (self.oacp > 13 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-TPDEL'
+ if (self.oacp > 16 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-TPREV'
+ if (self.oacp > 18 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-TPST'
+ if (self.oacp > 23 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-RDYC'
+ if (self.oacp > 25 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-DLYC'
+ if (self.oacp > 27 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-SCNFMT'
+
+ if (self.oacp > 8 and self.oaclen == 12):
+ self.cjtagstate = 'CJTAG-CP'
+ if (self.oacp > 32 and self.oaclen == 36):
+ self.cjtagstate = 'CJTAG-CP'
+
+ if (self.oacp > self.oaclen):
+ self.cjtagstate = 'OSCAN1'
+ self.oscan1cycle = 1
+ # Because Nuclei cJTAG device asserts a reset during cJTAG
+ # online activating.
+ self.state = 'TEST-LOGIC-RESET'
+ return
+
# Intro "tree"
if self.state == 'TEST-LOGIC-RESET':
self.state = 'TEST-LOGIC-RESET' if (tms) else 'RUN-TEST/IDLE'
@@ -162,8 +210,7 @@ class Decoder(srd.Decoder):
elif self.state == 'UPDATE-IR':
self.state = 'SELECT-DR-SCAN' if (tms) else 'RUN-TEST/IDLE'
- def handle_rising_tck_edge(self, pins):
- (tdi, tdo, tck, tms, trst, srst, rtck) = pins
+ def handle_rising_tck_edge(self, tdi, tdo, tck, tms, trst, srst, rtck):
# Rising TCK edges always advance the state machine.
self.advance_state_machine(tms)
@@ -179,6 +226,11 @@ class Decoder(srd.Decoder):
self.putx([jtag_states.index(self.oldstate), [self.oldstate]])
self.putp(['NEW STATE', self.state])
+ self.putx([21, [self.oldcjtagstate]])
+ if (self.oldcjtagstate.startswith('CJTAG-')):
+ self.putx([20, [str(self.oldtms)]])
+ self.oldtms = tms
+
# Upon SHIFT-*/EXIT1-* collect the current TDI/TDO values.
if self.oldstate.startswith('SHIFT-') or \
self.oldstate.startswith('EXIT1-'):
@@ -228,7 +280,50 @@ class Decoder(srd.Decoder):
self.ss_item = self.samplenum
+ def handle_tms_edge(self, tck, tms):
+ self.escape_edges = self.escape_edges + 1
+
+ def handle_tapc_state(self, tck, tms):
+ self.oldcjtagstate = self.cjtagstate
+
+ if self.escape_edges >= 8:
+ self.cjtagstate = '4-WIRE'
+ if self.escape_edges == 6:
+ self.cjtagstate = 'CJTAG-OAC'
+ self.oacp = 0
+ self.oaclen = 12
+
+ self.escape_edges = 0
+
def decode(self):
+ tdi_real = 0
+ tms_real = 0
+ tdo_real = 0
+
while True:
# Wait for a rising edge on TCK.
- self.handle_rising_tck_edge(self.wait({2: 'r'}))
+ (tdi, tdo, tck, tms, trst, srst, rtck) = self.wait({2: 'r'})
+ self.handle_tapc_state(tck, tms)
+
+ if (self.cjtagstate == 'OSCAN1'):
+ if (self.oscan1cycle == 0): # nTDI
+ if (tms == 0):
+ tdi_real = 1
+ else:
+ tdi_real = 0
+ self.oscan1cycle = 1
+ elif (self.oscan1cycle == 1): # TMS
+ tms_real = tms
+ self.oscan1cycle = 2
+ elif (self.oscan1cycle == 2): # TDO
+ tdo_real = tms
+ self.handle_rising_tck_edge(tdi_real, tdo_real, tck, tms_real, trst, srst, rtck)
+ self.oscan1cycle = 0
+ else:
+ self.handle_rising_tck_edge(tdi, tdo, tck, tms, trst, srst, rtck)
+
+ while (tck == 1):
+ (tdi, tdo, tck, tms_n, trst, srst, rtck) = self.wait([{2: 'f'}, {3: 'e'}])
+ if (tms_n != tms):
+ tms = tms_n
+ self.handle_tms_edge(tck, tms)