Minor fixes and cosmetics in XPCU driver

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1108 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Kolja Waschk 17 years ago
parent e0b7eebb9b
commit 571f7261ae

@ -38,6 +38,16 @@
#include <errno.h>
#include <string.h>
// #define VERBOSE 1
#undef VERBOSE
typedef struct
{
int last_tdo;
}
xpc_cable_params_t;
static int last_tdo;
/* Connectivity on Spartan-3E starter kit:
*
* = FX2 Port A =
@ -221,7 +231,9 @@ xpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, uint8_t
return -1;
}
#if 0
#if VERBOSE
{
int i;
printf("###\n");
printf("reqno = %02X\n", reqno);
printf("bits = %d\n", bits);
@ -231,6 +243,7 @@ xpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, uint8_t
printf("a6_display(\"%02X\", \"", bits);
for(i=0;i<in_len;i++) printf("%02X%s", in[i], (i+1<in_len)?",":"");
printf("\", ");
}
#endif
if(usb_bulk_write(xpcu, 0x02, (char*)in, in_len, 1000)<0)
@ -248,10 +261,13 @@ xpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, uint8_t
}
}
#if 0
#if VERBOSE
{
int i;
printf("\"");
for(i=0;i<out_len;i++) printf("%02X%s", out[i], (i+1<out_len)?",":"");
printf("\")\n");
}
#endif
return 0;
@ -262,56 +278,44 @@ xpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, uint8_t
static int
xpcu_common_init( cable_t *cable )
{
uint16_t buf;
struct usb_dev_handle *xpcu;
int r;
uint16_t buf;
struct usb_dev_handle *xpcu;
if (usbconn_open( cable->link.usb )) return -1;
if (usbconn_open( cable->link.usb )) return -1;
xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle;
if(xpcu_request_28(xpcu, 0x11)<0)
{
usb_close(xpcu);
return -1;
};
xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle;
if(xpcu_write_gpio(xpcu, 8)<0)
{
usb_close(xpcu);
return -1;
};
r = xpcu_request_28(xpcu, 0x11);
if (r>=0) r = xpcu_write_gpio(xpcu, 8);
/* Read firmware version (constant embedded in firmware) */
if(xpcu_read_firmware_version(xpcu, &buf) < 0)
{
usb_close(xpcu);
return -1;
}
else
if (r>=0) r = xpcu_read_firmware_version(xpcu, &buf);
if (r>=0)
{
printf("firmware version = 0x%04X (%u)\n", buf, buf);
};
/* Read CPLD version (via GPIF) */
if(xpcu_read_cpld_version(xpcu, &buf) < 0)
{
usb_close(xpcu);
return -1;
}
else
if (r>=0) xpcu_read_cpld_version(xpcu, &buf);
if (r>=0)
{
printf("cable CPLD version = 0x%04X (%u)\n", buf, buf);
if(buf == 0)
{
printf("Warning: version '0' can't be correct. Please try resetting the cable\n");
r = -1;
};
};
PARAM_TRST(cable) = 1;
if (r<0)
{
usb_close(xpcu);
};
return 0;
return r;
}
static int
@ -332,20 +336,58 @@ xpc_ext_init( cable_t *cable )
{
struct usb_dev_handle *xpcu;
uint8_t zero[2] = {0,0};
uint8_t iostate;
int r;
if (xpcu_common_init( cable )<0) return -1;
free(cable->params);
cable->params = NULL;
r = xpcu_common_init( cable );
if (r<0) return r;
cable->params = malloc(sizeof(xpc_cable_params_t));
if(cable->params == NULL) r = -1;
xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle;
if (xpcu_request_28(xpcu, 0x11)<0)
if (xpcu_select_gpio(xpcu, 1)<0) return -1;
if (xpcu_output_enable(xpcu, 1)<0) return -1;
if (xpcu_shift(xpcu, 0xA6, 2, 2, zero, 0, NULL)<0) return -1;
if (xpcu_read_gpio(xpcu, &iostate)<0) return -1;
if (xpcu_request_28(xpcu, 0x12)<0) return -1;
if (r>=0) r = xpcu_request_28(xpcu, 0x11);
if (r>=0) r = xpcu_output_enable(xpcu, 1);
if (r>=0) r = xpcu_shift(xpcu, 0xA6, 2, 2, zero, 0, NULL);
if (r>=0) r = xpcu_request_28(xpcu, 0x12);
return 0;
if (r<0)
{
usb_close(xpcu);
free(cable->params);
cable->params = NULL;
}
return r;
}
/* ---------------------------------------------------------------------- */
static void
xpc_ext_done( cable_t *cable )
{
struct usb_dev_handle *xpcu;
xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle;
xpcu_output_enable(xpcu, 0);
generic_usbconn_done( cable );
}
/* ---------------------------------------------------------------------- */
static void
xpc_ext_free( cable_t *cable )
{
if(cable->params)
{
free(cable->params);
cable->params = NULL;
}
generic_usbconn_free( cable );
}
/* ---------------------------------------------------------------------- */
@ -402,8 +444,6 @@ xpc_set_trst( cable_t *cable, int trst )
/* ---------------------------------------------------------------------- */
static int last_tdo;
static void
xpc_ext_clock( cable_t *cable, int tms, int tdi, int n )
{
@ -419,7 +459,8 @@ xpc_ext_clock( cable_t *cable, int tms, int tdi, int n )
for(i=0;i<n;i++) xpcu_shift(xpcu, 0xA6, 1, 2, clock, 2, tdo);
last_tdo = tdo[1] ? 1:0;
last_tdo = tdo[1] ? 1:0;
// ((xpc_cable_params_t*)(cable->params))->last_tdo = tdo[1] ? 1:0;
}
/* ---------------------------------------------------------------------- */
@ -427,21 +468,24 @@ xpc_ext_clock( cable_t *cable, int tms, int tdi, int n )
static int
xpc_ext_get_tdo( cable_t *cable )
{
return last_tdo;
return last_tdo;
// return ((xpc_cable_params_t*)(cable->params))->last_tdo;
}
/* ---------------------------------------------------------------------- */
#define XPC_A6_CHUNKSIZE 1 /* 16-bit words */
/* 16-bit words. More than 4 currently leads to bit errors; 13 to serious problems */
#define XPC_A6_CHUNKSIZE 4
typedef struct
{
cable_t *cable;
struct usb_dev_handle *xpcu;
int in_bits;
int out_bits;
int out_done;
uint8_t *out;
uint8_t in[XPC_A6_CHUNKSIZE*2];
uint8_t buf[XPC_A6_CHUNKSIZE*2];
}
xpc_ext_transfer_state_t;
@ -452,6 +496,7 @@ xpcu_do_ext_transfer( xpc_ext_transfer_state_t *xts )
{
int r;
int in_len, out_len;
// int last_tdo;
in_len = 2 * (xts->in_bits >> 2);
if ((xts->in_bits & 3) != 0) in_len += 2;
@ -459,9 +504,16 @@ xpcu_do_ext_transfer( xpc_ext_transfer_state_t *xts )
out_len = 2 * (xts->out_bits >> 4);
if ((xts->out_bits & 15) != 0) out_len += 2;
r = xpcu_shift (xts->xpcu, 0xA6, xts->in_bits, in_len, xts->in, out_len, xts->in);
if(xts->out != NULL)
{
r = xpcu_shift (xts->xpcu, 0xA6, xts->in_bits, in_len, xts->buf, out_len, xts->buf);
}
else
{
r = xpcu_shift (xts->xpcu, 0xA6, xts->in_bits, in_len, xts->buf, 0, NULL);
}
if(r>=0 && xts->out != NULL)
if(r >= 0 && xts->out_bits > 0)
{
int out_idx = 0;
int out_rem = xts->out_bits;
@ -470,13 +522,18 @@ xpcu_do_ext_transfer( xpc_ext_transfer_state_t *xts )
{
uint32_t mask, rxw;
rxw = (xts->in[out_idx+1]<<8) | xts->in[out_idx];
rxw = (xts->buf[out_idx+1]<<8) | xts->buf[out_idx];
/* In the last (incomplete) word, the data isn't shifted completely to LSB */
mask = (out_rem >= 16) ? 1 : (1<<(16 - out_rem));
for(;mask <= 32768 && out_rem > 0; mask <<= 1)
while(mask <= 32768 && out_rem > 0)
{
xts->out[xts->out_done++] = (rxw & mask) ? 1 : 0;
last_tdo = (rxw & mask) ? 1 : 0;
xts->out[xts->out_done] = last_tdo;
xts->out_done++;
mask <<= 1;
out_rem--;
}
@ -487,6 +544,8 @@ xpcu_do_ext_transfer( xpc_ext_transfer_state_t *xts )
xts->in_bits = 0;
xts->out_bits = 0;
// ((xpc_cable_params_t*)(xts->cable->params))->last_tdo = last_tdo;
return r;
}
@ -500,24 +559,24 @@ xpcu_add_bit_for_ext_transfer( xpc_ext_transfer_state_t *xts, char in, char is_r
if(bit_idx == 0)
{
xts->in[buf_idx] = 0;
xts->in[buf_idx+1] = 0;
xts->buf[buf_idx] = 0;
xts->buf[buf_idx+1] = 0;
};
xts->in_bits++;
if(is_real)
{
if(in) xts->in[buf_idx] |= (0x01<<bit_idx);
if(in) xts->buf[buf_idx] |= (0x01<<bit_idx);
if(xts->out)
{
xts->in[buf_idx+1] |= (0x11<<bit_idx);
xts->buf[buf_idx+1] |= (0x11<<bit_idx);
xts->out_bits++;
}
else
{
xts->in[buf_idx+1] |= (0x01<<bit_idx);
xts->buf[buf_idx+1] |= (0x01<<bit_idx);
}
}
}
@ -530,7 +589,7 @@ xpc_ext_transfer( cable_t *cable, int len, char *in, char *out )
int i,j;
xpc_ext_transfer_state_t xts;
#if 0
#if VERBOSE
printf("---\n");
printf("transfer size %d, %s output\n", len, (out!=NULL) ? "with" : "without");
printf("tdi: ");
@ -543,11 +602,12 @@ xpc_ext_transfer( cable_t *cable, int len, char *in, char *out )
xts.in_bits = 0;
xts.out_bits = 0;
xts.out_done = 0;
xts.cable = cable;
for(i=0,j=0; i<len && j>=0; i++)
{
xpcu_add_bit_for_ext_transfer( &xts, in[i], 1 );
if(xts.in_bits == (4*XPC_A6_CHUNKSIZE*4 - 1))
if(xts.in_bits == (4*XPC_A6_CHUNKSIZE - 1))
{
j = xpcu_do_ext_transfer( &xts );
}
@ -600,9 +660,9 @@ cable_driver_t xpc_ext_cable_driver = {
N_("Xilinx Platform Cable USB external chain"),
generic_usbconn_connect,
generic_disconnect,
generic_usbconn_free,
xpc_ext_free,
xpc_ext_init,
generic_usbconn_done,
xpc_ext_done,
generic_set_frequency,
xpc_ext_clock,
xpc_ext_get_tdo,

Loading…
Cancel
Save