Esempio n. 1
0
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