X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fopendous.c;h=6af3b28f489209fee1aa3420a210c71abbe0288f;hp=3a6cf5c693bad67bb929adccb8dc2f84751cffa4;hb=7568a91c8e2398a113f0b40a2a24a1b91ed12c95;hpb=df7a6b08a69cdf13d4a0adc9b6fc9e56cdcaa18e diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 3a6cf5c693..6af3b28f48 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -25,7 +25,7 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -36,42 +36,61 @@ #include #include "libusb_common.h" #include -#include #include -#define ESTICK_VID 0x1781 -#define ESTICK_PID 0xC0C0 - -#define OPENDOUS_VID 0x03EB -#define OPENDOUS_PID 0x204F +#define OPENDOUS_MAX_VIDS_PIDS 4 +/* define some probes with similar interface */ +struct opendous_probe { + char *name; + uint16_t VID[OPENDOUS_MAX_VIDS_PIDS]; + uint16_t PID[OPENDOUS_MAX_VIDS_PIDS]; + uint8_t READ_EP; + uint8_t WRITE_EP; + uint8_t CONTROL_TRANSFER; + int BUFFERSIZE; +}; -/* pid could be specified at runtime */ -static uint16_t vids[] = { OPENDOUS_VID, ESTICK_VID, 0 }; -static uint16_t pids[] = { OPENDOUS_PID, ESTICK_PID, 0 }; +static struct opendous_probe opendous_probes[] = { + {"usbprog-jtag", {0x1781, 0}, {0x0C63, 0}, 0x82, 0x02, 0x00, 510 }, + {"opendous", {0x1781, 0x03EB, 0}, {0xC0C0, 0x204F, 0}, 0x81, 0x02, 0x00, 360 }, + {"usbvlab", {0x16C0, 0}, {0x05DC, 0}, 0x81, 0x02, 0x01, 360 }, + {NULL, {0x0000}, {0x0000}, 0x00, 0x00, 0x00, 0 } +}; -#define OPENDOUS_WRITE_ENDPOINT 0x02 -#define OPENDOUS_READ_ENDPOINT 0x81 +#define OPENDOUS_WRITE_ENDPOINT (opendous_probe->WRITE_EP) +#define OPENDOUS_READ_ENDPOINT (opendous_probe->READ_EP) static unsigned int opendous_hw_jtag_version = 1; #define OPENDOUS_USB_TIMEOUT 1000 -#define OPENDOUS_USB_BUFFER_SIZE 360 +#define OPENDOUS_USB_BUFFER_SIZE (opendous_probe->BUFFERSIZE) #define OPENDOUS_IN_BUFFER_SIZE (OPENDOUS_USB_BUFFER_SIZE) #define OPENDOUS_OUT_BUFFER_SIZE (OPENDOUS_USB_BUFFER_SIZE) /* Global USB buffers */ -static uint8_t usb_in_buffer[OPENDOUS_IN_BUFFER_SIZE]; -static uint8_t usb_out_buffer[OPENDOUS_OUT_BUFFER_SIZE]; +static uint8_t *usb_in_buffer; +static uint8_t *usb_out_buffer; /* Constants for OPENDOUS command */ #define OPENDOUS_MAX_SPEED 66 -#define OPENDOUS_MAX_TAP_TRANSMIT 350 /* even number is easier to handle */ +#define OPENDOUS_MAX_TAP_TRANSMIT ((opendous_probe->BUFFERSIZE)-10) #define OPENDOUS_MAX_INPUT_DATA (OPENDOUS_MAX_TAP_TRANSMIT*4) +/* TAP */ #define OPENDOUS_TAP_BUFFER_SIZE 65536 +struct pending_scan_result { + int first; /* First bit position in tdo_buffer to read */ + int length; /* Number of bits to read */ + struct scan_command *command; /* Corresponding scan command */ + uint8_t *buffer; +}; + +static int pending_scan_results_length; +static struct pending_scan_result *pending_scan_results_buffer; + #define MAX_PENDING_SCAN_RESULTS (OPENDOUS_MAX_INPUT_DATA) /* JTAG usb commands */ @@ -84,11 +103,16 @@ static uint8_t usb_out_buffer[OPENDOUS_OUT_BUFFER_SIZE]; #define JTAG_CMD_SET_SRST_TRST 0x6 #define JTAG_CMD_READ_CONFIG 0x7 +/* usbvlab control transfer */ +#define FUNC_START_BOOTLOADER 30 +#define FUNC_WRITE_DATA 0x50 +#define FUNC_READ_DATA 0x51 + +static char *opendous_type; +static struct opendous_probe *opendous_probe; + /* External interface functions */ static int opendous_execute_queue(void); -static int opendous_speed(int speed); -static int opendous_speed_div(int speed, int *khz); -static int opendous_khz(int khz, int *jtag_speed); static int opendous_init(void); static int opendous_quit(void); @@ -125,9 +149,7 @@ static int opendous_usb_read(struct opendous_jtag *opendous_jtag); int opendous_get_version_info(void); #ifdef _DEBUG_USB_COMMS_ -char time_str[50]; static void opendous_debug_buffer(uint8_t *buffer, int length); -char *opendous_get_time(char *); #endif static struct opendous_jtag *opendous_jtag_handle; @@ -135,6 +157,22 @@ static struct opendous_jtag *opendous_jtag_handle; /***************************************************************************/ /* External interface implementation */ +COMMAND_HANDLER(opendous_handle_opendous_type_command) +{ + if (CMD_ARGC == 0) + return ERROR_OK; + + /* only if the cable name wasn't overwritten by cmdline */ + if (opendous_type == NULL) { + /* REVISIT first verify that it's listed in cables[] ... */ + opendous_type = strdup(CMD_ARGV[0]); + } + + /* REVISIT it's probably worth returning the current value ... */ + + return ERROR_OK; +} + COMMAND_HANDLER(opendous_handle_opendous_info_command) { if (opendous_get_version_info() == ERROR_OK) { @@ -187,6 +225,13 @@ static const struct command_registration opendous_command_handlers[] = { .help = "access opendous HW JTAG command version", .usage = "[2|3]", }, + { + .name = "opendous_type", + .handler = &opendous_handle_opendous_type_command, + .mode = COMMAND_CONFIG, + .help = "set opendous type", + .usage = "[usbvlab|usbprog-jtag|opendous]", + }, COMMAND_REGISTRATION_DONE }; @@ -194,9 +239,6 @@ struct jtag_interface opendous_interface = { .name = "opendous", .commands = opendous_command_handlers, .execute_queue = opendous_execute_queue, - .speed = opendous_speed, - .speed_div = opendous_speed_div, - .khz = opendous_khz, .init = opendous_init, .quit = opendous_quit, }; @@ -262,7 +304,7 @@ static int opendous_execute_queue(void) break; case JTAG_SLEEP: - DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us); + DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); opendous_tap_execute(); jtag_sleep(cmd->cmd.sleep->us); break; @@ -276,36 +318,37 @@ static int opendous_execute_queue(void) return opendous_tap_execute(); } -/* Sets speed in kHz. */ -static int opendous_speed(int speed) +static int opendous_init(void) { - if (speed <= OPENDOUS_MAX_SPEED) { - /* one day... */ - return ERROR_OK; - } else - LOG_INFO("Requested speed %dkHz exceeds maximum of %dkHz, ignored", speed, OPENDOUS_MAX_SPEED); + int check_cnt; + struct opendous_probe *cur_opendous_probe; - return ERROR_OK; -} + cur_opendous_probe = opendous_probes; -static int opendous_speed_div(int speed, int *khz) -{ - *khz = speed; + if (opendous_type == NULL) { + opendous_type = strdup("opendous"); + LOG_WARNING("No opendous_type specified, using default 'opendous'"); + } - return ERROR_OK; -} + while (cur_opendous_probe->name) { + if (strcmp(cur_opendous_probe->name, opendous_type) == 0) { + opendous_probe = cur_opendous_probe; + break; + } + cur_opendous_probe++; + } -static int opendous_khz(int khz, int *jtag_speed) -{ - *jtag_speed = khz; - /* TODO: convert this into delay value for opendous */ + if (!opendous_probe) { + LOG_ERROR("No matching cable found for %s", opendous_type); + return ERROR_JTAG_INIT_FAILED; + } - return ERROR_OK; -} -static int opendous_init(void) -{ - int check_cnt; + usb_in_buffer = malloc(opendous_probe->BUFFERSIZE); + usb_out_buffer = malloc(opendous_probe->BUFFERSIZE); + + pending_scan_results_buffer = malloc( + MAX_PENDING_SCAN_RESULTS * sizeof(*pending_scan_results_buffer)); opendous_jtag_handle = opendous_usb_open(); @@ -336,6 +379,27 @@ static int opendous_init(void) static int opendous_quit(void) { opendous_usb_close(opendous_jtag_handle); + + if (usb_out_buffer) { + free(usb_out_buffer); + usb_out_buffer = NULL; + } + + if (usb_in_buffer) { + free(usb_in_buffer); + usb_in_buffer = NULL; + } + + if (pending_scan_results_buffer) { + free(pending_scan_results_buffer); + pending_scan_results_buffer = NULL; + } + + if (opendous_type) { + free(opendous_type); + opendous_type = NULL; + } + return ERROR_OK; } @@ -494,16 +558,6 @@ static int tap_length; static uint8_t tms_buffer[OPENDOUS_TAP_BUFFER_SIZE]; static uint8_t tdo_buffer[OPENDOUS_TAP_BUFFER_SIZE]; -struct pending_scan_result { - int first; /* First bit position in tdo_buffer to read */ - int length; /* Number of bits to read */ - struct scan_command *command; /* Corresponding scan command */ - uint8_t *buffer; -}; - -static int pending_scan_results_length; -static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS]; - static int last_tms; void opendous_tap_init(void) @@ -515,8 +569,9 @@ void opendous_tap_init(void) void opendous_tap_ensure_space(int scans, int bits) { int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length; + int available_bits = OPENDOUS_TAP_BUFFER_SIZE / 2 - tap_length; - if (scans > available_scans) + if ((scans > available_scans) || (bits > available_bits)) opendous_tap_execute(); } @@ -526,6 +581,8 @@ void opendous_tap_append_step(int tms, int tdi) unsigned char _tms = tms ? 1 : 0; unsigned char _tdi = tdi ? 1 : 0; + opendous_tap_ensure_space(0, 1); + int tap_index = tap_length / 4; int bits = (tap_length % 4) * 2; @@ -652,13 +709,13 @@ struct opendous_jtag *opendous_usb_open(void) struct opendous_jtag *result; struct jtag_libusb_device_handle *devh; - if (jtag_libusb_open(vids, pids, &devh) != ERROR_OK) + if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh) != ERROR_OK) return NULL; jtag_libusb_set_configuration(devh, 0); jtag_libusb_claim_interface(devh, 0); - result = (struct opendous_jtag *) malloc(sizeof(struct opendous_jtag)); + result = malloc(sizeof(*result)); result->usb_handle = devh; return result; } @@ -700,12 +757,18 @@ int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length) } #ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("%s: USB write begin", opendous_get_time(time_str)); + LOG_DEBUG("USB write begin"); #endif - result = jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \ - (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); + if (opendous_probe->CONTROL_TRANSFER) { + result = jtag_libusb_control_transfer(opendous_jtag->usb_handle, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, + FUNC_WRITE_DATA, 0, 0, (char *) usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); + } else { + result = jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \ + (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); + } #ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("%s: USB write end: %d bytes", opendous_get_time(time_str), result); + LOG_DEBUG("USB write end: %d bytes", result); #endif DEBUG_JTAG_IO("opendous_usb_write, out_length = %d, result = %d", out_length, result); @@ -720,12 +783,19 @@ int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length) int opendous_usb_read(struct opendous_jtag *opendous_jtag) { #ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("%s: USB read begin", opendous_get_time(time_str)); + LOG_DEBUG("USB read begin"); #endif - int result = jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT, - (char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT); + int result; + if (opendous_probe->CONTROL_TRANSFER) { + result = jtag_libusb_control_transfer(opendous_jtag->usb_handle, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, + FUNC_READ_DATA, 0, 0, (char *) usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT); + } else { + result = jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT, + (char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT); + } #ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("%s: USB read end: %d bytes", opendous_get_time(time_str), result); + LOG_DEBUG("USB read end: %d bytes", result); #endif DEBUG_JTAG_IO("opendous_usb_read, result = %d", result); @@ -754,15 +824,4 @@ void opendous_debug_buffer(uint8_t *buffer, int length) LOG_DEBUG("%s", line); } } - -char *opendous_get_time(char *str) -{ - struct timeb timebuffer; - char *timeline; - - ftime(&timebuffer); - timeline = ctime(&(timebuffer.time)); - snprintf(str, 49, "%.8s.%hu", &timeline[11], timebuffer.millitm); - return str; -} #endif