Search code examples
armcortex-mftdijtag

Where can I find the device specific JTAG instructions for Cortex-M3?


I'm trying to communicate with a Cortex-M3 based microcontroller (LPC1769) through JTAG. I already have the hardware required, and have managed to get an example program to work, but to progress further, I need to know the device-specific JTAG instructions that are available in this case. I have read the corresponding section of the Cortex-M3 technical reference manual (link), and all that told me, was that the device uses a standard CoreSight debug port. In particular, I'd like to read the device ID with the IDCODE instruction. Some sites suggest, that the IDCODE might be b0001 or b1110 for this device, but neither of them seem to work. b0001 seems more likely to me, as that's the value I read from the IR after the TAP has been reset.

I also considered the possibility, that the instruction I'm using is correct, and I'm just not reading the device ID register properly. I'm using an FTDI cable with the FT232H chip, and the application I'm using is based on FTDI's AN129 example code (link), using MPSSE commands. I use the 0x2A command to clock data in from the TAP, the 0x1B command to clock data out to the TAP, and the 0x3B command to do both simultaneously. If anyone could provide some insight, as to what I'm doing wrong (or whether I'm using the right IDCODE instruction at all), that would be much appreciated.

*EDIT: I made some progress, but the IDCODE instruction still eludes me. I managed to read the Device ID after setting the TAP controller to Test-Logic-Reset state (which loads the IDCODE instruction in the IR). However, I tried all possible (16) instructions, and while some of them resulted in different reads from the DR, none loaded the Device ID register.

This is the function I use to insert the instruction, once the TAP controller is in Shift-IR state:

int clockOut(FT_HANDLE* ftHandle, BYTE data, BYTE length)
{
    FT_STATUS ftStatus = FT_OK;
    BYTE byOutputBuffer[1024];      // Buffer to hold MPSSE commands and data to be sent to the FT232H
    DWORD dwNumBytesToSend = 0;     // Index to the output buffer
    DWORD dwNumBytesSent = 0;       // Count of actual bytes sent - used with FT_Write

    byOutputBuffer[dwNumBytesToSend++] = 0x1B;
    // Clock data out through Shift-DR
    byOutputBuffer[dwNumBytesToSend++] = length - 1;
    // Number of clock pulses = (length - 1) + 1; This way, the length given as the parameter of the function is the actual number of clock pulses.
    byOutputBuffer[dwNumBytesToSend++] = data;
    // Shift out data
    ftStatus = FT_Write(*ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
    // Send off the TMS command
    return ftStatus;
}

The length parameter is set to 4, and the data parameter is set to 0x0X (where I tried all possible values for X, neither of which led to success)


Solution

  • I managed to get it to work. The problem was, that when I sent out 4 bits to the IR, it in fact received 5. After finishing the transmission, the next rising edge of TCK was supposed to change the state of the TAP controller, but as it was still in the Shift-IR state, it not only changed the state, but also sampled the TDI, and did another (fifth) shift. To countermand this, I only shifted the lower 3 bits of the instruction, and then used a 0x4B MPSSE command, to simultaneously clock out a TMS signal (to change the state), and send out the MSB of the command.