# Initialize jtag = JtagEngine(frequency=TCK_FREQ) jtag.configure(FTDI_BOARD) jtag.reset() # Test Logic Reset (5 times of TMS=1) # To Shift-IR, Exit1-IR and finally move to UpdateIR jtag.write_ir(IDCODE) # Move to Shift-DR, repeat Shift-DR, wait 15ms, and move to Test-Logic Reset idcode = jtag.read_dr(32) print("IDCODE (reset): 0x%x" % int(idcode)) width = 0 dir = 1 while True: jtag.write_ir(WR_WIDTH) jtag.write_dr(BitSequence(width, msb=False, length=8)) width += dir * SPEED if width >= MAX_WIDTH: read_pwm() dir = -1 width = MAX_WIDTH elif width <= 0: read_pwm() dir = 1 width = 0 time.sleep(0.001)
class JtagUpload(object): def setUp(self): self.jtag = JtagEngine(trst=True, frequency=3E6) # New API - example is not compatible with lastest version self.jtag.configure("ftdi://ftdi:232h/1") self.jtag.reset() self.tool = JtagTool(self.jtag) def test_idcode_reset(self): """Read the IDCODE right after a JTAG reset""" self.jtag.reset() idcode = self.jtag.read_dr(32) self.jtag.go_idle() print("IDCODE (reset): 0x%x" % int(idcode)) def get_idcode(self): self.jtag.write_ir(JTAG_INSTR['IDCODE']) idcode = self.jtag.read_dr(32) self.jtag.go_idle() return idcode def use_debug_inst(self): # Use debug instruction self.jtag.write_ir(JTAG_INSTR['DEBUG']) # Writing to the Module Select Register # The top-level module is the simplest of the modules. It does not have a bus # interface, and has only a single register. This register is called the “module select # register”, and is used to select the active sub-module. The top module does not use # command opcodes the way the sub-modules do. Instead, a single bit in the input shift # register (the MSB) indicates whether the command is a write to the select register, or a # command to a sub-module (in which case the command is ignored by the top-level). The # value in the select register cannot be read back. # The top-level module provides enable signals to all sub-modules, based on the # value in the module select register. The value of the input shift register is also provided # to all modules. Finally, the serial TDO output of the ADI is selected from the sub- # module TDO outputs, based on the module select register. A block diagram of the top- # level module is shown in Figure 3. def select_debug_module(self, module): print("-D- Selecting module {}".format(module)) module = (module & 0x3) | 0x04 # Set MSB (bit 2) to 1 bs = BitSequence(module, msb=True, length=3) self.jtag.write_dr(bs) self.jtag.go_idle() # | Bit# | Access | Description | # | 52 | W | Top-Level Select - Set to '0' for all sub-module commands | # | 51:48 | W | Operation code | # | 47:16 | W | Address The first WishBone address which will be read from or written to | # | 15:0 | W | Count Total number of words to be transferred. Must be greater than 0. - | def read_access(self, address): error = False bs = BitSequence(1, msb=False, length=16) # Bits 15:0 -> Count=1 bs.append(BitSequence(address, msb=False, length=32)) # bits 47:16 -> 32-bit Address bs.append( BitSequence(ADV_DBG_IF_WB_CMD_BURST_READ_32, msb=False, length=4)) # Command bs.append(BitSequence(0, msb=True, length=1)) # Bit 52 self.jtag.write_dr(bs) # Now shift outputs self.jtag.change_state('shift_dr') # Read status bit seq = self.jtag.read(2) status = 0 while status == 0: status = self.jtag.read(1)[0] data = int(self.jtag.read(32)) crc = int(self.jtag.read(32)) # first word of a burst : crc_in = 0xFFFFFFFF expected_crc = self.compute_crc(data_in=data, length_bits=32, crc_in=0xFFFFFFFF) if crc != expected_crc: print( "-E- CRC error detected Data : {0:#010x}, CRC : {1:#010x} Computed CRC : {2:#010x}" .format(data, crc, expected_crc)) error = True self.jtag.go_idle() return data, error def write_access(self, address, data): bs = BitSequence(1, msb=False, length=16) # Bits 15:0 -> Count=1 bs.append(BitSequence(address, msb=False, length=32)) # bits 47:16 -> 32-bit Address bs.append( BitSequence(ADV_DBG_IF_WB_CMD_BURST_WRITE_32, msb=False, length=4)) # Command bs.append(BitSequence(0, msb=True, length=1)) # Bit 52 self.jtag.write_dr(bs) # High-speed mode - no status bit # Start bit bs = BitSequence(1, msb=False, length=1) bs.append(BitSequence(data, msb=False, length=32)) # Data # first word of a burst : crc_in = 0xFFFFFFFF crc = self.compute_crc(data_in=data, crc_in=0xFFFFFFFF, length_bits=32) bs.append(BitSequence(crc, msb=False, length=32)) # CRC self.jtag.change_state('shift_dr') self.jtag.write(bs) match = self.jtag.read(1) self.jtag.go_idle() return int(match) == 1 def _do_crc(self, data_in=0, length=0x20): crc_init = 0xFFFFFFFF crc_out = 0x0 crc_poly = 0xedb88320 crc_out = crc_init for i in range(0, length): if (data_in & (1 << i)) != 0: d = 0xFFFFFFFF else: d = 0x0 if (crc_out & 0x01) != 0: c = 0xFFFFFFFF else: c = 0x0 crc_out = crc_out >> 1 crc_out = crc_out ^ ((d ^ c) & crc_poly) #print(" crc_out:", hex(crc_out)) return crc_out def _set_cpuctrl_reg(self, val): self.write_access(NRV32_CPUCTRL_BASE, val) def reset_cpu(self): self._set_cpuctrl_reg(0x1) def release_cpu(self): self._set_cpuctrl_reg(0x0) #define CRC_POLY 0xEDB88320 #uint32_t compute_crc(uint32_t crc_in, uint32_t data_in,int length_bits) { # uint32_t crc_out, c, d; # int i; # crc_out = crc_in; # for(i = 0; i < length_bits; i++) { # d = ((data_in >> i) & 0x1) ? 0xffffffff : 0x0; # c = (crc_out & 0x1) ? 0xffffffff : 0x0; # crc_out = crc_out >> 1; # crc_out = crc_out ^ ((d ^ c) & CRC_POLY); # } # return crc_out #} def compute_crc(self, data_in, length_bits, crc_in): crc_poly = 0xEDB88320 crc_out = crc_in for i in range(0, length_bits): if ((data_in >> i) & 0x1): d = 0xFFFFFFFF else: d = 0 if (crc_out & 0x1): c = 0xFFFFFFFF else: c = 0 crc_out = crc_out >> 1 crc_out = crc_out ^ ((d ^ c) & crc_poly) return crc_out