low level control of jtag protocol

hi all,

I’m trying to control jtag at a low level (every single bit of tms, tdi etc.).

I have OLIMEX ARM-USB-OCD and I’m using mpsse commands with ftdxx API.

I tried JTAG APIs but it seems inmpossible to have a low level control. I don’t understand whether my software is bugged or I can’t use the API. I’m trying to read idcode from a xilinx spartan 2. I looked into the bsdl file to know which is the instruction register length and the ‘IDCODE’ instruction code. The better I obtained, after an afternoon of hard work, is the idcode shifted sx by 1.

Anyway… now I’m trying the mpsse commands. I don’t understand many things but the big question is:

how shall I do to get idcode?

My idea is:

  1. go to reset state with the command ‘clock to tms’, shifting 5 1’s. And here I got the first doubt: it is possible to shift only 5 bits instead of 7? “Documentaion” says that the command shifts bit 6 downto 0 to TMS and bit 7 is held static to TDI. But the ‘length’ parameter… what does it mean? The docs says nothing about it in the ‘clock to tms’ command.

  2. go to shift-ir state with the command ‘clock to tms’ shifting 00110. Again, I wonder if it is possible to shift only 5 bits.

  3. shift in the idcode instruction code (for spartan 2 is 01001). I don’t know how to do this. If I use ‘clock data bits out’ command, who controls the tms value? If I use ‘clock to tms’ command, using the last bit of the “Byte1” to control tdi, who garanties I shift only one bit and not 7 (“6 downto 0 shifted to tms”)?

  4. etc… I’d be happy if I understood all the above stuff

My last question is:

is there some other documentation about this, if you can call documentation the pdf on the tfdi chip site. Is there anyone who has clear examples about using this commands and APIs (also JTAG APIs)?

Thanks in advance

NIK

hi again,

I nearly managed to read idcode on the digilent’s pegasus board but got some problem.

The jtag chain is composed by two devices. The first (nearest to tdi) is the spartan2 and the second is the xcf01s (flash memory).

Spartan2 has a 5 bit instruction register and idcode instruction is 01001.

xcf01s has an 8 bit instruction register and bypass instruction is 11111111.

I want to read spartan2’s idcode.

I loaded bypass into the xcf01s device and then loaded idcode intruction into the spartan2 with the following code:

//LAST IN THE CHAIN
//xcf01s	(8 bit instr.)
WriteInstrBuffer[0] = 0xff;
status = JTAG_Write(devHandle, 		//device handle
                               true, 		       //write to instruction register
                               8, 			//write 8 bits (instr. reg. length)
                               (WriteDataByteBuffer *)&WriteInstrBuffer, 
                               1, 			//bits to write contained in 1 byte
                               PAUSE_INSTRUCTION_REGISTER_STATE);

//FIRST IN THE CHAIN
//xc2s50	(5 bit instr.)
WriteInstrBuffer[0] = 0x09;
status = JTAG_Write(devHandle, 		 //device handle
                                true, 			//write to instruction register
                                5, 			//write 5 bits (instr. reg. length)
                                (WriteDataByteBuffer *)&WriteInstrBuffer,
                                1, 			//bits to write contained in 1 byte
                                RUN_TEST_IDLE_STATE);

Then i read out the idcode with the following code:

status = JTAG_Read(devHandle, 		//device handle
                               false,			//read from data (idcode)register
                               32+1,		      //read 32 bits (idcode) + 1 bypass
                               (ReadDataByteBuffer*)&ReadDataBuffer,
                               &bytesRead,	  //actual number of bytes read
                               RUN_TEST_IDLE_STATE);

At the end I shift right by 1 bit the result and should obtain the idcode of the spartan2.

I encountered the following odd thing:

If I load the instructions, as in the first piece of code, only once and then read the idcode, I got the xcf01s’ idcode.

If I load the instructions and then readback the idcode, but, this time, all in a loop, after the first time i read the right idcode (spartan’s).

If, instead, I load the instructions only once and then read the idcode in a loop, I got always the flash’s idcode!

Making some trials, it seems to me that the result depends on the last parameter of the write/read functions: the state which is left the tap controller in at the end of the routine. I tried more or less all the possibile combinations but I coudn’t get the expected result (read the right idcode at the first read operation, without looping or without reloading the instructions more than once).

Have you any advice?

Is this the right place to post this stuff? If not, can you tell me which is the right one?

Thank you.

I wonder if it might be possible to use the JTAG subsystem of OpenOCD. The advantage is that you use code that is quite well tested already and also that it supports a lot of different JTAG cables.

As far as I remember, with OpenOCD you build a queue of JTAG commands and then execute through on the JTAG cable driver.

I don’t know if the JTAG subsystem of OpenOCD supports multiple devices in a chain.

Hi,

I tried to take a look ino the jtag subsystem of oocd but it is quite impossible to integrate in my application because of the following reasons:

  1. I need a low level control of the jtag commands. I have to perform not only stndard operations. Indeed I’m trying to use FTC_JTAG API but ot would be better to use MPSSE commands. The problem is that the commands are incomprehensible. The documentation is insufficient.

  2. It is very complex and has not been built as an API. It is difficult to extract from the whole tool.

But, because the jtag subsystem has been built using the MPPSE commands, I would appreciate if someone, who has a little more knowledge about this subsystem, explained the use of these commands to me.

thanks

bye

I found the MPSSE commands to be very well documented. During JTAG operation, you either shift data to TDI or TMS. When doing a TDI scan, TMS is held low, during a TMS scan you specify the TDI value with the most-significant bit, to allow the last bit of a shift cycle to be scanned.

The OpenOCD’s JTAG layer is built as an API, which is documented at http://openocd.berlios.de/web/?page_id=4

The complexity of the OpenOCD’s JTAG layer is necessary to allow large command queues to be built in order to achieve the highest possible performance.

I have no idea what the JTAG_xxx commands you’re using (are they from FTDI’s JTAG API?) actually do, but you always have to keep the JTAG statemachine in mind, especially when working with multiple devices in the chain. The statemachine is operated for all your devices in parallel, but data is shifted through sequentially. What’s shifted out on the first device’s TDO is input on the second device’s TDI, so when doing an IR scan you’re actually seeing TDI->[5-bit spartan IR]->[8-bit flash IR]->TDO.

You can write the two instruction registers with two scan operations, but only if you’re not moving through Update-IR - it depends on the JTAG API what states are passed through when moving from Pause-IR to another Shift-IR cycle.

Regards,

Dominic

Thanks a lot, Dominic!

Your answer lightened me.

Just two more questions about mpsse:

  1. what does the parameter ‘length’ mean in the command “clock to tms”?

You will agree with me that is not documented. I think it means the number of bits shifted clocked to tms but I think it should be written in a documentation. Besides, doc says

This [command] will send data bits 6 down to 0 to the TMS/CS pin

. I think it is not very clear whether ‘length’ is what I mean or not.

  1. I don’t understand how I decide to use positive edge commands rather than negative edge ones. How do I set the clock? By default what should I use?

Thank you again for the help!

Bye

  1. You’re right, that’s missing from the documentation, but the “length” parameter has the same meaning as for the other commands, i.e. you specify the number of bits or bytes to be scanned. While this isn’t documented it is working fine here.

  2. The use of the clock edges is defined by the JTAG standard - the TDI pin is sampled on the rising edge of TCK, so you should change it on the falling edge.

TDO changes it’s state on the falling edge of TCK, so you should sample it on the rising edge:

clock out on -ve, clock in on +ve

Regards,

Dominic

thank you very much!

Bye