URL
https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk
Subversion Repositories openrisc_2011-10-31
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 46 to Rev 47
- ↔ Reverse comparison
Rev 46 → Rev 47
/openrisc/trunk/or_debug_proxy/includes/usb_functions.h
77,7 → 77,7
int usb_dbg_wb_write8(uint32_t adr, uint8_t data); |
int usb_dbg_wb_write32(uint32_t adr, uint32_t data); |
int usb_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len); |
int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data); |
int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data, uint32_t length); |
int usb_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data); |
int usb_dbg_cpu0_write(uint32_t adr, uint32_t data); |
int usb_dbg_cpu0_write(uint32_t adr, uint32_t *data, uint32_t length); |
int usb_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data); |
/openrisc/trunk/or_debug_proxy/includes/usb_driver_calls.h
86,5 → 86,4
FT2232_USB_JTAG_CloseDevice(); |
|
int init_usb_jtag(); |
|
|
void reinit_usb_jtag(void); |
/openrisc/trunk/or_debug_proxy/includes/or_debug_proxy.h
141,11 → 141,11
/* write a block to wishbone */ |
int dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len); |
/* read a register from cpu */ |
int dbg_cpu0_read(uint32_t adr, uint32_t *data); |
int dbg_cpu0_read(uint32_t adr, uint32_t *data, uint32_t length); |
/* read a register from cpu module */ |
int dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data); |
/* write a cpu register */ |
int dbg_cpu0_write(uint32_t adr, uint32_t data); |
int dbg_cpu0_write(uint32_t adr, uint32_t *data, uint32_t length); |
/* write a cpu module register */ |
int dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data); |
|
/openrisc/trunk/or_debug_proxy/src/win_usb_driver_calls.c
328,9 → 328,15
return (jtagClose)(ftHandle); |
} |
|
void |
reinit_usb_jtag(void) |
{ |
FTC_STATUS Status = FTC_SUCCESS; |
if (DEBUG_USB_DRVR_FUNCS) printf("win_usb_driver_calls: reset_usb_jtag() - "); |
Status = (jtagInitDevice)(ftHandle, 0); |
if (DEBUG_USB_DRVR_FUNCS) printf("return Status: %d\n", (int) Status); |
} |
|
|
|
// Set clock frequency |
// Frequency = 12Mhz/((1+divisor)*2), |
// divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz |
/openrisc/trunk/or_debug_proxy/src/linux_usb_driver_calls.c
70,6 → 70,7
|
#include "FT2232cMpsseJtag.h" |
|
|
static FT2232cMpsseJtag *pFT2232cMpsseJtag = NULL; |
|
// Global USB JTAG device handle |
159,6 → 160,13
} |
|
|
void reinit_usb_jtag(void) |
{ |
FTC_STATUS Status = FTC_SUCCESS; |
if (DEBUG_USB_DRVR_FUNCS) printf("linux_usb_driver_calls: reset_usb_jtag() - "); |
Status = pFT2232cMpsseJtag->JTAG_InitDevice(ftHandle, 0); |
if (DEBUG_USB_DRVR_FUNCS) printf("return Status: %d\n", (int) Status); |
} |
|
// Set clock frequency |
// Frequency = 12Mhz/((1+divisor)*2), |
/openrisc/trunk/or_debug_proxy/src/usb_functions.c
146,7 → 146,8
for (i=0;i<length;i++) reverse |= (((data>>i)&1)<<(length-1-i)); |
return reverse; |
} |
// Constants that are used a lot, and were 5 bits, so might as well precalculate them |
// Constants that are used a lot, and were 5 bits, so might as well |
// precalculate them to save reversing them each time. |
// These are from or_debug_proxy.h, so if the original values change these |
// should be recalculated!! |
const uint8_t DI_GO_5BITREVERSED = 0x00; |
160,9 → 161,7
|
uint32_t npc, ppc, r1; |
unsigned char stalled; |
|
|
|
printf("Stalling or1k\n"); |
err = dbg_cpu0_write_ctrl(0, 0x01); // stall or1k |
|
171,12 → 170,12
printf("or1k should be stalled\n"); // check stall or1k |
exit(1); |
} |
|
uint32_t zero = 0; |
/* Clear Debug Reason Register (DRR) 0x3015 */ |
err = dbg_cpu0_write((6 << 11) + 21, 0); |
err = dbg_cpu0_read((0 << 11) + 16, &npc); /* Read NPC */ |
err = dbg_cpu0_read((0 << 11) + 18, &ppc); /* Read PPC */ |
err = dbg_cpu0_read(0x401, &r1); /* Read R1 */ |
err = dbg_cpu0_write((6 << 11) + 21, &zero, 4); |
err = dbg_cpu0_read((0 << 11) + 16, &npc, 4); /* Read NPC */ |
err = dbg_cpu0_read((0 << 11) + 18, &ppc, 4); /* Read PPC */ |
err = dbg_cpu0_read(0x401, &r1, 4); /* Read R1 */ |
|
if (err) |
{ |
185,36 → 184,23
exit(1); |
} |
printf("Read npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1); |
|
|
/* |
// Memory test - attempt to read and write massive arrays |
char biggest_array[65000]; |
int i; |
printf("Testing 65000 byte array write\n"); |
printf("Filling array...\n"); |
for(i=0;i<65000;i++) biggest_array[i] = i; |
printf("Writing array\n"); |
err = usb_dbg_wb_write_block32(0, (uint32_t *)biggest_array, 65000); |
printf("err = %d\n",err); |
*/ |
return; |
} |
|
/* |
void ensure_or1k_stalled(); |
|
// Function to check if the processor is stalled, if not, stall it. |
// this is useful in the event that GDB thinks the processor is stalled, but has, in fact |
// been hard reset on the board and is running. |
void ensure_or1k_stalled() |
{ |
unsigned char stalled; |
dbg_cpu0_read_ctrl(0, &stalled); |
if ((stalled & 0x1) != 0x1) |
{ |
if (DEBUG_CMDS) |
printf("Processor not stalled, like we thought\n"); |
|
// Set the TAP controller to its OR1k chain |
usb_set_tap_ir(JI_DEBUG); |
current_chain = -1; |
|
// Processor isn't stalled, contrary to what we though, so stall it |
printf("Stalling or1k\n"); |
dbg_cpu0_write_ctrl(0, 0x01); // stall or1k |
|
} |
} |
*/ |
/*---------------------------------------------------------------------------*/ |
/*!Write up to 32-bits to the JTAG bus via the USB device |
|
343,7 → 329,6
|
// if read ID was rubbish retry init - this is probably NOT the best way to do this... |
if ((id == 0xffffffff) | (id == 0x00000002) | (id == 0x00000000)) { |
//pFT2232cMpsseJtag->JTAG_CloseDevice(gFtHandle); |
// Platform independant driver call |
FT2232_USB_JTAG_CloseDevice(); |
if (reinit_count++ > 4){ |
364,6 → 349,24
return DBG_ERR_OK; |
} |
|
static void reset_tap(void) |
{ |
uint32_t id = 0; |
reinit_usb_jtag(); |
|
|
while (id != id_read_at_reset) |
{ |
usb_set_tap_ir(JI_IDCODE); |
id = usb_read_stream(32, RUN_TEST_IDLE_STATE); |
//printf("reset_tap: read ID %.8x\n",id); |
} |
//Return the chain to DEBUG mode |
usb_set_tap_ir(JI_DEBUG); |
|
} |
|
|
/* counts retries and returns zero if we should abort */ |
static int retry_no = 0; |
int retry_do() { |
609,16 → 612,38
|
//printf("%x %x %x\n", status, crc_read, crc_generated); |
/* CRCs must match, otherwise retry */ |
uint32_t tries = 0; |
if (crc_read != crc_generated) { |
//exit(1);//remove later |
if (!retry_do()) goto try_again; |
tries++; |
if (tries < 2) |
{ |
if (DEBUG_USB_DRVR_FUNCS) |
printf("usb_functions - usb_dbg_command - CRC fail. Going again\n"); |
goto try_again; |
} |
else if (tries < 8) |
{ |
reset_tap(); |
goto try_again; |
} |
else return DBG_ERR_CRC; |
} |
/* we should read expected status value, otherwise retry */ |
tries = 0; |
if (status != 0) { |
//exit(1);//remove later |
if (!retry_do()) goto try_again; |
if (tries < 2) |
{ |
if (DEBUG_USB_DRVR_FUNCS) |
printf("usb_functions - usb_dbg_command - bad status (%d). Going again\n",status); |
goto try_again; |
} |
else if (tries < 8) |
{ |
reset_tap(); |
goto try_again; |
} |
else return status; |
|
} |
/* reset retry counter */ |
retry_ok(); |
630,7 → 655,6
/* writes a ctrl reg */ |
int usb_dbg_ctrl(uint32_t reset, uint32_t stall) { |
uint32_t i,status, crc_generated, crc_read; |
|
// JTAG driver things |
FTC_STATUS Status = FTC_SUCCESS; |
WriteDataByteBuffer WriteDataBuffer; |
679,7 → 703,6
WriteDataBuffer[11]=0|((crc_w>>31)&1); |
|
|
//Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); |
// Platform independant driver call |
Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); |
|
716,16 → 739,38
|
/* CRCs must match, otherwise retry */ |
//printf("%x %x %x\n", status, crc_read, crc_generated); |
if (crc_read != crc_generated) { |
//exit(1);//Remove later!! |
if (!retry_do()) goto try_again; |
uint32_t tries = 0; |
if (crc_read != crc_generated) { |
tries++; |
if (tries < 2) |
{ |
if (DEBUG_USB_DRVR_FUNCS) |
printf("usb_functions - usb_dbg_ctrl - CRC fail. Going again\n"); |
goto try_again; |
} |
else if (tries < 8) |
{ |
reset_tap(); |
goto try_again; |
} |
else return DBG_ERR_CRC; |
} |
/* we should read expected status value, otherwise retry */ |
tries = 0; |
if (status != 0) { |
//exit(1);//Remove later!! |
if (!retry_do()) goto try_again; |
if (tries < 2) |
{ |
if (DEBUG_USB_DRVR_FUNCS) |
printf("usb_functions - usb_dbg_ctrl - bad status (%d). Going again\n",status); |
goto try_again; |
} |
else if (tries < 8) |
{ |
reset_tap(); |
goto try_again; |
} |
else return status; |
|
} |
|
/* reset retry counter */ |
828,18 → 873,44
// with the MSb going to the LSb |
status = bit_reverse_data(status, DC_STATUS_SIZE); |
crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE); |
|
|
/* CRCs must match, otherwise retry */ |
//printf("%x %x %x\n", status, crc_generated, crc_read); |
uint32_t tries = 0; |
if (crc_read != crc_generated) { |
if (!retry_do()) goto try_again; |
tries++; |
if (tries < 2) |
{ |
if (DEBUG_USB_DRVR_FUNCS) |
printf("usb_functions - usb_dbg_ctrl_read - CRC fail. Going again\n"); |
goto try_again; |
} |
else if (tries < 8) |
{ |
reset_tap(); |
goto try_again; |
} |
else return DBG_ERR_CRC; |
} |
} |
/* we should read expected status value, otherwise retry */ |
tries = 0; |
if (status != 0) { |
if (!retry_do()) goto try_again; |
if (tries < 2) |
{ |
if (DEBUG_USB_DRVR_FUNCS) |
printf("usb_functions - usb_dbg_ctrl_read - bad status (%d). Going again\n",status); |
goto try_again; |
} |
else if (tries < 8) |
{ |
reset_tap(); |
goto try_again; |
} |
else return status; |
|
} |
|
/* reset retry counter */ |
retry_ok(); |
return DBG_ERR_OK; |
850,6 → 921,7
int usb_dbg_go(unsigned char *data, uint16_t len, uint32_t read) { |
uint32_t status, crc_generated, crc_read; |
int i,j; |
int tries = 0; |
uint8_t data_byte; |
|
// JTAG driver things |
860,7 → 932,7
try_again: |
usb_dbg_set_chain(dbg_chain); |
if (DEBUG_CMDS) printf("\n"); |
if (DEBUG_CMDS) printf("go len is %d, read is %d\n", len, read); |
if (DEBUG_CMDS) printf("go len is %dbytes, read=%d (if 0, writing)\n", len, read); |
|
crc_w = 0xffffffff; |
// Try packing everyhing we want to send into one write buffer |
959,7 → 1031,7
// written to LSb first |
data[i] = bit_reverse_data(data[i],8); |
|
if (DEBUG_USB_DRVR_FUNCS) printf("%2x",data[i]); |
if (DEBUG_USB_DRVR_FUNCS) printf("%.2x",data[i]); |
} |
if (DEBUG_USB_DRVR_FUNCS) printf("\n"); |
|
994,22 → 1066,40
} |
|
crc_generated = crc_r; |
|
// Now bit reverse status and crc_read as we unpacked them |
// with the MSb going to the LSb |
status = bit_reverse_data(status, DC_STATUS_SIZE); |
crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE); |
|
|
/* CRCs must match, otherwise retry */ |
|
//printf("%x %x %x\n", status, crc_read, crc_generated); |
|
if (crc_read != crc_generated) { |
if (DEBUG_CMDS || DEBUG_USB_DRVR_FUNCS)printf("CRC mismatch: %x %x %x\n", status, crc_read, crc_generated); |
if (!retry_do()) goto try_again; |
tries++; |
if (tries < 8) |
{ |
if (DEBUG_USB_DRVR_FUNCS) printf("usb_functions - usb_dbg_go - CRC fail (%d) try %d. Going again\n",status, tries); |
reset_tap() ; |
goto try_again; |
} |
else return DBG_ERR_CRC; |
} |
//if (crc_read == crc_generated) |
//tries = 0; |
/* we should read expected status value, otherwise retry */ |
if (status != 0) { |
if (!retry_do()) goto try_again; |
tries++; |
if (tries < 8) |
{ |
if (DEBUG_USB_DRVR_FUNCS) printf("usb_functions - usb_dbg_go - bad status (%d) try %d. Going again\n",status, tries); |
reset_tap(); |
goto try_again; |
|
} |
else return status; |
|
} |
|
retry_ok(); |
1054,6 → 1144,7
|
/* write a block to wishbone */ |
int usb_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len) { |
if (DEBUG_CMDS) printf("usb_functions: wb_write_block %.8x %d bytes\n",adr, len); |
if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err; |
if ((err = usb_dbg_command(DBG_WB_WRITE32, adr, len))) return err; |
if ((err = usb_dbg_go((unsigned char*)data, len, 0))) return err; |
1062,22 → 1153,20
|
|
/* read a register from cpu */ |
int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data) { |
// uint32_t err; |
int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data, uint32_t length) { |
if ((err = usb_dbg_set_chain(DC_CPU0))) return err; |
if ((err = usb_dbg_command(DBG_CPU_READ, adr, 4))) return err; |
if ((err = usb_dbg_go((unsigned char*)data, 4, 1))) return err; |
*data = ntohl(*data); |
if ((err = usb_dbg_command(DBG_CPU_READ, adr, length))) return err; |
if ((err = usb_dbg_go((unsigned char*)data, length, 1))) return err; |
int i;for(i=0;i<(length/4);i++)data[i]=ntohl(data[i]); |
return DBG_ERR_OK; |
} |
|
/* write a cpu register */ |
int usb_dbg_cpu0_write(uint32_t adr, uint32_t data) { |
// uint32_t err; |
data = ntohl(data); |
int usb_dbg_cpu0_write(uint32_t adr, uint32_t *data, uint32_t length) { |
int i;for(i=0;i<(length/4);i++){data[i]=ntohl(data[i]);} |
if ((err = usb_dbg_set_chain(DC_CPU0))) return err; |
if ((err = usb_dbg_command(DBG_CPU_WRITE, adr, 4))) return err; |
if ((err = usb_dbg_go((unsigned char*)&data, 4, 0))) return err; |
if ((err = usb_dbg_command(DBG_CPU_WRITE, adr, length))) return err; |
if ((err = usb_dbg_go((unsigned char*)data, length, 0))) return err; |
return DBG_ERR_OK; |
} |
|
/openrisc/trunk/or_debug_proxy/src/or_debug_proxy.c
207,7 → 207,6
} |
|
|
|
int dbg_reset() |
{ |
#ifdef USB_ENDPOINT_ENABLED |
328,7 → 327,6
return DBG_ERR_INVALID_ENDPOINT; |
} |
|
|
/* write a block to wishbone */ |
int dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len) { |
#ifdef USB_ENDPOINT_ENABLED |
341,9 → 339,9
} |
|
/* read a register from cpu */ |
int dbg_cpu0_read(uint32_t adr, uint32_t *data) { |
int dbg_cpu0_read(uint32_t adr, uint32_t *data, uint32_t length) { |
#ifdef USB_ENDPOINT_ENABLED |
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read( adr, data); |
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read( adr, data, length); |
#endif |
#ifdef VPI_ENDPOINT_ENABLED |
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_read( adr, data); |
352,9 → 350,9
} |
|
/* write a cpu register */ |
int dbg_cpu0_write(uint32_t adr, uint32_t data) { |
int dbg_cpu0_write(uint32_t adr, uint32_t *data, uint32_t length) { |
#ifdef USB_ENDPOINT_ENABLED |
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write( adr, data); |
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write( adr, data, length); |
#endif |
#ifdef VPI_ENDPOINT_ENABLED |
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_write( adr, data); |
/openrisc/trunk/or_debug_proxy/src/gdb.c
128,7 → 128,9
character. Adding the EOS allows us to print out the packet as a |
string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed |
for register packets */ |
#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1) |
//#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1) |
#define GDB_BUF_MAX 4096 |
#define GDB_BUF_MAX_TIMES_TWO (GDB_BUF_MAX*2) |
|
/*! Size of the matchpoint hash table. Largest prime < 2^10 */ |
#define MP_HASH_SIZE 1021 |
251,7 → 253,7
include zero bytes */ |
struct rsp_buf |
{ |
char data[GDB_BUF_MAX]; |
char data[GDB_BUF_MAX_TIMES_TWO]; |
int len; |
}; |
|
2195,7 → 2197,7
} |
|
/* Make sure we won't overflow the buffer (2 chars per byte) */ |
if ((len * 2) >= GDB_BUF_MAX) |
if ((len * 2) >= GDB_BUF_MAX_TIMES_TWO) |
{ |
fprintf (stderr, "Warning: Memory read %s too large for RSP packet: " |
"truncated\n", p_buf->data); |
3524,10 → 3526,8
adr = adr & ~OR32_LINUX_VM_MASK; |
#endif |
|
|
switch (gdb_chain) { /* remap registers, to be compatible with jp1 */ |
case SC_RISC_DEBUG: if (adr == JTAG_RISCOP) adr = 0x00; |
return dbg_cpu0_write(adr, data) ? ERR_CRC : ERR_NONE; |
case SC_RISC_DEBUG: return dbg_cpu0_write(adr, &data, 4) ? ERR_CRC : ERR_NONE; |
case SC_REGISTER: return dbg_cpu0_write_ctrl(adr, data) ? ERR_CRC : ERR_NONE; |
case SC_WISHBONE: return dbg_wb_write32(adr, data) ? ERR_CRC : ERR_NONE; |
case SC_TRACE: return 0; |
3542,7 → 3542,7
#endif |
|
switch (gdb_chain) { |
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data) ? ERR_CRC : ERR_NONE; |
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data, 4) ? ERR_CRC : ERR_NONE; |
case SC_REGISTER: return dbg_cpu0_read_ctrl(adr, (unsigned char*)data) ? |
ERR_CRC : ERR_NONE; |
case SC_WISHBONE: return dbg_wb_read32(adr, data) ? ERR_CRC : ERR_NONE; |
3562,10 → 3562,9
if (DEBUG_CMDS) printf("rb %d\n", gdb_chain); |
|
switch (gdb_chain) { |
case SC_WISHBONE: |
{ |
return dbg_wb_read_block32(adr, data, len) ? ERR_CRC : ERR_NONE; |
} |
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data, len) ? ERR_CRC : ERR_NONE; |
case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ? ERR_CRC : ERR_NONE; |
|
default: return JTAG_PROXY_INVALID_CHAIN; |
} |
} |
3579,8 → 3578,8
|
if (DEBUG_CMDS) printf("wb %d\n", gdb_chain); |
switch (gdb_chain) { |
case SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ? |
ERR_CRC : ERR_NONE; |
case SC_RISC_DEBUG: return dbg_cpu0_write(adr, data, (uint32_t) len) ? ERR_CRC : ERR_NONE; |
case SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ? ERR_CRC : ERR_NONE; |
default: return JTAG_PROXY_INVALID_CHAIN; |
} |
} |
/openrisc/trunk/or_debug_proxy/Makefile
54,7 → 54,7
|
# Common Flags |
COMMON_CPPFLAGS = -I./includes |
COMMON_CXXFLAGS = -O2 -g |
COMMON_CXXFLAGS = -O2 |
COMMON_LDFLAGS = |
|
# Flags for static library |
/openrisc/trunk/or_debug_proxy/README
15,6 → 15,7
0.1.2 090511 jb@orsoc.se |
0.1.3 090604 jb@orsoc.se |
0.1.4 090828 jb@orsoc.se |
0.1.5 090903 jb@orsoc.se |
=============================================================================== |
-- Installation -- |
=============================================================================== |
325,6 → 326,18
used functions, accounting for 50% of execution were functions in the |
driver. This indicates that either better use of, or better |
implementation of, the driver could dramatically increase speed. |
SOLVED: It appears increasing the packet size of the GDB transfers can |
achieve a significant increase in speed. GDB queries the proxy at when |
it connects about its maximum packet size. It was previously 255 bytes |
and this meant larger downloads were "slow". Raising this transfer size |
to around 4kB (4096 bytes) resulted in a throughput increase of almost |
10-times. This is due to the fact that most of the transfer time is |
spent on waiting for the driver - the overhead per call is significant |
if only transferring 255 bytes, so increasing the amount per transfer |
reduces the amount of time waiting for the driver to perform the trans- |
action. Sizes greater than 4kB, for some reason, cause the driver to |
have issues - resulting in incorrect CRC reading and bad Status returns |
from the driver functions. Why this is so should be investigated. |
* USB<->JTAG Driver TODO: |
Get the latest version of the MPSSE function code (from |
http://ftdichip.com/Projects/MPSSE/FTCJTAG/FTCJTAG_Source.zip at last |