command_registration: add empty usage field to chained commands
[openocd.git] / src / jtag / drivers / jlink.c
index 30090582336029d8303f6f8bdba01763e032186f..c81579ab29e9a39242f584f53c020b57aed6ecda 100644 (file)
@@ -314,21 +314,20 @@ static int jlink_execute_queue(void)
 static int jlink_speed(int speed)
 {
        int ret;
-       uint32_t freq;
-       uint16_t divider;
+       struct jaylink_speed tmp;
        int max_speed;
 
        if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {
-               ret = jaylink_get_speeds(devh, &freq, &divider);
+               ret = jaylink_get_speeds(devh, &tmp);
 
                if (ret != JAYLINK_OK) {
                        LOG_ERROR("jaylink_get_speeds() failed: %s.",
-                               jaylink_strerror_name(ret));
+                               jaylink_strerror(ret));
                        return ERROR_JTAG_DEVICE_ERROR;
                }
 
-               freq = freq / 1000;
-               max_speed = freq / divider;
+               tmp.freq /= 1000;
+               max_speed = tmp.freq / tmp.div;
        } else {
                max_speed = JLINK_MAX_SPEED;
        }
@@ -350,7 +349,7 @@ static int jlink_speed(int speed)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_set_speed() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_JTAG_DEVICE_ERROR;
        }
 
@@ -379,7 +378,7 @@ static bool read_device_config(struct device_config *cfg)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_read_raw_config() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return false;
        }
 
@@ -410,7 +409,7 @@ static int select_interface(void)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_get_available_interfaces() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_JTAG_INIT_FAILED;
        }
 
@@ -423,7 +422,7 @@ static int select_interface(void)
 
        if (ret < 0) {
                LOG_ERROR("jaylink_select_interface() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_JTAG_INIT_FAILED;
        }
 
@@ -433,23 +432,23 @@ static int select_interface(void)
 static int jlink_register(void)
 {
        int ret;
-       int i;
+       size_t i;
        bool handle_found;
+       size_t count;
 
        if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER))
                return ERROR_OK;
 
-       ret = jaylink_register(devh, &conn, connlist, NULL, NULL);
+       ret = jaylink_register(devh, &conn, connlist, &count);
 
