drivers/jtag: usb_blaster add pin controls
Add pin controls (pin6 and pin8). These pins can be controled either : - with a fixed value (0 or 1) - by TRST or SRST reset signal (driven low when signal activated). Change-Id: Ie6a3e57fc6ba6a38fdb9a009c976e3febab8f578 Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Reviewed-on: http://openocd.zylin.com/1448 Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Tested-by: jenkins__archive__
parent
f550277482
commit
18e15390df
|
@ -82,11 +82,20 @@
|
||||||
*/
|
*/
|
||||||
#define BUF_LEN 4096
|
#define BUF_LEN 4096
|
||||||
|
|
||||||
|
enum gpio_steer {
|
||||||
|
FIXED_0 = 0,
|
||||||
|
FIXED_1,
|
||||||
|
SRST,
|
||||||
|
TRST,
|
||||||
|
};
|
||||||
|
|
||||||
struct ublast_info {
|
struct ublast_info {
|
||||||
int pin6;
|
enum gpio_steer pin6;
|
||||||
int pin8;
|
enum gpio_steer pin8;
|
||||||
int tms;
|
int tms;
|
||||||
int tdi;
|
int tdi;
|
||||||
|
bool trst_asserted;
|
||||||
|
bool srst_asserted;
|
||||||
uint8_t buf[BUF_LEN];
|
uint8_t buf[BUF_LEN];
|
||||||
int bufidx;
|
int bufidx;
|
||||||
|
|
||||||
|
@ -103,6 +112,10 @@ static struct ublast_info info = {
|
||||||
.ublast_vid = 0x09fb, /* Altera */
|
.ublast_vid = 0x09fb, /* Altera */
|
||||||
.ublast_pid = 0x6001, /* USB-Blaster */
|
.ublast_pid = 0x6001, /* USB-Blaster */
|
||||||
.lowlevel_name = NULL,
|
.lowlevel_name = NULL,
|
||||||
|
.srst_asserted = false,
|
||||||
|
.trst_asserted = false,
|
||||||
|
.pin6 = FIXED_1,
|
||||||
|
.pin8 = FIXED_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -218,20 +231,6 @@ static void ublast_flush_buffer(void)
|
||||||
#define SHMODE (1 << 7)
|
#define SHMODE (1 << 7)
|
||||||
#define READ_TDO (1 << 0)
|
#define READ_TDO (1 << 0)
|
||||||
|
|
||||||
/**
|
|
||||||
* ublast_reset - reset the JTAG device is possible
|
|
||||||
* @trst: 1 if TRST is to be asserted
|
|
||||||
* @srst: 1 if SRST is to be asserted
|
|
||||||
*
|
|
||||||
* This is not implemented yet. If pin6 or pin8 controlls the TRST/SRST, code
|
|
||||||
* should be added so that this function makes use of it.
|
|
||||||
*/
|
|
||||||
static void ublast_reset(int trst, int srst)
|
|
||||||
{
|
|
||||||
DEBUG_JTAG_IO("TODO: ublast_reset(%d,%d) isn't implemented!",
|
|
||||||
trst, srst);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ublast_queue_byte - queue one 'bitbang mode' byte for USB Blaster
|
* ublast_queue_byte - queue one 'bitbang mode' byte for USB Blaster
|
||||||
* @abyte: the byte to queue
|
* @abyte: the byte to queue
|
||||||
|
@ -250,6 +249,28 @@ static void ublast_queue_byte(uint8_t abyte)
|
||||||
DEBUG_JTAG_IO("(byte=0x%02x)", abyte);
|
DEBUG_JTAG_IO("(byte=0x%02x)", abyte);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ublast_compute_pin - compute if gpio should be asserted
|
||||||
|
* @steer: control (ie. TRST driven, SRST driven, of fixed)
|
||||||
|
*
|
||||||
|
* Returns pin value (1 means driven high, 0 mean driven low)
|
||||||
|
*/
|
||||||
|
bool ublast_compute_pin(enum gpio_steer steer)
|
||||||
|
{
|
||||||
|
switch (steer) {
|
||||||
|
case FIXED_0:
|
||||||
|
return 0;
|
||||||
|
case FIXED_1:
|
||||||
|
return 1;
|
||||||
|
case SRST:
|
||||||
|
return !info.srst_asserted;
|
||||||
|
case TRST:
|
||||||
|
return !info.trst_asserted;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ublast_build_out - build bitbang mode output byte
|
* ublast_build_out - build bitbang mode output byte
|
||||||
* @type: says if reading back TDO is required
|
* @type: says if reading back TDO is required
|
||||||
|
@ -261,8 +282,8 @@ static uint8_t ublast_build_out(enum scan_type type)
|
||||||
uint8_t abyte = 0;
|
uint8_t abyte = 0;
|
||||||
|
|
||||||
abyte |= info.tms ? TMS : 0;
|
abyte |= info.tms ? TMS : 0;
|
||||||
abyte |= info.pin6 ? NCE : 0;
|
abyte |= ublast_compute_pin(info.pin6) ? NCE : 0;
|
||||||
abyte |= info.pin8 ? NCS : 0;
|
abyte |= ublast_compute_pin(info.pin8) ? NCS : 0;
|
||||||
abyte |= info.tdi ? TDI : 0;
|
abyte |= info.tdi ? TDI : 0;
|
||||||
abyte |= LED;
|
abyte |= LED;
|
||||||
if (type == SCAN_IN || type == SCAN_IO)
|
if (type == SCAN_IN || type == SCAN_IO)
|
||||||
|
@ -270,6 +291,22 @@ static uint8_t ublast_build_out(enum scan_type type)
|
||||||
return abyte;
|
return abyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ublast_reset - reset the JTAG device is possible
|
||||||
|
* @trst: 1 if TRST is to be asserted
|
||||||
|
* @srst: 1 if SRST is to be asserted
|
||||||
|
*/
|
||||||
|
static void ublast_reset(int trst, int srst)
|
||||||
|
{
|
||||||
|
uint8_t out_value;
|
||||||
|
|
||||||
|
info.trst_asserted = trst;
|
||||||
|
info.srst_asserted = srst;
|
||||||
|
out_value = ublast_build_out(SCAN_OUT);
|
||||||
|
ublast_queue_byte(out_value);
|
||||||
|
ublast_flush_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ublast_clock_tms - clock a TMS transition
|
* ublast_clock_tms - clock a TMS transition
|
||||||
* @tms: the TMS to be sent
|
* @tms: the TMS to be sent
|
||||||
|
@ -841,24 +878,57 @@ COMMAND_HANDLER(ublast_handle_vid_pid_command)
|
||||||
COMMAND_HANDLER(ublast_handle_pin_command)
|
COMMAND_HANDLER(ublast_handle_pin_command)
|
||||||
{
|
{
|
||||||
uint8_t out_value;
|
uint8_t out_value;
|
||||||
|
const char * const pin_name = CMD_ARGV[0];
|
||||||
|
enum gpio_steer *steer = NULL;
|
||||||
|
static const char * const pin_val_str[] = {
|
||||||
|
[FIXED_0] = "0",
|
||||||
|
[FIXED_1] = "1",
|
||||||
|
[SRST] = "SRST driven",
|
||||||
|
[TRST] = "TRST driven",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (CMD_ARGC > 2) {
|
||||||
|
LOG_ERROR("%s takes exactly one or two arguments", CMD_NAME);
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(pin_name, "pin6"))
|
||||||
|
steer = &info.pin6;
|
||||||
|
if (!strcmp(pin_name, "pin8"))
|
||||||
|
steer = &info.pin8;
|
||||||
|
if (!steer) {
|
||||||
|
LOG_ERROR("%s: pin name must be \"pin6\" or \"pin8\"",
|
||||||
|
CMD_NAME);
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CMD_ARGC == 1) {
|
||||||
|
LOG_INFO("%s: %s is set as %s\n", CMD_NAME, pin_name,
|
||||||
|
pin_val_str[*steer]);
|
||||||
|
}
|
||||||
|
|
||||||
if (CMD_ARGC == 2) {
|
if (CMD_ARGC == 2) {
|
||||||
const char * const pin_name = CMD_ARGV[0];
|
const char * const pin_value = CMD_ARGV[1];
|
||||||
unsigned int state;
|
char val = pin_value[0];
|
||||||
|
|
||||||
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], state);
|
if (strlen(pin_value) > 1)
|
||||||
if ((state != 0) && (state != 1)) {
|
val = '?';
|
||||||
LOG_ERROR("%s: pin state must be 0 or 1", CMD_NAME);
|
switch (tolower(val)) {
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
case '0':
|
||||||
}
|
*steer = FIXED_0;
|
||||||
|
break;
|
||||||
if (!strcmp(pin_name, "pin6")) {
|
case '1':
|
||||||
info.pin6 = state;
|
*steer = FIXED_1;
|
||||||
} else if (!strcmp(pin_name, "pin8")) {
|
break;
|
||||||
info.pin8 = state;
|
case 't':
|
||||||
} else {
|
*steer = TRST;
|
||||||
LOG_ERROR("%s: pin name must be \"pin6\" or \"pin8\"",
|
break;
|
||||||
CMD_NAME);
|
case 's':
|
||||||
|
*steer = SRST;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_ERROR("%s: pin value must be 0, 1, s (SRST) or t (TRST)",
|
||||||
|
pin_value);
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,11 +937,8 @@ COMMAND_HANDLER(ublast_handle_pin_command)
|
||||||
ublast_queue_byte(out_value);
|
ublast_queue_byte(out_value);
|
||||||
ublast_flush_buffer();
|
ublast_flush_buffer();
|
||||||
}
|
}
|
||||||
return ERROR_OK;
|
|
||||||
} else {
|
|
||||||
LOG_ERROR("%s takes exactly two arguments", CMD_NAME);
|
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
||||||
}
|
}
|
||||||
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(ublast_handle_lowlevel_drv_command)
|
COMMAND_HANDLER(ublast_handle_lowlevel_drv_command)
|
||||||
|
@ -907,11 +974,11 @@ static const struct command_registration ublast_command_handlers[] = {
|
||||||
.usage = "(ftdi|ftd2xx)",
|
.usage = "(ftdi|ftd2xx)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "usb_blaster",
|
.name = "usb_blaster_pin",
|
||||||
.handler = ublast_handle_pin_command,
|
.handler = ublast_handle_pin_command,
|
||||||
.mode = COMMAND_ANY,
|
.mode = COMMAND_ANY,
|
||||||
.help = "set pin state for the unused GPIO pins",
|
.help = "show or set pin state for the unused GPIO pins",
|
||||||
.usage = "(pin6|pin8) (0|1)",
|
.usage = "(pin6|pin8) (0|1|s|t)",
|
||||||
},
|
},
|
||||||
COMMAND_REGISTRATION_DONE
|
COMMAND_REGISTRATION_DONE
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue