Example #1
0
 def shift_register(self, out, use_last=False):
     """Shift a BitSequence into the current register and retrieve the
        register output"""
     if not isinstance(out, BitSequence):
         return JtagError('Expect a BitSequence')
     length = len(out)
     if use_last:
         (out, self._last) = (out[:-1], int(out[-1]))
     byte_count = len(out)//8
     pos = 8*byte_count
     bit_count = len(out)-pos
     if not byte_count and not bit_count:
         raise JtagError("Nothing to shift")
     if byte_count:
         blen = byte_count-1
         #print "RW OUT %s" % out[:pos]
         cmd = Array('B', [Ftdi.RW_BYTES_PVE_NVE_LSB, blen, (blen>>8)&0xff])
         cmd.extend(out[:pos].tobytes(msby=True))
         self._stack_cmd(cmd)
         #print "push %d bytes" % byte_count
     if bit_count:
         #print "RW OUT %s" % out[pos:]
         cmd = Array('B', [Ftdi.RW_BITS_PVE_NVE_LSB, bit_count-1])
         cmd.append(out[pos:].tobyte())
         self._stack_cmd(cmd)
         #print "push %d bits" % bit_count
     self.sync()
     bs = BitSequence()
     byte_count = length//8
     pos = 8*byte_count
     bit_count = length-pos
     if byte_count:
         data = self._ftdi.read_data_bytes(byte_count, 4)
         if not data:
             raise JtagError('Unable to read data from FTDI')
         byteseq = BitSequence(bytes_=data, length=8*byte_count)
         #print "RW IN %s" % byteseq
         bs.append(byteseq)
         #print "pop %d bytes" % byte_count
     if bit_count:
         data = self._ftdi.read_data_bytes(1, 4)
         if not data:
             raise JtagError('Unable to read data from FTDI')
         byte = data[0]
         # need to shift bits as they are shifted in from the MSB in FTDI
         byte >>= 8-bit_count
         bitseq = BitSequence(byte, length=bit_count)
         bs.append(bitseq)
         #print "pop %d bits" % bit_count
     if len(bs) != length:
         raise AssertionError("Internal error")
     #self._ftdi.validate_mpsse()
     return bs
Example #2
0
 def read(self, length):
     """Read out a sequence of bits from TDO"""
     byte_count = length//8
     bit_count = length-8*byte_count
     bs = BitSequence()
     if byte_count:
         bytes = self._read_bytes(byte_count)
         bs.append(bytes)
     if bit_count:
         bits = self._read_bits(bit_count)
         bs.append(bits)
     return bs
Example #3
0
 def write(self, out, use_last=True):
     """Write a sequence of bits to TDI"""
     if isinstance(out, str):
         out = BitSequence(bytes_=out)
     elif not isinstance(out, BitSequence):
         out = BitSequence(out)
     if use_last:
         (out, self._last) = (out[:-1], bool(out[-1]))
     byte_count = len(out) // 8
     pos = 8 * byte_count
     bit_count = len(out) - pos
     if byte_count:
         self._write_bytes(out[:pos])
     if bit_count:
         self._write_bits(out[pos:])
Example #4
0
 def write_tms(self, tms):
     """Change the TAP controller state"""
     if not isinstance(tms, BitSequence):
         raise JtagError('Expect a BitSequence')
     length = len(tms)
     if not (0 < length < 8):
         raise JtagError('Invalid TMS length')
     out = BitSequence(tms, length=8)
     # apply the last TDO bit
     if self._last is not None:
         out[7] = self._last
     # print "TMS", tms, (self._last is not None) and 'w/ Last' or ''
     # reset last bit
     self._last = None
     cmd = Array('B', [Ftdi.WRITE_BITS_TMS_NVE, length-1, out.tobyte()])
     self._stack_cmd(cmd)
     self.sync()
Example #5
0
 def shift_register(self, length):
     if not self._sm.state_of('shift'):
         raise JtagError("Invalid state: %s" % self._sm.state())
     if self._sm.state_of('capture'):
         bs = BitSequence(False)
         self._ctrl.write_tms(bs)
         self._sm.handle_events(bs)
     return self._ctrl.shift_register(length)
Example #6
0
 def write_tms(self, tms):
     """Change the TAP controller state"""
     if not isinstance(tms, BitSequence):
         raise JtagError('Expect a BitSequence')
     length = len(tms)
     if not (0 < length < 8):
         raise JtagError('Invalid TMS length')
     out = BitSequence(tms, length=8)
     # apply the last TDO bit
     if self._last is not None:
         out[7] = self._last
     # print "TMS", tms, (self._last is not None) and 'w/ Last' or ''
     # reset last bit
     self._last = None
     cmd = Array('B', [Ftdi.WRITE_BITS_TMS_NVE, length - 1, out.tobyte()])
     self._stack_cmd(cmd)
     self.sync()
