X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fcmsis_dap_usb.c;h=6d55392d5a47bccf5fa229a7e5eb846946c50ac0;hb=b12fca236d191b0f280aaea0b63a5789480b5e05;hp=bd8d0bec7cd5215e1ceacdf3f954606bc71c3a16;hpb=f63b519385a8d6dca9b75f29f26d3144fd774bb4;p=fw%2Fopenocd diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c index bd8d0bec7..6d55392d5 100644 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ b/src/jtag/drivers/cmsis_dap_usb.c @@ -77,8 +77,8 @@ static bool swd_mode; #define CMD_DAP_RESET_TARGET 0x0A /* CMD_INFO */ -#define INFO_ID_VID 0x00 /* string */ -#define INFO_ID_PID 0x02 /* string */ +#define INFO_ID_VENDOR 0x01 /* string */ +#define INFO_ID_PRODUCT 0x02 /* string */ #define INFO_ID_SERNUM 0x03 /* string */ #define INFO_ID_FW_VER 0x04 /* string */ #define INFO_ID_TD_VEND 0x05 /* string */ @@ -229,14 +229,16 @@ static int cmsis_dap_usb_open(void) int i; struct hid_device_info *devs, *cur_dev; unsigned short target_vid, target_pid; - wchar_t *target_serial = NULL; - bool found = false; - bool serial_found = false; target_vid = 0; target_pid = 0; + if (hid_init() != 0) { + LOG_ERROR("unable to open HIDAPI"); + return ERROR_FAIL; + } + /* * The CMSIS-DAP specification stipulates: * "The Product String must contain "CMSIS-DAP" somewhere in the string. This is used by the @@ -268,12 +270,15 @@ static int cmsis_dap_usb_open(void) found = true; } + /* LPC-LINK2 has cmsis-dap on interface 0 and other HID functions on other interfaces */ + if (cur_dev->vendor_id == 0x1fc9 && cur_dev->product_id == 0x0090 && cur_dev->interface_number != 0) + found = false; + if (found) { /* we have found an adapter, so exit further checks */ /* check serial number matches if given */ if (cmsis_dap_serial != NULL) { if ((cur_dev->serial_number != NULL) && wcscmp(cmsis_dap_serial, cur_dev->serial_number) == 0) { - serial_found = true; break; } } else @@ -288,23 +293,16 @@ static int cmsis_dap_usb_open(void) if (NULL != cur_dev) { target_vid = cur_dev->vendor_id; target_pid = cur_dev->product_id; - if (serial_found) - target_serial = cmsis_dap_serial; } - hid_free_enumeration(devs); - if (target_vid == 0 && target_pid == 0) { LOG_ERROR("unable to find CMSIS-DAP device"); + hid_free_enumeration(devs); return ERROR_FAIL; } - if (hid_init() != 0) { - LOG_ERROR("unable to open HIDAPI"); - return ERROR_FAIL; - } - - dev = hid_open(target_vid, target_pid, target_serial); + dev = hid_open_path(cur_dev->path); + hid_free_enumeration(devs); if (dev == NULL) { LOG_ERROR("unable to open CMSIS-DAP device 0x%x:0x%x", target_vid, target_pid); @@ -335,7 +333,7 @@ static int cmsis_dap_usb_open(void) * board */ /* TODO: HID report descriptor should be parsed instead of * hardcoding a match by VID */ - if (target_vid == 0x03eb && target_pid != 0x2145) + if (target_vid == 0x03eb && target_pid != 0x2145 && target_pid != 0x2175) packet_size = 512 + 1; cmsis_dap_handle->packet_buffer = malloc(packet_size); @@ -364,8 +362,6 @@ static void cmsis_dap_usb_close(struct cmsis_dap *dap) free(pending_fifo[i].transfers); pending_fifo[i].transfers = NULL; } - - return; } static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen) @@ -509,15 +505,15 @@ static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data) return ERROR_OK; } -static int cmsis_dap_cmd_DAP_LED(uint8_t leds) +static int cmsis_dap_cmd_DAP_LED(uint8_t led, uint8_t state) { int retval; uint8_t *buffer = cmsis_dap_handle->packet_buffer; buffer[0] = 0; /* report number */ buffer[1] = CMD_DAP_LED; - buffer[2] = 0x00; - buffer[3] = leds; + buffer[2] = led; + buffer[3] = state; retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4); if (retval != ERROR_OK || buffer[1] != 0x00) { @@ -1007,7 +1003,7 @@ static int cmsis_dap_init(void) LOG_INFO("CMSIS-DAP: Interface Initialised (JTAG)"); } - /* Be conservative and supress submiting multiple HID requests + /* Be conservative and suppress submitting multiple HID requests * until we get packet count info from the adaptor */ cmsis_dap_handle->packet_count = 1; pending_queue_len = 12; @@ -1086,8 +1082,12 @@ static int cmsis_dap_init(void) if (retval != ERROR_OK) return ERROR_FAIL; } + /* Both LEDs on */ + retval = cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_ON); + if (retval != ERROR_OK) + return ERROR_FAIL; - retval = cmsis_dap_cmd_DAP_LED(0x03); /* Both LEDs on */ + retval = cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_ON); if (retval != ERROR_OK) return ERROR_FAIL; @@ -1102,9 +1102,6 @@ static int cmsis_dap_init(void) LOG_INFO("Connecting under reset"); } } - - cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */ - LOG_INFO("CMSIS-DAP: Interface ready"); return ERROR_OK; @@ -1119,28 +1116,31 @@ static int cmsis_dap_swd_init(void) static int cmsis_dap_quit(void) { cmsis_dap_cmd_DAP_Disconnect(); - cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */ + /* Both LEDs off */ + cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_OFF); + cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_OFF); cmsis_dap_usb_close(cmsis_dap_handle); return ERROR_OK; } -static void cmsis_dap_execute_reset(struct jtag_command *cmd) +static int cmsis_dap_reset(int trst, int srst) { /* Set both TRST and SRST even if they're not enabled as * there's no way to tristate them */ output_pins = 0; - if (!cmd->cmd.reset->srst) + if (!srst) output_pins |= SWJ_PIN_SRST; - if (!cmd->cmd.reset->trst) + if (!trst) output_pins |= SWJ_PIN_TRST; int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins, SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL); if (retval != ERROR_OK) LOG_ERROR("CMSIS-DAP: Interface reset failed"); + return retval; } static void cmsis_dap_execute_sleep(struct jtag_command *cmd) @@ -1246,7 +1246,7 @@ static void cmsis_dap_flush(void) if (!queued_seq_count) return; - DEBUG_JTAG_IO("Flushing %d queued sequences (%d bytes) with %d pending scan results to capture", + LOG_DEBUG_IO("Flushing %d queued sequences (%d bytes) with %d pending scan results to capture", queued_seq_count, queued_seq_buf_end, pending_scan_result_count); /* prep CMSIS-DAP packet */ @@ -1268,7 +1268,7 @@ static void cmsis_dap_flush(void) } #ifdef CMSIS_DAP_JTAG_DEBUG - DEBUG_JTAG_IO("USB response buf:"); + LOG_DEBUG_IO("USB response buf:"); for (int c = 0; c < queued_seq_buf_end + 3; ++c) printf("%02X ", buffer[c]); printf("\n"); @@ -1277,7 +1277,7 @@ static void cmsis_dap_flush(void) /* copy scan results into client buffers */ for (int i = 0; i < pending_scan_result_count; ++i) { struct pending_scan_result *scan = &pending_scan_results[i]; - DEBUG_JTAG_IO("Copying pending_scan_result %d/%d: %d bits from byte %d -> buffer + %d bits", + LOG_DEBUG_IO("Copying pending_scan_result %d/%d: %d bits from byte %d -> buffer + %d bits", i, pending_scan_result_count, scan->length, scan->first + 2, scan->buffer_offset); #ifdef CMSIS_DAP_JTAG_DEBUG for (uint32_t b = 0; b < DIV_ROUND_UP(scan->length, 8); ++b) @@ -1302,7 +1302,7 @@ static void cmsis_dap_flush(void) static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int s_offset, bool tms, uint8_t *tdo_buffer, int tdo_buffer_offset) { - DEBUG_JTAG_IO("[at %d] %d bits, tms %s, seq offset %d, tdo buf %p, tdo offset %d", + LOG_DEBUG_IO("[at %d] %d bits, tms %s, seq offset %d, tdo buf %p, tdo offset %d", queued_seq_buf_end, s_len, tms ? "HIGH" : "LOW", s_offset, tdo_buffer, tdo_buffer_offset); @@ -1310,12 +1310,12 @@ static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int return; if (s_len > 64) { - DEBUG_JTAG_IO("START JTAG SEQ SPLIT"); + LOG_DEBUG_IO("START JTAG SEQ SPLIT"); for (int offset = 0; offset < s_len; offset += 64) { int len = s_len - offset; if (len > 64) len = 64; - DEBUG_JTAG_IO("Splitting long jtag sequence: %d-bit chunk starting at offset %d", len, offset); + LOG_DEBUG_IO("Splitting long jtag sequence: %d-bit chunk starting at offset %d", len, offset); cmsis_dap_add_jtag_sequence( len, sequence, @@ -1325,7 +1325,7 @@ static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int tdo_buffer == NULL ? 0 : (tdo_buffer_offset + offset) ); } - DEBUG_JTAG_IO("END JTAG SEQ SPLIT"); + LOG_DEBUG_IO("END JTAG SEQ SPLIT"); return; } @@ -1362,7 +1362,7 @@ static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int /* queue a sequence of bits to clock out TMS, executing if the buffer is full */ static void cmsis_dap_add_tms_sequence(const uint8_t *sequence, int s_len) { - DEBUG_JTAG_IO("%d bits: %02X", s_len, *sequence); + LOG_DEBUG_IO("%d bits: %02X", s_len, *sequence); /* we use a series of CMD_DAP_JTAG_SEQ commands to toggle TMS, because even though it seems ridiculously inefficient, it allows us to combine TMS and scan sequences into the same @@ -1383,7 +1383,7 @@ static void cmsis_dap_state_move(void) tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - DEBUG_JTAG_IO("state move from %s to %s: %d clocks, %02X on tms", + LOG_DEBUG_IO("state move from %s to %s: %d clocks, %02X on tms", tap_state_name(tap_get_state()), tap_state_name(tap_get_end_state()), tms_scan_bits, tms_scan); cmsis_dap_add_tms_sequence(&tms_scan, tms_scan_bits); @@ -1395,7 +1395,7 @@ static void cmsis_dap_state_move(void) /* Execute a JTAG scan operation by queueing TMS and TDI/TDO sequences */ static void cmsis_dap_execute_scan(struct jtag_command *cmd) { - DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN", + LOG_DEBUG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN", jtag_scan_type(cmd->cmd.scan)); /* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */ @@ -1429,7 +1429,7 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd) for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) { scan_size += field->num_bits; - DEBUG_JTAG_IO("%s%s field %d/%d %d bits", + LOG_DEBUG_IO("%s%s field %d/%d %d bits", field->in_value ? "in" : "", field->out_value ? "out" : "", i, @@ -1437,7 +1437,7 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd) field->num_bits); if (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) { - DEBUG_JTAG_IO("Last field and have to move out of SHIFT state"); + LOG_DEBUG_IO("Last field and have to move out of SHIFT state"); /* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap * movement. This last field can't have length zero, it was checked above. */ cmsis_dap_add_jtag_sequence( @@ -1471,7 +1471,7 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd) 0); tap_set_state(tap_state_transition(tap_get_state(), 0)); } else { - DEBUG_JTAG_IO("Internal field, staying in SHIFT state afterwards"); + LOG_DEBUG_IO("Internal field, staying in SHIFT state afterwards"); /* Clocking part of a sequence into DR or IR with TMS=0, leaving TMS=0 at the end so we can continue later */ cmsis_dap_add_jtag_sequence( @@ -1489,7 +1489,7 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd) cmsis_dap_state_move(); } - DEBUG_JTAG_IO("%s scan, %i bits, end in %s", + LOG_DEBUG_IO("%s scan, %i bits, end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, tap_state_name(tap_get_end_state())); } @@ -1519,7 +1519,7 @@ static void cmsis_dap_pathmove(int num_states, tap_state_t *path) static void cmsis_dap_execute_pathmove(struct jtag_command *cmd) { - DEBUG_JTAG_IO("pathmove: %i states, end in %i", + LOG_DEBUG_IO("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); @@ -1557,7 +1557,7 @@ static void cmsis_dap_runtest(int num_cycles) static void cmsis_dap_execute_runtest(struct jtag_command *cmd) { - DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, + LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); cmsis_dap_end_state(cmd->cmd.runtest->end_state); @@ -1566,13 +1566,13 @@ static void cmsis_dap_execute_runtest(struct jtag_command *cmd) static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd) { - DEBUG_JTAG_IO("stableclocks %i cycles", cmd->cmd.runtest->num_cycles); + LOG_DEBUG_IO("stableclocks %i cycles", cmd->cmd.runtest->num_cycles); cmsis_dap_stableclocks(cmd->cmd.runtest->num_cycles); } static void cmsis_dap_execute_tms(struct jtag_command *cmd) { - DEBUG_JTAG_IO("TMS: %d bits", cmd->cmd.tms->num_bits); + LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits); cmsis_dap_cmd_DAP_SWJ_Sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits); } @@ -1581,10 +1581,6 @@ static void cmsis_dap_execute_tms(struct jtag_command *cmd) static void cmsis_dap_execute_command(struct jtag_command *cmd) { switch (cmd->type) { - case JTAG_RESET: - cmsis_dap_flush(); - cmsis_dap_execute_reset(cmd); - break; case JTAG_SLEEP: cmsis_dap_flush(); cmsis_dap_execute_sleep(cmd); @@ -1631,10 +1627,10 @@ static int cmsis_dap_execute_queue(void) static int cmsis_dap_speed(int speed) { if (speed > DAP_MAX_CLOCK) - LOG_INFO("High speed (adapter_khz %d) may be limited by adapter firmware.", speed); + LOG_INFO("High speed (adapter speed %d) may be limited by adapter firmware.", speed); if (speed == 0) { - LOG_ERROR("RTCK not supported. Set nonzero adapter_khz."); + LOG_ERROR("RTCK not supported. Set nonzero \"adapter speed\"."); return ERROR_JTAG_NOT_IMPLEMENTED; } @@ -1653,15 +1649,6 @@ static int cmsis_dap_khz(int khz, int *jtag_speed) return ERROR_OK; } -static int_least32_t cmsis_dap_swd_frequency(int_least32_t hz) -{ - if (hz > 0) - cmsis_dap_speed(hz / 1000); - - return hz; -} - - COMMAND_HANDLER(cmsis_dap_handle_info_command) { if (cmsis_dap_get_version_info() == ERROR_OK) @@ -1790,7 +1777,6 @@ static const struct command_registration cmsis_dap_command_handlers[] = { static const struct swd_driver cmsis_dap_swd_driver = { .init = cmsis_dap_swd_init, - .frequency = cmsis_dap_swd_frequency, .switch_seq = cmsis_dap_swd_switch_seq, .read_reg = cmsis_dap_swd_read_reg, .write_reg = cmsis_dap_swd_write_reg, @@ -1799,17 +1785,23 @@ static const struct swd_driver cmsis_dap_swd_driver = { static const char * const cmsis_dap_transport[] = { "swd", "jtag", NULL }; -struct jtag_interface cmsis_dap_interface = { - .name = "cmsis-dap", +static struct jtag_interface cmsis_dap_interface = { .supported = DEBUG_CAP_TMS_SEQ, - .commands = cmsis_dap_command_handlers, - .swd = &cmsis_dap_swd_driver, + .execute_queue = cmsis_dap_execute_queue, +}; + +struct adapter_driver cmsis_dap_adapter_driver = { + .name = "cmsis-dap", .transports = cmsis_dap_transport, + .commands = cmsis_dap_command_handlers, - .execute_queue = cmsis_dap_execute_queue, - .speed = cmsis_dap_speed, - .speed_div = cmsis_dap_speed_div, - .khz = cmsis_dap_khz, .init = cmsis_dap_init, .quit = cmsis_dap_quit, + .reset = cmsis_dap_reset, + .speed = cmsis_dap_speed, + .khz = cmsis_dap_khz, + .speed_div = cmsis_dap_speed_div, + + .jtag_ops = &cmsis_dap_interface, + .swd_ops = &cmsis_dap_swd_driver, };