Raul Fajardo - 2012-02-09

Hello everyone,

I am maintainer of the MinSoC project which uses the Advanced Debug System both under OpenCores. The Advanced Debug System is used to debug the OpenRISC softcore and includes a bridge which communicates with the JTAG TAP through cables and implements the debug interface protocol on top of it.

For the DLC9 cable, it has been using the bitbang mode for a while which was terribly slow. I noticed that you guys had a driver for the cable yourselves.

Analyzing your cable driver and adaptating/testing it on the Advanced Debug System, I noticed two issues:
Issue 1) You use a conservative number for your CPLD buffer level. I noticed that xc3sprog uses a challenging one instead. I have tried to use difference buffer levels and found a good number.
Xc3sprog: #define XPC_A6_CHUNKSIZE (1<<13)
The usb_bulk_write(xpcu, 0x02, (char*)in, in_len, 1000) function of xpcu_shift() failed for more than 4096 bytes leaving the cable in an inconsistent state until power off.

Also, instead of defining the chunksize in number of 16 bit words, I am using a byte number:
* send max 4096 bytes to CPLD
* this is equal to 8192 TDI plus 8192 TDO bits
#define CPLD_MAX_BYTES (1<<12)

Therefore, I also adapted the comparisons of in_bits to XPC_A6_CHUNKSIZE from:
xts.in_bits == (4*XPC_A6_CHUNKSIZE - 1)
xts.in_bits == (2*CPLD_MAX_BYTES - 1)

Issue 2) For burst reads:
You align every incoming TDO data although only the last 32 bit ones are unaligned. Furthermore, I have noticed that the description of the internal CPLD <-> USB transfers does not quite fit. Therefore, I formulated it again like this:
*   TDO data is shifted in from MSB to LSB and transferred 32-bit little-endian.
*   In a "full" word with 32 TDO bits, the earliest one reached bit 0.
*   The earliest of 31 bits however would be bit 1. A 17 bit transfer has the LSB
*   as the MSB of uint16_t, other bits are in uint16_t.
*   However, if the last packet is smaller than 16, only 2 bytes are transferred.
*   If there's only one TDO bit, it arrives as the MSB of the 16-bit word, uint16_t.
*   uint16_t is then skipped.
*   For full 32 bits blocks, the data is aligned. The last non 32-bits block arrives
*   non-aligned and has to be re-aligned. Half-words (16-bits) transfers have to be
*   re-aligned too.

I adapted the code accordingly, also avoiding useless copies of the already aligned chunks. See xpcusb_do_ext_transfer() under

Information: Finally, I'd like to inform that I successfully tested switching between bit-bang and burst modes without issues.
* The dynamic switch between FX2 and CPLD modes works fine. If a switch is required, the functions:
*         static int cable_xpcusb_fx2_init();
*         static int cable_xpcusb_cpld_init();
* can be called. The variable cpld_ctrl can tell if the CPLD is active (1) or FX2 (0).

I hope that helps our open source drivers to get better.

Kind regards,
Raul Fajardo