Example #7
0
 def detect_register_size(self):
     # Freely inpired from UrJTAG
     # Need to contact authors, or to replace this code to comply with
     # the GPL license (GPL vs. LGPL with Python is a bit fuzzy for me)
     if not self._engine._sm.state_of('shift'):
         raise JtagError("Invalid state: %s" % self._engine._sm.state())
     if self._engine._sm.state_of('capture'):
         bs = BitSequence(False)
         self._engine._ctrl.write_tms(bs)
         self._engine._sm.handle_events(bs)
     MAX_REG_LEN = 1024
     PATTERN_LEN = 8
     stuck = None
     for length in range(1, MAX_REG_LEN):
         print "Testing for length %d" % length
         if length > 5:
             return
         zero = BitSequence(length=length)
         inj = BitSequence(length=length+PATTERN_LEN)
         inj.inc()
         for p in range(1, 1<<PATTERN_LEN):
             ok = False
             self._engine.write(zero, False)
             rcv = self._engine.shift_register(inj)
             try:
                 tdo = rcv.invariant()
             except ValueError:
                 tdo = None
             if stuck is None:
                 stuck = tdo
             if stuck != tdo:
                 stuck = None
             rcv >>= length
             if rcv == inj:
                 ok = True
             else:
                 break
             inj.inc()
         if ok:
             print "Register detected length: %d" % length
             return length
     if stuck is not None:
         raise JtagError('TDO seems to be stuck')
     raise JtagError('Unable to detect register length')
Example #8
0
 def shift_register(self, out, use_last=False):
     """Shift a BitSequence into the current register and retrieve the
        register output"""
     if not isinstance(out, BitSequence):
         return JtagError('Expect a BitSequence')
     length = len(out)
     if use_last:
         (out, self._last) = (out[:-1], int(out[-1]))
     byte_count = len(out) // 8
     pos = 8 * byte_count
     bit_count = len(out) - pos
     if not byte_count and not bit_count:
         raise JtagError("Nothing to shift")
     if byte_count:
         blen = byte_count - 1
         #print "RW OUT %s" % out[:pos]
         cmd = Array('B',
                     [Ftdi.RW_BYTES_PVE_NVE_LSB, blen, (blen >> 8) & 0xff])
         cmd.extend(out[:pos].tobytes(msby=True))
         self._stack_cmd(cmd)
         #print "push %d bytes" % byte_count
     if bit_count:
         #print "RW OUT %s" % out[pos:]
         cmd = Array('B', [Ftdi.RW_BITS_PVE_NVE_LSB, bit_count - 1])
         cmd.append(out[pos:].tobyte())
         self._stack_cmd(cmd)
         #print "push %d bits" % bit_count
     self.sync()
     bs = BitSequence()
     byte_count = length // 8
     pos = 8 * byte_count
     bit_count = length - pos
     if byte_count:
         data = self._ftdi.read_data_bytes(byte_count, 4)
         if not data:
             raise JtagError('Unable to read data from FTDI')
         byteseq = BitSequence(bytes_=data, length=8 * byte_count)
         #print "RW IN %s" % byteseq
         bs.append(byteseq)
         #print "pop %d bytes" % byte_count
     if bit_count:
         data = self._ftdi.read_data_bytes(1, 4)
         if not data:
             raise JtagError('Unable to read data from FTDI')
         byte = data[0]
         # need to shift bits as they are shifted in from the MSB in FTDI
         byte >>= 8 - bit_count
         bitseq = BitSequence(byte, length=bit_count)
         bs.append(bitseq)
         #print "pop %d bits" % bit_count
     if len(bs) != length:
         raise AssertionError("Internal error")
     #self._ftdi.validate_mpsse()
     return bs
Example #9
0
 def get_events(self, path):
     """Build up an event sequence from a state sequence, so that the
        resulting event sequence allows the JTAG state machine to advance
        from the first state to the last one of the input sequence"""
     events = []
     for s, d in zip(path[:-1], path[1:]):
         for e, x in enumerate(s.exits):
             if x == d:
                 events.append(e)
     if len(events) != len(path) - 1:
         raise JtagError("Invalid path")
     return BitSequence(events)
Example #10
0
 def _read_bytes(self, length):
     """Read out bytes from TDO"""
     data = ''
     if length > JtagController.FTDI_PIPE_LEN:
         raise JtagError("Cannot fit into FTDI fifo")
     alen = length - 1
     cmd = Array('B',
                 [Ftdi.READ_BYTES_NVE_LSB, alen & 0xff, (alen >> 8) & 0xff])
     self._stack_cmd(cmd)
     self.sync()
     data = self._ftdi.read_data_bytes(length, 4)
     bs = BitSequence(bytes_=data, length=8 * length)
     #print "READ BYTES %s" % bs
     return bs
Example #11
0
 def _read_bits(self, length):
     """Read out bits from TDO"""
     data = ''
     if length > 8:
         raise JtagError("Cannot fit into FTDI fifo")
     cmd = Array('B', [Ftdi.READ_BITS_NVE_LSB, length - 1])
     self._stack_cmd(cmd)
     self.sync()
     data = self._ftdi.read_data_bytes(1, 4)
     # need to shift bits as they are shifted in from the MSB in FTDI
     byte = ord(data) >> 8 - bit_count
     bs = BitSequence(byte, length=length)
     #print "READ BITS %s" % (bs)
     return bs