-       if (ret < 0) {
-               LOG_ERROR("jaylink_register() failed: %s.",
-                       jaylink_strerror_name(ret));
+       if (ret != JAYLINK_OK) {
+               LOG_ERROR("jaylink_register() failed: %s.", jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
        handle_found = false;
 
-       for (i = 0; i < ret; i++) {
+       for (i = 0; i < count; i++) {
                if (connlist[i].handle == conn.handle) {
                        handle_found = true;
                        break;
@@ -482,7 +481,7 @@ static bool adjust_swd_buffer_size(void)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_get_free_memory() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return false;
        }
 
@@ -502,6 +501,39 @@ static bool adjust_swd_buffer_size(void)
        return true;
 }
 
+static int jaylink_log_handler(const struct jaylink_context *ctx,
+               enum jaylink_log_level level, const char *format, va_list args,
+               void *user_data)
+{
+       enum log_levels tmp;
+
+       switch (level) {
+       case JAYLINK_LOG_LEVEL_ERROR:
+               tmp = LOG_LVL_ERROR;
+               break;
+       case JAYLINK_LOG_LEVEL_WARNING:
+               tmp = LOG_LVL_WARNING;
+               break;
+       /*
+        * Forward info messages to the debug output because they are more verbose
+        * than info messages of OpenOCD.
+        */
+       case JAYLINK_LOG_LEVEL_INFO:
+       case JAYLINK_LOG_LEVEL_DEBUG:
+               tmp = LOG_LVL_DEBUG;
+               break;
+       case JAYLINK_LOG_LEVEL_DEBUG_IO:
+               tmp = LOG_LVL_DEBUG_IO;
+               break;
+       default:
+               tmp = LOG_LVL_WARNING;
+       }
+
+       log_vprintf_lf(tmp, __FILE__, __LINE__, __func__, format, args);
+
+       return 0;
+}
+
 static int jlink_init(void)
 {
        int ret;
@@ -514,28 +546,63 @@ static int jlink_init(void)
        struct jaylink_hardware_status hwstatus;
        enum jaylink_usb_address address;
        size_t length;
+       size_t num_devices;
+       uint32_t host_interfaces;
+
+       LOG_DEBUG("Using libjaylink %s (compiled with %s).",
+               jaylink_version_package_get_string(), JAYLINK_VERSION_PACKAGE_STRING);
+
+       if (!jaylink_library_has_cap(JAYLINK_CAP_HIF_USB) && use_usb_address) {
+               LOG_ERROR("J-Link driver does not support USB devices.");
+               return ERROR_JTAG_INIT_FAILED;
+       }
 
        ret = jaylink_init(&jayctx);
 
        if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_init() failed: %s.",
-                       jaylink_strerror_name(ret));
+               LOG_ERROR("jaylink_init() failed: %s.", jaylink_strerror(ret));
                return ERROR_JTAG_INIT_FAILED;
        }
 
-       ret = jaylink_get_device_list(jayctx, &devs);
+       ret = jaylink_log_set_callback(jayctx, &jaylink_log_handler, NULL);
 
-       if (ret < 0) {
-               LOG_ERROR("jaylink_get_device_list() failed: %s.",
-                       jaylink_strerror_name(ret));
+       if (ret != JAYLINK_OK) {
+               LOG_ERROR("jaylink_log_set_callback() failed: %s.",
+                       jaylink_strerror(ret));
                jaylink_exit(jayctx);
                return ERROR_JTAG_INIT_FAILED;
        }
 
-       found_device = false;
+       host_interfaces = JAYLINK_HIF_USB;
+
+       if (use_serial_number)
+               host_interfaces |= JAYLINK_HIF_TCP;
+
+       ret = jaylink_discovery_scan(jayctx, host_interfaces);
+
+       if (ret != JAYLINK_OK) {
+               LOG_ERROR("jaylink_discovery_scan() failed: %s.",
+                       jaylink_strerror(ret));
+               jaylink_exit(jayctx);
+               return ERROR_JTAG_INIT_FAILED;
+       }
 
-       if (!use_serial_number && !use_usb_address)
-               LOG_INFO("No device selected, using first device.");
+       ret = jaylink_get_devices(jayctx, &devs, &num_devices);
+
+       if (ret != JAYLINK_OK) {
+               LOG_ERROR("jaylink_get_devices() failed: %s.", jaylink_strerror(ret));
+               jaylink_exit(jayctx);
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       if (!use_serial_number && !use_usb_address && num_devices > 1) {
+               LOG_ERROR("Multiple devices found, specify the desired device.");
+               jaylink_free_devices(devs, true);
+               jaylink_exit(jayctx);
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       found_device = false;
 
        for (i = 0; devs[i]; i++) {
                if (use_serial_number) {
@@ -545,7 +612,7 @@ static int jlink_init(void)
                                continue;
                        } else if (ret != JAYLINK_OK) {
                                LOG_WARNING("jaylink_device_get_serial_number() failed: %s.",
-                                       jaylink_strerror_name(ret));
+                                       jaylink_strerror(ret));
                                continue;
                        }
 
@@ -556,9 +623,11 @@ static int jlink_init(void)
                if (use_usb_address) {
                        ret = jaylink_device_get_usb_address(devs[i], &address);
 
-                       if (ret != JAYLINK_OK) {
+                       if (ret == JAYLINK_ERR_NOT_SUPPORTED) {
+                               continue;
+                       } else if (ret != JAYLINK_OK) {
                                LOG_WARNING("jaylink_device_get_usb_address() failed: %s.",
-                                       jaylink_strerror_name(ret));
+                                       jaylink_strerror(ret));
                                continue;
                        }
 
@@ -573,10 +642,10 @@ static int jlink_init(void)
                        break;
                }
 
-               LOG_ERROR("Failed to open device: %s.", jaylink_strerror_name(ret));
+               LOG_ERROR("Failed to open device: %s.", jaylink_strerror(ret));
        }
 
-       jaylink_free_device_list(devs, 1);
+       jaylink_free_devices(devs, true);
 
        if (!found_device) {
                LOG_ERROR("No J-Link device found.");
@@ -593,7 +662,7 @@ static int jlink_init(void)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_get_firmware_version() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                jaylink_close(devh);
                jaylink_exit(jayctx);
                return ERROR_JTAG_INIT_FAILED;
@@ -608,7 +677,7 @@ static int jlink_init(void)
        ret = jaylink_get_caps(devh, caps);
 
        if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_get_caps() failed: %s.", jaylink_strerror_name(ret));
+               LOG_ERROR("jaylink_get_caps() failed: %s.", jaylink_strerror(ret));
                jaylink_close(devh);
                jaylink_exit(jayctx);
                return ERROR_JTAG_INIT_FAILED;
@@ -619,21 +688,21 @@ static int jlink_init(void)
 
                if (ret != JAYLINK_OK) {
                        LOG_ERROR("jaylink_get_extended_caps() failed:  %s.",
-                               jaylink_strerror_name(ret));
+                               jaylink_strerror(ret));
                        jaylink_close(devh);
                        jaylink_exit(jayctx);
                        return ERROR_JTAG_INIT_FAILED;
                }
        }
 
-       jtag_command_version = JAYLINK_JTAG_V2;
+       jtag_command_version = JAYLINK_JTAG_VERSION_2;
 
        if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_HW_VERSION)) {
                ret = jaylink_get_hardware_version(devh, &hwver);
 
                if (ret != JAYLINK_OK) {
                        LOG_ERROR("Failed to retrieve hardware version: %s.",
-                               jaylink_strerror_name(ret));
+                               jaylink_strerror(ret));
                        jaylink_close(devh);
                        jaylink_exit(jayctx);
                        return ERROR_JTAG_INIT_FAILED;
@@ -642,7 +711,7 @@ static int jlink_init(void)
                LOG_INFO("Hardware version: %u.%02u", hwver.major, hwver.minor);
 
                if (hwver.major >= 5)
-                       jtag_command_version = JAYLINK_JTAG_V3;
+                       jtag_command_version = JAYLINK_JTAG_VERSION_3;
        }
 
        if (iface == JAYLINK_TIF_SWD) {
@@ -674,7 +743,7 @@ static int jlink_init(void)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_get_hardware_status() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                jaylink_close(devh);
                jaylink_exit(jayctx);
                return ERROR_JTAG_INIT_FAILED;
@@ -685,7 +754,7 @@ static int jlink_init(void)
 
        conn.handle = 0;
        conn.pid = 0;
-       conn.hid = 0;
+       strcpy(conn.hid, "0.0.0.0");
        conn.iid = 0;
        conn.cid = 0;
 
@@ -729,21 +798,21 @@ static int jlink_init(void)
 static int jlink_quit(void)
 {
        int ret;
+       size_t count;
 
        if (trace_enabled) {
                ret = jaylink_swo_stop(devh);
 
                if (ret != JAYLINK_OK)
-                       LOG_ERROR("jaylink_swo_stop() failed: %s.",
-                               jaylink_strerror_name(ret));
+                       LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror(ret));
        }
 
        if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) {
-               ret = jaylink_unregister(devh, &conn, connlist, NULL, NULL);
+               ret = jaylink_unregister(devh, &conn, connlist, &count);
 
-               if (ret < 0)
+               if (ret != JAYLINK_OK)
                        LOG_ERROR("jaylink_unregister() failed: %s.",
-                               jaylink_strerror_name(ret));
+                               jaylink_strerror(ret));
        }
 
        jaylink_close(devh);
@@ -878,14 +947,22 @@ COMMAND_HANDLER(jlink_usb_command)
 
 COMMAND_HANDLER(jlink_serial_command)
 {
+       int ret;
+
        if (CMD_ARGC != 1) {
                command_print(CMD_CTX, "Need exactly one argument for jlink serial.");
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       if (sscanf(CMD_ARGV[0], "%" SCNd32, &serial_number) != 1) {
+       ret = jaylink_parse_serial_number(CMD_ARGV[0], &serial_number);
+
+       if (ret == JAYLINK_ERR) {
                command_print(CMD_CTX, "Invalid serial number: %s.", CMD_ARGV[0]);
                return ERROR_FAIL;
+       } else if (ret != JAYLINK_OK) {
+               command_print(CMD_CTX, "jaylink_parse_serial_number() failed: %s.",
+                       jaylink_strerror(ret));
+               return ERROR_FAIL;
        }
 
        use_serial_number = true;
@@ -903,7 +980,7 @@ COMMAND_HANDLER(jlink_handle_hwstatus_command)
 
        if (ret != JAYLINK_OK) {
                command_print(CMD_CTX, "jaylink_get_hardware_status() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -935,7 +1012,7 @@ COMMAND_HANDLER(jlink_handle_free_memory_command)
 
        if (ret != JAYLINK_OK) {
                command_print(CMD_CTX, "jaylink_get_free_memory() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -951,10 +1028,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
 
        if (!CMD_ARGC) {
                switch (jtag_command_version) {
-                       case JAYLINK_JTAG_V2:
+                       case JAYLINK_JTAG_VERSION_2:
                                version = 2;
                                break;
-                       case JAYLINK_JTAG_V3:
+                       case JAYLINK_JTAG_VERSION_3:
                                version = 3;
                                break;
                        default:
@@ -970,10 +1047,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
 
                switch (tmp) {
                        case 2:
-                               jtag_command_version = JAYLINK_JTAG_V2;
+                               jtag_command_version = JAYLINK_JTAG_VERSION_2;
                                break;
                        case 3:
-                               jtag_command_version = JAYLINK_JTAG_V3;
+                               jtag_command_version = JAYLINK_JTAG_VERSION_3;
                                break;
                        default:
                                command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]);
@@ -1017,7 +1094,7 @@ COMMAND_HANDLER(jlink_handle_target_power_command)
 
        if (ret != JAYLINK_OK) {
                command_print(CMD_CTX, "jaylink_set_target_power() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -1123,7 +1200,7 @@ static int poll_trace(uint8_t *buf, size_t *size)
        ret = jaylink_swo_read(devh, buf, &length);
 
        if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_swo_read() failed: %s.", jaylink_strerror_name(ret));
+               LOG_ERROR("jaylink_swo_read() failed: %s.", jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -1144,7 +1221,7 @@ static uint32_t calculate_trace_buffer_size(void)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_get_free_memory() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -1186,7 +1263,7 @@ static bool check_trace_freq(struct jaylink_swo_speed speed,
        return false;
 }
 
-static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
+static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
                uint32_t port_size, unsigned int *trace_freq)
 {
        int ret;
@@ -1198,7 +1275,7 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
                return ERROR_FAIL;
        }
 
-       if (pin_protocol != ASYNC_UART) {
+       if (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) {
                LOG_ERROR("Selected pin protocol is not supported.");
                return ERROR_FAIL;
        }
@@ -1208,7 +1285,7 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
        ret = jaylink_swo_stop(devh);
 
        if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror_name(ret));
+               LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -1234,7 +1311,7 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_swo_get_speeds() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -1250,8 +1327,7 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
                buffer_size);
 
        if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_start_swo() failed: %s.",
-                       jaylink_strerror_name(ret));
+               LOG_ERROR("jaylink_start_swo() failed: %s.", jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -1510,7 +1586,7 @@ COMMAND_HANDLER(jlink_handle_config_write_command)
 
        if (ret != JAYLINK_OK) {
                LOG_ERROR("jaylink_write_raw_config() failed: %s.",
-                       jaylink_strerror_name(ret));
+                       jaylink_strerror(ret));
                return ERROR_FAIL;
        }
 
@@ -1545,6 +1621,123 @@ COMMAND_HANDLER(jlink_handle_config_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(jlink_handle_emucom_write_command)
+{
+       int ret;
+       size_t tmp;
+       uint32_t channel;
+       uint32_t length;
+       uint8_t *buf;
+       size_t dummy;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
+               LOG_ERROR("Device does not support EMUCOM.");
+               return ERROR_FAIL;
+       }
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
+
+       tmp = strlen(CMD_ARGV[1]);
+
+       if (tmp % 2 != 0) {
+               LOG_ERROR("Data must be encoded as hexadecimal pairs.");
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+       }
+
+       buf = malloc(tmp / 2);
+
+       if (!buf) {
+               LOG_ERROR("Failed to allocate buffer.");
+               return ERROR_FAIL;
+       }
+
+       dummy = unhexify(buf, CMD_ARGV[1], tmp / 2);
+
+       if (dummy != (tmp / 2)) {
+               LOG_ERROR("Data must be encoded as hexadecimal pairs.");
+               free(buf);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+       }
+
+       length = tmp / 2;
+       ret = jaylink_emucom_write(devh, channel, buf, &length);
+
+       free(buf);
+
+       if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
+               LOG_ERROR("Channel not supported by the device.");
+               return ERROR_FAIL;
+       } else if (ret != JAYLINK_OK) {
+               LOG_ERROR("Failed to write to channel: %s.", jaylink_strerror(ret));
+               return ERROR_FAIL;
+       }
+
+       if (length != (tmp / 2))
+               LOG_WARNING("Only %" PRIu32 " bytes written to the channel.", length);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(jlink_handle_emucom_read_command)
+{
+       int ret;
+       uint32_t channel;
+       uint32_t length;
+       uint8_t *buf;
+       size_t tmp;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
+               LOG_ERROR("Device does not support EMUCOM.");
+               return ERROR_FAIL;
+       }
+
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
+
+       buf = malloc(length * 3 + 1);
+
+       if (!buf) {
+               LOG_ERROR("Failed to allocate buffer.");
+               return ERROR_FAIL;
+       }
+
+       ret = jaylink_emucom_read(devh, channel, buf, &length);
+
+       if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
+               LOG_ERROR("Channel is not supported by the device.");
+               free(buf);
+               return ERROR_FAIL;
+       } else if (ret == JAYLINK_ERR_DEV_NOT_AVAILABLE) {
+               LOG_ERROR("Channel is not available for the requested amount of data. "
+                       "%" PRIu32 " bytes are avilable.", length);
+               free(buf);
+               return ERROR_FAIL;
+       } else if (ret != JAYLINK_OK) {
+               LOG_ERROR("Failed to read from channel: %s.", jaylink_strerror(ret));
+               free(buf);
+               return ERROR_FAIL;
+       }
+
+       tmp = hexify((char *)buf + length, buf, length, 2 * length + 1);
+
+       if (tmp != 2 * length) {
+               LOG_ERROR("Failed to convert data into hexadecimal string.");
+               free(buf);
+               return ERROR_FAIL;
+       }
+
+       command_print(CMD_CTX, "%s", buf + length);
+       free(buf);
+
+       return ERROR_OK;
+}
+
 static const struct command_registration jlink_config_subcommand_handlers[] = {
        {
                .name = "usb",
@@ -1590,6 +1783,24 @@ static const struct command_registration jlink_config_subcommand_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
+static const struct command_registration jlink_emucom_subcommand_handlers[] = {
+       {
+               .name = "write",
+               .handler = &jlink_handle_emucom_write_command,
+               .mode = COMMAND_EXEC,
+               .help = "write to a channel",
+               .usage = "<channel> <data>",
+       },
+       {
+               .name = "read",
+               .handler = &jlink_handle_emucom_read_command,
+               .mode = COMMAND_EXEC,
+               .help = "read from a channel",
+               .usage = "<channel> <length>"
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
 static const struct command_registration jlink_subcommand_handlers[] = {
        {
                .name = "jtag",
@@ -1638,6 +1849,14 @@ static const struct command_registration jlink_subcommand_handlers[] = {
                .help = "access the device configuration. If no argument is given "
                        "this will show the device configuration",
                .chain = jlink_config_subcommand_handlers,
+               .usage = "[<cmd>]",
+       },
+       {
+               .name = "emucom",
+               .mode = COMMAND_EXEC,
+               .help = "access EMUCOM channel",
+               .chain = jlink_emucom_subcommand_handlers,
+               .usage = "",
        },
        COMMAND_REGISTRATION_DONE
 };
@@ -1648,6 +1867,7 @@ static const struct command_registration jlink_command_handlers[] = {
                .mode = COMMAND_ANY,
                .help = "perform jlink management",
                .chain = jlink_subcommand_handlers,
+               .usage = "",
        },
        COMMAND_REGISTRATION_DONE
 };
@@ -1769,7 +1989,7 @@ static int jlink_flush(void)
                tap_length, jtag_command_version);
 
        if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_jtag_io() failed: %s.", jaylink_strerror_name(ret));
+               LOG_ERROR("jaylink_jtag_io() failed: %s.", jaylink_strerror(ret));
                jlink_tap_init();
                return ERROR_JTAG_QUEUE_FAILED;
        }
@@ -1875,7 +2095,7 @@ static int jlink_swd_run_queue(void)
        ret = jaylink_swd_io(devh, tms_buffer, tdi_buffer, tdo_buffer, tap_length);
 
        if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_swd_io() failed: %s.", jaylink_strerror_name(ret));
+               LOG_ERROR("jaylink_swd_io() failed: %s.", jaylink_strerror(ret));
                goto skip;
        }
 
@@ -1913,7 +2133,7 @@ skip:
 static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
 {
        uint8_t data_parity_trn[DIV_ROUND_UP(32 + 1, 8)];
-       if (tap_length + 46 + 8 + ap_delay_clk >= sizeof(tdi_buffer) * 8 ||
+       if (tap_length + 46 + 8 + ap_delay_clk >= swd_buffer_size * 8 ||
            pending_scan_results_length == MAX_PENDING_SCAN_RESULTS) {
                /* Not enough room in the queue. Run the queue. */
                queued_retval = jlink_swd_run_queue();

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)