Example #12
0
 def detect_register_size(self):
     # Freely inpired from UrJTAG
     # Need to contact authors, or to replace this code to comply with
     # the GPL license (GPL vs. LGPL with Python is a bit fuzzy for me)
     if not self._engine._sm.state_of('shift'):
         raise JtagError("Invalid state: %s" % self._engine._sm.state())
     if self._engine._sm.state_of('capture'):
         bs = BitSequence(False)
         self._engine._ctrl.write_tms(bs)
         self._engine._sm.handle_events(bs)
     MAX_REG_LEN = 1024
     PATTERN_LEN = 8
     stuck = None
     for length in range(1, MAX_REG_LEN):
         print "Testing for length %d" % length
         if length > 5:
             return
         zero = BitSequence(length=length)
         inj = BitSequence(length=length + PATTERN_LEN)
         inj.inc()
         for p in range(1, 1 << PATTERN_LEN):
             ok = False
             self._engine.write(zero, False)
             rcv = self._engine.shift_register(inj)
             try:
                 tdo = rcv.invariant()
             except ValueError:
                 tdo = None
             if stuck is None:
                 stuck = tdo
             if stuck != tdo:
                 stuck = None
             rcv >>= length
             if rcv == inj:
                 ok = True
             else:
                 break
             inj.inc()
         if ok:
             print "Register detected length: %d" % length
             return length
     if stuck is not None:
         raise JtagError('TDO seems to be stuck')
     raise JtagError('Unable to detect register length')
Example #13
0
 def read(self, length):
     """Read out a sequence of bits from TDO"""
     byte_count = length // 8
     bit_count = length - 8 * byte_count
     bs = BitSequence()
     if byte_count:
         bytes = self._read_bytes(byte_count)
         bs.append(bytes)
     if bit_count:
         bits = self._read_bits(bit_count)
         bs.append(bits)
     return bs
Example #14
0
 def reset(self, sync=False):
     """Reset the attached TAP controller.
        sync sends the command immediately (no caching)
     """
     # we can either send a TRST HW signal or perform 5 cycles with TMS=1
     # to move the remote TAP controller back to 'test_logic_reset' state
     # do both for now
     if not self._ftdi:
         raise JtagError("FTDI controller terminated")
     if self._trst:
         # nTRST
         value = 0
         cmd = Array('B', [Ftdi.SET_BITS_LOW, value, self.direction])
         self._ftdi.write_data(cmd)
         time.sleep(0.1)
         # nTRST should be left to the high state
         value = JtagController.TRST_BIT
         cmd = Array('B', [Ftdi.SET_BITS_LOW, value, self.direction])
         self._ftdi.write_data(cmd)
         time.sleep(0.1)
     # TAP reset (even with HW reset, could be removed though)
     self.write_tms(BitSequence('11111'))
     if sync:
         self.sync()
Example #15
0
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys
import time
import unittest
from pyftdi.pyftdi.jtag import JtagEngine, JtagTool
from pyftdi.pyftdi.bits import BitSequence

# Should match the tested device
JTAG_INSTR = {
    'SAMPLE': BitSequence('0001', msb=True, length=4),
    'PRELOAD': BitSequence('0001', msb=True, length=4),
    'IDCODE': BitSequence('0100', msb=True, length=4),
    'BYPASS': BitSequence('1111', msb=True, length=4)
}


class JtagTestCase(unittest.TestCase):
    def setUp(self):
        self.jtag = JtagEngine(trst=True, frequency=3E6)
        self.jtag.configure(vendor=0x403, product=0x6011, interface=1)
        self.jtag.reset()
        self.tool = JtagTool(self.jtag)

    def tearDown(self):
        del self.jtag
Example #16
0
# ARE DISCLAIMED. IN NO EVENT SHALL NEOTION BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys
import time
from pyftdi.pyftdi.jtag import JtagEngine
from pyftdi.pyftdi.bits import BitSequence

# ARM 926
JTAG_INSTR = {
    'EXTEST': BitSequence('0000', msb=True, length=4),
    'SAMPLE': BitSequence('0011', msb=True, length=4),
    'PRELOAD': BitSequence('0011', msb=True, length=4),
    'SCAN_N': BitSequence('0010', msb=True, length=4),
    'INTEST': BitSequence('1100', msb=True, length=4),
    'IDCODE': BitSequence('1110', msb=True, length=4),
    'BYPASS': BitSequence('1111', msb=True, length=4),
    'RESTART': BitSequence('0100', msb=True, length=4)
}


class ArmJtag(object):
    """JTAG helper for ARM core"""
    def __init__(self, vendor, product, interface):
        self.jtag = JtagEngine()
        self.jtag.configure(vendor, product, interface)