You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(57) |
Oct
|
Nov
|
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(14) |
Nov
(36) |
Dec
(7) |
| 2007 |
Jan
(48) |
Feb
(10) |
Mar
(17) |
Apr
(8) |
May
(35) |
Jun
(28) |
Jul
(50) |
Aug
(71) |
Sep
(40) |
Oct
(19) |
Nov
(22) |
Dec
(143) |
| 2008 |
Jan
(184) |
Feb
(549) |
Mar
(381) |
Apr
(388) |
May
(148) |
Jun
(128) |
Jul
(502) |
Aug
(243) |
Sep
(136) |
Oct
(327) |
Nov
(252) |
Dec
(475) |
| 2009 |
Jan
(344) |
Feb
(185) |
Mar
(338) |
Apr
(826) |
May
(1559) |
Jun
(1429) |
Jul
(817) |
Aug
(451) |
Sep
(639) |
Oct
(935) |
Nov
(1222) |
Dec
(826) |
| 2010 |
Jan
(552) |
Feb
(532) |
Mar
(355) |
Apr
(206) |
May
(162) |
Jun
(203) |
Jul
(168) |
Aug
(232) |
Sep
(270) |
Oct
(259) |
Nov
(439) |
Dec
(468) |
| 2011 |
Jan
(224) |
Feb
(249) |
Mar
(278) |
Apr
(381) |
May
(316) |
Jun
(637) |
Jul
(544) |
Aug
(465) |
Sep
(159) |
Oct
(440) |
Nov
(139) |
Dec
|
| 2012 |
Jan
(204) |
Feb
(383) |
Mar
(295) |
Apr
(196) |
May
(590) |
Jun
(158) |
Jul
(167) |
Aug
(177) |
Sep
(179) |
Oct
(301) |
Nov
(144) |
Dec
(173) |
| 2013 |
Jan
(299) |
Feb
(120) |
Mar
(238) |
Apr
(140) |
May
(69) |
Jun
(133) |
Jul
(160) |
Aug
(107) |
Sep
(164) |
Oct
(196) |
Nov
(105) |
Dec
(74) |
| 2014 |
Jan
(205) |
Feb
(156) |
Mar
(175) |
Apr
(181) |
May
(162) |
Jun
(158) |
Jul
(117) |
Aug
(109) |
Sep
(148) |
Oct
(106) |
Nov
(82) |
Dec
(72) |
| 2015 |
Jan
(191) |
Feb
(205) |
Mar
(197) |
Apr
(163) |
May
(136) |
Jun
(36) |
Jul
(79) |
Aug
(55) |
Sep
(64) |
Oct
(146) |
Nov
(142) |
Dec
(78) |
| 2016 |
Jan
(65) |
Feb
(190) |
Mar
(53) |
Apr
(38) |
May
(95) |
Jun
(53) |
Jul
(58) |
Aug
(113) |
Sep
(96) |
Oct
(59) |
Nov
(136) |
Dec
(124) |
| 2017 |
Jan
(80) |
Feb
(109) |
Mar
(163) |
Apr
(78) |
May
(61) |
Jun
(73) |
Jul
(29) |
Aug
(47) |
Sep
(60) |
Oct
(76) |
Nov
(48) |
Dec
(35) |
| 2018 |
Jan
(138) |
Feb
(84) |
Mar
(109) |
Apr
(49) |
May
(24) |
Jun
(62) |
Jul
(96) |
Aug
(116) |
Sep
(53) |
Oct
(99) |
Nov
(80) |
Dec
(88) |
| 2019 |
Jan
(100) |
Feb
(141) |
Mar
(72) |
Apr
(174) |
May
(129) |
Jun
(102) |
Jul
(52) |
Aug
(45) |
Sep
(28) |
Oct
(43) |
Nov
(78) |
Dec
(47) |
| 2020 |
Jan
(113) |
Feb
(72) |
Mar
(94) |
Apr
(141) |
May
(82) |
Jun
(68) |
Jul
(125) |
Aug
(76) |
Sep
(33) |
Oct
(184) |
Nov
(61) |
Dec
(95) |
| 2021 |
Jan
(109) |
Feb
(77) |
Mar
(145) |
Apr
(116) |
May
(134) |
Jun
(113) |
Jul
(71) |
Aug
(118) |
Sep
(116) |
Oct
(92) |
Nov
(124) |
Dec
(68) |
| 2022 |
Jan
(57) |
Feb
(61) |
Mar
(57) |
Apr
(74) |
May
(86) |
Jun
(80) |
Jul
(43) |
Aug
(85) |
Sep
(120) |
Oct
(88) |
Nov
(100) |
Dec
(108) |
| 2023 |
Jan
(39) |
Feb
(56) |
Mar
(92) |
Apr
(81) |
May
(84) |
Jun
(72) |
Jul
(182) |
Aug
(82) |
Sep
(54) |
Oct
(68) |
Nov
(67) |
Dec
(75) |
| 2024 |
Jan
(79) |
Feb
(65) |
Mar
(42) |
Apr
(47) |
May
(68) |
Jun
(111) |
Jul
(43) |
Aug
(73) |
Sep
(100) |
Oct
(35) |
Nov
(100) |
Dec
(99) |
| 2025 |
Jan
(71) |
Feb
(68) |
Mar
(44) |
Apr
(40) |
May
(92) |
Jun
(45) |
Jul
(86) |
Aug
(60) |
Sep
(76) |
Oct
(69) |
Nov
(102) |
Dec
(43) |
| 2026 |
Jan
(51) |
Feb
(81) |
Mar
(62) |
Apr
(59) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <ge...@op...> - 2026-04-26 10:06:22
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9597 -- gerrit commit 00e2e4f34aa25a1d1444f98ffe5f6ed2cd97669f Author: Marc Schink <de...@za...> Date: Thu Apr 23 22:10:42 2026 +0200 adapter/hla: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'hla_vid_pid' command for backwards compatibility, but mark it as deprecated. Change-Id: Ie3dc8333f5fb863ff68537b803a0b6e96cf35b09 Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index b030d8d212..5b33328525 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3327,10 +3327,6 @@ Currently Not Supported. Specifies the adapter layout to use. @end deffn -@deffn {Config Command} {hla vid_pid} [vid pid]+ -Pairs of vendor IDs and product IDs of the device. -@end deffn - @deffn {Config Command} {hla stlink_backend} (usb | tcp [port]) @emph{ST-Link only:} Choose between 'exclusive' USB communication (the default backend) or 'shared' mode using ST-Link TCP server (the default port is 7184). diff --git a/src/jtag/drivers/nulink_usb.c b/src/jtag/drivers/nulink_usb.c index 66cf25a6d1..df140ba58d 100644 --- a/src/jtag/drivers/nulink_usb.c +++ b/src/jtag/drivers/nulink_usb.c @@ -1030,7 +1030,7 @@ static int nulink_usb_open(struct hl_interface_param *param, void **fd) if (param->transport != HL_TRANSPORT_SWD) return TARGET_UNKNOWN; - if (!param->vid[0] && !param->pid[0]) { + if (!adapter_usb_get_vids()[0] && !adapter_usb_get_pids()[0]) { LOG_ERROR("Missing vid/pid"); return ERROR_FAIL; } @@ -1068,8 +1068,9 @@ static int nulink_usb_open(struct hl_interface_param *param, void **fd) while (cur_dev) { bool found = false; - for (unsigned int i = 0; param->vid[i] || param->pid[i]; i++) { - if (param->vid[i] == cur_dev->vendor_id && param->pid[i] == cur_dev->product_id) { + for (unsigned int i = 0; adapter_usb_get_vids()[i] != 0; i++) { + if (cur_dev->vendor_id == adapter_usb_get_vids()[i] && + cur_dev->product_id == adapter_usb_get_pids()[i]) { found = true; break; } diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index bac9c26cb5..c64e149cbb 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3642,8 +3642,9 @@ static int stlink_tcp_open(void *handle, struct hl_interface_param *param) stlink_used = h->tcp_backend_priv.recv_buf[44]; /* check the vid:pid */ - for (int i = 0; param->vid[i]; i++) { - if (param->vid[i] == h->vid && param->pid[i] == h->pid) { + for (unsigned int i = 0; adapter_usb_get_vids()[i]; i++) { + if (h->vid == adapter_usb_get_vids()[i] && + h->pid == adapter_usb_get_pids()[i]) { stlink_id_matched = true; break; } diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c index 5bac659c48..cd740b296d 100644 --- a/src/jtag/drivers/ti_icdi_usb.c +++ b/src/jtag/drivers/ti_icdi_usb.c @@ -665,13 +665,14 @@ static int icdi_usb_open(struct hl_interface_param *param, void **fd) return ERROR_FAIL; } - for (uint8_t i = 0; param->vid[i] && param->pid[i]; ++i) - LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", param->transport, - param->vid[i], param->pid[i], adapter_get_required_serial() ? adapter_get_required_serial() : ""); + for (unsigned int i = 0; adapter_usb_get_vids()[i]; ++i) + LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", + param->transport, adapter_usb_get_vids()[i], adapter_usb_get_pids()[i], + adapter_get_required_serial() ? adapter_get_required_serial() : ""); /* TI (Stellaris) ICDI provides its serial number in the USB descriptor; no need to provide a callback here. */ - jtag_libusb_open(param->vid, param->pid, NULL, &h->usb_dev, NULL); + jtag_libusb_open(adapter_usb_get_vids(), adapter_usb_get_pids(), NULL, &h->usb_dev, NULL); if (!h->usb_dev) { LOG_ERROR("open failed"); diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index a9d196ccec..9fa1df92ca 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -26,8 +26,6 @@ static struct hl_interface hl_if = { .param = { .device_desc = NULL, - .vid = { 0 }, - .pid = { 0 }, .transport = HL_TRANSPORT_UNKNOWN, .connect_under_reset = false, .use_stlink_tcp = false, @@ -248,33 +246,6 @@ COMMAND_HANDLER(hl_interface_handle_layout_command) return ERROR_FAIL; } -COMMAND_HANDLER(hl_interface_handle_vid_pid_command) -{ - if (CMD_ARGC > HLA_MAX_USB_IDS * 2) { - LOG_WARNING("ignoring extra IDs in hla_vid_pid " - "(maximum is %d pairs)", HLA_MAX_USB_IDS); - CMD_ARGC = HLA_MAX_USB_IDS * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete hla_vid_pid configuration directive"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - unsigned int i; - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], hl_if.param.vid[i / 2]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], hl_if.param.pid[i / 2]); - } - - /* - * Explicitly terminate, in case there are multiple instances of - * hla_vid_pid. - */ - hl_if.param.vid[i / 2] = hl_if.param.pid[i / 2] = 0; - - return ERROR_OK; -} - COMMAND_HANDLER(hl_interface_handle_stlink_backend_command) { /* default values */ @@ -330,13 +301,6 @@ static const struct command_registration hl_interface_subcommand_handlers[] = { .help = "set the layout of the adapter", .usage = "layout_name", }, - { - .name = "vid_pid", - .handler = &hl_interface_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor and product ID of the adapter", - .usage = "(vid pid)*", - }, { .name = "stlink_backend", .handler = &hl_interface_handle_stlink_backend_command, diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h index c0ee05498d..8701c033ab 100644 --- a/src/jtag/hla/hla_interface.h +++ b/src/jtag/hla/hla_interface.h @@ -21,10 +21,6 @@ enum e_hl_transports; struct hl_interface_param { /** */ const char *device_desc; - /** List of recognised VIDs */ - uint16_t vid[HLA_MAX_USB_IDS + 1]; - /** List of recognised PIDs */ - uint16_t pid[HLA_MAX_USB_IDS + 1]; /** */ enum hl_transports transport; /** */ diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index dede6d5018..482eb86da7 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -1174,8 +1174,8 @@ proc "hla_device_desc" {desc} { lappend _telnet_autocomplete_skip "hla_vid_pid" proc "hla_vid_pid" {args} { - echo "DEPRECATED! use 'hla vid_pid', not 'hla_vid_pid'" - eval hla vid_pid $args + echo "DEPRECATED! use 'adapter usb vid_pid', not 'hla_vid_pid'" + eval adapter usb vid_pid $args } lappend _telnet_autocomplete_skip "hla_command" diff --git a/tcl/interface/hpmicro/hpmicro_evk.cfg b/tcl/interface/hpmicro/hpmicro_evk.cfg index 2d8e04fca0..c106505ac4 100644 --- a/tcl/interface/hpmicro/hpmicro_evk.cfg +++ b/tcl/interface/hpmicro/hpmicro_evk.cfg @@ -2,7 +2,7 @@ # Copyright (c) 2021 HPMicro adapter driver ftdi -ftdi_vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi_layout_init 0x0208 0x020b ftdi_layout_signal nTRST -data 0x0200 -noe 0x0400 diff --git a/tcl/interface/nulink.cfg b/tcl/interface/nulink.cfg index be68347e73..86b0a421af 100644 --- a/tcl/interface/nulink.cfg +++ b/tcl/interface/nulink.cfg @@ -7,7 +7,7 @@ adapter driver hla hla layout nulink hla device_desc "Nu-Link" -hla vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201 +adapter usb vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201 # Only swd is supported transport select swd diff --git a/tcl/interface/stlink-hla.cfg b/tcl/interface/stlink-hla.cfg index 5c4adb8973..adbfda8e20 100644 --- a/tcl/interface/stlink-hla.cfg +++ b/tcl/interface/stlink-hla.cfg @@ -11,7 +11,9 @@ echo "Consider updating your ST-Link firmware to a version >= V2J24 (2015)" adapter driver hla hla layout stlink hla device_desc "ST-LINK" -hla vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757 +adapter usb vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d \ + 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 \ + 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757 # Optionally specify the serial number of ST-LINK/V2 usb device. ST-LINK/V2 # devices seem to have serial numbers with unreadable characters. ST-LINK/V2 diff --git a/tcl/interface/ti-icdi.cfg b/tcl/interface/ti-icdi.cfg index c13d27e8b1..fdd879a7e9 100644 --- a/tcl/interface/ti-icdi.cfg +++ b/tcl/interface/ti-icdi.cfg @@ -11,7 +11,7 @@ adapter driver hla hla layout ti-icdi -hla vid_pid 0x1cbe 0x00fd +adapter usb vid_pid 0x1cbe 0x00fd # Optionally specify the serial number of TI-ICDI devices, for when using # multiple devices. Serial numbers can be obtained using lsusb -v -- |
|
From: <ge...@op...> - 2026-04-26 10:06:22
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9598 -- gerrit commit 4a9a6188a57423c16cdafd60f71ffd21dd14627f Author: Marc Schink <de...@za...> Date: Sun Apr 26 10:30:52 2026 +0200 adapter/usb-blaster: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'usb_blaster_vid_pid' command for backwards compatibility, but mark it as deprecated. Change-Id: I3f16e50100c9ce80fa5d06884631fb4575fce465 Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 5b33328525..21ba7c2c98 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2993,22 +2993,25 @@ remote_bitbang host mysocket @deffn {Interface Driver} {usb_blaster} USB JTAG/USB-Blaster compatibles over one of the userspace libraries -for FTDI chips. These interfaces have several commands, used to -configure the driver before initializing the JTAG scan chain: +for FTDI chips. -@deffn {Config Command} {usb_blaster vid_pid} vid pid -The vendor ID and product ID of the FTDI FT245 device. If not specified, -default values are used. -Currently, only one @var{vid}, @var{pid} pair may be given, e.g. for -Altera USB-Blaster (default): +Use @command{adapter usb vid_pid} to specify the vendor and product ID of the +FT256 device. If not specified, default values are used. + +For example, Altera USB-Blaster (default): @example -usb_blaster vid_pid 0x09FB 0x6001 +adapter usb vid_pid 0x09FB 0x6001 @end example The following VID/PID is for Kolja Waschk's USB JTAG: @example -usb_blaster vid_pid 0x16C0 0x06AD +adapter usb vid_pid 0x16C0 0x06AD @end example -@end deffn + +Note that the second VID/PID pair passed to @command{adapter usb vid_pid} is +used to detect uninitialized devices. + +This driver has several commands, used for configuration before initializing the +JTAG scan chain: @deffn {Command} {usb_blaster pin} (@option{pin6}|@option{pin8}) (@option{0}|@option{1}|@option{s}|@option{t}) Sets the state or function of the unused GPIO pins on USB-Blasters diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index 81344664e2..b952732779 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -63,6 +63,7 @@ #endif /* project specific includes */ +#include <jtag/adapter.h> #include <jtag/interface.h> #include <jtag/commands.h> #include <helper/time_support.h> @@ -825,9 +826,9 @@ static int ublast_execute_queue(struct jtag_command *cmd_queue) */ static int ublast_init(void) { - int ret, i; + int ret; - for (i = 0; lowlevel_drivers_map[i].name; i++) { + for (unsigned int i = 0; lowlevel_drivers_map[i].name; i++) { if (info.lowlevel_name) { if (!strcmp(lowlevel_drivers_map[i].name, info.lowlevel_name)) { info.drv = lowlevel_drivers_map[i].drv_register(); @@ -853,6 +854,24 @@ static int ublast_init(void) return ERROR_JTAG_DEVICE_ERROR; } + unsigned int num_vid_pid_pairs = 0; + + for (unsigned int i = 0; adapter_usb_get_vids()[i]; i++) + num_vid_pid_pairs++; + + if (num_vid_pid_pairs > 0) { + info.ublast_vid = adapter_usb_get_vids()[0]; + info.ublast_pid = adapter_usb_get_pids()[0]; + } + + if (num_vid_pid_pairs > 1) { + info.ublast_vid_uninit = adapter_usb_get_vids()[1]; + info.ublast_pid_uninit = adapter_usb_get_pids()[1]; + } + + if (num_vid_pid_pairs > 2) + LOG_WARNING("ignoring extra IDs in adapter usb vid_pid (maximum is 2 pairs)"); + /* * Register the lowlevel driver */ @@ -893,31 +912,6 @@ static int ublast_quit(void) return info.drv->close(info.drv); } -COMMAND_HANDLER(ublast_handle_vid_pid_command) -{ - if (CMD_ARGC > 4) { - LOG_WARNING("ignoring extra IDs in ublast_vid_pid " - "(maximum is 2 pairs)"); - CMD_ARGC = 4; - } - - if (CMD_ARGC >= 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], info.ublast_vid); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], info.ublast_pid); - } else { - LOG_WARNING("incomplete ublast_vid_pid configuration"); - } - - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2], info.ublast_vid_uninit); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], info.ublast_pid_uninit); - } else { - LOG_WARNING("incomplete ublast_vid_pid configuration"); - } - - return ERROR_OK; -} - COMMAND_HANDLER(ublast_handle_pin_command) { uint8_t out_value; @@ -1006,15 +1000,6 @@ COMMAND_HANDLER(ublast_firmware_command) static const struct command_registration ublast_subcommand_handlers[] = { - { - .name = "vid_pid", - .handler = ublast_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the USB-Blaster and " - "vendor ID and product ID of the uninitialized device " - "for USB-Blaster II", - .usage = "vid pid vid_uninit pid_uninit", - }, { .name = "lowlevel_driver", .handler = ublast_handle_lowlevel_drv_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 482eb86da7..247058436a 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -817,8 +817,8 @@ proc usb_blaster_device_desc args { lappend _telnet_autocomplete_skip usb_blaster_vid_pid proc usb_blaster_vid_pid args { - echo "DEPRECATED! use 'usb_blaster vid_pid' not 'usb_blaster_vid_pid'" - eval usb_blaster vid_pid $args + echo "DEPRECATED! use 'adapter usb vid_pid' not 'usb_blaster_vid_pid'" + eval adapter usb vid_pid $args } lappend _telnet_autocomplete_skip usb_blaster_lowlevel_driver diff --git a/tcl/board/altera_sockit.cfg b/tcl/board/altera_sockit.cfg index bbd87d6466..3df6f87429 100644 --- a/tcl/board/altera_sockit.cfg +++ b/tcl/board/altera_sockit.cfg @@ -14,7 +14,7 @@ adapter driver usb_blaster source [find target/altera_fpgasoc.cfg] # If the USB Blaster II were supported, these settings would be needed -#usb_blaster vid_pid 0x09fb 0x6810 +#adapter usb vid_pid 0x09fb 0x6810 #usb_blaster device_desc "USB-Blaster II" adapter speed 100 diff --git a/tcl/interface/altera-usb-blaster.cfg b/tcl/interface/altera-usb-blaster.cfg index cc6057b510..c9a56b268a 100644 --- a/tcl/interface/altera-usb-blaster.cfg +++ b/tcl/interface/altera-usb-blaster.cfg @@ -9,5 +9,5 @@ adapter driver usb_blaster usb_blaster lowlevel_driver ftdi # These are already the defaults. -# usb_blaster vid_pid 0x09FB 0x6001 +# adapter usb vid_pid 0x09FB 0x6001 # usb_blaster device_desc "USB-Blaster" diff --git a/tcl/interface/altera-usb-blaster2.cfg b/tcl/interface/altera-usb-blaster2.cfg index 93f9809b03..95927676bb 100644 --- a/tcl/interface/altera-usb-blaster2.cfg +++ b/tcl/interface/altera-usb-blaster2.cfg @@ -5,6 +5,6 @@ # adapter driver usb_blaster -usb_blaster vid_pid 0x09fb 0x6010 0x09fb 0x6810 +adapter usb vid_pid 0x09fb 0x6010 0x09fb 0x6810 usb_blaster lowlevel_driver ublast2 usb_blaster firmware /path/to/quartus/blaster_6810.hex diff --git a/tcl/interface/usb-jtag.cfg b/tcl/interface/usb-jtag.cfg index 039c748b37..c7f3d60c24 100644 --- a/tcl/interface/usb-jtag.cfg +++ b/tcl/interface/usb-jtag.cfg @@ -32,7 +32,7 @@ # driver but ixo-usb-jtag requires the ftdi driver. adapter driver usb_blaster -usb_blaster vid_pid 0x16C0 0x06AD +adapter usb vid_pid 0x16C0 0x06AD usb_blaster device_desc "Van Ooijen Technische Informatica" # ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the # ftdi modes, using ublast2 will cause openocd to hang. -- |
|
From: <ge...@op...> - 2026-04-26 10:06:15
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9591 -- gerrit commit 39e1e8d55dc3d315e156040ee90e947096888c16 Author: Marc Schink <de...@za...> Date: Thu Apr 23 16:22:13 2026 +0200 adapter/ftdi: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'ftdi_vid_pid' command for backwards compatibility, but mark it as deprecated. Change-Id: Ieb65bc3a76bff3e681325958c0486217a629bfc4 Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index d6225876e6..e7f02c4123 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2761,14 +2761,6 @@ signal. The following output buffer configurations are supported: These interfaces have several commands, used to configure the driver before initializing the JTAG scan chain: -@deffn {Config Command} {ftdi vid_pid} [vid pid]+ -The vendor ID and product ID of the adapter. Up to eight -[@var{vid}, @var{pid}] pairs may be given, e.g. -@example -ftdi vid_pid 0x0403 0xcff8 0x15ba 0x0003 -@end example -@end deffn - @deffn {Config Command} {ftdi device_desc} description Provides the USB device description (the @emph{iProduct string}) of the adapter. If not specified, the device description is ignored diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index c57972ccef..9f32c2ab57 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -128,11 +128,6 @@ static bool oscan1_mode; static bool jscan3_mode; #endif -#define MAX_USB_IDS 8 -/* vid = pid = 0 marks the end of the list */ -static uint16_t ftdi_vid[MAX_USB_IDS + 1] = { 0 }; -static uint16_t ftdi_pid[MAX_USB_IDS + 1] = { 0 }; - static struct mpsse_ctx *mpsse_ctx; struct signal { @@ -734,13 +729,14 @@ static int ftdi_initialize(void) else LOG_DEBUG("ftdi interface using shortest path jtag state transitions"); - if (!ftdi_vid[0] && !ftdi_pid[0]) { - LOG_ERROR("Please specify ftdi vid_pid"); + if (!adapter_usb_get_vids()[0] && !adapter_usb_get_pids()[0]) { + LOG_ERROR("Please specify 'adapter usb vid_pid'"); return ERROR_JTAG_INIT_FAILED; } - mpsse_ctx = mpsse_open(ftdi_vid, ftdi_pid, ftdi_device_desc, - adapter_get_required_serial(), adapter_usb_get_location(), ftdi_channel); + mpsse_ctx = mpsse_open(adapter_usb_get_vids(), adapter_usb_get_pids(), + ftdi_device_desc, adapter_get_required_serial(), + adapter_usb_get_location(), ftdi_channel); if (!mpsse_ctx) return ERROR_JTAG_INIT_FAILED; @@ -1240,36 +1236,6 @@ COMMAND_HANDLER(ftdi_handle_get_signal_command) return ERROR_OK; } -COMMAND_HANDLER(ftdi_handle_vid_pid_command) -{ - if (CMD_ARGC > MAX_USB_IDS * 2) { - LOG_WARNING("ignoring extra IDs in ftdi vid_pid " - "(maximum is %d pairs)", MAX_USB_IDS); - CMD_ARGC = MAX_USB_IDS * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete ftdi vid_pid configuration directive"); - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - /* remove the incomplete trailing id */ - CMD_ARGC -= 1; - } - - unsigned int i; - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], ftdi_vid[i >> 1]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], ftdi_pid[i >> 1]); - } - - /* - * Explicitly terminate, in case there are multiples instances of - * ftdi vid_pid. - */ - ftdi_vid[i >> 1] = ftdi_pid[i >> 1] = 0; - - return ERROR_OK; -} - COMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command) { const struct nvp *n; @@ -1364,13 +1330,6 @@ static const struct command_registration ftdi_subcommand_handlers[] = { .help = "read the value of a layout-specific signal", .usage = "name", }, - { - .name = "vid_pid", - .handler = &ftdi_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the FTDI device", - .usage = "(vid pid)*", - }, { .name = "tdo_sample_edge", .handler = &ftdi_handle_tdo_sample_edge_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 441f2cccb1..03a01e6a2b 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -313,8 +313,8 @@ proc ftdi_get_signal args { lappend _telnet_autocomplete_skip ftdi_vid_pid proc ftdi_vid_pid args { - echo "DEPRECATED! use 'ftdi vid_pid' not 'ftdi_vid_pid'" - eval ftdi vid_pid $args + echo "DEPRECATED! use 'adapter usb vid_pid' not 'ftdi_vid_pid'" + eval adapter usb vid_pid $args } lappend _telnet_autocomplete_skip ftdi_tdo_sample_edge diff --git a/tcl/board/bemicro_cycloneiii.cfg b/tcl/board/bemicro_cycloneiii.cfg index 591a070478..0ae75693b6 100644 --- a/tcl/board/bemicro_cycloneiii.cfg +++ b/tcl/board/bemicro_cycloneiii.cfg @@ -6,7 +6,7 @@ adapter driver ftdi ftdi channel 0 ftdi layout_init 0x0008 0x008b -ftdi vid_pid 0x0403 0xa4a0 +adapter usb vid_pid 0x0403 0xa4a0 reset_config none transport select jtag diff --git a/tcl/board/calao-usb-a9260.cfg b/tcl/board/calao-usb-a9260.cfg index 52fede0fa5..26aa535eea 100644 --- a/tcl/board/calao-usb-a9260.cfg +++ b/tcl/board/calao-usb-a9260.cfg @@ -4,7 +4,7 @@ adapter driver ftdi ftdi device_desc "USB-A9260" -ftdi vid_pid 0x0403 0x6001 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6001 0x0403 0x6010 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/board/calao-usb-a9g20-c01.cfg b/tcl/board/calao-usb-a9g20-c01.cfg index d2017864a9..49d368d8ad 100644 --- a/tcl/board/calao-usb-a9g20-c01.cfg +++ b/tcl/board/calao-usb-a9g20-c01.cfg @@ -5,7 +5,7 @@ adapter driver ftdi ftdi device_desc "USB-A9G20" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/board/certuspro_evaluation.cfg b/tcl/board/certuspro_evaluation.cfg index ba2f17c221..b46695b543 100644 --- a/tcl/board/certuspro_evaluation.cfg +++ b/tcl/board/certuspro_evaluation.cfg @@ -3,7 +3,7 @@ # https://www.latticesemi.com/products/developmentboardsandkits/certuspro-nx-versa-board adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 0 ftdi layout_init 0x0008 0x008b diff --git a/tcl/board/digilent_analog_discovery.cfg b/tcl/board/digilent_analog_discovery.cfg index 1bc239b632..fcad504969 100644 --- a/tcl/board/digilent_analog_discovery.cfg +++ b/tcl/board/digilent_analog_discovery.cfg @@ -11,7 +11,7 @@ adapter driver ftdi ftdi device_desc "Digilent USB Device" -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi layout_init 0x8008 0x800b diff --git a/tcl/board/digilent_anvyl.cfg b/tcl/board/digilent_anvyl.cfg index e820028779..5982ffe78a 100644 --- a/tcl/board/digilent_anvyl.cfg +++ b/tcl/board/digilent_anvyl.cfg @@ -8,7 +8,7 @@ adapter driver ftdi adapter speed 30000 ftdi device_desc "Digilent USB Device" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # channel 0 is the JTAG channel # channel 1 is a user serial channel to pins on the FPGA diff --git a/tcl/board/digilent_cmod_s7.cfg b/tcl/board/digilent_cmod_s7.cfg index b975f9d370..9d94545953 100644 --- a/tcl/board/digilent_cmod_s7.cfg +++ b/tcl/board/digilent_cmod_s7.cfg @@ -7,7 +7,7 @@ adapter driver ftdi ftdi channel 0 ftdi layout_init 0x0008 0x008b -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 reset_config none transport select jtag diff --git a/tcl/board/digilent_nexys_video.cfg b/tcl/board/digilent_nexys_video.cfg index b60ec912fc..50e5292472 100644 --- a/tcl/board/digilent_nexys_video.cfg +++ b/tcl/board/digilent_nexys_video.cfg @@ -7,7 +7,7 @@ adapter driver ftdi adapter speed 30000 ftdi device_desc "Digilent USB Device" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # channel 0 is dedicated for Digilent's DPTI Interface # channel 1 is used for JTAG diff --git a/tcl/board/digilent_zybo.cfg b/tcl/board/digilent_zybo.cfg index 8573399f84..ad27978612 100644 --- a/tcl/board/digilent_zybo.cfg +++ b/tcl/board/digilent_zybo.cfg @@ -10,7 +10,7 @@ adapter driver ftdi ftdi channel 0 #ftdi_device_desc "Digilent Adept USB Device" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x3088 0x1f8b ftdi layout_signal nSRST -data 0x3000 -oe 0x1000 ftdi layout_signal LED -data 0x0010 diff --git a/tcl/board/easydevkits/esp32-wrover-e-ftdi-jtag-devkit.cfg b/tcl/board/easydevkits/esp32-wrover-e-ftdi-jtag-devkit.cfg index 30cfb5797d..57b0852a8a 100644 --- a/tcl/board/easydevkits/esp32-wrover-e-ftdi-jtag-devkit.cfg +++ b/tcl/board/easydevkits/esp32-wrover-e-ftdi-jtag-devkit.cfg @@ -12,7 +12,7 @@ adapter driver ftdi # Identify the device ftdi device_desc "EasyDevKit" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # interface 0 is JTAG; interface 1 is the uart ftdi channel 0 diff --git a/tcl/board/ecp5_evaluation.cfg b/tcl/board/ecp5_evaluation.cfg index 1aafac4944..4e794e26a8 100644 --- a/tcl/board/ecp5_evaluation.cfg +++ b/tcl/board/ecp5_evaluation.cfg @@ -5,7 +5,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 0 ftdi layout_init 0x0008 0x008b diff --git a/tcl/board/gatemate_eval.cfg b/tcl/board/gatemate_eval.cfg index c4d3f3dfda..cbb9ff291e 100644 --- a/tcl/board/gatemate_eval.cfg +++ b/tcl/board/gatemate_eval.cfg @@ -5,7 +5,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 0 ftdi layout_init 0x0014 0x011b diff --git a/tcl/board/gowin_runber.cfg b/tcl/board/gowin_runber.cfg index aaa316f7ad..5e0addf6ad 100644 --- a/tcl/board/gowin_runber.cfg +++ b/tcl/board/gowin_runber.cfg @@ -4,7 +4,7 @@ # https://www.seeedstudio.com/Gowin-RUNBER-Development-Board-p-4779.html adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 0 ftdi layout_init 0x0008 0x008b diff --git a/tcl/board/gumstix-aerocore.cfg b/tcl/board/gumstix-aerocore.cfg index ddadc88c0b..e6591c4192 100644 --- a/tcl/board/gumstix-aerocore.cfg +++ b/tcl/board/gumstix-aerocore.cfg @@ -3,7 +3,7 @@ # JTAG for the STM32F4x chip used on the Gumstix AeroCore is available on # the first interface of a Quad FTDI chip. nTRST is bit 4. adapter driver ftdi -ftdi vid_pid 0x0403 0x6011 +adapter usb vid_pid 0x0403 0x6011 ftdi layout_init 0x0000 0x001b ftdi layout_signal nTRST -data 0x0010 diff --git a/tcl/board/kasli.cfg b/tcl/board/kasli.cfg index d85e1ca152..9256d4b577 100644 --- a/tcl/board/kasli.cfg +++ b/tcl/board/kasli.cfg @@ -2,7 +2,7 @@ adapter driver ftdi ftdi device_desc "Quad RS232-HS" -ftdi vid_pid 0x0403 0x6011 +adapter usb vid_pid 0x0403 0x6011 ftdi channel 0 ftdi layout_init 0x0008 0x000b # adapter usb location 1:8 diff --git a/tcl/board/nds32_corvettef1.cfg b/tcl/board/nds32_corvettef1.cfg index 7300ce04a2..0c2114d9e5 100644 --- a/tcl/board/nds32_corvettef1.cfg +++ b/tcl/board/nds32_corvettef1.cfg @@ -8,7 +8,7 @@ adapter speed 10000 adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/board/numato_mimas_a7.cfg b/tcl/board/numato_mimas_a7.cfg index 82d6a561b2..5f795a1b66 100644 --- a/tcl/board/numato_mimas_a7.cfg +++ b/tcl/board/numato_mimas_a7.cfg @@ -11,7 +11,7 @@ adapter driver ftdi ftdi device_desc "Mimas Artix 7 FPGA Module" -ftdi vid_pid 0x2a19 0x1009 +adapter usb vid_pid 0x2a19 0x1009 # channel 0 is for custom purpose by users (like uart, fifo etc) # channel 1 is reserved for JTAG (by-default) or SPI (possible via changing solder jumpers) diff --git a/tcl/board/quark_d2000_refboard.cfg b/tcl/board/quark_d2000_refboard.cfg index 3af5735a8b..7887d06c1d 100644 --- a/tcl/board/quark_d2000_refboard.cfg +++ b/tcl/board/quark_d2000_refboard.cfg @@ -4,7 +4,7 @@ # the board has an onboard FTDI FT232H chip adapter driver ftdi -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi channel 0 ftdi layout_init 0x0000 0x030b diff --git a/tcl/board/sayma_amc.cfg b/tcl/board/sayma_amc.cfg index b714609221..2323cf72a3 100644 --- a/tcl/board/sayma_amc.cfg +++ b/tcl/board/sayma_amc.cfg @@ -14,7 +14,7 @@ adapter driver ftdi ftdi device_desc "Quad RS232-HS" -ftdi vid_pid 0x0403 0x6011 +adapter usb vid_pid 0x0403 0x6011 ftdi channel 0 # Use this to distinguish multiple boards by topology #adapter usb location 5:1 diff --git a/tcl/board/sifive/hifive1.cfg b/tcl/board/sifive/hifive1.cfg index f69dc4fcc0..07e6541392 100644 --- a/tcl/board/sifive/hifive1.cfg +++ b/tcl/board/sifive/hifive1.cfg @@ -4,7 +4,7 @@ adapter speed 10000 adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0008 0x001b ftdi layout_signal nSRST -oe 0x0020 -data 0x0020 diff --git a/tcl/board/trion_t20_bga256.cfg b/tcl/board/trion_t20_bga256.cfg index 572329ff61..ee6b484cd7 100644 --- a/tcl/board/trion_t20_bga256.cfg +++ b/tcl/board/trion_t20_bga256.cfg @@ -9,7 +9,7 @@ # CRESET_N and SS_N pins in addition to the standard JTAG pins. adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 1 ftdi layout_init 0x0008 0x008b diff --git a/tcl/interface/ftdi/100ask-openjtag.cfg b/tcl/interface/ftdi/100ask-openjtag.cfg index 5ab9252c69..272d602013 100644 --- a/tcl/interface/ftdi/100ask-openjtag.cfg +++ b/tcl/interface/ftdi/100ask-openjtag.cfg @@ -11,7 +11,7 @@ adapter driver ftdi ftdi device_desc "USB<=>JTAG&RS232" -ftdi vid_pid 0x1457 0x5118 +adapter usb vid_pid 0x1457 0x5118 ftdi layout_init 0x0f08 0x0f1b ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/interface/ftdi/ashling-opella-ld-jtag.cfg b/tcl/interface/ftdi/ashling-opella-ld-jtag.cfg index 6256aa0c2b..6ea042777f 100644 --- a/tcl/interface/ftdi/ashling-opella-ld-jtag.cfg +++ b/tcl/interface/ftdi/ashling-opella-ld-jtag.cfg @@ -7,7 +7,7 @@ adapter driver ftdi ftdi device_desc "Opella-LD Debug Probe" -ftdi vid_pid 0x0B6B 0x0040 +adapter usb vid_pid 0x0B6B 0x0040 ftdi tdo_sample_edge falling ftdi layout_init 0x0A68 0xFF7B ftdi channel 0 diff --git a/tcl/interface/ftdi/ashling-opella-ld-swd.cfg b/tcl/interface/ftdi/ashling-opella-ld-swd.cfg index 4a4e4e0680..107e1b146c 100644 --- a/tcl/interface/ftdi/ashling-opella-ld-swd.cfg +++ b/tcl/interface/ftdi/ashling-opella-ld-swd.cfg @@ -7,7 +7,7 @@ adapter driver ftdi ftdi device_desc "Opella-LD Debug Probe" -ftdi vid_pid 0x0B6B 0x0040 +adapter usb vid_pid 0x0B6B 0x0040 ftdi layout_init 0x0860 0x0b7b ftdi channel 0 ftdi layout_signal JTAGOE -data 0x0010 diff --git a/tcl/interface/ftdi/axm0432.cfg b/tcl/interface/ftdi/axm0432.cfg index 50083996c3..590d9f2394 100644 --- a/tcl/interface/ftdi/axm0432.cfg +++ b/tcl/interface/ftdi/axm0432.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "Symphony SoundBite" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0c08 0x0c2b ftdi layout_signal nTRST -data 0x0800 diff --git a/tcl/interface/ftdi/c232hm.cfg b/tcl/interface/ftdi/c232hm.cfg index 23c8f3af23..43340e9b82 100644 --- a/tcl/interface/ftdi/c232hm.cfg +++ b/tcl/interface/ftdi/c232hm.cfg @@ -20,7 +20,7 @@ adapter driver ftdi #ftdi device_desc "C232HM-EDHSL-0" # Common PID for FT232H -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 # Layout # High data byte 0x40 configures red LED on ACBUS6 initially high (unlit, since active-low) diff --git a/tcl/interface/ftdi/cortino.cfg b/tcl/interface/ftdi/cortino.cfg index 8bc8d6e4cc..6e4f6e56e2 100644 --- a/tcl/interface/ftdi/cortino.cfg +++ b/tcl/interface/ftdi/cortino.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Cortino" -ftdi vid_pid 0x0640 0x0032 +adapter usb vid_pid 0x0640 0x0032 ftdi layout_init 0x0108 0x010b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/digilent-hs1.cfg b/tcl/interface/ftdi/digilent-hs1.cfg index 6a632ed268..5a418fd64f 100644 --- a/tcl/interface/ftdi/digilent-hs1.cfg +++ b/tcl/interface/ftdi/digilent-hs1.cfg @@ -5,7 +5,7 @@ adapter driver ftdi ftdi device_desc "Digilent Adept USB Device" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # channel 1 does not have any functionality ftdi channel 0 # just TCK TDI TDO TMS, no reset diff --git a/tcl/interface/ftdi/digilent-hs2.cfg b/tcl/interface/ftdi/digilent-hs2.cfg index 89c9e4b6c4..4652d62e4a 100644 --- a/tcl/interface/ftdi/digilent-hs2.cfg +++ b/tcl/interface/ftdi/digilent-hs2.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Digilent Adept USB Device" -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi channel 0 ftdi layout_init 0x00e8 0x60eb diff --git a/tcl/interface/ftdi/digilent_jtag_hs3.cfg b/tcl/interface/ftdi/digilent_jtag_hs3.cfg index 78a233feb5..fc45650ba1 100644 --- a/tcl/interface/ftdi/digilent_jtag_hs3.cfg +++ b/tcl/interface/ftdi/digilent_jtag_hs3.cfg @@ -5,7 +5,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi device_desc "Digilent USB Device" # From Digilent support: diff --git a/tcl/interface/ftdi/digilent_jtag_smt2.cfg b/tcl/interface/ftdi/digilent_jtag_smt2.cfg index ac623a796d..8c723c060d 100644 --- a/tcl/interface/ftdi/digilent_jtag_smt2.cfg +++ b/tcl/interface/ftdi/digilent_jtag_smt2.cfg @@ -10,7 +10,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi layout_init 0x20e8 0x3feb ftdi layout_signal nSRST -data 0x2000 diff --git a/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg b/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg index 38236bc107..5abd31602e 100644 --- a/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg +++ b/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg @@ -14,7 +14,7 @@ adapter driver ftdi ftdi device_desc "Digilent USB Device" -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi channel 0 ftdi layout_init 0x00e8 0x60eb reset_config none diff --git a/tcl/interface/ftdi/dlp-usb1232h.cfg b/tcl/interface/ftdi/dlp-usb1232h.cfg index 67fee6b0f5..ce855d8b74 100644 --- a/tcl/interface/ftdi/dlp-usb1232h.cfg +++ b/tcl/interface/ftdi/dlp-usb1232h.cfg @@ -16,7 +16,7 @@ echo "mailing list, so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0008 0x000b ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/dp_busblaster.cfg b/tcl/interface/ftdi/dp_busblaster.cfg index 373e122c46..8c6f6c2762 100644 --- a/tcl/interface/ftdi/dp_busblaster.cfg +++ b/tcl/interface/ftdi/dp_busblaster.cfg @@ -15,7 +15,7 @@ and use dp_busblaster_kt-link.cfg instead" adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/interface/ftdi/dp_busblaster_kt-link.cfg b/tcl/interface/ftdi/dp_busblaster_kt-link.cfg index 222ca3810b..20b79a8a0d 100644 --- a/tcl/interface/ftdi/dp_busblaster_kt-link.cfg +++ b/tcl/interface/ftdi/dp_busblaster_kt-link.cfg @@ -13,7 +13,7 @@ adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x8c28 0xff3b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/interface/ftdi/esp32_devkitj_v1.cfg b/tcl/interface/ftdi/esp32_devkitj_v1.cfg index 438d14be23..c3139894fe 100644 --- a/tcl/interface/ftdi/esp32_devkitj_v1.cfg +++ b/tcl/interface/ftdi/esp32_devkitj_v1.cfg @@ -5,7 +5,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6010 0x0403 0x6014 # interface 1 is the uart ftdi channel 0 diff --git a/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg b/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg index c531f3da0c..ae1b20564d 100644 --- a/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg +++ b/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg @@ -8,7 +8,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6010 0x0403 0x6014 # interface 1 is the uart ftdi channel 0 diff --git a/tcl/interface/ftdi/flossjtag-noeeprom.cfg b/tcl/interface/ftdi/flossjtag-noeeprom.cfg index 1008e1ae68..658c0dfd75 100644 --- a/tcl/interface/ftdi/flossjtag-noeeprom.cfg +++ b/tcl/interface/ftdi/flossjtag-noeeprom.cfg @@ -21,7 +21,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0008 0x000b ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/flossjtag.cfg b/tcl/interface/ftdi/flossjtag.cfg index 90ba63a4cd..13c4136385 100644 --- a/tcl/interface/ftdi/flossjtag.cfg +++ b/tcl/interface/ftdi/flossjtag.cfg @@ -20,7 +20,7 @@ echo "Please report your experience with this file to openocd-devel mailing list echo "so it could be marked as working or fixed." adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi device_desc "FLOSS-JTAG" # adapter serial "FJ000001" diff --git a/tcl/interface/ftdi/flyswatter.cfg b/tcl/interface/ftdi/flyswatter.cfg index 8bce00dbbf..9f59542c3b 100644 --- a/tcl/interface/ftdi/flyswatter.cfg +++ b/tcl/interface/ftdi/flyswatter.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Flyswatter" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0818 0x0cfb ftdi layout_signal nTRST -data 0x0010 diff --git a/tcl/interface/ftdi/flyswatter2.cfg b/tcl/interface/ftdi/flyswatter2.cfg index ebc00fe601..4c0a5c3e05 100644 --- a/tcl/interface/ftdi/flyswatter2.cfg +++ b/tcl/interface/ftdi/flyswatter2.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Flyswatter2" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0538 0x057b ftdi layout_signal LED -ndata 0x0400 diff --git a/tcl/interface/ftdi/ft232h-module-swd.cfg b/tcl/interface/ftdi/ft232h-module-swd.cfg index d09ccf16d4..e7fe463a7e 100644 --- a/tcl/interface/ftdi/ft232h-module-swd.cfg +++ b/tcl/interface/ftdi/ft232h-module-swd.cfg @@ -10,7 +10,7 @@ adapter driver ftdi -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 # data MSB..LSB direction (1:out) MSB..LSB # 0000'0000'0011'0000 0000'0000'0011'1011 diff --git a/tcl/interface/ftdi/gw16042.cfg b/tcl/interface/ftdi/gw16042.cfg index 326a88fa02..0e7b097d54 100644 --- a/tcl/interface/ftdi/gw16042.cfg +++ b/tcl/interface/ftdi/gw16042.cfg @@ -21,7 +21,7 @@ adapter driver ftdi ftdi device_desc "USB-JTAG" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0058 0x007b ftdi layout_signal nTRST -data 0x0010 diff --git a/tcl/interface/ftdi/hie-jtag.cfg b/tcl/interface/ftdi/hie-jtag.cfg index 6694df0484..155e041384 100644 --- a/tcl/interface/ftdi/hie-jtag.cfg +++ b/tcl/interface/ftdi/hie-jtag.cfg @@ -7,7 +7,7 @@ adapter driver ftdi ftdi channel 0 -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi device_desc "HIE JTAG Debugger" ftdi layout_init 0x0c08 0x4f1b diff --git a/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg index d5d24e5fc5..17a222b311 100644 --- a/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "NXHX 10-ETM" -ftdi vid_pid 0x0640 0x0028 +adapter usb vid_pid 0x0640 0x0028 ftdi layout_init 0x0308 0x030b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg index 003b9df6b3..5d5c262b41 100644 --- a/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "NXHX 500-ETM" -ftdi vid_pid 0x0640 0x0028 +adapter usb vid_pid 0x0640 0x0028 ftdi layout_init 0x0308 0x030b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/hilscher_nxhx500_re.cfg b/tcl/interface/ftdi/hilscher_nxhx500_re.cfg index 97ad38075d..39afe43f23 100644 --- a/tcl/interface/ftdi/hilscher_nxhx500_re.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx500_re.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "NXHX 500-RE" -ftdi vid_pid 0x0640 0x0028 +adapter usb vid_pid 0x0640 0x0028 ftdi layout_init 0x0308 0x030b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg index 06280c1ffd..0ae7088819 100644 --- a/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "NXHX 50-ETM" -ftdi vid_pid 0x0640 0x0028 +adapter usb vid_pid 0x0640 0x0028 ftdi layout_init 0x0308 0x030b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/hilscher_nxhx50_re.cfg b/tcl/interface/ftdi/hilscher_nxhx50_re.cfg index f14be626b0..fb1bdb2e9e 100644 --- a/tcl/interface/ftdi/hilscher_nxhx50_re.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx50_re.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "NXHX50-RE" -ftdi vid_pid 0x0640 0x0028 +adapter usb vid_pid 0x0640 0x0028 ftdi layout_init 0x0308 0x030b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/hitex_lpc1768stick.cfg b/tcl/interface/ftdi/hitex_lpc1768stick.cfg index 91bd5a8423..3d32201953 100644 --- a/tcl/interface/ftdi/hitex_lpc1768stick.cfg +++ b/tcl/interface/ftdi/hitex_lpc1768stick.cfg @@ -9,7 +9,7 @@ adapter driver ftdi ftdi device_desc "LPC1768-Stick" -ftdi vid_pid 0x0640 0x0026 +adapter usb vid_pid 0x0640 0x0026 ftdi layout_init 0x0388 0x038b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/hitex_str9-comstick.cfg b/tcl/interface/ftdi/hitex_str9-comstick.cfg index f698677a63..bbeefd15c5 100644 --- a/tcl/interface/ftdi/hitex_str9-comstick.cfg +++ b/tcl/interface/ftdi/hitex_str9-comstick.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "STR9-comStick" -ftdi vid_pid 0x0640 0x002c +adapter usb vid_pid 0x0640 0x002c ftdi layout_init 0x0108 0x010b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/icebear.cfg b/tcl/interface/ftdi/icebear.cfg index 4a763994b5..230d8af0ca 100644 --- a/tcl/interface/ftdi/icebear.cfg +++ b/tcl/interface/ftdi/icebear.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "ICEbear JTAG adapter" -ftdi vid_pid 0x0403 0xc140 +adapter usb vid_pid 0x0403 0xc140 ftdi layout_init 0x0028 0x002b ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/imx8mp-evk.cfg b/tcl/interface/ftdi/imx8mp-evk.cfg index 02564dc99e..b53c4b6c09 100644 --- a/tcl/interface/ftdi/imx8mp-evk.cfg +++ b/tcl/interface/ftdi/imx8mp-evk.cfg @@ -13,7 +13,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6011 +adapter usb vid_pid 0x0403 0x6011 ftdi channel 0 ftdi layout_init 0x00f8 0x000b diff --git a/tcl/interface/ftdi/incircuit-icprog.cfg b/tcl/interface/ftdi/incircuit-icprog.cfg index 81f2872205..f46b0a902e 100644 --- a/tcl/interface/ftdi/incircuit-icprog.cfg +++ b/tcl/interface/ftdi/incircuit-icprog.cfg @@ -9,7 +9,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0508 0x0f1b ftdi layout_signal nSRST -noe 0x0400 -data 0x0800 diff --git a/tcl/interface/ftdi/iotlab-usb.cfg b/tcl/interface/ftdi/iotlab-usb.cfg index b7a004e848..c607548678 100644 --- a/tcl/interface/ftdi/iotlab-usb.cfg +++ b/tcl/interface/ftdi/iotlab-usb.cfg @@ -6,7 +6,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0008 0x000b ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/isodebug.cfg b/tcl/interface/ftdi/isodebug.cfg index 0a6e0807ec..4b9a406dde 100644 --- a/tcl/interface/ftdi/isodebug.cfg +++ b/tcl/interface/ftdi/isodebug.cfg @@ -4,7 +4,7 @@ # 5 kV isolated JTAG/SWD + UART adapter by Unjo AB adapter driver ftdi -ftdi vid_pid 0x22b7 0x150d +adapter usb vid_pid 0x22b7 0x150d ftdi layout_init 0x0ff8 0xfffb diff --git a/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg b/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg index ea60dcfc39..74d4f55a9d 100644 --- a/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg +++ b/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "JTAG-lock-pick Tiny 2" -ftdi vid_pid 0x0403 0x8220 +adapter usb vid_pid 0x0403 0x8220 ftdi layout_init 0x8c28 0xff3b ftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000 diff --git a/tcl/interface/ftdi/jtagkey.cfg b/tcl/interface/ftdi/jtagkey.cfg index 1c1c09d3fd..a066cf5e8b 100644 --- a/tcl/interface/ftdi/jtagkey.cfg +++ b/tcl/interface/ftdi/jtagkey.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Amontec JTAGkey" -ftdi vid_pid 0x0403 0xcff8 +adapter usb vid_pid 0x0403 0xcff8 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/interface/ftdi/jtagkey2.cfg b/tcl/interface/ftdi/jtagkey2.cfg index 80df347c38..68a8fe228d 100644 --- a/tcl/interface/ftdi/jtagkey2.cfg +++ b/tcl/interface/ftdi/jtagkey2.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Amontec JTAGkey-2" -ftdi vid_pid 0x0403 0xcff8 +adapter usb vid_pid 0x0403 0xcff8 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/interface/ftdi/jtagkey2p.cfg b/tcl/interface/ftdi/jtagkey2p.cfg index 3a76bd085a..72ab634fb8 100644 --- a/tcl/interface/ftdi/jtagkey2p.cfg +++ b/tcl/interface/ftdi/jtagkey2p.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Amontec JTAGkey-2P" -ftdi vid_pid 0x0403 0xcff8 +adapter usb vid_pid 0x0403 0xcff8 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/interface/ftdi/kt-link.cfg b/tcl/interface/ftdi/kt-link.cfg index 61c6b831b7..60a9bdd9ec 100644 --- a/tcl/interface/ftdi/kt-link.cfg +++ b/tcl/interface/ftdi/kt-link.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "KT-LINK" -ftdi vid_pid 0x0403 0xbbe2 +adapter usb vid_pid 0x0403 0xbbe2 ftdi layout_init 0x8c28 0xff3b ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/interface/ftdi/lambdaconcept_ecpix-5.cfg b/tcl/interface/ftdi/lambdaconcept_ecpix-5.cfg index df4955f8a1..7a79183a27 100644 --- a/tcl/interface/ftdi/lambdaconcept_ecpix-5.cfg +++ b/tcl/interface/ftdi/lambdaconcept_ecpix-5.cfg @@ -8,7 +8,7 @@ adapter driver ftdi adapter speed 10000 ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0xfff8 0xfffb transport select jtag diff --git a/tcl/interface/ftdi/lisa-l.cfg b/tcl/interface/ftdi/lisa-l.cfg index 75c5cbe7fd..e35e8ce09e 100644 --- a/tcl/interface/ftdi/lisa-l.cfg +++ b/tcl/interface/ftdi/lisa-l.cfg @@ -13,7 +13,7 @@ echo "mailing list, so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "Lisa/L" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 1 ftdi layout_init 0x0008 0x180b diff --git a/tcl/interface/ftdi/luminary-icdi.cfg b/tcl/interface/ftdi/luminary-icdi.cfg index 9142503dd0..ffc92b6d95 100644 --- a/tcl/interface/ftdi/luminary-icdi.cfg +++ b/tcl/interface/ftdi/luminary-icdi.cfg @@ -19,7 +19,7 @@ adapter driver ftdi ftdi device_desc "Luminary Micro ICDI Board" -ftdi vid_pid 0x0403 0xbcda +adapter usb vid_pid 0x0403 0xbcda ftdi layout_init 0x00a8 0x00eb ftdi layout_signal nSRST -noe 0x0020 diff --git a/tcl/interface/ftdi/luminary-lm3s811.cfg b/tcl/interface/ftdi/luminary-lm3s811.cfg index 98be166fd6..bf9b2aa64e 100644 --- a/tcl/interface/ftdi/luminary-lm3s811.cfg +++ b/tcl/interface/ftdi/luminary-lm3s811.cfg @@ -15,7 +15,7 @@ adapter driver ftdi ftdi device_desc "LM3S811 Evaluation Board" -ftdi vid_pid 0x0403 0xbcd9 +adapter usb vid_pid 0x0403 0xbcd9 ftdi layout_init 0x0088 0x008b ftdi layout_signal nSRST -data 0x0020 -oe 0x0020 diff --git a/tcl/interface/ftdi/luminary.cfg b/tcl/interface/ftdi/luminary.cfg index 27d9a9da05..f34d74fca3 100644 --- a/tcl/interface/ftdi/luminary.cfg +++ b/tcl/interface/ftdi/luminary.cfg @@ -28,7 +28,7 @@ adapter driver ftdi ftdi device_desc "Stellaris Evaluation Board" -ftdi vid_pid 0x0403 0xbcd9 +adapter usb vid_pid 0x0403 0xbcd9 ftdi layout_init 0x00a8 0x00eb ftdi layout_signal nSRST -noe 0x0020 diff --git a/tcl/interface/ftdi/m53evk.cfg b/tcl/interface/ftdi/m53evk.cfg index 2d9c30448b..409d62ed61 100644 --- a/tcl/interface/ftdi/m53evk.cfg +++ b/tcl/interface/ftdi/m53evk.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 0 ftdi layout_init 0x0008 0x000b diff --git a/tcl/interface/ftdi/mbftdi.cfg b/tcl/interface/ftdi/mbftdi.cfg index 09cec9ffb3..dc9f2ca698 100644 --- a/tcl/interface/ftdi/mbftdi.cfg +++ b/tcl/interface/ftdi/mbftdi.cfg @@ -13,6 +13,6 @@ adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0008 0x000b diff --git a/tcl/interface/ftdi/minimodule-swd.cfg b/tcl/interface/ftdi/minimodule-swd.cfg index 3eb2f53278..8d21503e5a 100644 --- a/tcl/interface/ftdi/minimodule-swd.cfg +++ b/tcl/interface/ftdi/minimodule-swd.cfg @@ -41,11 +41,11 @@ adapter driver ftdi #Select your module type and channel #ftdi device_desc "FT2232H MiniModule" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 #ftdi channel 1 #ftdi device_desc "FT4232H MiniModule" -#ftdi vid_pid 0x0403 0x6011 +#adapter usb vid_pid 0x0403 0x6011 #ftdi channel 1 ftdi layout_init 0x0000 0x000b diff --git a/tcl/interface/ftdi/minimodule.cfg b/tcl/interface/ftdi/minimodule.cfg index 825d7c1dc8..4adad78856 100644 --- a/tcl/interface/ftdi/minimodule.cfg +++ b/tcl/interface/ftdi/minimodule.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "FT2232H MiniModule" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # Every pin set as high impedance except TCK, TDI, TDO and TMS ftdi layout_init 0x0008 0x000b diff --git a/tcl/interface/ftdi/minispartan6.cfg b/tcl/interface/ftdi/minispartan6.cfg index f12bae621c..c22886c141 100644 --- a/tcl/interface/ftdi/minispartan6.cfg +++ b/tcl/interface/ftdi/minispartan6.cfg @@ -6,7 +6,7 @@ adapter driver ftdi # The miniSpartan6+ sadly doesn't have a custom device description, so we just # have to hope you got it right. #ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # interface 1 is the uart ftdi channel 0 # just TCK TDI TDO TMS, no reset diff --git a/tcl/interface/ftdi/miniwiggler.cfg b/tcl/interface/ftdi/miniwiggler.cfg index ebaa97920b..e6d6903cab 100644 --- a/tcl/interface/ftdi/miniwiggler.cfg +++ b/tcl/interface/ftdi/miniwiggler.cfg @@ -26,7 +26,7 @@ adapter driver ftdi ftdi device_desc "DAS JDS miniWiggler V3.1" -ftdi vid_pid 0x058b 0x0043 +adapter usb vid_pid 0x058b 0x0043 ftdi channel 0 ftdi layout_init 0x0008 0x001b diff --git a/tcl/interface/ftdi/neodb.cfg b/tcl/interface/ftdi/neodb.cfg index d3b35412fb..42babc2b9d 100644 --- a/tcl/interface/ftdi/neodb.cfg +++ b/tcl/interface/ftdi/neodb.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Debug Board for Neo1973" -ftdi vid_pid 0x1457 0x5118 +adapter usb vid_pid 0x1457 0x5118 ftdi layout_init 0x0508 0x0f1b ftdi layout_signal nTRST -data 0x0200 -noe 0x0100 diff --git a/tcl/interface/ftdi/ngxtech.cfg b/tcl/interface/ftdi/ngxtech.cfg index 635333fb97..e961defcc2 100644 --- a/tcl/interface/ftdi/ngxtech.cfg +++ b/tcl/interface/ftdi/ngxtech.cfg @@ -14,7 +14,7 @@ echo "as working or fixed." adapter driver ftdi ftdi device_desc "NGX JTAG" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0508 0x0f1b ftdi layout_signal nTRST -data 0x0200 -noe 0x0100 diff --git a/tcl/interface/ftdi/olimex-arm-jtag-cjtag.cfg b/tcl/interface/ftdi/olimex-arm-jtag-cjtag.cfg index 25addb0ca6..abd7d90a34 100644 --- a/tcl/interface/ftdi/olimex-arm-jtag-cjtag.cfg +++ b/tcl/interface/ftdi/olimex-arm-jtag-cjtag.cfg @@ -14,7 +14,7 @@ interface ftdi ftdi oscan1_mode on ftdi device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" -ftdi vid_pid 0x15ba 0x002a +adapter usb vid_pid 0x15ba 0x002a ftdi layout_init 0x0808 0x0a1b ftdi layout_signal nSRST -oe 0x0200 diff --git a/tcl/interface/ftdi/olimex-arm-usb-ocd-h-cjtag.cfg b/tcl/interface/ftdi/olimex-arm-usb-ocd-h-cjtag.cfg index 85d66ef018..bbd7613885 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-ocd-h-cjtag.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-ocd-h-cjtag.cfg @@ -9,7 +9,7 @@ interface ftdi ftdi oscan1_mode on ftdi device_desc "Olimex OpenOCD JTAG ARM-USB-OCD-H" -ftdi vid_pid 0x15ba 0x002b +adapter usb vid_pid 0x15ba 0x002b ftdi layout_init 0x0808 0x0a1b ftdi layout_signal nSRST -oe 0x0200 diff --git a/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg b/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg index cd11ad8e11..a568b8b0b8 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Olimex OpenOCD JTAG ARM-USB-OCD-H" -ftdi vid_pid 0x15ba 0x002b +adapter usb vid_pid 0x15ba 0x002b ftdi layout_init 0x0908 0x0b1b ftdi layout_signal nSRST -oe 0x0200 diff --git a/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg b/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg index d2261e2b77..ba5386af1f 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Olimex OpenOCD JTAG" -ftdi vid_pid 0x15ba 0x0003 +adapter usb vid_pid 0x15ba 0x0003 ftdi layout_init 0x0c08 0x0f1b ftdi layout_signal nSRST -oe 0x0200 diff --git a/tcl/interface/ftdi/olimex-arm-usb-tiny-h-cjtag.cfg b/tcl/interface/ftdi/olimex-arm-usb-tiny-h-cjtag.cfg index ee09e81e2a..bd32b4b48d 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-tiny-h-cjtag.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-tiny-h-cjtag.cfg @@ -14,7 +14,7 @@ interface ftdi ftdi oscan1_mode on ftdi device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" -ftdi vid_pid 0x15ba 0x002a +adapter usb vid_pid 0x15ba 0x002a ftdi layout_init 0x0808 0x0a1b ftdi layout_signal nSRST -oe 0x0200 diff --git a/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg b/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg index a2b3e3edfc..1e43974402 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" -ftdi vid_pid 0x15ba 0x002a +adapter usb vid_pid 0x15ba 0x002a ftdi layout_init 0x0808 0x0a1b ftdi layout_signal nSRST -oe 0x0200 diff --git a/tcl/interface/ftdi/olimex-jtag-tiny.cfg b/tcl/interface/ftdi/olimex-jtag-tiny.cfg index 7d8e81da3c..f3a83c8e3e 100644 --- a/tcl/interface/ftdi/olimex-jtag-tiny.cfg +++ b/tcl/interface/ftdi/olimex-jtag-tiny.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Olimex OpenOCD JTAG TINY" -ftdi vid_pid 0x15ba 0x0004 +adapter usb vid_pid 0x15ba 0x0004 ftdi layout_init 0x0808 0x0a1b ftdi layout_signal nSRST -oe 0x0200 diff --git a/tcl/interface/ftdi/oocdlink.cfg b/tcl/interface/ftdi/oocdlink.cfg index 0e99b67a4d..226567b706 100644 --- a/tcl/interface/ftdi/oocdlink.cfg +++ b/tcl/interface/ftdi/oocdlink.cfg @@ -14,7 +14,7 @@ echo "as working or fixed." adapter driver ftdi ftdi device_desc "OOCDLink" -ftdi vid_pid 0x0403 0xbaf8 +adapter usb vid_pid 0x0403 0xbaf8 ftdi layout_init 0x0508 0x0f1b ftdi layout_signal nTRST -data 0x0200 -noe 0x0100 diff --git a/tcl/interface/ftdi/opendous_ftdi.cfg b/tcl/interface/ftdi/opendous_ftdi.cfg index 5d6f5aee1a..0bd7fdab95 100644 --- a/tcl/interface/ftdi/opendous_ftdi.cfg +++ b/tcl/interface/ftdi/opendous_ftdi.cfg @@ -11,7 +11,7 @@ adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 1 ftdi layout_init 0x0c08 0x0f1b diff --git a/tcl/interface/ftdi/openocd-usb-hs.cfg b/tcl/interface/ftdi/openocd-usb-hs.cfg index af1f61c33d..a270d10fc1 100644 --- a/tcl/interface/ftdi/openocd-usb-hs.cfg +++ b/tcl/interface/ftdi/openocd-usb-hs.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Dual RS232-HS" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0508 0x0f1b ftdi layout_signal nTRST -data 0x0200 -noe 0x0100 diff --git a/tcl/interface/ftdi/openocd-usb.cfg b/tcl/interface/ftdi/openocd-usb.cfg index c333d65ca9..e9dea563c5 100644 --- a/tcl/interface/ftdi/openocd-usb.cfg +++ b/tcl/interface/ftdi/openocd-usb.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Dual RS232" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0508 0x0f1b ftdi layout_signal nTRST -data 0x0200 -noe 0x0100 diff --git a/tcl/interface/ftdi/openrd.cfg b/tcl/interface/ftdi/openrd.cfg index b6b2d1d93e..875ca0a07f 100644 --- a/tcl/interface/ftdi/openrd.cfg +++ b/tcl/interface/ftdi/openrd.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "OpenRD JTAGKey FT2232D B" -ftdi vid_pid 0x0403 0x9e90 +adapter usb vid_pid 0x0403 0x9e90 ftdi channel 0 ftdi layout_init 0x0608 0x0f1b diff --git a/tcl/interface/ftdi/pipistrello.cfg b/tcl/interface/ftdi/pipistrello.cfg index 29ecd12292..2a27f45b2a 100644 --- a/tcl/interface/ftdi/pipistrello.cfg +++ b/tcl/interface/ftdi/pipistrello.cfg @@ -4,7 +4,7 @@ # http://www.saanlima.com/download/pipistrello-v2.0/pipistrello_v2_schematic.pdf adapter driver ftdi ftdi device_desc "Pipistrello LX45" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # interface 1 is the uart ftdi channel 0 # just TCK TDI TDO TMS, no reset diff --git a/tcl/interface/ftdi/pls_spc5.cfg b/tcl/interface/ftdi/pls_spc5.cfg index 3b3c2d6475..09a21ff4dc 100644 --- a/tcl/interface/ftdi/pls_spc5.cfg +++ b/tcl/interface/ftdi/pls_spc5.cfg @@ -28,7 +28,7 @@ adapter driver ftdi ftdi device_desc "PLS USB/JTAG Adapter for SPC5xxx" -ftdi vid_pid 0x263d 0x4001 +adapter usb vid_pid 0x263d 0x4001 ftdi channel 0 ftdi layout_init 0x0008 0x000b diff --git a/tcl/interface/ftdi/redbee-econotag.cfg b/tcl/interface/ftdi/redbee-econotag.cfg index d0d3d833e1..2491ea0eb9 100644 --- a/tcl/interface/ftdi/redbee-econotag.cfg +++ b/tcl/interface/ftdi/redbee-econotag.cfg @@ -16,7 +16,7 @@ echo "Please report your experience with this file to openocd-devel mailing list echo "so it could be marked as working or fixed." adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0c08 0x0c2b ftdi layout_signal nTRST -data 0x0800 diff --git a/tcl/interface/ftdi/redbee-usb.cfg b/tcl/interface/ftdi/redbee-usb.cfg index 98805536d2..880c5d53eb 100644 --- a/tcl/interface/ftdi/redbee-usb.cfg +++ b/tcl/interface/ftdi/redbee-usb.cfg @@ -16,7 +16,7 @@ echo "Please report your experience with this file to openocd-devel mailing list echo "so it could be marked as working or fixed." adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 1 ftdi layout_init 0x0c08 0x0c2b diff --git a/tcl/interface/ftdi/sheevaplug.cfg b/tcl/interface/ftdi/sheevaplug.cfg index 29c8688091..c889a634ea 100644 --- a/tcl/interface/ftdi/sheevaplug.cfg +++ b/tcl/interface/ftdi/sheevaplug.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "SheevaPlug JTAGKey FT2232D B" -ftdi vid_pid 0x9e88 0x9e8f +adapter usb vid_pid 0x9e88 0x9e8f ftdi channel 0 ftdi layout_init 0x0608 0x0f1b diff --git a/tcl/interface/ftdi/signalyzer-lite.cfg b/tcl/interface/ftdi/signalyzer-lite.cfg index e6c3839c98..068de80ef2 100644 --- a/tcl/interface/ftdi/signalyzer-lite.cfg +++ b/tcl/interface/ftdi/signalyzer-lite.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "Signalyzer LITE" -ftdi vid_pid 0x0403 0xbca1 +adapter usb vid_pid 0x0403 0xbca1 ftdi layout_init 0x0008 0x000b ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/signalyzer.cfg b/tcl/interface/ftdi/signalyzer.cfg index fa7a7edc1e..739a5702bf 100644 --- a/tcl/interface/ftdi/signalyzer.cfg +++ b/tcl/interface/ftdi/signalyzer.cfg @@ -13,7 +13,7 @@ echo "so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "Signalyzer" -ftdi vid_pid 0x0403 0xbca0 +adapter usb vid_pid 0x0403 0xbca0 ftdi layout_init 0x0008 0x000b ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/sipeed-rv-debugger.cfg b/tcl/interface/ftdi/sipeed-rv-debugger.cfg index ca65398c6e..ae4ee90bf8 100644 --- a/tcl/interface/ftdi/sipeed-rv-debugger.cfg +++ b/tcl/interface/ftdi/sipeed-rv-debugger.cfg @@ -8,6 +8,6 @@ adapter driver ftdi adapter speed 6000 ftdi device_desc "JTAG Debugger" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0008 0x001b ftdi layout_signal nSRST -oe 0x0020 -data 0x0020 diff --git a/tcl/interface/ftdi/sipeed-usb-jtag-debugger.cfg b/tcl/interface/ftdi/sipeed-usb-jtag-debugger.cfg index 8a804eca67..b13bc0bf67 100644 --- a/tcl/interface/ftdi/sipeed-usb-jtag-debugger.cfg +++ b/tcl/interface/ftdi/sipeed-usb-jtag-debugger.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Dual RS232" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 0 # Every pin set as high impedance except TCK, TDI, TDO, TMS and RST diff --git a/tcl/interface/ftdi/snps_sdp.cfg b/tcl/interface/ftdi/snps_sdp.cfg index eb2aecc87a..242c238c28 100644 --- a/tcl/interface/ftdi/snps_sdp.cfg +++ b/tcl/interface/ftdi/snps_sdp.cfg @@ -11,7 +11,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0088 0x008b ftdi channel 1 diff --git a/tcl/interface/ftdi/steppenprobe.cfg b/tcl/interface/ftdi/steppenprobe.cfg index f84efe61ed..28b302eeb6 100644 --- a/tcl/interface/ftdi/steppenprobe.cfg +++ b/tcl/interface/ftdi/steppenprobe.cfg @@ -6,7 +6,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # Initial Layout ftdi layout_init 0x0058 0x99fb diff --git a/tcl/interface/ftdi/stm32-stick.cfg b/tcl/interface/ftdi/stm32-stick.cfg index 1d72d20e35..af9d2a8a5a 100644 --- a/tcl/interface/ftdi/stm32-stick.cfg +++ b/tcl/interface/ftdi/stm32-stick.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "STM32-PerformanceStick" -ftdi vid_pid 0x0640 0x002d +adapter usb vid_pid 0x0640 0x002d ftdi layout_init 0x0388 0x038b ftdi layout_signal nTRST -data 0x0100 diff --git a/tcl/interface/ftdi/ti-icdi.cfg b/tcl/interface/ftdi/ti-icdi.cfg index 964de76e6a..75b7152aca 100644 --- a/tcl/interface/ftdi/ti-icdi.cfg +++ b/tcl/interface/ftdi/ti-icdi.cfg @@ -9,7 +9,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0451 0xc32a +adapter usb vid_pid 0x0451 0xc32a ftdi layout_init 0x00a8 0x00eb ftdi layout_signal nSRST -noe 0x0020 diff --git a/tcl/interface/ftdi/tigard.cfg b/tcl/interface/ftdi/tigard.cfg index 43ce0ad1d1..f73d26690a 100644 --- a/tcl/interface/ftdi/tigard.cfg +++ b/tcl/interface/ftdi/tigard.cfg @@ -6,7 +6,7 @@ adapter driver ftdi ftdi device_desc "Tigard V1.1" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi channel 1 diff --git a/tcl/interface/ftdi/tumpa-lite.cfg b/tcl/interface/ftdi/tumpa-lite.cfg index e3f12e3b12..1184146dca 100644 --- a/tcl/interface/ftdi/tumpa-lite.cfg +++ b/tcl/interface/ftdi/tumpa-lite.cfg @@ -7,7 +7,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x8a99 +adapter usb vid_pid 0x0403 0x8a99 ftdi layout_init 0x0038 0x087b ftdi layout_signal nTRST -data 0x0020 -oe 0x0020 diff --git a/tcl/interface/ftdi/tumpa.cfg b/tcl/interface/ftdi/tumpa.cfg index db4311bfe1..b28abe3432 100644 --- a/tcl/interface/ftdi/tumpa.cfg +++ b/tcl/interface/ftdi/tumpa.cfg @@ -7,7 +7,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x8a98 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x8a98 0x0403 0x6010 ftdi layout_init 0x0038 0x087b ftdi layout_signal nTRST -data 0x0020 diff --git a/tcl/interface/ftdi/turtelizer2-revB.cfg b/tcl/interface/ftdi/turtelizer2-revB.cfg index f90fc58c1b..574c697411 100644 --- a/tcl/interface/ftdi/turtelizer2-revB.cfg +++ b/tcl/interface/ftdi/turtelizer2-revB.cfg @@ -13,7 +13,7 @@ echo "mailing list, so it could be marked as working or fixed." adapter driver ftdi ftdi device_desc "Turtelizer JTAG/RS232 Adapter" -ftdi vid_pid 0x0403 0xbdc8 +adapter usb vid_pid 0x0403 0xbdc8 ftdi layout_init 0x0008 0x0c5b ftdi layout_signal nSRST -oe 0x0040 diff --git a/tcl/interface/ftdi/turtelizer2-revC.cfg b/tcl/interface/ftdi/turtelizer2-revC.cfg index 94617a1dd1..4afd24cac4 100644 --- a/tcl/interface/ftdi/turtelizer2-revC.cfg +++ b/tcl/interface/ftdi/turtelizer2-revC.cfg @@ -8,7 +8,7 @@ adapter driver ftdi ftdi device_desc "Turtelizer JTAG/RS232 Adapter" -ftdi vid_pid 0x0403 0xbdc8 +adapter usb vid_pid 0x0403 0xbdc8 ftdi layout_init 0x0008 0x0c7b ftdi layout_signal nTRST -oe 0x0020 diff --git a/tcl/interface/ftdi/um232h.cfg b/tcl/interface/ftdi/um232h.cfg index 6be08b59cb..657162c0f4 100644 --- a/tcl/interface/ftdi/um232h.cfg +++ b/tcl/interface/ftdi/um232h.cfg @@ -11,7 +11,7 @@ adapter driver ftdi #ftdi device_desc "UM232H" -ftdi vid_pid 0x0403 0x6014 +adapter usb vid_pid 0x0403 0x6014 ftdi layout_init 0xfff8 0xfffb ftdi layout_signal nTRST -data 0x0100 -oe 0x0100 diff --git a/tcl/interface/ftdi/vpaclink.cfg b/tcl/interface/ftdi/vpaclink.cfg index ff508f2dcd..ed8fbcaa80 100644 --- a/tcl/interface/ftdi/vpaclink.cfg +++ b/tcl/interface/ftdi/vpaclink.cfg @@ -14,7 +14,7 @@ echo "as working or fixed." adapter driver ftdi ftdi device_desc "VPACLink" -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 ftdi layout_init 0x0508 0x0f1b ftdi layout_signal nTRST -data 0x0200 -noe 0x0100 diff --git a/tcl/interface/ftdi/xds100v2.cfg b/tcl/interface/ftdi/xds100v2.cfg index 373df4f49b..eed552a6db 100644 --- a/tcl/interface/ftdi/xds100v2.cfg +++ b/tcl/interface/ftdi/xds100v2.cfg @@ -10,7 +10,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0xa6d0 0x0403 0x6010 +adapter usb vid_pid 0x0403 0xa6d0 0x0403 0x6010 ftdi layout_init 0x0038 0x597b diff --git a/tcl/interface/ftdi/xds100v3.cfg b/tcl/interface/ftdi/xds100v3.cfg index dc722336f1..86852510d2 100644 --- a/tcl/interface/ftdi/xds100v3.cfg +++ b/tcl/interface/ftdi/xds100v3.cfg @@ -10,4 +10,4 @@ source [find interface/ftdi/xds100v2.cfg] # The USB ids are different. -ftdi vid_pid 0x0403 0xa6d1 +adapter usb vid_pid 0x0403 0xa6d1 diff --git a/tcl/interface/ftdi/xt_kc705_ml605.cfg b/tcl/interface/ftdi/xt_kc705_ml605.cfg index dda8c0a2b6..13b0e85c96 100644 --- a/tcl/interface/ftdi/xt_kc705_ml605.cfg +++ b/tcl/interface/ftdi/xt_kc705_ml605.cfg @@ -3,7 +3,7 @@ # adapter driver ftdi -ftdi vid_pid 0x0403 0x6010 +adapter usb vid_pid 0x0403 0x6010 # Specify "adapter serial <identifier>" here as needed ftdi layout_init 0x0010 0x007b diff --git a/tcl/interface/microchip/embedded_flashpro5.cfg b/tcl/interface/microchip/embedded_flashpro5.cfg index 117a54458e..a3adf94746 100644 --- a/tcl/interface/microchip/embedded_flashpro5.cfg +++ b/tcl/interface/microchip/embedded_flashpro5.cfg @@ -10,7 +10,7 @@ adapter driver ftdi # vidpid 1514:2008 = embedded flashpro5 # vidpid 1514:200a = pic64gx -ftdi vid_pid 0x1514 0x2008 0x1514 0x200a +adapter usb vid_pid 0x1514 0x2008 0x1514 0x200a # That FTDI has 4 channels (channel 0 and 1 are MPSSE-capable, 2 and 3 are bitbang ftdi channel 0 -- |
|
From: <ge...@op...> - 2026-04-26 10:06:15
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9596 -- gerrit commit caa8a30dc4cb0017dee6f44af0cf0bafaeeac10c Author: Marc Schink <de...@za...> Date: Thu Apr 23 21:43:55 2026 +0200 adapter/esp-usb-jtag: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'espusbjtag vid_pid' command for backwards compatibility, but mark it as deprecated. Change-Id: Ib02795607ab44d4d4da04068a16eb508892c42ad Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 211d76d8f1..b030d8d212 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3776,13 +3776,6 @@ espusbjtag setio 0 1 0 1 0 @end example @end deffn -@deffn {Config Command} {espusbjtag vid_pid} vid_pid -Set vendor ID and product ID for the ESP usb jtag driver -@example -espusbjtag vid_pid 0x303a 0x1001 -@end example -@end deffn - @deffn {Config Command} {espusbjtag caps_descriptor} caps_descriptor Set the jtag descriptor to read capabilities of ESP usb jtag driver @example diff --git a/src/jtag/drivers/esp_usb_jtag.c b/src/jtag/drivers/esp_usb_jtag.c index a133035110..20794e9ef8 100644 --- a/src/jtag/drivers/esp_usb_jtag.c +++ b/src/jtag/drivers/esp_usb_jtag.c @@ -218,8 +218,6 @@ struct esp_usb_jtag { static struct esp_usb_jtag esp_usb_jtag_priv; static struct esp_usb_jtag *priv = &esp_usb_jtag_priv; -static int esp_usb_vid; -static int esp_usb_pid; static int esp_usb_jtag_caps; static int esp_usb_target_chip_id; @@ -476,9 +474,6 @@ static int esp_usb_jtag_init(void) { memset(priv, 0, sizeof(struct esp_usb_jtag)); - const uint16_t vids[] = { esp_usb_vid, 0 }; /* must be null terminated */ - const uint16_t pids[] = { esp_usb_pid, 0 }; /* must be null terminated */ - bitq_interface = &priv->bitq_interface; bitq_interface->out = esp_usb_jtag_out; bitq_interface->flush = esp_usb_jtag_flush; @@ -487,7 +482,8 @@ static int esp_usb_jtag_init(void) bitq_interface->in_rdy = esp_usb_jtag_in_rdy; bitq_interface->in = esp_usb_jtag_in; - int r = jtag_libusb_open(vids, pids, NULL, &priv->usb_device, NULL); + int r = jtag_libusb_open(adapter_usb_get_vids(), adapter_usb_get_pids(), + NULL, &priv->usb_device, NULL); if (r != ERROR_OK) { LOG_ERROR("esp_usb_jtag: could not find or open device!"); goto out; @@ -693,18 +689,6 @@ COMMAND_HANDLER(esp_usb_jtag_setio_cmd) return ERROR_OK; } -COMMAND_HANDLER(esp_usb_jtag_vid_pid) -{ - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_vid); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], esp_usb_pid); - LOG_INFO("esp_usb_jtag: VID set to 0x%x and PID to 0x%x", esp_usb_vid, esp_usb_pid); - - return ERROR_OK; -} - COMMAND_HANDLER(esp_usb_jtag_caps_descriptor) { if (CMD_ARGC != 1) @@ -742,13 +726,6 @@ static const struct command_registration esp_usb_jtag_subcommands[] = { .help = "Manually set the status of the output lines", .usage = "tdi tms tck trst srst" }, - { - .name = "vid_pid", - .handler = &esp_usb_jtag_vid_pid, - .mode = COMMAND_CONFIG, - .help = "set vendor ID and product ID for ESP usb jtag driver", - .usage = "vid pid", - }, { .name = "caps_descriptor", .handler = &esp_usb_jtag_caps_descriptor, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 24a5bdda78..dede6d5018 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -241,6 +241,13 @@ proc interface_list args { eval adapter list $args } +lappend _telnet_autocomplete_skip "espusbjtag vid_pid" +proc "espusbjtag vid_pid" args { + echo "DEPRECATED! use 'adapter usb vid_pid' not 'espusbjtag vid_pid'" + eval adapter usb vid_pid $args +} + + lappend _telnet_autocomplete_skip ftdi_location proc ftdi_location args { echo "DEPRECATED! use 'adapter usb location' not 'ftdi_location'" diff --git a/tcl/interface/esp_usb_bridge.cfg b/tcl/interface/esp_usb_bridge.cfg index 9342239e77..9354855bad 100644 --- a/tcl/interface/esp_usb_bridge.cfg +++ b/tcl/interface/esp_usb_bridge.cfg @@ -5,5 +5,5 @@ adapter driver esp_usb_jtag -espusbjtag vid_pid 0x303a 0x1002 +adapter usb vid_pid 0x303a 0x1002 espusbjtag caps_descriptor 0x030A # string descriptor index:10 diff --git a/tcl/interface/esp_usb_jtag.cfg b/tcl/interface/esp_usb_jtag.cfg index 583a92d6a6..eff1224a85 100644 --- a/tcl/interface/esp_usb_jtag.cfg +++ b/tcl/interface/esp_usb_jtag.cfg @@ -5,7 +5,7 @@ adapter driver esp_usb_jtag -espusbjtag vid_pid 0x303a 0x1001 +adapter usb vid_pid 0x303a 0x1001 espusbjtag caps_descriptor 0x2000 transport select jtag -- |
|
From: <ge...@op...> - 2026-04-26 10:06:13
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9593 -- gerrit commit a5d4f12d1cce220a4c150aaf3527c5e00c16675c Author: Marc Schink <de...@za...> Date: Thu Apr 23 21:10:10 2026 +0200 adapter/ch347: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Change-Id: I3736449fe3ece4bcda458169f6c78c922a31671e Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 5576be4740..ebd31ae685 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2604,15 +2604,6 @@ command @ref{adapter gpio, @command{adapter gpio led}}. This driver has these driver-specific command: -@deffn {Config Command} {ch347 vid_pid} [vid pid]+ -The vendor ID and product ID of the CH347F or CH347T device in mode 3. If not specified -the driver will use vendor ID 0x1a86 and product ID 0x55dd. -Currently, up to four [@var{vid}, @var{pid}] pairs may be given, e.g. -@example -ch347 vid_pid 0x1a86 0x55dd 0x1a86 0x55de -@end example -@end deffn - @deffn {Config Command} {ch347 device_desc} description If specified connect to a device which exactly has this product description string. If not specified the first found device with the correct vendor diff --git a/src/jtag/drivers/ch347.c b/src/jtag/drivers/ch347.c index c031ceece2..31762eb475 100644 --- a/src/jtag/drivers/ch347.c +++ b/src/jtag/drivers/ch347.c @@ -255,8 +255,6 @@ static bool swd_mode; static uint16_t default_ch347_vids[] = {DEFAULT_VENDOR_ID, DEFAULT_VENDOR_ID, DEFAULT_VENDOR_ID, 0}; static uint16_t default_ch347_pids[] = {DEFAULT_CH347T_PRODUCT_ID, DEFAULT_CH347F_PRODUCT_ID, DEFAULT_OTHER_PRODUCT_ID, 0}; -static uint16_t custom_ch347_vids[] = {0, 0, 0, 0}; -static uint16_t custom_ch347_pids[] = {0, 0, 0, 0}; static char *ch347_device_desc; static uint8_t ch347_activity_led_gpio_pin = 0xFF; static bool ch347_activity_led_active_high; @@ -1420,8 +1418,13 @@ static int ch347_execute_queue(struct jtag_command *cmd_queue) */ static int ch347_open_device(void) { - const uint16_t *ch347_vids = custom_ch347_vids[0] != 0 ? custom_ch347_vids : default_ch347_vids; - const uint16_t *ch347_pids = custom_ch347_pids[0] != 0 ? custom_ch347_pids : default_ch347_pids; + const uint16_t *ch347_vids = default_ch347_vids; + const uint16_t *ch347_pids = default_ch347_pids; + + if (adapter_usb_get_vids()[0] != 0) { + ch347_vids = adapter_usb_get_vids(); + ch347_pids = adapter_usb_get_pids(); + } int retval = jtag_libusb_open(ch347_vids, ch347_pids, ch347_device_desc, &ch347_handle, NULL); if (retval != ERROR_OK) { @@ -1773,24 +1776,6 @@ static int ch347_speed_get_index(int khz, int *speed_idx) return ERROR_OK; } -/** - * @brief The command handler for setting the device usb vid/pid - * - * @return ERROR_OK at success; ERROR_COMMAND_SYNTAX_ERROR otherwise - */ -COMMAND_HANDLER(ch347_handle_vid_pid_command) -{ - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - for (int i = 0; i < (int)(MIN(CMD_ARGC, ARRAY_SIZE(custom_ch347_pids))); i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], custom_ch347_vids[i / 2]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], custom_ch347_pids[i / 2]); - } - - return ERROR_OK; -} - /** * @brief The command handler for setting the device description that should be found * @@ -1807,13 +1792,6 @@ COMMAND_HANDLER(ch347_handle_device_desc_command) } static const struct command_registration ch347_subcommand_handlers[] = { - { - .name = "vid_pid", - .handler = &ch347_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the CH347 device", - .usage = "(vid pid)*", - }, { .name = "device_desc", .handler = &ch347_handle_device_desc_command, diff --git a/tcl/board/easydevkits/esp32-wrover-e-wch-jtag-devkit.cfg b/tcl/board/easydevkits/esp32-wrover-e-wch-jtag-devkit.cfg index 76f1435beb..53a4098f0e 100644 --- a/tcl/board/easydevkits/esp32-wrover-e-wch-jtag-devkit.cfg +++ b/tcl/board/easydevkits/esp32-wrover-e-wch-jtag-devkit.cfg @@ -11,8 +11,8 @@ adapter driver ch347 # Identify the device +adapter usb vid_pid 0x1a86 0x55dd ch347 device_desc "EasyDevKit" -ch347 vid_pid 0x1a86 0x55dd # Configure activity LED # Note: The LED is active-low on GPIO4. -- |
|
From: <ge...@op...> - 2026-04-26 10:06:08
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9592 -- gerrit commit 58865dfac6b5059b231e990b284bdd050dadc991 Author: Marc Schink <de...@za...> Date: Thu Apr 23 21:02:28 2026 +0200 adapter/ft232r: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'ft232r_vid_pid' command for backwards compatibility, but mark it as deprecated. Change-Id: I6234207ac3840626954411aa49a9a3bed040323d Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index e7f02c4123..5576be4740 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2911,11 +2911,6 @@ FT232R These interfaces have several commands, used to configure the driver before initializing the JTAG scan chain: -@deffn {Config Command} {ft232r vid_pid} @var{vid} @var{pid} -The vendor ID and product ID of the adapter. If not specified, default -0x0403:0x6001 is used. -@end deffn - @deffn {Config Command} {ft232r jtag_nums} @var{tck} @var{tms} @var{tdi} @var{tdo} Set four JTAG GPIO numbers at once. If not specified, default 0 3 1 2 or TXD CTS RXD RTS is used. diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 5bd934c386..e668909a5f 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -58,8 +58,10 @@ #define FT232R_BUF_SIZE_EXTRA 4096 -static uint16_t ft232r_vid = 0x0403; /* FTDI */ -static uint16_t ft232r_pid = 0x6001; /* FT232R */ +// Default VID/PID pair for FTDI FT232R. +static uint16_t ft232r_vids[] = {0x0403, 0}; +static uint16_t ft232r_pids[] = {0x6001, 0}; + static struct libusb_device_handle *adapter; static uint8_t *ft232r_output; @@ -244,12 +246,24 @@ static int ft232r_speed(int divisor) static int ft232r_init(void) { - uint16_t avids[] = {ft232r_vid, 0}; - uint16_t apids[] = {ft232r_pid, 0}; - if (jtag_libusb_open(avids, apids, NULL, &adapter, NULL)) { + const uint16_t *vids = ft232r_vids; + const uint16_t *pids = ft232r_pids; + + if (adapter_usb_get_vids()[0] != 0) { + vids = adapter_usb_get_vids(); + pids = adapter_usb_get_pids(); + } + + if (jtag_libusb_open(vids, pids, NULL, &adapter, NULL)) { + char usb_vid_pid_str[256] = {0}; + for (unsigned int i = 0; vids[i] != 0; i++) + snprintf(usb_vid_pid_str + strlen(usb_vid_pid_str), + sizeof(usb_vid_pid_str) - strlen(usb_vid_pid_str), + "%04x:%04x ", vids[i], pids[i]); + const char *ft232r_serial_desc = adapter_get_required_serial(); - LOG_ERROR("ft232r not found: vid=%04x, pid=%04x, serial=%s\n", - ft232r_vid, ft232r_pid, (!ft232r_serial_desc) ? "[any]" : ft232r_serial_desc); + LOG_ERROR("ft232r not found: serial=%s, vid/pid=%s\n", + (!ft232r_serial_desc) ? "[any]" : ft232r_serial_desc, usb_vid_pid_str); return ERROR_JTAG_INIT_FAILED; } @@ -385,22 +399,6 @@ static int ft232r_bit_name_to_number(const char *name) return -1; } -COMMAND_HANDLER(ft232r_handle_vid_pid_command) -{ - if (CMD_ARGC > 2) { - LOG_WARNING("ignoring extra IDs in ft232r_vid_pid " - "(maximum is 1 pair)"); - CMD_ARGC = 2; - } - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], ft232r_vid); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], ft232r_pid); - } else - LOG_WARNING("incomplete ft232r_vid_pid configuration"); - - return ERROR_OK; -} - COMMAND_HANDLER(ft232r_handle_jtag_nums_command) { if (CMD_ARGC == 4) { @@ -541,13 +539,6 @@ COMMAND_HANDLER(ft232r_handle_restore_serial_command) } static const struct command_registration ft232r_subcommand_handlers[] = { - { - .name = "vid_pid", - .handler = ft232r_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "USB VID and PID of the adapter", - .usage = "vid pid", - }, { .name = "jtag_nums", .handler = ft232r_handle_jtag_nums_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 03a01e6a2b..8264c0db87 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -840,8 +840,8 @@ proc ft232r_serial_desc args { lappend _telnet_autocomplete_skip ft232r_vid_pid proc ft232r_vid_pid args { - echo "DEPRECATED! use 'ft232r vid_pid' not 'ft232r_vid_pid'" - eval ft232r vid_pid $args + echo "DEPRECATED! use 'adapter usb vid_pid' not 'ft232r_vid_pid'" + eval adapter usb vid_pid $args } lappend _telnet_autocomplete_skip ft232r_jtag_nums diff --git a/tcl/interface/ft232r/radiona_ulx3s.cfg b/tcl/interface/ft232r/radiona_ulx3s.cfg index 3fc3d7105e..54a82f1590 100644 --- a/tcl/interface/ft232r/radiona_ulx3s.cfg +++ b/tcl/interface/ft232r/radiona_ulx3s.cfg @@ -7,7 +7,7 @@ adapter driver ft232r adapter speed 1000 -ft232r vid_pid 0x0403 0x6015 +adapter usb vid_pid 0x0403 0x6015 ft232r tck_num DSR ft232r tms_num DCD ft232r tdi_num RI -- |
|
From: <ge...@op...> - 2026-04-26 10:06:08
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9595 -- gerrit commit e127aa1652b7d02984537cac4de35a076a4be5b9 Author: Marc Schink <de...@za...> Date: Thu Apr 23 21:36:04 2026 +0200 adapter/openjtag: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Change-Id: Ic545de25fd8a48a1b287e7efb43195c4fe8dc40b Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index be54d600e0..211d76d8f1 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3646,15 +3646,6 @@ Currently valid @var{variant} values include: The USB device description string of the adapter. This value is only used with the standard variant. @end deffn - -@deffn {Config Command} {openjtag vid_pid} vid pid -The USB vendor ID and product ID of the adapter. If not specified, default -0x0403:0x6001 is used. -This value is only used with the standard variant. -@example -openjtag vid_pid 0x403 0x6014 -@end example -@end deffn @end deffn diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index fc9507af34..bfa094bd62 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -32,6 +32,7 @@ #include "config.h" #endif +#include <jtag/adapter.h> #include <jtag/interface.h> #include <jtag/commands.h> #include "libusb_helper.h" @@ -74,8 +75,8 @@ enum openjtag_tap_state { #include "libftdi_helper.h" /* OpenJTAG vid/pid */ -static uint16_t openjtag_vid = 0x0403; -static uint16_t openjtag_pid = 0x6001; +static uint16_t openjtag_vids[] = {0x0403, 0}; +static uint16_t openjtag_pids[] = {0x6001, 0}; static char *openjtag_device_desc; @@ -387,10 +388,20 @@ static int openjtag_init_standard(void) if (ftdi_init(&ftdic) < 0) return ERROR_JTAG_INIT_FAILED; - /* context, vendor id, product id, description, serial id */ - if (ftdi_usb_open_desc(&ftdic, openjtag_vid, openjtag_pid, openjtag_device_desc, NULL) < 0) { - LOG_ERROR("unable to open ftdi device: %s", ftdic.error_str); - return ERROR_JTAG_INIT_FAILED; + const uint16_t *vids = openjtag_vids; + const uint16_t *pids = openjtag_pids; + + if (adapter_usb_get_vids()[0] != 0) { + vids = adapter_usb_get_vids(); + pids = adapter_usb_get_pids(); + } + + for (unsigned int i = 0; vids[i] != 0; i++) { + /* context, vendor id, product id, description, serial id */ + if (ftdi_usb_open_desc(&ftdic, vids[i], pids[i], openjtag_device_desc, NULL) < 0) { + LOG_ERROR("unable to open ftdi device: %s", ftdic.error_str); + return ERROR_JTAG_INIT_FAILED; + } } if (ftdi_usb_reset(&ftdic) < 0) { @@ -868,17 +879,6 @@ COMMAND_HANDLER(openjtag_handle_variant_command) return ERROR_OK; } -COMMAND_HANDLER(openjtag_handle_vid_pid_command) -{ - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], openjtag_vid); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], openjtag_pid); - - return ERROR_OK; -} - static const struct command_registration openjtag_subcommand_handlers[] = { { .name = "device_desc", @@ -894,13 +894,6 @@ static const struct command_registration openjtag_subcommand_handlers[] = { .help = "set the OpenJTAG variant", .usage = "variant-string", }, - { - .name = "vid_pid", - .handler = openjtag_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "USB VID and PID of the adapter", - .usage = "vid pid", - }, COMMAND_REGISTRATION_DONE }; -- |
|
From: <ge...@op...> - 2026-04-26 10:06:08
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9594 -- gerrit commit fb530dbb83361a0f093b82007421fe3e26911954 Author: Marc Schink <de...@za...> Date: Thu Apr 23 21:18:30 2026 +0200 adapter/cmsis-dap: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'cmsis_dap_vid_pid' command for backwards compatibility, but mark it as deprecated. Change-Id: I044c8b49a0715408595723d3a8c7a9b6c9318c62 Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index ebd31ae685..be54d600e0 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2618,15 +2618,6 @@ ch347 device_desc "EasyDevKit" ARM CMSIS-DAP compliant based adapter v1 (USB HID based) or v2 (USB bulk or TCP/IP). -@deffn {Config Command} {cmsis-dap vid_pid} [vid pid]+ -The vendor ID and product ID of the CMSIS-DAP device. If not specified -the driver will attempt to auto detect the CMSIS-DAP device. -Currently, up to eight [@var{vid}, @var{pid}] pairs may be given, e.g. -@example -cmsis-dap vid_pid 0xc251 0xf001 0x0d28 0x0204 -@end example -@end deffn - @deffn {Config Command} {cmsis-dap backend} [@option{auto}|@option{usb_bulk}|@option{hid}|@option{tcp}] Specifies how to communicate with the adapter: diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index 9f60a5ede4..759a6738d6 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -78,10 +78,6 @@ static const struct cmsis_dap_backend *const cmsis_dap_backends[] = { * PID 0x0204: MBED CMSIS-DAP */ -#define MAX_USB_IDS 8 -/* vid = pid = 0 marks the end of the list */ -static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 }; -static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 }; static int cmsis_dap_backend = -1; static bool swd_mode; static bool cmsis_dap_quirk_mode; /* enable expensive workarounds */ @@ -283,7 +279,8 @@ static int cmsis_dap_open(void) /* Use forced backend */ backend = cmsis_dap_backends[cmsis_dap_backend]; if (backend->open) - retval = backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()); + retval = backend->open(dap, adapter_usb_get_vids(), + adapter_usb_get_pids(), adapter_get_required_serial()); else LOG_ERROR("Requested CMSIS-DAP backend is disabled by configure"); @@ -294,7 +291,7 @@ static int cmsis_dap_open(void) if (!backend->open) continue; - retval = backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()); + retval = backend->open(dap, adapter_usb_get_vids(), adapter_usb_get_pids(), adapter_get_required_serial()); if (retval == ERROR_OK) break; } @@ -2184,36 +2181,6 @@ COMMAND_HANDLER(cmsis_dap_handle_cmd_command) return ERROR_OK; } -COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command) -{ - if (CMD_ARGC > MAX_USB_IDS * 2) { - LOG_WARNING("ignoring extra IDs in cmsis-dap vid_pid " - "(maximum is %d pairs)", MAX_USB_IDS); - CMD_ARGC = MAX_USB_IDS * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete cmsis-dap vid_pid configuration directive"); - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - /* remove the incomplete trailing id */ - CMD_ARGC -= 1; - } - - unsigned int i; - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], cmsis_dap_vid[i >> 1]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], cmsis_dap_pid[i >> 1]); - } - - /* - * Explicitly terminate, in case there are multiples instances of - * cmsis_dap_vid_pid. - */ - cmsis_dap_vid[i >> 1] = cmsis_dap_pid[i >> 1] = 0; - - return ERROR_OK; -} - COMMAND_HANDLER(cmsis_dap_handle_backend_command) { if (CMD_ARGC != 1) @@ -2272,13 +2239,6 @@ static const struct command_registration cmsis_dap_subcommand_handlers[] = { .usage = "", .help = "issue cmsis-dap command", }, - { - .name = "vid_pid", - .handler = &cmsis_dap_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the CMSIS-DAP device", - .usage = "(vid pid)*", - }, { .name = "backend", .handler = &cmsis_dap_handle_backend_command, diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h index 880fc33502..4272ab4831 100644 --- a/src/jtag/drivers/cmsis_dap.h +++ b/src/jtag/drivers/cmsis_dap.h @@ -65,7 +65,7 @@ enum cmsis_dap_blocking { struct cmsis_dap_backend { const char *name; - int (*open)(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial); + int (*open)(struct cmsis_dap *dap, const uint16_t vids[], const uint16_t pids[], const char *serial); void (*close)(struct cmsis_dap *dap); int (*read)(struct cmsis_dap *dap, int transfer_timeout_ms, enum cmsis_dap_blocking blocking); diff --git a/src/jtag/drivers/cmsis_dap_tcp.c b/src/jtag/drivers/cmsis_dap_tcp.c index 7894550fe2..0c86f94564 100644 --- a/src/jtag/drivers/cmsis_dap_tcp.c +++ b/src/jtag/drivers/cmsis_dap_tcp.c @@ -113,8 +113,8 @@ static int cmsis_dap_tcp_alloc(struct cmsis_dap *dap, unsigned int pkt_sz); static void cmsis_dap_tcp_free(struct cmsis_dap *dap); static int cmsis_dap_tcp_open(struct cmsis_dap *dap, - uint16_t vids[] __attribute__((unused)), - uint16_t pids[] __attribute__((unused)), + const uint16_t vids[] __attribute__((unused)), + const uint16_t pids[] __attribute__((unused)), const char *serial __attribute__((unused))) { // Skip the open if the user has not provided a hostname. diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c index d34d4e31c1..ac684f49b5 100644 --- a/src/jtag/drivers/cmsis_dap_usb_bulk.c +++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c @@ -63,7 +63,7 @@ static void cmsis_dap_usb_close(struct cmsis_dap *dap); static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz); static void cmsis_dap_usb_free(struct cmsis_dap *dap); -static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial) +static int cmsis_dap_usb_open(struct cmsis_dap *dap, const uint16_t vids[], const uint16_t pids[], const char *serial) { int err; struct libusb_context *ctx; diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c b/src/jtag/drivers/cmsis_dap_usb_hid.c index a4058ec803..8d4de68857 100644 --- a/src/jtag/drivers/cmsis_dap_usb_hid.c +++ b/src/jtag/drivers/cmsis_dap_usb_hid.c @@ -68,7 +68,7 @@ static void cmsis_dap_hid_close(struct cmsis_dap *dap); static int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz); static void cmsis_dap_hid_free(struct cmsis_dap *dap); -static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial) +static int cmsis_dap_hid_open(struct cmsis_dap *dap, const uint16_t vids[], const uint16_t pids[], const char *serial) { hid_device *dev = NULL; int i; diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 8264c0db87..24a5bdda78 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -1143,8 +1143,8 @@ proc "cmsis_dap_backend" {backend} { lappend _telnet_autocomplete_skip "cmsis_dap_vid_pid" proc "cmsis_dap_vid_pid" {args} { - echo "DEPRECATED! use 'cmsis-dap vid_pid', not 'cmsis_dap_vid_pid'" - eval cmsis-dap vid_pid $args + echo "DEPRECATED! use 'adapter usb vid_pid', not 'cmsis_dap_vid_pid'" + eval adapter usb vid_pid $args } lappend _telnet_autocomplete_skip "cmsis_dap_usb" -- |
|
From: <ge...@op...> - 2026-04-26 07:38:02
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9590 -- gerrit commit 0a1949e1b12d2f5dfc328d15e54b69927f06f2b9 Author: Tomas Vanek <va...@fb...> Date: Sun Feb 11 18:01:24 2024 +0100 target/riscv: DM access on a DAP Modify riscv target to optionally accept -dap and -ap-num options instead of -chain-position The selected AP is used as an alternative DMI. DTM version is fixed to 1 because DTM control scan is not available. Basic DM access works. riscv_batch works without a configurable delay. Also an optional read back request in riscv_batch_add_dm_write() is silently ignored. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I5399207d897d93419198c40b521e4464e04ff1a6 diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c index 5acbddaf37..bd59deb193 100644 --- a/src/target/riscv/batch.c +++ b/src/target/riscv/batch.c @@ -10,6 +10,8 @@ #include "riscv.h" #include "field_helpers.h" +#include <target/arm_adi_v5.h> + // TODO: DTM_DMI_MAX_ADDRESS_LENGTH should be reduced to 32 (per the debug spec) #define DTM_DMI_MAX_ADDRESS_LENGTH ((1<<DTM_DTMCS_ABITS_LENGTH)-1) #define DMI_SCAN_MAX_BIT_LENGTH (DTM_DMI_MAX_ADDRESS_LENGTH + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH) @@ -50,35 +52,45 @@ struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans) out->bscan_ctxt = NULL; out->read_keys = NULL; - /* FIXME: There is potential for memory usage reduction. We could allocate - * smaller buffers than DMI_SCAN_BUF_SIZE (that is, buffers that correspond to - * the real DR scan length on the given target) */ - out->data_out = malloc(sizeof(*out->data_out) * scans * DMI_SCAN_BUF_SIZE); - if (!out->data_out) { - LOG_ERROR("Failed to allocate data_out in RISC-V batch."); - goto alloc_error; - }; + struct riscv_info *r = riscv_info(target); + out->emulated = r->alternative_dmi; + + if (out->emulated && r->get_dmi_ap) + out->ap = r->get_dmi_ap(target); + + if (!out->emulated) { + /* FIXME: There is potential for memory usage reduction. We could allocate + * smaller buffers than DMI_SCAN_BUF_SIZE (that is, buffers that correspond to + * the real DR scan length on the given target) */ + out->data_out = malloc(sizeof(*out->data_out) * scans * DMI_SCAN_BUF_SIZE); + if (!out->data_out) { + LOG_ERROR("Failed to allocate data_out in RISC-V batch."); + goto alloc_error; + }; + } out->data_in = malloc(sizeof(*out->data_in) * scans * DMI_SCAN_BUF_SIZE); if (!out->data_in) { LOG_ERROR("Failed to allocate data_in in RISC-V batch."); goto alloc_error; } - out->fields = malloc(sizeof(*out->fields) * scans); - if (!out->fields) { - LOG_ERROR("Failed to allocate fields in RISC-V batch."); - goto alloc_error; - } - out->delay_classes = malloc(sizeof(*out->delay_classes) * scans); - if (!out->delay_classes) { - LOG_ERROR("Failed to allocate delay_classes in RISC-V batch."); - goto alloc_error; - } - if (bscan_tunnel_ir_width != 0) { - out->bscan_ctxt = malloc(sizeof(*out->bscan_ctxt) * scans); - if (!out->bscan_ctxt) { - LOG_ERROR("Failed to allocate bscan_ctxt in RISC-V batch."); + if (!out->emulated) { + out->fields = malloc(sizeof(*out->fields) * scans); + if (!out->fields) { + LOG_ERROR("Failed to allocate fields in RISC-V batch."); + goto alloc_error; + } + out->delay_classes = malloc(sizeof(*out->delay_classes) * scans); + if (!out->delay_classes) { + LOG_ERROR("Failed to allocate delay_classes in RISC-V batch."); goto alloc_error; } + if (bscan_tunnel_ir_width != 0) { + out->bscan_ctxt = malloc(sizeof(*out->bscan_ctxt) * scans); + if (!out->bscan_ctxt) { + LOG_ERROR("Failed to allocate bscan_ctxt in RISC-V batch."); + goto alloc_error; + } + } } out->read_keys = malloc(sizeof(*out->read_keys) * scans); if (!out->read_keys) { @@ -335,6 +347,36 @@ void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint32_t address, uint // otherwise return an error (during batch creation or when the batch is executed). assert(batch->used_scans < batch->allocated_scans); + if (batch->emulated) { + if (batch->queued_retval == ERROR_OK) { + if (batch->ap) { + uint32_t dmi_addr = 4 * riscv_get_dmi_address(batch->target, address); + batch->queued_retval = mem_ap_write_u32(batch->ap, dmi_addr, data); +#ifdef DMI_WRITE_READBACK + if (read_back && batch->queued_retval == ERROR_OK) { + uint32_t *data_in = (uint32_t *)batch->data_in; + data_in = &data_in[batch->used_scans]; + batch->queued_retval = mem_ap_read_u32(batch->ap, dmi_addr, data_in); + batch->used_scans++; + } +#endif + } else { + uint32_t dmi_addr = riscv_get_dmi_address(batch->target, address); + batch->queued_retval = riscv_dmi_write(batch->target, dmi_addr, data); +#ifdef DMI_WRITE_READBACK + if (read_back && batch->queued_retval == ERROR_OK) { + uint32_t *data_in = (uint32_t *)batch->data_in; + data_in = &data_in[batch->used_scans]; + batch->queued_retval = riscv_dmi_read(batch->target, + data_in, dmi_addr); + batch->used_scans++; + } +#endif + } + } + batch->last_scan = RISCV_SCAN_TYPE_WRITE; + return; + } struct scan_field *field = batch->fields + batch->used_scans; field->num_bits = get_dmi_scan_length(batch->target); @@ -365,30 +407,53 @@ size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint32_t address, // otherwise return an error (during batch creation or when the batch is executed). assert(batch->used_scans < batch->allocated_scans); - struct scan_field *field = batch->fields + batch->used_scans; + if (batch->emulated) { + if (batch->queued_retval == ERROR_OK) { + uint32_t *data_in = (uint32_t *)batch->data_in; + data_in = &data_in[batch->used_scans]; + if (batch->ap) { + uint32_t dmi_addr = 4 * riscv_get_dmi_address(batch->target, address); + batch->queued_retval = mem_ap_read_u32(batch->ap, dmi_addr, data_in); + } else { + uint32_t dmi_addr = riscv_get_dmi_address(batch->target, address); + batch->queued_retval = riscv_dmi_read(batch->target, + data_in, dmi_addr); + } + } + batch->read_keys[batch->read_keys_used] = batch->used_scans; + } else { + struct scan_field *field = batch->fields + batch->used_scans; - field->num_bits = get_dmi_scan_length(batch->target); - assert(field->num_bits <= DMI_SCAN_MAX_BIT_LENGTH); + field->num_bits = get_dmi_scan_length(batch->target); + assert(field->num_bits <= DMI_SCAN_MAX_BIT_LENGTH); - uint8_t *out_value = batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE; - uint8_t *in_value = batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE; + uint8_t *out_value = batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE; + uint8_t *in_value = batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE; - field->out_value = out_value; - field->in_value = in_value; - riscv_fill_dmi_read(batch->target, out_value, address); - riscv_fill_dm_nop(batch->target, in_value); + field->out_value = out_value; + field->in_value = in_value; + riscv_fill_dmi_read(batch->target, out_value, address); + riscv_fill_dm_nop(batch->target, in_value); + + batch->delay_classes[batch->used_scans] = delay_class; + batch->read_keys[batch->read_keys_used] = batch->used_scans + 1; + } - batch->delay_classes[batch->used_scans] = delay_class; batch->last_scan = RISCV_SCAN_TYPE_READ; batch->used_scans++; - batch->read_keys[batch->read_keys_used] = batch->used_scans; return batch->read_keys_used++; } uint32_t riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key) { assert(key < batch->read_keys_used); + if (batch->emulated) { + if (batch->queued_retval == ERROR_OK) + return DTM_DMI_OP_SUCCESS; + else + return DTM_DMI_OP_FAILED; + } size_t index = batch->read_keys[key]; assert(index < batch->used_scans); uint8_t *base = batch->data_in + DMI_SCAN_BUF_SIZE * index; @@ -401,6 +466,10 @@ uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t k assert(key < batch->read_keys_used); size_t index = batch->read_keys[key]; assert(index < batch->used_scans); + if (batch->emulated) { + uint32_t *data_in = (uint32_t *)batch->data_in; + return data_in[index]; + } uint8_t *base = batch->data_in + DMI_SCAN_BUF_SIZE * index; /* extract "data" field from the DMI read result */ return buf_get_u32(base, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH); @@ -409,6 +478,9 @@ uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t k void riscv_batch_add_nop(struct riscv_batch *batch) { assert(batch->used_scans < batch->allocated_scans); + if (batch->emulated) + return; + struct scan_field *field = batch->fields + batch->used_scans; field->num_bits = get_dmi_scan_length(batch->target); @@ -438,6 +510,10 @@ size_t riscv_batch_available_scans(struct riscv_batch *batch) bool riscv_batch_was_batch_busy(const struct riscv_batch *batch) { assert(batch->was_run); + + if (batch->emulated) + return false; + assert(batch->used_scans); assert(batch->last_scan == RISCV_SCAN_TYPE_NOP); return riscv_batch_was_scan_busy(batch, batch->used_scans - 1); diff --git a/src/target/riscv/batch.h b/src/target/riscv/batch.h index 5d8b57234e..687a2babd5 100644 --- a/src/target/riscv/batch.h +++ b/src/target/riscv/batch.h @@ -7,6 +7,8 @@ #include "jtag/jtag.h" #include "riscv.h" +#include "target/arm_adi_v5.h" + enum riscv_scan_type { RISCV_SCAN_TYPE_INVALID, RISCV_SCAN_TYPE_NOP, @@ -159,6 +161,10 @@ struct riscv_batch { * Only valid when `was_run` is set. */ unsigned int last_scan_delay; + + bool emulated; + int queued_retval; + struct adiv5_ap *ap; }; /* Allocates (or frees) a new scan set. "scans" is the maximum number of JTAG diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 22128d7ab7..236646c1ed 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -18,6 +18,7 @@ #include "target/algorithm.h" #include "target/target_type.h" #include <helper/align.h> +#include <target/arm_adi_v5.h> #include <helper/log.h> #include "jtag/jtag.h" #include "target/register.h" @@ -138,6 +139,8 @@ typedef struct { * abstractcs.busy may have remained set. In that case we may need to * re-check the busy state before executing these operations. */ bool abstract_cmd_maybe_busy; + + struct adiv5_ap *dmi_ap; } dm013_info_t; typedef struct { @@ -257,6 +260,9 @@ typedef struct { /* This hart was placed into a halt group in examine(). */ bool haltgroup_supported; + + /* DM is accessed other way than by JTAG */ + bool alternative_dmi; } riscv013_info_t; static OOCD_LIST_HEAD(dm_list); @@ -280,6 +286,7 @@ static dm013_info_t *get_dm(struct target *target) if (info->dm) return info->dm; + struct riscv_info *r = riscv_info(target); unsigned int abs_chain_position = target->tap->abs_chain_position; dm013_info_t *entry; @@ -305,11 +312,28 @@ static dm013_info_t *get_dm(struct target *target) dm->base = target->dbgbase; dm->current_hartid = 0; dm->hart_count = -1; + + if (r->alternative_dmi) { + struct riscv_private_config *config = riscv_private_config(target); + struct adiv5_private_config *pc = &config->adi_pc; + dm->dmi_ap = dap_get_ap(pc->dap, pc->ap_num); + if (!dm->dmi_ap) { + LOG_TARGET_ERROR(target, "Cannot use %s AP 0x%08" PRIx64 " for DM access", + adiv5_dap_name(pc->dap), pc->ap_num); + free(dm); + return NULL; + } + } + INIT_LIST_HEAD(&dm->target_list); list_add(&dm->list, &dm_list); } info->dm = dm; + + if (dm->dmi_ap) + info->alternative_dmi = true; + target_list_t *target_entry; list_for_each_entry(target_entry, &dm->target_list, list) { if (target_entry->target == target) @@ -343,12 +367,22 @@ static void riscv013_dm_free(struct target *target) } if (list_empty(&dm->target_list)) { + if (dm->dmi_ap) + dap_put_ap(dm->dmi_ap); + list_del(&dm->list); free(dm); } info->dm = NULL; } +static struct adiv5_ap *riscv013_get_dmi_ap(struct target *target) +{ + dm013_info_t *dm = get_dm(target); + + return dm->dmi_ap; +} + static struct riscv_debug_reg_ctx get_riscv_debug_reg_ctx(const struct target *target) { if (!target_was_examined(target)) { @@ -406,8 +440,13 @@ static uint32_t set_dmcontrol_hartsel(uint32_t initial, int hart_index) /*** Utility functions. ***/ -static void select_dmi(struct jtag_tap *tap) +static void select_dmi(struct target *target) { + riscv013_info_t *info = get_info(target); + if (info->alternative_dmi) + return; + + struct jtag_tap *tap = target->tap; if (bscan_tunnel_ir_width != 0) { select_dmi_via_bscan(tap); return; @@ -2001,53 +2040,60 @@ static int examine(struct target *target) /* Don't need to select dbus, since the first thing we do is read dtmcontrol. */ LOG_TARGET_DEBUG(target, "dbgbase=0x%x", target->dbgbase); - uint32_t dtmcontrol; - if (dtmcs_scan(target->tap, 0, &dtmcontrol) != ERROR_OK || dtmcontrol == 0) { - LOG_TARGET_ERROR(target, "Could not scan dtmcontrol. Check JTAG connectivity/board power."); - return ERROR_FAIL; - } + riscv013_info_t *info = get_info(target); - LOG_TARGET_DEBUG(target, "dtmcontrol=0x%x", dtmcontrol); - LOG_DEBUG_REG(target, DTM_DTMCS, dtmcontrol); + info->index = target->coreid; - if (get_field(dtmcontrol, DTM_DTMCS_VERSION) != 1) { - LOG_TARGET_ERROR(target, "Unsupported DTM version %" PRIu32 ". (dtmcontrol=0x%" PRIx32 ")", - get_field32(dtmcontrol, DTM_DTMCS_VERSION), dtmcontrol); + dm013_info_t *dm = get_dm(target); + if (!dm) return ERROR_FAIL; - } - riscv013_info_t *info = get_info(target); + if (!info->alternative_dmi) { + uint32_t dtmcontrol; + if (dtmcs_scan(target->tap, 0, &dtmcontrol) != ERROR_OK || dtmcontrol == 0) { + LOG_TARGET_ERROR(target, "Could not scan dtmcontrol. Check JTAG connectivity/board power."); + return ERROR_FAIL; + } - info->index = target->coreid; - info->abits = get_field(dtmcontrol, DTM_DTMCS_ABITS); - info->dtmcs_idle = get_field(dtmcontrol, DTM_DTMCS_IDLE); + LOG_TARGET_DEBUG(target, "dtmcontrol=0x%x", dtmcontrol); + LOG_DEBUG_REG(target, DTM_DTMCS, dtmcontrol); - if (info->abits > RISCV013_DTMCS_ABITS_MAX) { - /* Max. address width given by the debug specification is exceeded */ - LOG_TARGET_ERROR(target, "The target's debug bus (DMI) address width exceeds " - "the maximum:"); - LOG_TARGET_ERROR(target, " found dtmcs.abits = %d; maximum is abits = %d.", - info->abits, RISCV013_DTMCS_ABITS_MAX); - return ERROR_FAIL; - } + if (get_field(dtmcontrol, DTM_DTMCS_VERSION) != 1) { + LOG_TARGET_ERROR(target, "Unsupported DTM version %" PRIu32 ". (dtmcontrol=0x%" PRIx32 ")", + get_field32(dtmcontrol, DTM_DTMCS_VERSION), dtmcontrol); + return ERROR_FAIL; + } - if (info->abits == 0) { - LOG_TARGET_ERROR(target, - "dtmcs.abits is zero. Check JTAG connectivity/board power"); - return ERROR_FAIL; - } - if (info->abits < RISCV013_DTMCS_ABITS_MIN) { - /* The requirement for minimum DMI address width of 7 bits is part of - * the RISC-V Debug spec since Jan-20-2017 (commit 03df6ee7). However, - * implementations exist that implement narrower DMI address. For example - * Spike as of Q1/2025 uses dmi.abits = 6. - * - * For that reason, warn the user but continue. - */ - LOG_TARGET_WARNING(target, "The target's debug bus (DMI) address width is " - "lower than the minimum:"); - LOG_TARGET_WARNING(target, " found dtmcs.abits = %d; minimum is abits = %d.", - info->abits, RISCV013_DTMCS_ABITS_MIN); + info->abits = get_field(dtmcontrol, DTM_DTMCS_ABITS); + info->dtmcs_idle = get_field(dtmcontrol, DTM_DTMCS_IDLE); + + if (info->abits > RISCV013_DTMCS_ABITS_MAX) { + /* Max. address width given by the debug specification is exceeded */ + LOG_TARGET_ERROR(target, "The target's debug bus (DMI) address width exceeds " + "the maximum:"); + LOG_TARGET_ERROR(target, " found dtmcs.abits = %d; maximum is abits = %d.", + info->abits, RISCV013_DTMCS_ABITS_MAX); + return ERROR_FAIL; + } + + if (info->abits == 0) { + LOG_TARGET_ERROR(target, + "dtmcs.abits is zero. Check JTAG connectivity/board power"); + return ERROR_FAIL; + } + if (info->abits < RISCV013_DTMCS_ABITS_MIN) { + /* The requirement for minimum DMI address width of 7 bits is part of + * the RISC-V Debug spec since Jan-20-2017 (commit 03df6ee7). However, + * implementations exist that implement narrower DMI address. For example + * Spike as of Q1/2025 uses dmi.abits = 6. + * + * For that reason, warn the user but continue. + */ + LOG_TARGET_WARNING(target, "The target's debug bus (DMI) address width is " + "lower than the minimum:"); + LOG_TARGET_WARNING(target, " found dtmcs.abits = %d; minimum is abits = %d.", + info->abits, RISCV013_DTMCS_ABITS_MIN); + } } if (!check_dbgbase_exists(target)) { @@ -2515,7 +2561,20 @@ static int batch_run(struct target *target, struct riscv_batch *batch) { RISCV_INFO(r); RISCV013_INFO(info); - select_dmi(target->tap); + select_dmi(target); + + if (batch->emulated) { + if (batch->ap) { + int retval = dap_run(batch->ap->dap); + if (retval == ERROR_OK) + batch->was_run = true; + + return retval; + } + + return ERROR_OK; + } + riscv_batch_add_nop(batch); const int result = riscv_batch_run_from(batch, 0, &info->learned_delays, /*resets_delays*/ r->reset_delays_wait >= 0, @@ -2538,7 +2597,20 @@ static int batch_run(struct target *target, struct riscv_batch *batch) static int batch_run_timeout(struct target *target, struct riscv_batch *batch) { RISCV013_INFO(info); - select_dmi(target->tap); + select_dmi(target); + + if (batch->emulated) { + if (batch->ap) { + int retval = dap_run(batch->ap->dap); + if (retval == ERROR_OK) + batch->was_run = true; + + return retval; + } + + return ERROR_OK; + } + riscv_batch_add_nop(batch); size_t finished_scans = 0; @@ -2894,6 +2966,8 @@ static int init_target(struct command_context *cmd_ctx, return ERROR_FAIL; } generic_info->sample_memory = sample_memory; + generic_info->get_dmi_ap = riscv013_get_dmi_ap; + riscv013_info_t *info = get_info(target); info->progbufsize = -1; @@ -2909,7 +2983,7 @@ static int assert_reset(struct target *target) RISCV013_INFO(info); int result; - select_dmi(target->tap); + select_dmi(target); if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) { /* Run the user-supplied script if there is one. */ @@ -2963,7 +3037,7 @@ static int deassert_reset(struct target *target) return ERROR_FAIL; int result; - select_dmi(target->tap); + select_dmi(target); /* Clear the reset, but make sure haltreq is still set */ uint32_t control = 0; control = set_field(control, DM_DMCONTROL_DMACTIVE, 1); @@ -4455,7 +4529,7 @@ read_memory_progbuf(struct target *target, const struct riscv_mem_access_args ar { assert(riscv_mem_access_is_read(args)); - select_dmi(target->tap); + select_dmi(target); memset(args.read_buffer, 0, args.count * args.size); if (execute_autofence(target) != ERROR_OK) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 0688ad327b..cfe1c2ee17 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -13,6 +13,7 @@ #include "target/target.h" #include "target/algorithm.h" #include "target/target_type.h" +#include <target/arm_adi_v5.h> #include <target/smp.h> #include "jtag/jtag.h" #include "target/register.h" @@ -477,7 +478,7 @@ static struct target_type *get_target_type(struct target *target) static struct riscv_private_config *alloc_default_riscv_private_config(void) { - struct riscv_private_config * const config = malloc(sizeof(*config)); + struct riscv_private_config * const config = calloc(1, sizeof(*config)); if (!config) { LOG_ERROR("Out of memory!"); return NULL; @@ -638,7 +639,7 @@ static int riscv_jim_configure(struct target *target, int e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts, goi->argv[0], &n); if (e != JIM_OK) - return JIM_CONTINUE; + return adiv5_jim_configure_ext(target, goi, &config->adi_pc, ADI_CONFIGURE_DAP_OPTIONAL); e = jim_getopt_obj(goi, NULL); if (e != JIM_OK) @@ -755,7 +756,6 @@ static void riscv_deinit_target(struct target *target) } free(target->arch_info); - target->arch_info = NULL; } @@ -2480,14 +2480,23 @@ static int riscv_examine(struct target *target) /* Don't need to select dbus, since the first thing we do is read dtmcontrol. */ RISCV_INFO(info); - uint32_t dtmcontrol; - if (dtmcs_scan(target->tap, 0, &dtmcontrol) != ERROR_OK || dtmcontrol == 0) { - LOG_TARGET_ERROR(target, "Could not read dtmcontrol. Check JTAG connectivity/board power."); - return ERROR_FAIL; + uint32_t dtm_version; + + struct adiv5_private_config *pc = target->private_config; + if (adiv5_verify_config(pc) == ERROR_OK) { + dtm_version = 1; + info->alternative_dmi = true; + } else { + uint32_t dtmcontrol; + if (dtmcs_scan(target->tap, 0, &dtmcontrol) != ERROR_OK || dtmcontrol == 0) { + LOG_TARGET_ERROR(target, "Could not read dtmcontrol. Check JTAG connectivity/board power."); + return ERROR_FAIL; + } + + LOG_TARGET_DEBUG(target, "dtmcontrol=0x%" PRIx32, dtmcontrol); + dtm_version = get_field(dtmcontrol, DTMCONTROL_VERSION); + LOG_TARGET_DEBUG(target, "version=0x%" PRIx32, dtm_version); } - LOG_TARGET_DEBUG(target, "dtmcontrol=0x%" PRIx32, dtmcontrol); - uint32_t dtm_version = get_field(dtmcontrol, DTMCONTROL_VERSION); - LOG_TARGET_DEBUG(target, "version=0x%" PRIx32, dtm_version); struct target_type *tt; if (info->dtm_version == DTM_DTMCS_VERSION_UNKNOWN) { @@ -4663,7 +4672,7 @@ uint32_t riscv_get_dmi_address(const struct target *target, uint32_t dm_address) return r->get_dmi_address(target, dm_address); } -static int riscv_dmi_read(struct target *target, uint32_t *value, uint32_t address) +int riscv_dmi_read(struct target *target, uint32_t *value, uint32_t address) { if (!target) { LOG_ERROR("target is NULL!"); @@ -4681,7 +4690,7 @@ static int riscv_dmi_read(struct target *target, uint32_t *value, uint32_t addre return r->dmi_read(target, value, address); } -static int riscv_dmi_write(struct target *target, uint32_t dmi_address, uint32_t value) +int riscv_dmi_write(struct target *target, uint32_t dmi_address, uint32_t value) { if (!target) { LOG_ERROR("target is NULL!"); diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 2a0a9b95f0..f6958af8ad 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -12,6 +12,7 @@ struct riscv_program; #include "target/semihosting_common.h" #include "target/target.h" #include "target/register.h" +#include <target/arm_adi_v5.h> #include <helper/command.h> #include <helper/bits.h> @@ -307,6 +308,8 @@ struct riscv_info { unsigned int (*data_bits)(struct target *target); + struct adiv5_ap *(*get_dmi_ap)(struct target *target); + COMMAND_HELPER((*print_info), struct target *target); /* Storage for arch_info of non-custom registers. */ @@ -365,6 +368,8 @@ struct riscv_info { bool wp_allow_ge_lt_trigger; bool autofence; + + bool alternative_dmi; }; enum riscv_priv_mode { @@ -378,6 +383,7 @@ enum riscv_priv_mode { struct riscv_private_config { bool dcsr_ebreak_fields[N_RISCV_MODE]; + struct adiv5_private_config adi_pc; }; static inline struct riscv_private_config @@ -487,6 +493,9 @@ unsigned int riscv_get_dmi_address_bits(const struct target *target); uint32_t riscv_get_dmi_address(const struct target *target, uint32_t dm_address); +int riscv_dmi_read(struct target *target, uint32_t *value, uint32_t dmi_address); +int riscv_dmi_write(struct target *target, uint32_t dmi_address, uint32_t value); + int riscv_enumerate_triggers(struct target *target); int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint); -- |
|
From: <ge...@op...> - 2026-04-26 07:38:00
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9588 -- gerrit commit d56698ae0d208de8c50aa9b0d9f56a409a372ae4 Author: Tomas Vanek <va...@fb...> Date: Mon Oct 27 12:55:26 2025 +0100 tcl/target/rp2350: hide and expose CSR registers Hide CSRs not implemented on Hazard3 RISC-V cores. Expose implemented CSRs not exposed by default. The customization helps little bit in making 'reg' list somewhat shorter, prevents lot of OpenOCD errors like Error: RTOS: failed to get register 3667 and gdb errors like Could not fetch register "hgeip"; remote failure reply '0E' Change-Id: I78b90e727b901eb012e3fe9b6d2cf7912e5dfe02 Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/tcl/target/rp2350.cfg b/tcl/target/rp2350.cfg index afa16261c4..27233b88fb 100644 --- a/tcl/target/rp2350.cfg +++ b/tcl/target/rp2350.cfg @@ -96,9 +96,24 @@ if { [info exists _TARGETNAME_CM0] } { $_TARGETNAME_CM0 configure -event reset-init { rp2xxx rom_api_call FC } } +proc rv_config { __TARGETNAME } { + $__TARGETNAME riscv virt2phys_mode off + $__TARGETNAME riscv hide_csrs 7 0x15 0x17 0x45-0x49 + $__TARGETNAME riscv hide_csrs 0x102 0x103 0x107 0x10a-0x10f + $__TARGETNAME riscv hide_csrs 0x145-0x149 0x14d 0x15d + $__TARGETNAME riscv hide_csrs 0x200-0x280 0x307 0x30c-0x30f 0x31c-0x31f + $__TARGETNAME riscv hide_csrs 0x323-0x33f 0x345-0x34a 0x34b 0x3a4-0x3af + $__TARGETNAME riscv hide_csrs 0x3c0-0x79f 0x7a3 0x7a8 0x7aa 0x7b2 0x7b3 + $__TARGETNAME riscv hide_csrs 0xb03-0xb1f 0xb83-0xb9f + $__TARGETNAME riscv expose_csrs 0xbe0=meiea 0xbe1=meipa 0xbe2=meifa + $__TARGETNAME riscv expose_csrs 0xbe3=meipra 0xbe4=meinext 0xbe5=meicontext + $__TARGETNAME riscv expose_csrs 0xbf0=msleep + $__TARGETNAME riscv hide_csrs 0xc01 0xc03-0xc1f 0xc81 0xc83-0xc9f 0xda0 0xe12 +} + if { [info exists _TARGETNAME_RV0] } { target create $_TARGETNAME_RV0 riscv -dap $_CHIPNAME.dap -ap-num 0xa000 -coreid 0 - $_TARGETNAME_RV0 riscv virt2phys_mode off + rv_config $_TARGETNAME_RV0 $_TARGETNAME_RV0 configure -event reset-init "_rv_reset_init" @@ -115,7 +130,7 @@ if { [info exists _TARGETNAME_CM1] } { if { [info exists _TARGETNAME_RV1] } { target create $_TARGETNAME_RV1 riscv -dap $_CHIPNAME.dap -ap-num 0xa000 -coreid 1 - $_TARGETNAME_RV1 riscv virt2phys_mode off + rv_config $_TARGETNAME_RV1 } if { [info exists USE_SMP] } { -- |
|
From: <ge...@op...> - 2026-04-26 07:37:56
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9589 -- gerrit commit 0fe07010ec2f5c1c358e75f2f7d6e69efb33cd4f Author: Tomas Vanek <va...@fb...> Date: Sun Nov 30 12:09:47 2025 +0100 target/riscv: make memory bus read faster Prepare up to 256 memory reads in a single batch. Change-Id: Ic27e54418f98c48c5cffedfb77ad2d20a540bb6c Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 50e0f83dd8..22128d7ab7 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -3375,9 +3375,6 @@ static int read_memory_bus_v1(struct target *target, const struct riscv_mem_acce target_addr_t next_address = address; target_addr_t end_address = address + (increment ? count : 1) * size; - /* TODO: Reading all the elements in a single batch will boost the - * performance. - */ while (next_address < end_address) { uint32_t sbcs_write = set_field(0, DM_SBCS_SBREADONADDR, 1); sbcs_write |= sb_sbaccess(size); @@ -3402,17 +3399,20 @@ static int read_memory_bus_v1(struct target *target, const struct riscv_mem_acce * be unnecessary. */ uint32_t sbvalue[4] = {0}; - for (uint32_t i = (next_address - address) / size; i < count - 1; i++) { + for (uint32_t i = (next_address - address) / size; i < count - 1;) { const uint32_t size_in_words = DIV_ROUND_UP(size, 4); - struct riscv_batch *batch = riscv_batch_alloc(target, size_in_words); + const uint32_t chunk = MIN(256 / size_in_words, (count - 1 - i)); + struct riscv_batch *batch = riscv_batch_alloc(target, chunk * size_in_words); /* Read of sbdata0 must be performed as last because it * starts the new bus data transfer * (in case "sbcs.sbreadondata" was set above). * We don't want to start the next bus read before we * fetch all the data from the last bus read. */ - for (uint32_t j = size_in_words - 1; j > 0; --j) - riscv_batch_add_dm_read(batch, sbdata[j], RISCV_DELAY_BASE); - riscv_batch_add_dm_read(batch, sbdata[0], RISCV_DELAY_SYSBUS_READ); + for (uint32_t m = 0; m < chunk; m++) { + for (uint32_t j = size_in_words - 1; j > 0; --j) + riscv_batch_add_dm_read(batch, sbdata[j], RISCV_DELAY_BASE); + riscv_batch_add_dm_read(batch, sbdata[0], RISCV_DELAY_SYSBUS_READ); + } int res = batch_run_timeout(target, batch); if (res != ERROR_OK) { @@ -3421,14 +3421,19 @@ static int read_memory_bus_v1(struct target *target, const struct riscv_mem_acce } const size_t last_key = batch->read_keys_used - 1; - for (size_t k = 0; k <= last_key; ++k) { - sbvalue[k] = riscv_batch_get_dmi_read_data(batch, last_key - k); - buf_set_u32(buffer + i * size + k * 4, 0, MIN(32, 8 * size), sbvalue[k]); + size_t k = 0; + for (uint32_t m = 0; k <= last_key && m < chunk; m++) { + for (int j = size_in_words - 1; j >= 0; j--) { + uint32_t d = riscv_batch_get_dmi_read_data(batch, k); + buf_set_u32(buffer + (i + m) * size + j * 4, 0, MIN(32, 8 * size), d); + sbvalue[j] = d; + k++; + } + const target_addr_t read_addr = address + (i + m) * increment; + log_memory_access(read_addr, sbvalue, size, true); } - riscv_batch_free(batch); - const target_addr_t read_addr = address + i * increment; - log_memory_access(read_addr, sbvalue, size, true); + i += chunk; } uint32_t sbcs_read = 0; -- |
|
From: <ge...@op...> - 2026-04-24 11:51:14
|
This is an automated email from Gerrit. "Evgeniy Naydanov <eu...@gm...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9587 -- gerrit commit 0339e4ad884992457886147323fa4e516e2e321e Author: Evgeniy Naydanov <eu...@gm...> Date: Thu Mar 12 14:52:21 2026 +0300 target/riscv: drop version-specific `arch_state()` Drop these placeholders. This is a part of the effort to eliminate "fake" `riscv013_target` and `riscv011_target` `target_type`s. Link: http://review.openocd.org/id/Ied5756fb61bceb9b428a54b7fffb02818f94d935 Change-Id: I055ce3114178cc870a6679aa91bc5477870bbeea Signed-off-by: Evgeniy Naydanov <eu...@gm...> diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index 2bef2228e1..8fd3792bf1 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -2347,11 +2347,6 @@ static int access_memory(struct target *target, const struct riscv_mem_access_ar return read_memory(target, args); } -static int arch_state(struct target *target) -{ - return ERROR_OK; -} - static COMMAND_HELPER(riscv011_print_info, struct target *target) { /* Abstract description. */ @@ -2472,6 +2467,4 @@ struct target_type riscv011_target = { .assert_reset = assert_reset, .deassert_reset = deassert_reset, - - .arch_state = arch_state, }; diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 50e0f83dd8..4c5159fb87 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -5076,10 +5076,6 @@ static unsigned int riscv013_get_progbufsize(const struct target *target) return r->progbufsize; } -static int arch_state(struct target *target) -{ - return ERROR_OK; -} struct target_type riscv013_target = { .name = "riscv", @@ -5094,8 +5090,6 @@ struct target_type riscv013_target = { .assert_reset = assert_reset, .deassert_reset = deassert_reset, - - .arch_state = arch_state }; /*** 0.13-specific implementations of various RISC-V helper functions. ***/ diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index e92366d446..1c9ae812ee 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -3565,11 +3565,7 @@ static int riscv_arch_state(struct target *target) target_name(target), debug_reason_name(target), semihosting_active ? " Semihosting is active." : ""); - struct target_type *tt = get_target_type(target); - if (!tt) - return ERROR_FAIL; - assert(tt->arch_state); - return tt->arch_state(target); + return ERROR_OK; } /* Algorithm must end with a software breakpoint instruction. */ -- |
|
From: <ge...@op...> - 2026-04-23 19:13:34
|
This is an automated email from Gerrit. "Name of user not set <wil...@gm...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9586 -- gerrit commit e37057465e6fe31036447986ec47cbf28db35684 Author: William Markezana <wil...@gm...> Date: Fri Apr 10 12:45:43 2026 -0400 jtag/drivers: add T-Head CK-Link JTAG adapter driver Add support for the T-Head CK-Link Lite V2 probe family, including the Bouffalo Lab BL616/BL702 CK-Link clones used as built-in debuggers on BL618/BL702 evaluation boards. The wire protocol is a framed command format over USB bulk endpoints, reverse-engineered from T-Head's DebugServer binary. The driver implements: - Full DebugServer init sequence: selfreg setup, operational clock, 5-wire -> 2-wire -> 5-wire mode toggle (effective TAP reset). - JTAG_SCAN via the probe's single-entry batch opcode with IR caching across execute_queue boundaries; end-of-queue flush populates the IR scan's in_value with hardware-captured Capture-IR data. - Opcode-aware response-frame checksum validation. Selfreg reads use sum-mod-256; JTAG batch responses exclude the last dr_tdo byte. - Clock-divider control (freq_kHz = 48000 / (N+1)) with once-warning clamp when the requested speed exceeds the DebugServer-validated ceiling (2526 kHz). - libusb serial-number filter via adapter_get_required_serial() and kernel-driver auto-detach on Linux. - TCL command 'cklink vid_pid (vid pid)+' to override defaults. Known protocol limitations, surfaced as one-time warnings rather than silent data loss: - Scans exceed 255 bits: the batch opcode encodes bit-counts in single bytes. Clamp + TDI pass-through for the un-shifted portion, which gives OpenOCD's bypass chain-length probe the expected end-of-chain marker. - Back-to-back IR scans: the batch opcode requires both IR and DR phases; mid-queue flushing a deferred IR with a dummy DR would trigger spurious DMI transactions. Single-TAP chains only. - JTAG_TMS, JTAG_PATHMOVE: no TMS-sequence opcode exposed. Return ERROR_JTAG_NOT_IMPLEMENTED. - RTCK: not supported, return ERROR_JTAG_NOT_IMPLEMENTED. Tested against BL618 (VID 0x42bf, PID 0xb210) and BL702 eval boards: IDCODE read, RISC-V DM examine, halt, register read, memory read, single-step, hardware breakpoints, GDB RSP server all functional. Change-Id: If6adaec0445748f3e97078bf980c502eff4d5001 Signed-off-by: William Markezana <wil...@gm...> diff --git a/NEWS b/NEWS index 9db6c5feee..4b77a446d1 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ This file includes highlights of the changes made in the OpenOCD source archive release. JTAG Layer: + * Added support for T-Head CK-Link Lite JTAG adapters, including the + Bouffalo Lab BL616/BL702 clone probes (BL618 eval board debugger). Boundary Scan: diff --git a/configure.ac b/configure.ac index 0d5f0eb354..515f4af119 100644 --- a/configure.ac +++ b/configure.ac @@ -128,6 +128,7 @@ m4_define([USB1_ADAPTERS], [[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]], [[ftdi_cjtag], [cJTAG (OScan1, JScan3) tunneled thru MPSSE], [FTDI_CJTAG]], [[ch347], [CH347 based devices], [CH347]], + [[cklink], [T-Head CK-Link JTAG Probe], [CKLINK]], [[stlink], [ST-Link Programmer], [HLADAPTER_STLINK]], [[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]], [[ulink], [Keil ULINK JTAG Programmer], [ULINK]], diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules index 151b4e2c06..0f49e1a2c0 100644 --- a/contrib/60-openocd.rules +++ b/contrib/60-openocd.rules @@ -269,4 +269,8 @@ ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2750", MODE="660", GROUP="plugdev", # CMSIS-DAP compatible adapters ATTRS{product}=="*CMSIS-DAP*", MODE="660", GROUP="plugdev", TAG+="uaccess" +# T-Head CK-Link Lite and Bouffalo Lab BL616/BL702 clones +ATTRS{idVendor}=="32bf", ATTRS{idProduct}=="b210", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="42bf", ATTRS{idProduct}=="b210", MODE="660", GROUP="plugdev", TAG+="uaccess" + LABEL="openocd_rules_end" diff --git a/doc/openocd.texi b/doc/openocd.texi index a21a3e4bda..d016cc5d3c 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2615,6 +2615,24 @@ ch347 device_desc "EasyDevKit" @end deffn @end deffn +@deffn {Interface Driver} {cklink} +Driver for the T-Head CK-Link Lite V2 JTAG probe and Bouffalo Lab +BL616/BL702 clones, including the built-in debugger on Bouffalo BL618 +evaluation boards. Communication is over USB bulk endpoints using a +T-Head DebugServer-compatible framed command protocol. + +The driver only supports JTAG transport and a single-TAP chain. The +probe runs at a fixed clock; @command{adapter speed} requests are +accepted but ignored (with a one-time warning). @command{JTAG_TMS} and +@command{JTAG_PATHMOVE} are not supported by this probe's protocol. + +@deffn {Config Command} {cklink vid_pid} [vid pid]+ +Override the built-in VID/PID table. By default the driver matches +0x42bf/0xb210 (Bouffalo) and 0x32bf/0xb210 (T-Head). Up to eight +@var{vid}/@var{pid} pairs may be specified. +@end deffn +@end deffn + @deffn {Interface Driver} {cmsis-dap} ARM CMSIS-DAP compliant based adapter v1 (USB HID based) or v2 (USB bulk or TCP/IP). diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index 5216e5d774..ad08b0e0c8 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -213,6 +213,9 @@ endif if CH347 DRIVERFILES += %D%/ch347.c endif +if CKLINK +DRIVERFILES += %D%/cklink.c +endif DRIVERHEADERS = \ %D%/bitbang.h \ diff --git a/src/jtag/drivers/cklink.c b/src/jtag/drivers/cklink.c new file mode 100644 index 0000000000..efbbd85a44 --- /dev/null +++ b/src/jtag/drivers/cklink.c @@ -0,0 +1,802 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * T-Head CK-Link JTAG adapter driver. * + * * + * Supports the CK-Link Lite V2 wire protocol used by T-Head probes and * + * Bouffalo Lab BL616/BL702 CK-Link clones. USB bulk with a framed * + * command protocol reverse-engineered from T-Head's DebugServer. * + * * + * Copyright (C) 2026 by William Markezana * + * <wil...@gm...> * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <assert.h> + +#include <jtag/adapter.h> +#include <jtag/interface.h> +#include <jtag/commands.h> +#include <helper/binarybuffer.h> +#include <helper/bits.h> +#include <helper/time_support.h> +#include "libusb_helper.h" + +/* USB identification. VID/PID table is extendable via `cklink vid_pid`. */ +#define CKLINK_VID_BOUFFALO 0x42bf +#define CKLINK_VID_THEAD 0x32bf +#define CKLINK_PID_LITE_V2 0xb210 +#define CKLINK_MAX_VID_PIDS 8 + +#define CKLINK_USB_INTERFACE 0 +#define CKLINK_EP_OUT 0x02 +#define CKLINK_EP_IN 0x81 +#define CKLINK_USB_TIMEOUT_MS 1000 +#define CKLINK_USB_BUF_SIZE 2048 + +/* Wire-protocol framing bytes */ +#define CKLINK_FRAME_START 0x68 +#define CKLINK_FRAME_END 0x16 + +/* Response frame layout: start + status + payload + checksum + end */ +#define CKLINK_FRAME_OVERHEAD 4 +#define CKLINK_RESP_PAYLOAD_OFFSET 2 + +/* Opcodes */ +#define CKLINK_OP_SELFREG_WRITE 0x06 +#define CKLINK_OP_SELFREG_READ 0x87 +#define CKLINK_OP_JTAG_BATCH 0x88 + +/* Self-register indices */ +#define CKLINK_SR_CSR 0 /* clock divider + CDI mode */ +#define CKLINK_SR_MTCR_WAIT 1 /* target-comm wait cycles */ +#define CKLINK_SR_JTAG_CONFIG 8 /* JTAG config word */ +#define CKLINK_SELFREG_BYTES 4 + +/* + * Init values replayed from a captured DebugServer session. + * sr0 (CSR): byte 0 = clock divider, byte 3 = CDI mode (0x60=5-wire JTAG, + * 0x61=2-wire cJTAG). The 5->2->5 mode toggle at end of init acts as a + * TAP reset: the wire driver re-initializes on each switch. + * sr1 MTCR_WAIT = 1000 cycles. sr8 JTAG_CONFIG: opaque, known-good. + */ +#define CKLINK_SR0_SETUP_CLK_BYTE 0x17 /* ~2000 kHz */ +#define CKLINK_SR0_RUN_CLK_BYTE 0x12 /* ~2526 kHz, DebugServer default */ +#define CKLINK_SR0_MODE_JTAG 0x60 +#define CKLINK_SR0_MODE_CJTAG 0x61 +#define CKLINK_SR1_INIT_VALUE 0x000003e8 +#define CKLINK_SR8_INIT_VALUE 0x00622250 + +/* freq_kHz = 48000 / (N + 1); cap at DebugServer-validated 0x12. */ +#define CKLINK_CLK_SOURCE_KHZ 48000 +#define CKLINK_CLK_DIV_MIN CKLINK_SR0_RUN_CLK_BYTE +#define CKLINK_CLK_DIV_MAX 0xff + +#define CKLINK_CSR(clk, mode) (((uint32_t)(mode) << 24) | (clk)) + +/* Batch opcode encodes IR/DR bit-counts in single bytes. */ +#define CKLINK_MAX_SCAN_BITS 255 +#define CKLINK_MAX_SCAN_BYTES 32 /* DIV_ROUND_UP(255, 8) */ + +/* Synthesized IR when a DR scan arrives without a cached IR. */ +#define CKLINK_PLACEHOLDER_IR_BITS 5 +#define CKLINK_PLACEHOLDER_IR_VALUE 0x01 + +struct cklink_ctx { + struct libusb_device_handle *usb_dev; + uint8_t tx_buf[CKLINK_USB_BUF_SIZE]; + uint8_t rx_buf[CKLINK_USB_BUF_SIZE]; + uint8_t csr_clk; + uint8_t ir_value[CKLINK_MAX_SCAN_BYTES]; + unsigned int ir_bits; + struct jtag_command *pending_ir_cmd; + uint8_t *scan_tdi; + uint8_t *scan_tdo; + size_t scan_buf_size; + bool long_scan_warned; + bool dropped_ir_warned; +}; + +static struct cklink_ctx *cklink_handle; + +/* VID/PID table, NULL-terminated pairs; extendable via `cklink vid_pid`. */ +static uint16_t cklink_vids[CKLINK_MAX_VID_PIDS + 1] = { + CKLINK_VID_BOUFFALO, + CKLINK_VID_THEAD, +}; +static uint16_t cklink_pids[CKLINK_MAX_VID_PIDS + 1] = { + CKLINK_PID_LITE_V2, + CKLINK_PID_LITE_V2, +}; + +/* Sum-mod-256. */ +static uint8_t cklink_checksum(const uint8_t *buf, int len) +{ + unsigned int sum = 0; + for (int i = 0; i < len; i++) + sum += buf[i]; + return (uint8_t)(sum & 0xff); +} + +/* Send a framed command; NULL rxlen means fire-and-forget (selfreg writes + * are not acknowledged). @p opcode selects the response-checksum rule. */ +static int cklink_usb_xfer(struct cklink_ctx *ck, uint8_t opcode, + int txlen, int *rxlen) +{ + int actual = 0; + int ret = jtag_libusb_bulk_write(ck->usb_dev, CKLINK_EP_OUT, + (char *)ck->tx_buf, txlen, + CKLINK_USB_TIMEOUT_MS, &actual); + if (ret != ERROR_OK || actual != txlen) { + LOG_ERROR("CK-Link bulk write failed (ret=%d, actual=%d/%d)", + ret, actual, txlen); + return ERROR_FAIL; + } + + if (!rxlen) + return ERROR_OK; + + ret = jtag_libusb_bulk_read(ck->usb_dev, CKLINK_EP_IN, + (char *)ck->rx_buf, CKLINK_USB_BUF_SIZE, + CKLINK_USB_TIMEOUT_MS, &actual); + if (ret != ERROR_OK || actual < CKLINK_FRAME_OVERHEAD) { + LOG_ERROR("CK-Link bulk read failed (ret=%d, actual=%d)", + ret, actual); + return ERROR_FAIL; + } + if (ck->rx_buf[0] != CKLINK_FRAME_START) { + LOG_ERROR("CK-Link bad response start byte 0x%02x", + ck->rx_buf[0]); + return ERROR_FAIL; + } + if (ck->rx_buf[actual - 1] != CKLINK_FRAME_END) { + LOG_ERROR("CK-Link bad response end byte 0x%02x", + ck->rx_buf[actual - 1]); + return ERROR_FAIL; + } + /* + * RX checksum is opcode-specific: selfreg reads sum all payload; + * single-entry JTAG batch sums all except the last byte of dr_tdo. + */ + int csum_end = (opcode == CKLINK_OP_JTAG_BATCH) ? actual - 3 + : actual - 2; + uint8_t computed = cklink_checksum(ck->rx_buf, csum_end); + if (computed != ck->rx_buf[actual - 2]) { + LOG_ERROR("CK-Link response checksum mismatch: op=0x%02x stated=0x%02x computed=0x%02x", + opcode, ck->rx_buf[actual - 2], computed); + return ERROR_FAIL; + } + /* Status byte semantics undocumented; log non-zero for traces. */ + if (ck->rx_buf[1] != 0) { + LOG_DEBUG("CK-Link op=0x%02x returned status=0x%02x", + opcode, ck->rx_buf[1]); + } + *rxlen = actual; + return ERROR_OK; +} + +static int cklink_frame_start(struct cklink_ctx *ck, uint8_t opcode) +{ + ck->tx_buf[0] = CKLINK_FRAME_START; + ck->tx_buf[1] = opcode; + return 2; +} + +static int cklink_frame_end(struct cklink_ctx *ck, int pos) +{ + assert(pos + 2 <= CKLINK_USB_BUF_SIZE); + ck->tx_buf[pos] = cklink_checksum(ck->tx_buf, pos); + ck->tx_buf[pos + 1] = CKLINK_FRAME_END; + return pos + 2; +} + +static int cklink_selfreg_write(struct cklink_ctx *ck, uint8_t reg, + const uint8_t *value) +{ + int pos = cklink_frame_start(ck, CKLINK_OP_SELFREG_WRITE); + ck->tx_buf[pos++] = reg; + memcpy(&ck->tx_buf[pos], value, CKLINK_SELFREG_BYTES); + pos += CKLINK_SELFREG_BYTES; + pos = cklink_frame_end(ck, pos); + return cklink_usb_xfer(ck, CKLINK_OP_SELFREG_WRITE, pos, NULL); +} + +static int cklink_selfreg_read(struct cklink_ctx *ck, uint8_t reg, uint8_t *value) +{ + int pos = cklink_frame_start(ck, CKLINK_OP_SELFREG_READ); + ck->tx_buf[pos++] = reg; + pos = cklink_frame_end(ck, pos); + + int rxlen = 0; + int ret = cklink_usb_xfer(ck, CKLINK_OP_SELFREG_READ, pos, &rxlen); + if (ret != ERROR_OK) + return ret; + + const int expected = CKLINK_FRAME_OVERHEAD + CKLINK_SELFREG_BYTES; + if (rxlen < expected) { + LOG_ERROR("CK-Link selfreg read response too short (%d < %d)", + rxlen, expected); + return ERROR_FAIL; + } + memcpy(value, &ck->rx_buf[CKLINK_RESP_PAYLOAD_OFFSET], + CKLINK_SELFREG_BYTES); + return ERROR_OK; +} + +/* Single-entry batch scan. Scans > 255 bits are clamped with a one-time + * warning: chunking across entries breaks Shift-DR continuity, and + * erroring out here breaks OpenOCD's chain probe's -expected-id recovery. */ +static int cklink_jtag_scan(struct cklink_ctx *ck, + unsigned int ir_bits, const uint8_t *ir_tdi, + uint8_t *ir_tdo, + unsigned int dr_bits, const uint8_t *dr_tdi, + uint8_t *dr_tdo) +{ + if ((ir_bits > CKLINK_MAX_SCAN_BITS || dr_bits > CKLINK_MAX_SCAN_BITS) + && !ck->long_scan_warned) { + LOG_WARNING("CK-Link: scan exceeds %u-bit per-entry limit (ir=%u dr=%u); clamping", + CKLINK_MAX_SCAN_BITS, ir_bits, dr_bits); + ck->long_scan_warned = true; + } + if (ir_bits > CKLINK_MAX_SCAN_BITS) + ir_bits = CKLINK_MAX_SCAN_BITS; + if (dr_bits > CKLINK_MAX_SCAN_BITS) + dr_bits = CKLINK_MAX_SCAN_BITS; + + const unsigned int ir_bytes = DIV_ROUND_UP(ir_bits, 8); + const unsigned int dr_bytes = DIV_ROUND_UP(dr_bits, 8); + + int pos = cklink_frame_start(ck, CKLINK_OP_JTAG_BATCH); + ck->tx_buf[pos++] = 0; /* entry_count - 1 */ + ck->tx_buf[pos++] = (uint8_t)ir_bits; + if (ir_tdi) + memcpy(&ck->tx_buf[pos], ir_tdi, ir_bytes); + else + memset(&ck->tx_buf[pos], 0, ir_bytes); + pos += ir_bytes; + ck->tx_buf[pos++] = (uint8_t)dr_bits; + if (dr_tdi) + memcpy(&ck->tx_buf[pos], dr_tdi, dr_bytes); + else + memset(&ck->tx_buf[pos], 0, dr_bytes); + pos += dr_bytes; + pos = cklink_frame_end(ck, pos); + + int rxlen = 0; + int ret = cklink_usb_xfer(ck, CKLINK_OP_JTAG_BATCH, pos, &rxlen); + if (ret != ERROR_OK) + return ret; + + /* Response: start + status + ir_tdo + dr_echo + dr_tdo + csum + end. */ + const unsigned int expected = + CKLINK_FRAME_OVERHEAD + ir_bytes + 1 + dr_bytes; + if ((unsigned int)rxlen < expected) { + LOG_ERROR("CK-Link scan response truncated: got %d, need %u (ir=%u dr=%u)", + rxlen, expected, ir_bits, dr_bits); + return ERROR_FAIL; + } + + if (ir_tdo && ir_bytes) + memcpy(ir_tdo, &ck->rx_buf[CKLINK_RESP_PAYLOAD_OFFSET], ir_bytes); + + const unsigned int dr_tdo_offset = + CKLINK_RESP_PAYLOAD_OFFSET + ir_bytes + 1; + if (dr_tdo) + memcpy(dr_tdo, &ck->rx_buf[dr_tdo_offset], dr_bytes); + + return ERROR_OK; +} + +/* Shift num_bits of idle cycles, chunked to the 255-bit protocol limit. */ +static int cklink_idle_cycles(struct cklink_ctx *ck, unsigned int num_bits) +{ + static const uint8_t zeros[CKLINK_MAX_SCAN_BYTES] = { 0 }; + + while (num_bits > 0) { + unsigned int chunk = num_bits > CKLINK_MAX_SCAN_BITS + ? CKLINK_MAX_SCAN_BITS : num_bits; + int ret = cklink_jtag_scan(ck, 0, NULL, NULL, + chunk, zeros, NULL); + if (ret != ERROR_OK) + return ret; + num_bits -= chunk; + } + return ERROR_OK; +} + +/* Flush a pending IR with a 1-bit dummy DR so its in_value gets populated + * with real captured IR TDO. Called at end of execute_queue so Capture-IR + * validation sees real hardware data. */ +static int cklink_flush_pending_ir(struct cklink_ctx *ck) +{ + if (!ck || !ck->pending_ir_cmd) + return ERROR_OK; + + uint8_t ir_tdo[CKLINK_MAX_SCAN_BYTES] = { 0 }; + uint8_t dummy_dr = 0; + int ret = cklink_jtag_scan(ck, ck->ir_bits, ck->ir_value, ir_tdo, + 1, &dummy_dr, NULL); + if (ret != ERROR_OK) + return ret; + + struct scan_command *scan = ck->pending_ir_cmd->cmd.scan; + unsigned int off = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) { + struct scan_field *f = &scan->fields[i]; + if (f->in_value) { + buf_set_buf(ir_tdo, off, f->in_value, 0, + f->num_bits); + } + off += f->num_bits; + } + ck->pending_ir_cmd = NULL; + /* ir_bits/ir_value stay valid: hardware IR is still what we cached. */ + return ERROR_OK; +} + +static int cklink_execute_scan(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + struct scan_command *scan = cmd->cmd.scan; + + unsigned int total_bits = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) + total_bits += scan->fields[i].num_bits; + + if (total_bits == 0) + return ERROR_OK; + + const unsigned int total_bytes = DIV_ROUND_UP(total_bits, 8); + if (total_bytes > ck->scan_buf_size) { + uint8_t *ntdi = realloc(ck->scan_tdi, total_bytes); + uint8_t *ntdo = realloc(ck->scan_tdo, total_bytes); + if (!ntdi || !ntdo) { + LOG_ERROR("CK-Link: out of memory for %u-bit scan", + total_bits); + /* Partial success is fine; freed in cklink_quit. */ + if (ntdi) + ck->scan_tdi = ntdi; + if (ntdo) + ck->scan_tdo = ntdo; + return ERROR_FAIL; + } + ck->scan_tdi = ntdi; + ck->scan_tdo = ntdo; + ck->scan_buf_size = total_bytes; + } + memset(ck->scan_tdi, 0, total_bytes); + memset(ck->scan_tdo, 0, total_bytes); + + unsigned int bit_offset = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) { + struct scan_field *field = &scan->fields[i]; + if (field->out_value) { + buf_set_buf(field->out_value, 0, ck->scan_tdi, + bit_offset, field->num_bits); + } + bit_offset += field->num_bits; + } + + if (scan->ir_scan) { + /* + * Defer IR until paired with a DR (batch needs both). + * Back-to-back IR drops the first: mid-queue flush would + * cycle Capture-DR/Update-DR on the previous IR's register + * (e.g. DMI), triggering spurious transactions. + */ + if (total_bytes > sizeof(ck->ir_value)) { + LOG_ERROR("CK-Link: IR scan of %u bits exceeds cache (%zu bytes)", + total_bits, sizeof(ck->ir_value)); + return ERROR_JTAG_QUEUE_FAILED; + } + if (ck->pending_ir_cmd) { + if (!ck->dropped_ir_warned) { + LOG_WARNING("CK-Link: back-to-back IR scan dropped pending IR; multi-TAP chains are not supported"); + ck->dropped_ir_warned = true; + } else { + LOG_DEBUG("CK-Link: dropping pending IR (%u bits) before new IR scan", + ck->ir_bits); + } + } + memcpy(ck->ir_value, ck->scan_tdi, total_bytes); + ck->ir_bits = total_bits; + ck->pending_ir_cmd = cmd; + return ERROR_OK; + } + + /* No cached IR yet: inject IDCODE placeholder so chain detection works. */ + const uint8_t placeholder_ir = CKLINK_PLACEHOLDER_IR_VALUE; + const unsigned int eff_ir_bits = ck->ir_bits ? ck->ir_bits + : CKLINK_PLACEHOLDER_IR_BITS; + const uint8_t *eff_ir_value = ck->ir_bits ? ck->ir_value : &placeholder_ir; + if (!ck->ir_bits) + LOG_DEBUG("CK-Link: DR scan with no cached IR; injecting IDCODE placeholder"); + + uint8_t ir_tdo_buf[CKLINK_MAX_SCAN_BYTES] = { 0 }; + int ret = cklink_jtag_scan(ck, eff_ir_bits, eff_ir_value, ir_tdo_buf, + total_bits, ck->scan_tdi, ck->scan_tdo); + if (ret != ERROR_OK) + return ret; + + /* Scatter captured IR TDO back into the deferred IR command's fields. */ + if (ck->pending_ir_cmd) { + struct scan_command *ir_scan = ck->pending_ir_cmd->cmd.scan; + unsigned int ir_off = 0; + for (unsigned int i = 0; i < ir_scan->num_fields; i++) { + struct scan_field *f = &ir_scan->fields[i]; + if (f->in_value) { + buf_set_buf(ir_tdo_buf, ir_off, + f->in_value, 0, f->num_bits); + } + ir_off += f->num_bits; + } + ck->pending_ir_cmd = NULL; + } + + /* + * For clamped scans, fill un-shifted TDO with caller's TDI (models + * "no more TAPs past the limit" - a bare wire). Gives OpenOCD's + * bypass chain-length probe the expected end-of-chain marker. + */ + if (total_bits > CKLINK_MAX_SCAN_BITS) { + buf_set_buf(ck->scan_tdi, CKLINK_MAX_SCAN_BITS, + ck->scan_tdo, CKLINK_MAX_SCAN_BITS, + total_bits - CKLINK_MAX_SCAN_BITS); + } + + bit_offset = 0; + for (unsigned int i = 0; i < scan->num_fields; i++) { + struct scan_field *field = &scan->fields[i]; + if (field->in_value) { + buf_set_buf(ck->scan_tdo, bit_offset, + field->in_value, 0, field->num_bits); + } + bit_offset += field->num_bits; + } + + return ERROR_OK; +} + +static int cklink_write_csr(struct cklink_ctx *ck, uint8_t clk, uint8_t mode) +{ + uint8_t buf[CKLINK_SELFREG_BYTES]; + h_u32_to_le(buf, CKLINK_CSR(clk, mode)); + return cklink_selfreg_write(ck, CKLINK_SR_CSR, buf); +} + +/* khz -> sr0 byte 0 divider, rounded up so we never exceed the request. */ +static uint8_t cklink_khz_to_div(int khz) +{ + if (khz <= 0) + return CKLINK_CLK_DIV_MAX; + int n = ((CKLINK_CLK_SOURCE_KHZ + khz - 1) / khz) - 1; + if (n < CKLINK_CLK_DIV_MIN) + n = CKLINK_CLK_DIV_MIN; + if (n > CKLINK_CLK_DIV_MAX) + n = CKLINK_CLK_DIV_MAX; + return (uint8_t)n; +} + +static int cklink_execute_tlr_reset(struct cklink_ctx *ck) +{ + /* Probe-side reset via 5->2->5 mode toggle; target TAP reset not guaranteed. */ + int ret; + + ret = cklink_write_csr(ck, ck->csr_clk, CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, ck->csr_clk, CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, ck->csr_clk, CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + + ck->ir_bits = 0; + memset(ck->ir_value, 0, sizeof(ck->ir_value)); + ck->pending_ir_cmd = NULL; + tap_set_state(TAP_RESET); + return ERROR_OK; +} + +static int cklink_execute_runtest(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + return cklink_idle_cycles(ck, cmd->cmd.runtest->num_cycles); +} + +static int cklink_execute_stableclocks(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + /* TMS=0 shifts only hold state in RTI; other stable states would advance. */ + return cklink_idle_cycles(ck, cmd->cmd.stableclocks->num_cycles); +} + +static int cklink_execute_tms(struct jtag_command *cmd) +{ + /* No TMS-sequence opcode: honoring JTAG_TMS is impossible. */ + LOG_ERROR("CK-Link: JTAG_TMS (%u bits) is not supported by this probe", + cmd->cmd.tms->num_bits); + return ERROR_JTAG_NOT_IMPLEMENTED; +} + +static int cklink_execute_reset(struct cklink_ctx *ck, struct jtag_command *cmd) +{ + /* Only TRST is meaningful here: we have no separate SRST control. */ + if (cmd->cmd.reset->trst) + return cklink_execute_tlr_reset(ck); + return ERROR_OK; +} + +static int cklink_execute_queue(struct jtag_command *cmd_queue) +{ + struct cklink_ctx *ck = cklink_handle; + if (!ck) + return ERROR_JTAG_INIT_FAILED; + + for (struct jtag_command *cmd = cmd_queue; cmd; cmd = cmd->next) { + int ret; + + switch (cmd->type) { + case JTAG_SCAN: + ret = cklink_execute_scan(ck, cmd); + break; + case JTAG_TLR_RESET: + ret = cklink_execute_tlr_reset(ck); + break; + case JTAG_RUNTEST: + ret = cklink_execute_runtest(ck, cmd); + break; + case JTAG_RESET: + ret = cklink_execute_reset(ck, cmd); + break; + case JTAG_PATHMOVE: + /* No TMS-sequence opcode: honoring PATHMOVE is impossible. */ + LOG_ERROR("CK-Link: JTAG_PATHMOVE is not supported by this probe"); + ret = ERROR_JTAG_NOT_IMPLEMENTED; + break; + case JTAG_STABLECLOCKS: + ret = cklink_execute_stableclocks(ck, cmd); + break; + case JTAG_TMS: + ret = cklink_execute_tms(cmd); + break; + case JTAG_SLEEP: + jtag_sleep(cmd->cmd.sleep->us); + ret = ERROR_OK; + break; + default: + LOG_ERROR("CK-Link: unsupported JTAG command %d", + cmd->type); + return ERROR_JTAG_QUEUE_FAILED; + } + if (ret != ERROR_OK) + return ret; + } + /* Flush so any un-paired IR's in_value is populated before OpenOCD reads. */ + return cklink_flush_pending_ir(ck); +} + +static int cklink_probe_init(struct cklink_ctx *ck) +{ + uint8_t sr1[CKLINK_SELFREG_BYTES]; + uint8_t sr8[CKLINK_SELFREG_BYTES]; + uint8_t readback[CKLINK_SELFREG_BYTES]; + int ret; + + h_u32_to_le(sr1, CKLINK_SR1_INIT_VALUE); + h_u32_to_le(sr8, CKLINK_SR8_INIT_VALUE); + + /* DebugServer init sequence, replayed verbatim. */ + ret = cklink_write_csr(ck, CKLINK_SR0_SETUP_CLK_BYTE, + CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_selfreg_write(ck, CKLINK_SR_MTCR_WAIT, sr1); + if (ret != ERROR_OK) + return ret; + ret = cklink_selfreg_write(ck, CKLINK_SR_JTAG_CONFIG, sr8); + if (ret != ERROR_OK) + return ret; + + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + + /* 5->2->5 mode toggle: effective TAP reset. */ + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_CJTAG); + if (ret != ERROR_OK) + return ret; + ret = cklink_write_csr(ck, CKLINK_SR0_RUN_CLK_BYTE, + CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + + ret = cklink_selfreg_read(ck, CKLINK_SR_CSR, readback); + if (ret != ERROR_OK) + return ret; + if (readback[3] != CKLINK_SR0_MODE_JTAG) { + LOG_WARNING("CK-Link: sr0 mode byte is 0x%02x, expected 0x%02x (5-wire JTAG)", + readback[3], CKLINK_SR0_MODE_JTAG); + } + ck->csr_clk = CKLINK_SR0_RUN_CLK_BYTE; + + /* Pre-load IR = IDCODE; 1-bit DR is the minimum the batch opcode accepts. */ + const uint8_t idcode_ir = CKLINK_PLACEHOLDER_IR_VALUE; + const uint8_t dummy_dr = 0; + return cklink_jtag_scan(ck, CKLINK_PLACEHOLDER_IR_BITS, &idcode_ir, NULL, + 1, &dummy_dr, NULL); +} + +static int cklink_init(void) +{ + struct cklink_ctx *ck = calloc(1, sizeof(*ck)); + if (!ck) { + LOG_ERROR("CK-Link: out of memory"); + return ERROR_JTAG_INIT_FAILED; + } + + const char *serial = adapter_get_required_serial(); + if (jtag_libusb_open(cklink_vids, cklink_pids, serial, + &ck->usb_dev, NULL) != ERROR_OK) { + LOG_ERROR("CK-Link probe not found"); + free(ck); + return ERROR_JTAG_INIT_FAILED; + } + + libusb_set_auto_detach_kernel_driver(ck->usb_dev, 1); + + int claim = libusb_claim_interface(ck->usb_dev, CKLINK_USB_INTERFACE); + if (claim != 0) { + LOG_ERROR("CK-Link: failed to claim interface %d: %s", + CKLINK_USB_INTERFACE, libusb_error_name(claim)); + jtag_libusb_close(ck->usb_dev); + free(ck); + return ERROR_JTAG_INIT_FAILED; + } + + if (cklink_probe_init(ck) != ERROR_OK) { + LOG_ERROR("CK-Link: probe initialization failed"); + libusb_release_interface(ck->usb_dev, CKLINK_USB_INTERFACE); + jtag_libusb_close(ck->usb_dev); + free(ck); + return ERROR_JTAG_INIT_FAILED; + } + + cklink_handle = ck; + tap_set_state(TAP_RESET); + LOG_INFO("CK-Link Lite V2 initialized (5-wire JTAG)"); + return ERROR_OK; +} + +static int cklink_quit(void) +{ + if (!cklink_handle) + return ERROR_OK; + + libusb_release_interface(cklink_handle->usb_dev, + CKLINK_USB_INTERFACE); + jtag_libusb_close(cklink_handle->usb_dev); + free(cklink_handle->scan_tdi); + free(cklink_handle->scan_tdo); + free(cklink_handle); + cklink_handle = NULL; + return ERROR_OK; +} + +static int cklink_speed(int speed) +{ + struct cklink_ctx *ck = cklink_handle; + if (!ck) + return ERROR_OK; /* called before init */ + + uint8_t div = cklink_khz_to_div(speed); + if (div == ck->csr_clk) + return ERROR_OK; + int ret = cklink_write_csr(ck, div, CKLINK_SR0_MODE_JTAG); + if (ret != ERROR_OK) + return ret; + ck->csr_clk = div; + int actual = CKLINK_CLK_SOURCE_KHZ / (div + 1); + LOG_DEBUG("CK-Link: adapter speed: requested %d kHz, programmed %d kHz (div=0x%02x)", + speed, actual, div); + return ERROR_OK; +} + +static int cklink_khz(int khz, int *jtag_speed) +{ + if (khz == 0) { + LOG_ERROR("CK-Link: adaptive clocking (RTCK) is not supported"); + return ERROR_JTAG_NOT_IMPLEMENTED; + } + uint8_t div = cklink_khz_to_div(khz); + int achievable = CKLINK_CLK_SOURCE_KHZ / (div + 1); + if (achievable != khz) { + static int last_clamp_khz; + if (khz != last_clamp_khz) { + LOG_WARNING("CK-Link: requested %d kHz clamped to %d kHz (div=0x%02x)", + khz, achievable, div); + last_clamp_khz = khz; + } + } + *jtag_speed = achievable; + return ERROR_OK; +} + +static int cklink_speed_div(int speed, int *khz) +{ + *khz = speed; + return ERROR_OK; +} + +COMMAND_HANDLER(cklink_handle_vid_pid_command) +{ + if (CMD_ARGC < 2 || CMD_ARGC % 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + unsigned int pairs = CMD_ARGC / 2; + if (pairs > CKLINK_MAX_VID_PIDS) { + LOG_ERROR("CK-Link: too many vid/pid pairs (max %d)", + CKLINK_MAX_VID_PIDS); + return ERROR_COMMAND_SYNTAX_ERROR; + } + for (unsigned int i = 0; i < pairs; i++) { + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2 * i], cklink_vids[i]); + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2 * i + 1], cklink_pids[i]); + if (cklink_vids[i] == 0 || cklink_pids[i] == 0) { + LOG_ERROR("CK-Link: vid/pid must be non-zero (pair %u)", i); + return ERROR_COMMAND_SYNTAX_ERROR; + } + } + cklink_vids[pairs] = 0; + cklink_pids[pairs] = 0; + return ERROR_OK; +} + +static const struct command_registration cklink_subcommand_handlers[] = { + { + .name = "vid_pid", + .handler = &cklink_handle_vid_pid_command, + .mode = COMMAND_CONFIG, + .help = "VID/PID pairs of CK-Link probes to match (replaces defaults)", + .usage = "(vid pid)+", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration cklink_command_handlers[] = { + { + .name = "cklink", + .mode = COMMAND_ANY, + .help = "perform cklink management", + .chain = cklink_subcommand_handlers, + .usage = "<subcommand> [args...]", + }, + COMMAND_REGISTRATION_DONE +}; + +static struct jtag_interface cklink_jtag_interface = { + .execute_queue = cklink_execute_queue, +}; + +struct adapter_driver cklink_adapter_driver = { + .name = "cklink", + .transport_ids = TRANSPORT_JTAG, + .transport_preferred_id = TRANSPORT_JTAG, + .commands = cklink_command_handlers, + + .init = cklink_init, + .quit = cklink_quit, + .speed = cklink_speed, + .khz = cklink_khz, + .speed_div = cklink_speed_div, + + .jtag_ops = &cklink_jtag_interface, +}; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 51cbf9ac0d..5c6c8eea93 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -380,6 +380,7 @@ extern struct adapter_driver at91rm9200_adapter_driver; extern struct adapter_driver bcm2835gpio_adapter_driver; extern struct adapter_driver buspirate_adapter_driver; extern struct adapter_driver ch347_adapter_driver; +extern struct adapter_driver cklink_adapter_driver; extern struct adapter_driver cmsis_dap_adapter_driver; extern struct adapter_driver dmem_dap_adapter_driver; extern struct adapter_driver dummy_adapter_driver; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index caf5ace999..60c7364c64 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -62,6 +62,9 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_CH347 == 1 &ch347_adapter_driver, #endif +#if BUILD_CKLINK == 1 + &cklink_adapter_driver, +#endif #if BUILD_CMSIS_DAP_USB == 1 || BUILD_CMSIS_DAP_HID == 1 || BUILD_CMSIS_DAP_TCP == 1 &cmsis_dap_adapter_driver, #endif diff --git a/tcl/interface/cklink.cfg b/tcl/interface/cklink.cfg new file mode 100644 index 0000000000..fb017aa056 --- /dev/null +++ b/tcl/interface/cklink.cfg @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# T-Head CK-Link JTAG adapter (including Bouffalo BL616/BL702 clones) +# + +adapter driver cklink -- |
|
From: <ge...@op...> - 2026-04-23 12:27:58
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9585 -- gerrit commit cc15f48a37609e3d23b144f04a6d7a4a9de09057 Author: Marc Schink <de...@za...> Date: Wed Apr 22 17:09:02 2026 +0200 adapter/stlink: Delegate USB VID/PID parsing to adapter core Use the USB VID/PIDs provided by the adapter core instead of parsing them in the driver code. Keep the legacy 'st-link vid_pid' command for backwards compatibility, but mark it as deprecated. Checkpatch-ignore: LONG_LINE Change-Id: Ibd56adda044845148f0b130dcaf5e98b412be3be Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index ee97868508..7dcb0be176 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3410,10 +3410,6 @@ ST-LINK server software module}. @emph{Note:} ST-Link TCP server does not support the SWIM transport. @end deffn -@deffn {Config Command} {st-link vid_pid} [vid pid]+ -Pairs of vendor IDs and product IDs of the device. -@end deffn - @deffn {Command} {st-link cmd} rx_n (tx_byte)+ Sends an arbitrary command composed by the sequence of bytes @var{tx_byte} and receives @var{rx_n} bytes. diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index b4d21100cc..bac9c26cb5 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3406,7 +3406,7 @@ static int stlink_usb_usb_open(void *handle, struct hl_interface_param *param) in order to become operational. */ do { - if (jtag_libusb_open(param->vid, param->pid, NULL, + if (jtag_libusb_open(adapter_usb_get_vids(), adapter_usb_get_pids(), NULL, &h->usb_backend_priv.fd, stlink_usb_get_alternate_serial) != ERROR_OK) { LOG_ERROR("open failed"); return ERROR_FAIL; @@ -3740,9 +3740,9 @@ static int stlink_open(struct hl_interface_param *param, enum stlink_mode mode, h->st_mode = mode; - for (unsigned int i = 0; param->vid[i]; i++) { + for (unsigned int i = 0; adapter_usb_get_vids()[i]; i++) { LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", - h->st_mode, param->vid[i], param->pid[i], + h->st_mode, adapter_usb_get_vids()[i], adapter_usb_get_pids()[i], adapter_get_required_serial() ? adapter_get_required_serial() : ""); } @@ -4984,31 +4984,6 @@ static int stlink_dap_trace_read(uint8_t *buf, size_t *size) return stlink_usb_trace_read(stlink_dap_handle, buf, size); } -/** */ -COMMAND_HANDLER(stlink_dap_vid_pid) -{ - unsigned int i, max_usb_ids = HLA_MAX_USB_IDS; - - if (CMD_ARGC > max_usb_ids * 2) { - LOG_WARNING("ignoring extra IDs in vid_pid " - "(maximum is %d pairs)", max_usb_ids); - CMD_ARGC = max_usb_ids * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete vid_pid configuration directive"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], stlink_dap_param.vid[i / 2]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], stlink_dap_param.pid[i / 2]); - } - - /* null termination */ - stlink_dap_param.vid[i / 2] = stlink_dap_param.pid[i / 2] = 0; - - return ERROR_OK; -} - /** */ COMMAND_HANDLER(stlink_dap_backend_command) { @@ -5074,13 +5049,6 @@ COMMAND_HANDLER(stlink_dap_cmd_command) /** */ static const struct command_registration stlink_dap_subcommand_handlers[] = { - { - .name = "vid_pid", - .handler = stlink_dap_vid_pid, - .mode = COMMAND_CONFIG, - .help = "USB VID and PID of the adapter", - .usage = "(vid pid)+", - }, { .name = "backend", .handler = &stlink_dap_backend_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index f24e57ab06..441f2cccb1 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -1183,6 +1183,12 @@ proc "hla_stlink_backend" {args} { eval hla stlink_backend $args } +lappend _telnet_autocomplete_skip "st-link vid_pid" +proc "st-link vid_pid" {args} { + echo "DEPRECATED! use 'adapter usb vid_pid', not 'st-link vid_pid'" + eval adapter usb vid_pid $args +} + lappend _telnet_autocomplete_skip "kitprog_init_acquire_psoc" proc "kitprog_init_acquire_psoc" {} { echo "DEPRECATED! use 'kitprog init_acquire_psoc', not 'kitprog_init_acquire_psoc'" diff --git a/tcl/interface/stlink.cfg b/tcl/interface/stlink.cfg index 48c5656615..2cea18f20a 100644 --- a/tcl/interface/stlink.cfg +++ b/tcl/interface/stlink.cfg @@ -17,7 +17,7 @@ if { [adapter name] == "hla" } { } adapter driver st-link -st-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757 +adapter usb vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757 # transport select jtag # transport select swd -- |
|
From: <ge...@op...> - 2026-04-23 12:27:57
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9584 -- gerrit commit cf53fbd49d8d166917bf5e0ea6ed78fac92b08b6 Author: Marc Schink <de...@za...> Date: Wed Apr 22 17:08:20 2026 +0200 adapter: Implement USB VID/PID parsing Currently, eight adapter drivers each implement their own USB VID/PID parsing, leading to duplicated code. Implement VID/PID parsing in the adapter core, similar to how device serials are handled. Driver specific changes will follow in a separate patch series. Change-Id: I314915f79874f9d7becba0d4094efcd2c694f0f0 Signed-off-by: Marc Schink <de...@za...> diff --git a/doc/openocd.texi b/doc/openocd.texi index a21a3e4bda..ee97868508 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2496,6 +2496,14 @@ mapping may not support all of the listed options. Returns the name of the debug adapter driver being used. @end deffn +@deffn {Config Command} {adapter usb vid_pid} [vid pid]+ +Specifies the USB vendor and product IDs of the adapter to use. +Currently, up to 16 [@var{vid}, @var{pid}] pairs may be given, e.g. +@example +adapter usb vid_pid 0xc251 0xf001 0x0d28 0x0204 +@end example +@end deffn + @deffn {Config Command} {adapter usb location} [<bus>-<port>[.<port>]...] Displays or specifies the physical USB port of the adapter to use. The path roots at @var{bus} and walks down the physical ports, with each diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 7bf049cd86..a023438528 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -34,12 +34,17 @@ enum adapter_clk_mode { #define DEFAULT_CLOCK_SPEED_KHZ 100U +#define MAX_USB_IDS 16 + /** * Adapter configuration */ static struct { bool adapter_initialized; char *usb_location; + // vid = pid = 0 marks the end of the list. + uint16_t usb_vids[MAX_USB_IDS + 1]; + uint16_t usb_pids[MAX_USB_IDS + 1]; char *serial; enum adapter_clk_mode clock_mode; int speed_khz; @@ -325,6 +330,16 @@ static void adapter_usb_set_location(const char *location) } #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */ +const uint16_t *adapter_usb_get_vids(void) +{ + return adapter_config.usb_vids; +} + +const uint16_t *adapter_usb_get_pids(void) +{ + return adapter_config.usb_pids; +} + const char *adapter_usb_get_location(void) { return adapter_config.usb_location; @@ -1104,7 +1119,38 @@ COMMAND_HANDLER(handle_usb_location_command) } #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */ +COMMAND_HANDLER(handle_usb_vid_pid_command) +{ + if (MAX_USB_IDS * 2 < CMD_ARGC) { + LOG_WARNING("ignoring extra IDs in vid_pid " + "(maximum is %d pairs)", MAX_USB_IDS); + CMD_ARGC = MAX_USB_IDS * 2; + } + if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { + LOG_WARNING("incomplete vid_pid configuration directive"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + unsigned int i; + for (i = 0; i < CMD_ARGC; i += 2) { + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], adapter_config.usb_vids[i / 2]); + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], adapter_config.usb_pids[i / 2]); + } + + /* null termination */ + adapter_config.usb_vids[i / 2] = 0; + adapter_config.usb_pids[i / 2] = 0; + + return ERROR_OK; +} + static const struct command_registration adapter_usb_command_handlers[] = { + { + .name = "vid_pid", + .handler = &handle_usb_vid_pid_command, + .mode = COMMAND_CONFIG, + .help = "display or set the USB VID and PID of the USB device", + .usage = "(vid pid)*", + }, #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS { .name = "location", diff --git a/src/jtag/adapter.h b/src/jtag/adapter.h index 6e957cbdc0..4254ae96dc 100644 --- a/src/jtag/adapter.h +++ b/src/jtag/adapter.h @@ -95,6 +95,11 @@ const char *adapter_usb_get_location(void); /** @returns true if USB location string is "<dev_bus>-<port_path[0]>[.<port_path[1]>[...]]" */ bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len); +/** @returns USB VIDs set with command 'adapter usb vid_pid' */ +const uint16_t *adapter_usb_get_vids(void); +/** @returns USB PIDs set with command 'adapter usb vid_pid' */ +const uint16_t *adapter_usb_get_pids(void); + /** @returns The current adapter speed setting. */ int adapter_get_speed(int *speed); -- |
|
From: Tomas V. <to...@us...> - 2026-04-23 09:19:12
|
--- **[tickets:#470] adapter speed changes in target events fails with a fixed speed adapter** **Status:** new **Milestone:** 0.12.0 **Created:** Thu Apr 23, 2026 09:19 AM UTC by Tomas Vanek **Last Updated:** Thu Apr 23, 2026 09:19 AM UTC **Owner:** nobody If we use a fixed speed adapter (e.g. linuxgpiod) `adapter speed` command in the configuration phase is silently ignored. On the other hand `adapter speed` after `init` fails with `Translation from khz to adapter speed not implemented` Since merging 5049: target: use LOG_USER to print errors in events | https://review.openocd.org/c/openocd/+/5049 `adapter speed` used in an event (typically `reset-start` and `reset-init`) logs this: ``` > reset halt Translation from khz to adapter speed not implemented [stm32u3x.cpu] Execution of event reset-start failed: /home/vanekt/o/tcl//target/stm32x5x_common.cfg:125: Error: Traceback (most recent call last): File "embedded:startup.tcl", line 1471, in ocd_process_reset ocd_process_reset_inner halt File "/home/vanekt/o/tcl//target/stm32x5x_common.cfg", line 125, in ocd_process_reset_inner {adapter speed} 480 ``` IMO OpenOCD should accept a fixed speed adapter without making such noise. Moreover if the event contains some other Tcl commands after `adapter speed` they don't get executed. Possible solutions: - use `catch` with `adapter speed` in all event handlers. Con: more than 30 occurrences. - modify adapter.c code not to return error in case of a fixed speed adapter used --- Sent from sourceforge.net because ope...@li... is subscribed to https://sourceforge.net/p/openocd/tickets/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/openocd/admin/tickets/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |
|
From: Stefan B. <ste...@us...> - 2026-04-23 09:06:14
|
--- **[tickets:#469] Fix build with GCC 16.x** **Status:** new **Milestone:** 0.12.0 **Created:** Thu Apr 23, 2026 09:06 AM UTC by Stefan Becker **Last Updated:** Thu Apr 23, 2026 09:06 AM UTC **Owner:** nobody **Attachments:** - [0001-build-fix-build-with-GCC-16.x.patch](https://sourceforge.net/p/openocd/tickets/469/attachment/0001-build-fix-build-with-GCC-16.x.patch) (3.8 kB; text/x-patch) GCC 16.x has stricter settings, e.g. `strchr()` on `const char` buffer can only be assigned to `const char` pointer. Attached git patch with the fixes. Tested build on Fedora 44. --- Sent from sourceforge.net because ope...@li... is subscribed to https://sourceforge.net/p/openocd/tickets/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/openocd/admin/tickets/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |
|
From: <ge...@op...> - 2026-04-22 06:26:45
|
This is an automated email from Gerrit. "Sameer Srivastava <s-s...@ti...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9527 -- gerrit commit 99e9a4a6b32116f3ce9331b8e066a183d7d6d537 Author: Sameer Srivastava <s-s...@ti...> Date: Sun Mar 8 12:15:13 2026 +0530 src: flash: nor: added am13e230x flash driver Flashing uses the am13e230x flash loader that runs from SRAM, matching the CC26xx pattern. The algorithm is loaded into SRAM and started via target_start_algorithm. OpenOCD streams sector data into two ping-pong buffers; the algorithm erases each sector and programs it using direct FCTL register access. Signed-off-by: Sameer Srivastava <s-s...@ti...> Change-Id: Ifb910a545146514574fb4efecc3ad5aec38e2576 diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 5c4737f7ac..e2b72dd2b4 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -11,6 +11,7 @@ noinst_LTLIBRARIES += %D%/libocdflashnor.la NOR_DRIVERS = \ %D%/aduc702x.c \ %D%/aducm360.c \ + %D%/am13e230x.c \ %D%/ambiqmicro.c \ %D%/artery.c \ %D%/at91sam4.c \ diff --git a/src/flash/nor/am13e230x.c b/src/flash/nor/am13e230x.c new file mode 100644 index 0000000000..8f9d5632fc --- /dev/null +++ b/src/flash/nor/am13e230x.c @@ -0,0 +1,713 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + * + * NOR flash driver for AM13E230X class of uC from Texas Instruments. + * + * Erase uses direct register writes via the debug probe. + * Write uses an on-device algorithm loaded into SRAM (see + * contrib/loaders/flash/am13e230x/ and am13e230x.h). + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include "am13e230x.h" +#include <helper/binarybuffer.h> +#include <helper/bits.h> +#include <helper/time_support.h> +#include <target/algorithm.h> +#include <target/armv7m.h> + +/* Region memory map */ +#define AM13_FLASH_BASE_MAIN 0x00000000 +#define AM13_FLASH_BASE_NONMAIN 0x60100000 +#define AM13_NONMAIN_SIZE_PER_BANK 0x1000 + +/* Factory region registers */ +#define AM13_FACTORYREGION 0x60111000 +#define AM13_TRACEID (AM13_FACTORYREGION + 0x000) +#define AM13_DID (AM13_FACTORYREGION + 0x004) +#define AM13_SRAMFLASH (AM13_FACTORYREGION + 0x01C) + +/* Flash controller (NVMNW) registers */ +#define FLASH_CONTROL_BASE 0x40042000 +#define FCTL_REG_CMDEXEC (FLASH_CONTROL_BASE + 0x1100) +#define FCTL_REG_CMDTYPE (FLASH_CONTROL_BASE + 0x1104) +#define FCTL_REG_CMDADDR (FLASH_CONTROL_BASE + 0x1120) +#define FCTL_REG_CMDBYTEN (FLASH_CONTROL_BASE + 0x1124) +#define FCTL_REG_CMDDATAINDEX (FLASH_CONTROL_BASE + 0x112C) +#define FCTL_REG_CMDDATA0 (FLASH_CONTROL_BASE + 0x1130) +#define FCTL_REG_CMDWEPROTA (FLASH_CONTROL_BASE + 0x11D0) +#define FCTL_REG_CMDWEPROTB (FLASH_CONTROL_BASE + 0x11D4) +#define FCTL_REG_CMDWEPROTNM (FLASH_CONTROL_BASE + 0x1210) +#define FCTL_REG_STATCMD (FLASH_CONTROL_BASE + 0x13D0) + +/* GSC flash semaphore registers */ +#define GSC_BASE 0x40046000 +#define GSC_REG_FPC_FLSEMREQ (GSC_BASE + 0x1800) +#define GSC_REG_FPC_FLSEMCLR (GSC_BASE + 0x1804) + +/* STATCMD bits */ +#define FCTL_STATCMD_CMDDONE 0x00000001 +#define FCTL_STATCMD_CMDPASS 0x00000002 +#define FCTL_STATCMD_CMDINPROGRESS 0x00000004 + +/* CMDEXEC / CMDTYPE constants */ +#define FCTL_CMDEXEC_EXECUTE 0x00000001 +#define FCTL_CMDTYPE_PROGRAM 0x00000001 +#define FCTL_CMDTYPE_ERASE 0x00000002 +#define FCTL_CMDTYPE_CLEARSTATUS 0x00000005 +#define FCTL_CMDTYPE_SIZE_ONEWORD 0x00000000 +#define FCTL_CMDTYPE_SIZE_SECTOR 0x00000040 + +/* 128-bit program with hardware ECC generation (matches SDK PROGRAM_128_WITH_ECC) */ +#define AM13_PROGRAM_128_BYTEN 0x0003FFFF + +#define AM13_FLASH_WORD_SIZE 16 + +#define AM13_FLASH_TIMEOUT_MS 8000 +#define AM13_SECTOR_SIZE_BYTES 0x800 +#define TI_MANUFACTURER_ID 0x17 + +/* Flash loader algorithm binary */ +static const uint8_t am13_algo[] = { +#include "../../../contrib/loaders/flash/am13e230x/am13e230x_algo.inc" +}; + +struct am13_flash_bank { + uint32_t did; + uint32_t traceid; + unsigned int main_flash_size_kb; + unsigned int main_flash_num_banks; + unsigned int sram_size_kb; + unsigned int sector_size; + + /* Algorithm state */ + struct working_area *working_area; + struct armv7m_algorithm armv7m_info; +}; + +static int am13_auto_probe(struct flash_bank *bank); + +/* + * GSC flash semaphore must be held before any flash operation. + * The debug probe and the CPU have separate ownership tracking + * (FLSEMSTAT.DBGACC), so the erase path (debug probe) and the + * write path (on-device algorithm) each acquire it independently. + */ + +static void am13_request_gsc_semaphore(struct flash_bank *bank) +{ + target_write_u32(bank->target, GSC_REG_FPC_FLSEMREQ, 1); +} + +static void am13_clear_gsc_semaphore(struct flash_bank *bank) +{ + target_write_u32(bank->target, GSC_REG_FPC_FLSEMCLR, 1); +} + +/* ---------- Flash controller helpers (erase path only) ---------- */ + +static const struct { + unsigned char bit; + const char *name; +} am13_fctl_errors[] = { + { 2, "CMDINPROGRESS" }, + { 4, "FAILWEPROT" }, + { 5, "FAILVERIFY" }, + { 6, "FAILILLADDR" }, + { 7, "FAILMODE" }, + { 12, "FAILMISC" }, +}; + +static const char *am13_fctl_strerror(uint32_t status) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(am13_fctl_errors); i++) { + if (status & BIT(am13_fctl_errors[i].bit)) + return am13_fctl_errors[i].name; + } + return "FAILUNKNOWN"; +} + +static int am13_fctl_wait_done(struct flash_bank *bank) +{ + struct target *target = bank->target; + uint32_t status = 0; + int64_t start_ms = timeval_ms(); + + while ((status & FCTL_STATCMD_CMDDONE) == 0) { + int retval = target_read_u32(target, FCTL_REG_STATCMD, &status); + if (retval != ERROR_OK) + return retval; + if (timeval_ms() - start_ms > AM13_FLASH_TIMEOUT_MS) + break; + keep_alive(); + } + + if ((status & FCTL_STATCMD_CMDPASS) == 0) { + LOG_ERROR("Flash command failed: %s", am13_fctl_strerror(status)); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +static int am13_fctl_clear_status(struct flash_bank *bank) +{ + struct target *target = bank->target; + uint32_t status; + int64_t start_ms; + int retval; + + retval = target_write_u32(target, FCTL_REG_CMDTYPE, FCTL_CMDTYPE_CLEARSTATUS); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_EXECUTE); + if (retval != ERROR_OK) + return retval; + + start_ms = timeval_ms(); + do { + retval = target_read_u32(target, FCTL_REG_STATCMD, &status); + if (retval != ERROR_OK) + return retval; + if (timeval_ms() - start_ms > AM13_FLASH_TIMEOUT_MS) { + LOG_ERROR("Timeout waiting for clear status"); + return ERROR_FAIL; + } + keep_alive(); + } while (status & FCTL_STATCMD_CMDINPROGRESS); + + return ERROR_OK; +} + +static int am13_fctl_unprotect(struct flash_bank *bank) +{ + struct target *target = bank->target; + int retval; + + switch (bank->base) { + case AM13_FLASH_BASE_MAIN: + retval = target_write_u32(target, FCTL_REG_CMDWEPROTA, 0); + if (retval != ERROR_OK) + return retval; + return target_write_u32(target, FCTL_REG_CMDWEPROTB, 0); + case AM13_FLASH_BASE_NONMAIN: + return target_write_u32(target, FCTL_REG_CMDWEPROTNM, 0); + default: + return ERROR_FLASH_BANK_INVALID; + } +} + +static int am13_fctl_sector_erase(struct flash_bank *bank, uint32_t addr) +{ + struct target *target = bank->target; + int retval; + + retval = am13_fctl_clear_status(bank); + if (retval != ERROR_OK) + return retval; + + retval = am13_fctl_unprotect(bank); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDTYPE, + FCTL_CMDTYPE_ERASE | FCTL_CMDTYPE_SIZE_SECTOR); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDADDR, addr); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_EXECUTE); + if (retval != ERROR_OK) + return retval; + + return am13_fctl_wait_done(bank); +} + +/* ---------- Flash driver callbacks ---------- */ + +FLASH_BANK_COMMAND_HANDLER(am13_flash_bank_command) +{ + switch (bank->base) { + case AM13_FLASH_BASE_MAIN: + case AM13_FLASH_BASE_NONMAIN: + break; + default: + LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); + return ERROR_FAIL; + } + + struct am13_flash_bank *am13_info = calloc(1, sizeof(*am13_info)); + if (!am13_info) + return ERROR_FAIL; + + bank->driver_priv = am13_info; + am13_info->sector_size = AM13_SECTOR_SIZE_BYTES; + + return ERROR_OK; +} + +static int am13_protect_check(struct flash_bank *bank) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + /* Protection resets after every operation; report as unprotected */ + for (unsigned int i = 0; i < bank->num_sectors; i++) + bank->sectors[i].is_protected = 0; + + return ERROR_OK; +} + +static int am13_erase(struct flash_bank *bank, unsigned int first, + unsigned int last) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + int retval; + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + am13_request_gsc_semaphore(bank); + + for (unsigned int s = first; s <= last; s++) { + uint32_t addr; + + if (bank->base == AM13_FLASH_BASE_NONMAIN) + addr = AM13_FLASH_BASE_NONMAIN + s * am13_info->sector_size; + else + addr = s * am13_info->sector_size; + + retval = am13_fctl_sector_erase(bank, addr); + if (retval != ERROR_OK) { + LOG_ERROR("Sector erase failed at 0x%08" PRIx32, addr); + am13_clear_gsc_semaphore(bank); + return retval; + } + } + + am13_clear_gsc_semaphore(bank); + return ERROR_OK; +} + +/* ---------- Direct write fallback (via debug probe) ---------- */ + +/* + * Word-by-word flash write using direct register access from the debug + * probe. Slower than the on-device algorithm but does not require SRAM, + * so it works as a fallback when the algorithm cannot be loaded (e.g., + * SRAM is needed by a RAM-resident application). + */ +static int am13_write_direct(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct target *target = bank->target; + uint32_t addr = bank->base + offset; + int retval; + + am13_request_gsc_semaphore(bank); + + while (count > 0) { + uint32_t n = MIN(count, AM13_FLASH_WORD_SIZE); + uint8_t word[AM13_FLASH_WORD_SIZE]; + + /* Pad partial words with 0xFF */ + memset(word, 0xFF, sizeof(word)); + memcpy(word, buffer, n); + + /* Clear status + unprotect before every word (per SDK) */ + retval = am13_fctl_clear_status(bank); + if (retval != ERROR_OK) + break; + + retval = am13_fctl_unprotect(bank); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDTYPE, + FCTL_CMDTYPE_PROGRAM | FCTL_CMDTYPE_SIZE_ONEWORD); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDBYTEN, + AM13_PROGRAM_128_BYTEN); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDADDR, + addr & 0xFFFFFFF0); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDDATAINDEX, + (addr >> 4) & 3); + if (retval != ERROR_OK) + break; + + retval = target_write_buffer(target, FCTL_REG_CMDDATA0, + AM13_FLASH_WORD_SIZE, word); + if (retval != ERROR_OK) + break; + + retval = target_write_u32(target, FCTL_REG_CMDEXEC, + FCTL_CMDEXEC_EXECUTE); + if (retval != ERROR_OK) + break; + + retval = am13_fctl_wait_done(bank); + if (retval != ERROR_OK) + break; + + addr += n; + buffer += n; + count -= n; + } + + am13_clear_gsc_semaphore(bank); + return retval; +} + +/* ---------- Flash loader algorithm ---------- */ + +static int am13_algo_init(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + int retval; + + retval = am13_auto_probe(bank); + if (retval != ERROR_OK) + return retval; + + /* Allocate SRAM for algorithm + buffers */ + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + + retval = target_alloc_working_area(target, AM13_ALGO_WORKING_SIZE, + &am13_info->working_area); + if (retval != ERROR_OK) { + LOG_ERROR("AM13: insufficient SRAM for flash loader (%u bytes)", + AM13_ALGO_WORKING_SIZE); + return retval; + } + + if (am13_info->working_area->address != AM13_ALGO_BASE) { + LOG_ERROR("AM13: working area at wrong address"); + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + retval = target_write_buffer(target, AM13_ALGO_BASE, + sizeof(am13_algo), am13_algo); + if (retval != ERROR_OK) { + LOG_ERROR("AM13: failed to load flash algorithm"); + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + return retval; + } + + /* + * Release any debug-held GSC semaphore so the algorithm (CPU) + * can acquire it — the flash controller tracks ownership via + * FLSEMSTAT.DBGACC and rejects mismatched access. + */ + am13_clear_gsc_semaphore(bank); + + /* Disable NVIC — stale Zephyr ISRs would fault on overwritten SRAM */ + for (uint32_t icer = 0xE000E180; icer <= 0xE000E19C; icer += 4) + target_write_u32(target, icer, 0xFFFFFFFF); + + /* Disable MPU — previous app may restrict peripheral access */ + target_write_u32(target, 0xE000ED94, 0x00000000); + + am13_info->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + am13_info->armv7m_info.core_mode = ARM_MODE_THREAD; + + /* + * Force privileged Thread mode via reg_param. OpenOCD's + * armv7m_start_algorithm only updates CONTROL when the requested + * mode differs from current — but if Zephyr was also in Thread + * mode with nPRIV=1, CONTROL is left untouched and the algorithm + * inherits unprivileged mode. + */ + struct reg_param reg_params[1]; + init_reg_param(®_params[0], "pmsk_bpri_fltmsk_ctrl", 32, PARAM_OUT); + buf_set_u32(reg_params[0].value, 0, 32, 0x00000000); + + LOG_DEBUG("AM13: starting flash algorithm"); + retval = target_start_algorithm(target, 0, NULL, 1, reg_params, + AM13_ALGO_BASE, 0, + &am13_info->armv7m_info); + + destroy_reg_param(®_params[0]); + + if (retval != ERROR_OK) { + LOG_ERROR("AM13: failed to start flash algorithm"); + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + } + + return retval; +} + +static int am13_algo_quit(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + + (void)target_halt(target); + + int retval = target_wait_algorithm(target, 0, NULL, 0, NULL, + 0, AM13_FLASH_TIMEOUT_MS, + &am13_info->armv7m_info); + + am13_clear_gsc_semaphore(bank); + + target_free_working_area(target, am13_info->working_area); + am13_info->working_area = NULL; + + return retval; +} + +static int am13_algo_wait_done(struct flash_bank *bank, uint32_t params_addr) +{ + struct target *target = bank->target; + uint32_t status = AM13_BUFFER_FULL; + int64_t start_ms = timeval_ms(); + int retval; + + while (status == AM13_BUFFER_FULL) { + retval = target_read_u32(target, params_addr + AM13_STATUS_OFFSET, + &status); + if (retval != ERROR_OK) + return retval; + + int64_t elapsed_ms = timeval_ms() - start_ms; + if (elapsed_ms > 500) + keep_alive(); + if (elapsed_ms > AM13_FLASH_TIMEOUT_MS) + break; + } + + if (status != AM13_BUFFER_EMPTY) { + LOG_ERROR("AM13: flash algorithm error, status=0x%08" PRIx32, + status); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +static int am13_write(struct flash_bank *bank, const unsigned char *buffer, + unsigned int offset, unsigned int count) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + struct am13_algo_params algo_params[2]; + int retval; + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + retval = am13_algo_init(bank); + if (retval != ERROR_OK) { + LOG_INFO("AM13: algorithm unavailable, falling back to direct writes"); + return am13_write_direct(bank, buffer, offset, count); + } + + static const uint32_t params_addr[] = { + AM13_ALGO_PARAMS_0, AM13_ALGO_PARAMS_1 + }; + static const uint32_t buffer_addr[] = { + AM13_ALGO_BUFFER_0, AM13_ALGO_BUFFER_1 + }; + + uint32_t address = bank->base + offset; + uint32_t index = 0; + int64_t start_ms = timeval_ms(); + + buf_set_u32(algo_params[0].cmd, 0, 32, AM13_CMD_ERASE_AND_PROGRAM); + buf_set_u32(algo_params[1].cmd, 0, 32, AM13_CMD_ERASE_AND_PROGRAM); + + while (count > 0) { + uint32_t size = MIN(count, AM13_SECTOR_SIZE_BYTES); + + retval = target_write_buffer(target, buffer_addr[index], + size, buffer); + if (retval != ERROR_OK) + break; + + buf_set_u32(algo_params[index].dest, 0, 32, address); + buf_set_u32(algo_params[index].len, 0, 32, size); + buf_set_u32(algo_params[index].status, 0, 32, AM13_BUFFER_FULL); + + /* Write dest/len/cmd/status only — preserve algorithm's buf_addr */ + retval = target_write_buffer(target, params_addr[index], + offsetof(struct am13_algo_params, buf_addr), + (uint8_t *)&algo_params[index]); + if (retval != ERROR_OK) + break; + + index ^= 1; + retval = am13_algo_wait_done(bank, params_addr[index]); + if (retval != ERROR_OK) + break; + + count -= size; + buffer += size; + address += size; + + if (timeval_ms() - start_ms > 500) + keep_alive(); + } + + /* Wait for the last submitted buffer */ + if (retval == ERROR_OK) { + index ^= 1; + retval = am13_algo_wait_done(bank, params_addr[index]); + } + + (void)am13_algo_quit(bank); + return retval; +} + +/* ---------- Probe ---------- */ + +static int am13_probe(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct am13_flash_bank *am13_info = bank->driver_priv; + uint32_t did, sramflash; + int retval; + + retval = target_read_u32(target, AM13_DID, &did); + if (retval != ERROR_OK) + return retval; + + if (((did & GENMASK(11, 1)) >> 1) != TI_MANUFACTURER_ID) { + LOG_ERROR("AM13: unexpected manufacturer ID in DID=0x%08" PRIx32, + did); + return ERROR_FAIL; + } + + am13_info->did = did; + + retval = target_read_u32(target, AM13_TRACEID, &am13_info->traceid); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u32(target, AM13_SRAMFLASH, &sramflash); + if (retval != ERROR_OK) + return retval; + + am13_info->main_flash_size_kb = sramflash & GENMASK(11, 0); + am13_info->main_flash_num_banks = (sramflash & GENMASK(13, 12)) >> 12; + am13_info->sram_size_kb = (sramflash & GENMASK(25, 16)) >> 16; + + free(bank->sectors); + bank->sectors = NULL; + + unsigned int num_sectors; + switch (bank->base) { + case AM13_FLASH_BASE_MAIN: + bank->size = am13_info->main_flash_size_kb * 1024; + num_sectors = bank->size / am13_info->sector_size; + break; + case AM13_FLASH_BASE_NONMAIN: + bank->size = am13_info->main_flash_num_banks * AM13_NONMAIN_SIZE_PER_BANK; + num_sectors = bank->size / am13_info->sector_size; + break; + default: + LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); + return ERROR_FAIL; + } + + if (num_sectors == 0) { + bank->num_sectors = 0; + bank->size = 0; + return ERROR_OK; + } + + bank->num_sectors = num_sectors; + bank->sectors = calloc(num_sectors, sizeof(struct flash_sector)); + if (!bank->sectors) + return ERROR_FAIL; + + for (unsigned int i = 0; i < num_sectors; i++) { + bank->sectors[i].offset = i * am13_info->sector_size; + bank->sectors[i].size = am13_info->sector_size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 0; + } + + LOG_INFO("AM13: %s flash: %u KB (%u sectors), %u bank(s), SRAM: %u KB", + (bank->base == AM13_FLASH_BASE_MAIN) ? "MAIN" : "NONMAIN", + (unsigned int)(bank->size / 1024), num_sectors, + am13_info->main_flash_num_banks, + am13_info->sram_size_kb); + + return ERROR_OK; +} + +static int am13_auto_probe(struct flash_bank *bank) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + + if (am13_info->did) + return ERROR_OK; + + return am13_probe(bank); +} + +static int get_am13_info(struct flash_bank *bank, + struct command_invocation *cmd) +{ + struct am13_flash_bank *am13_info = bank->driver_priv; + + if (!am13_info->did) + return ERROR_FLASH_BANK_NOT_PROBED; + + command_print_sameline(cmd, "AM13E23X: DID=0x%08" PRIx32 + " TRACEID=0x%08" PRIx32 + " banks=%u", + am13_info->did, am13_info->traceid, + am13_info->main_flash_num_banks); + return ERROR_OK; +} + +const struct flash_driver am13_flash = { + .name = "am13", + .flash_bank_command = am13_flash_bank_command, + .erase = am13_erase, + .protect = NULL, + .write = am13_write, + .read = default_flash_read, + .probe = am13_probe, + .auto_probe = am13_auto_probe, + .erase_check = default_flash_blank_check, + .protect_check = am13_protect_check, + .info = get_am13_info, + .free_driver_priv = default_flash_free_driver_priv, +}; diff --git a/src/flash/nor/am13e230x.h b/src/flash/nor/am13e230x.h new file mode 100644 index 0000000000..3849e5ad01 --- /dev/null +++ b/src/flash/nor/am13e230x.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + * + * Flash loader algorithm parameters for AM13E230X. + * Addresses must match the linker script in + * contrib/loaders/flash/am13e230x/am13e230x.lds + ***************************************************************************/ + +#ifndef OPENOCD_FLASH_NOR_AM13E230X_H +#define OPENOCD_FLASH_NOR_AM13E230X_H + +/* Algorithm is loaded at the base of SRAM */ +#define AM13_ALGO_BASE 0x20000000 + +/* Parameter blocks (two, for ping-pong) */ +#define AM13_ALGO_PARAMS_0 0x20002000 +#define AM13_ALGO_PARAMS_1 0x20002014 + +/* Data buffers (each one sector = 2 KB) */ +#define AM13_ALGO_BUFFER_0 0x20002100 +#define AM13_ALGO_BUFFER_1 0x20002900 + +/* Total working area needed */ +#define AM13_ALGO_WORKING_SIZE (AM13_ALGO_BUFFER_1 + 0x800 - AM13_ALGO_BASE) + +/* Handshake values (must match loader main.c) */ +#define AM13_BUFFER_EMPTY 0x00000000 +#define AM13_BUFFER_FULL 0xFFFFFFFF + +/* Offset of the status field within flash_params */ +#define AM13_STATUS_OFFSET 0x0C + +/* Commands (must match loader main.c) */ +#define AM13_CMD_NO_ACTION 0 +#define AM13_CMD_ERASE_ALL 1 +#define AM13_CMD_PROGRAM 2 +#define AM13_CMD_ERASE_AND_PROGRAM 3 +#define AM13_CMD_ERASE_SECTORS 4 + +/* Parameter block layout (matches struct flash_params in loader) */ +struct am13_algo_params { + uint8_t dest[4]; + uint8_t len[4]; + uint8_t cmd[4]; + uint8_t status[4]; + uint8_t buf_addr[4]; +}; + +#endif /* OPENOCD_FLASH_NOR_AM13E230X_H */ diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index afb73a3fb2..3748292c77 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -240,6 +240,7 @@ const struct flash_driver *flash_driver_find_by_name(const char *name); // Keep in alphabetic order this list of drivers extern const struct flash_driver aduc702x_flash; extern const struct flash_driver aducm360_flash; +extern const struct flash_driver am13_flash; extern const struct flash_driver ambiqmicro_flash; extern const struct flash_driver artery_flash; extern const struct flash_driver at91sam3_flash; diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index 094b5a76ba..fa3f315bac 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -19,6 +19,7 @@ static const struct flash_driver * const flash_drivers[] = { // Keep in alphabetic order the list of drivers &aduc702x_flash, &aducm360_flash, + &am13_flash, &ambiqmicro_flash, &artery_flash, &at91sam3_flash, -- |
|
From: <ge...@op...> - 2026-04-22 06:26:43
|
This is an automated email from Gerrit. "Sameer Srivastava <s-s...@ti...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9525 -- gerrit commit cb28a05c91e73629d2888ad8af6c30bde05dc69c Author: Sameer Srivastava <s-s...@ti...> Date: Sun Mar 8 12:10:37 2026 +0530 tcl: added am13e230x target and launchpad cfg - target defines SRAM work area and flash region - board selects xds110 interface and speed Signed-off-by: Sameer Srivastava <s-s...@ti...> Change-Id: I6cb9f52867a1a64895d9ff81f0c38b228578fc1a diff --git a/tcl/board/ti/am13e230x-launchpad.cfg b/tcl/board/ti/am13e230x-launchpad.cfg new file mode 100644 index 0000000000..2ca32ceaa8 --- /dev/null +++ b/tcl/board/ti/am13e230x-launchpad.cfg @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ +# + +source [find interface/xds110.cfg] +adapter speed 10000 +source [find target/ti/am13e230x.cfg] +init +reset halt diff --git a/tcl/target/ti/am13e230x.cfg b/tcl/target/ti/am13e230x.cfg new file mode 100644 index 0000000000..4bf0b608ff --- /dev/null +++ b/tcl/target/ti/am13e230x.cfg @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ +# +# Texas Instruments AM13E230X - ARM Cortex-M33 @ 200MHz +# + +source [find bitsbytes.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME AM13E230X +} + +if { [info exists CPUTAPID] } { + set _DAP_TAPID $CPUTAPID +} else { + set _DAP_TAPID 0x6ba00477 +} + +transport select jtag + +set _DAP_ID $_DAP_TAPID + +jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID + +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap + +if { [info exists WORKAREABASE] } { + set _WORKAREABASE $WORKAREABASE +} else { + set _WORKAREABASE 0x20000000 +} +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x18000 +} + +$_TARGETNAME configure -work-area-phys $_WORKAREABASE -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME.main am13 0x00000000 0 0 0 $_TARGETNAME +flash bank $_FLASHNAME.nonmain am13 0x60100000 0 0 0 $_TARGETNAME + +if {![using_hla]} { + cortex_m reset_config sysresetreq +} -- |
|
From: <ge...@op...> - 2026-04-22 06:26:40
|
This is an automated email from Gerrit. "Sameer Srivastava <s-s...@ti...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9526 -- gerrit commit f9f25125f68995287b29214402a80ca70a68b314 Author: Sameer Srivastava <s-s...@ti...> Date: Sun Mar 8 12:12:04 2026 +0530 contrib: loaders: add am13e230x flash loader algorithm Created a flash loader for AM13E230X that receives flash sectors via shared memory ping-pong buffers, similar to the CC26xx flash loader. Signed-off-by: Sameer Srivastava <s-s...@ti...> Change-Id: If5759b6f513cf94a0208d1bf4e95eb012a297d17 diff --git a/contrib/loaders/flash/am13e230x/Makefile b/contrib/loaders/flash/am13e230x/Makefile new file mode 100644 index 0000000000..689e4cdf85 --- /dev/null +++ b/contrib/loaders/flash/am13e230x/Makefile @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + +BIN2C = ../../../../src/helper/bin2char.sh + +CROSS_COMPILE ?= arm-none-eabi- +GCC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy + +FLAGS = -mcpu=cortex-m33 -mthumb -Os +FLAGS += -ffunction-sections -fdata-sections +FLAGS += -g -gdwarf-3 -gstrict-dwarf +FLAGS += -Wall -fno-strict-aliasing -fno-builtin +FLAGS += -nostdlib -nostartfiles + +CFLAGS = -c -I. + +OBJS := \ + startup.o \ + main.o \ + flash.o + +all: am13e230x_algo.inc + +%.o: %.c + @echo 'Building: $<' + $(GCC) $(FLAGS) $(CFLAGS) -o "$@" "$<" + +am13e230x_algo.out: $(OBJS) + @echo 'Linking: $@' + $(GCC) $(FLAGS) -o $@ $(OBJS) -Wl,-T"am13e230x.lds" + +%.bin: %.out + @echo 'Objcopy: $@' + $(OBJCOPY) -Obinary $< $@ + +%.inc: %.bin + @echo 'Bin2Char: $@' + $(BIN2C) < $< > $@ + rm $< $*.out + +clean: + rm -rf *.o *.d *.out *.bin *.inc *.map + +.PRECIOUS: %.bin + +.PHONY: all clean diff --git a/contrib/loaders/flash/am13e230x/am13e230x.lds b/contrib/loaders/flash/am13e230x/am13e230x.lds new file mode 100644 index 0000000000..db0fc1da76 --- /dev/null +++ b/contrib/loaders/flash/am13e230x/am13e230x.lds @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/****************************************************************************** + * + * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + * + * Linker script for AM13E230X flash loader algorithm. + * Everything runs from SRAM. Params and buffers are at fixed addresses + * that the OpenOCD driver knows about (see am13e230x.h). + * + *****************************************************************************/ + +ENTRY( entry ) + +MEMORY +{ + /* Code, data, bss, stack */ + PROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x2000 + /* Params and data buffers at known addresses */ + BUFFERS (RWX) : ORIGIN = 0x20002000, LENGTH = 0x1100 +} + +SECTIONS +{ + .text : + { + _text = .; + *(.entry*) + *(.text*) + _etext = .; + } > PROGRAM + + .data : + { + _data = .; + *(.rodata*) + *(.data*) + _edata = .; + } > PROGRAM + + .bss : + { + __bss_start__ = .; + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + __bss_end__ = .; + } > PROGRAM + + .stack : + { + _stack = .; + *(.stack*) + _estack = .; + } > PROGRAM + + .buffers : + { + _buffers = .; + *(.buffers.params) + . = 0x100; + *(.buffers.buf0) + *(.buffers.buf1) + _ebuffers = .; + } > BUFFERS +} diff --git a/contrib/loaders/flash/am13e230x/am13e230x_algo.inc b/contrib/loaders/flash/am13e230x/am13e230x_algo.inc new file mode 100644 index 0000000000..3ebb130274 --- /dev/null +++ b/contrib/loaders/flash/am13e230x/am13e230x_algo.inc @@ -0,0 +1,785 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x4f,0xf0,0x00,0x00,0x80,0xf3,0x14,0x88, +0xbf,0xf3,0x6f,0x8f,0xdf,0xf8,0x18,0xd0,0x06,0x48,0x07,0x49,0x4f,0xf0,0x00,0x02, +0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0x07,0xf8,0xfe,0xe7, +0x68,0x04,0x00,0x20,0xd8,0x02,0x00,0x20,0xd8,0x02,0x00,0x20,0x2d,0xe9,0xf0,0x47, +0x00,0x25,0x34,0x4c,0x34,0x4b,0x4f,0xf0,0x14,0x09,0x23,0x61,0x33,0x4b,0xa8,0x46, +0x63,0x62,0x23,0x7b,0x25,0x73,0x63,0x7b,0x65,0x73,0xa3,0x7b,0xa5,0x73,0xe3,0x7b, +0xe5,0x73,0x94,0xf8,0x20,0x30,0x84,0xf8,0x20,0x50,0x94,0xf8,0x21,0x30,0x84,0xf8, +0x21,0x50,0x94,0xf8,0x22,0x30,0x84,0xf8,0x22,0x50,0x94,0xf8,0x23,0x30,0x84,0xf8, +0x23,0x50,0x00,0xf0,0x8f,0xf8,0x09,0xfb,0x05,0xf7,0xe6,0x19,0x06,0xf1,0x08,0x02, +0x53,0x68,0x00,0x2b,0xfc,0xd0,0xb3,0x68,0x03,0x2b,0x0c,0xd0,0x04,0x2b,0x17,0xd0, +0x02,0x2b,0x0c,0xd0,0x40,0xf2,0x03,0x12,0x14,0x23,0x03,0xfb,0x05,0x43,0xda,0x60, +0x00,0xf0,0x80,0xf8,0xfe,0xe7,0xe0,0x59,0x00,0xf0,0x84,0xf8,0x38,0xbb,0x30,0x69, +0xe1,0x59,0x72,0x68,0x00,0xf0,0x98,0xf8,0x48,0xb1,0x4f,0xf4,0x81,0x72,0xeb,0xe7, +0x54,0xf8,0x07,0xa0,0xe3,0x59,0x72,0x68,0x9e,0x18,0x56,0x45,0x10,0xd8,0x09,0xfb, +0x05,0x43,0x1a,0x7b,0x83,0xf8,0x0c,0x80,0x5a,0x7b,0x83,0xf8,0x0d,0x80,0x9a,0x7b, +0x83,0xf8,0x0e,0x80,0xda,0x7b,0x85,0xf0,0x01,0x05,0x83,0xf8,0x0f,0x80,0xc2,0xe7, +0x50,0x46,0x00,0xf0,0x5f,0xf8,0x10,0xb9,0x0a,0xf5,0x00,0x6a,0xe5,0xe7,0x40,0xf2, +0x01,0x12,0xc9,0xe7,0x00,0x20,0x00,0x20,0x00,0x21,0x00,0x20,0x00,0x29,0x00,0x20, +0xfe,0xe7,0x00,0x00,0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x01,0x23,0x0d,0x49, +0xc1,0xf8,0x00,0x31,0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x4f,0xf4,0x00,0x03, +0x01,0x3b,0xd1,0xf8,0xd0,0x23,0x0a,0xd0,0x02,0xf0,0x07,0x00,0x04,0x28,0xf7,0xd0, +0x12,0xf0,0x02,0x0f,0x0c,0xbf,0x6f,0xf0,0x01,0x00,0x00,0x20,0x70,0x47,0x4f,0xf0, +0xff,0x30,0x70,0x47,0x00,0x30,0x04,0x40,0x05,0x22,0x0d,0x4b,0xc3,0xf8,0x04,0x21, +0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x01,0x22,0xc3,0xf8,0x00,0x21,0xbf,0xf3, +0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x4f,0xf4,0x00,0x02,0xd3,0xf8,0xd0,0x03,0x10,0xf0, +0x04,0x00,0x00,0xd1,0x70,0x47,0x01,0x3a,0xf7,0xd1,0x4f,0xf0,0xff,0x30,0x70,0x47, +0x00,0x30,0x04,0x40,0x01,0x22,0x02,0x4b,0xc3,0xf8,0x00,0x28,0x70,0x47,0x00,0xbf, +0x00,0x70,0x04,0x40,0x01,0x22,0x02,0x4b,0xc3,0xf8,0x04,0x28,0x70,0x47,0x00,0xbf, +0x00,0x70,0x04,0x40,0x08,0xb5,0x01,0x46,0xff,0xf7,0xce,0xff,0x78,0xb9,0x42,0x22, +0x08,0x4b,0x21,0xf0,0x0f,0x01,0xc3,0xf8,0xd0,0x01,0xc3,0xf8,0xd4,0x01,0xc3,0xf8, +0x04,0x21,0xc3,0xf8,0x20,0x11,0xbd,0xe8,0x08,0x40,0xff,0xf7,0x9b,0xbf,0x4f,0xf0, +0xff,0x30,0x08,0xbd,0x00,0x30,0x04,0x40,0x2d,0xe9,0xf0,0x4f,0x06,0x46,0x89,0x46, +0x15,0x46,0xdf,0xf8,0xc8,0xa0,0xdf,0xf8,0xc8,0x80,0x85,0xb0,0x0d,0xb9,0x28,0x46, +0x4c,0xe0,0x10,0x2d,0x2f,0x46,0x28,0xbf,0x10,0x27,0x7b,0x07,0x4e,0xd0,0x0f,0x23, +0x6a,0x46,0x6c,0x46,0xff,0x20,0xf9,0x1d,0x21,0xf0,0x07,0x01,0x01,0x3b,0x02,0xf8, +0x01,0x0b,0xfb,0xd2,0x22,0x46,0x33,0x46,0xf0,0x19,0x83,0x42,0x39,0xd1,0x08,0x29, +0x1d,0xbf,0x4f,0xf0,0x01,0x0b,0x0b,0xfa,0x01,0xfb,0x0b,0xf1,0xff,0x3b,0xdf,0xf8, +0x84,0xb0,0x18,0xbf,0x4b,0xf4,0x40,0x3b,0xff,0xf7,0x86,0xff,0x00,0x22,0x01,0x23, +0xca,0xf8,0xd0,0x21,0xca,0xf8,0xd4,0x21,0xca,0xf8,0x04,0x31,0x29,0xf0,0x0f,0x03, +0xca,0xf8,0x24,0xb1,0xca,0xf8,0x20,0x31,0xc9,0xf3,0x01,0x13,0xca,0xf8,0x2c,0x31, +0xa3,0x78,0x60,0x78,0x1b,0x04,0x43,0xea,0x00,0x23,0x20,0x78,0x04,0x34,0x03,0x43, +0x14,0xf8,0x01,0x0c,0x43,0xea,0x00,0x63,0x42,0xf8,0x08,0x30,0x04,0x32,0x91,0x42, +0xee,0xd8,0xff,0xf7,0x3f,0xff,0x60,0xb1,0x4f,0xf0,0xff,0x30,0x05,0xb0,0xbd,0xe8, +0xf0,0x8f,0x13,0xf8,0x01,0xcb,0x02,0xf8,0x01,0xcb,0xbe,0xe7,0x34,0x46,0x39,0x46, +0xbd,0xe7,0xb9,0x44,0x3e,0x44,0xed,0x1b,0xa0,0xe7,0x00,0xbf,0x00,0x30,0x04,0x40, +0x30,0x31,0x04,0x40,0xff,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,... [truncated message content] |
|
From: <ge...@op...> - 2026-04-19 11:44:34
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9582 -- gerrit commit 2e96a667f6f3b2b96fd6387daad7620af8195519 Author: Marc Schink <de...@za...> Date: Sat Apr 18 16:19:56 2026 +0200 adapters/xvc: Fix xvc_init_tcp() Avoid calling setsockopt() on an invalid socket when the TCP connection setup fails. While at it, restructure the code and apply const-correctness. Change-Id: I1dc3da89321c5d0b4c76c145501c80206a3c9de4 Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index 8a1bc7c7fd..d5a5810f35 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -324,10 +324,13 @@ static int xvc_reset(int trst, int srst) static int xvc_init_tcp(int *fd) { - struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM}; - LOG_INFO("Connecting to %s:%s", xvc_host ? xvc_host : "localhost", xvc_port); + const struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM + }; + struct addrinfo *result; // Obtain address(es) matching host/port. int s = getaddrinfo(xvc_host, xvc_port, &hints, &result); @@ -350,20 +353,12 @@ static int xvc_init_tcp(int *fd) if (*fd == (int)INVALID_SOCKET) continue; #endif - if (connect(*fd, rp->ai_addr, rp->ai_addrlen) != -1) break; close_socket(*fd); } - /* We work hard to collapse the writes into the minimum number, so when - * we write something we want to get it to the other end of the - * connection as fast as possible. */ - int one = 1; - // On Windows optval has to be a const char *. - setsockopt(*fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)); - freeaddrinfo(result); if (!rp) { @@ -371,6 +366,13 @@ static int xvc_init_tcp(int *fd) return ERROR_FAIL; } + /* We work hard to collapse the writes into the minimum number, so when + * we write something we want to get it to the other end of the + * connection as fast as possible. */ + int one = 1; + // On Windows optval has to be a const char *. + setsockopt(*fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)); + return ERROR_OK; } -- |
|
From: <ge...@op...> - 2026-04-19 11:44:34
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9580 -- gerrit commit d0157905af08a1a2e3a33b02bc4c9e2ed272824d Author: Marc Schink <de...@za...> Date: Sat Apr 18 14:48:05 2026 +0200 adapters/xvc: Use proper data types Use 'unsigned int' and 'size_t' instead of 'int' where appropriate. Change-Id: I26514081312260d21af862a91a6e10fb577ea97b Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index 6e70936e07..3d1c431ce1 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -133,8 +133,8 @@ static int xvc_flush(void) unsigned int number_of_bytes = xvc_bits_to_bytes(xvc_used_bits); // Creates the header. const char *shift = "shift:"; - int shift_len = strlen(shift); - int cp_offset = 0; + size_t shift_len = strlen(shift); + size_t cp_offset = 0; // Copies the header. memcpy(xvc_send_buf + cp_offset, shift, shift_len); // Updates the offset. @@ -149,11 +149,11 @@ static int xvc_flush(void) memcpy(xvc_send_buf + cp_offset, xvc_tdi_buf, number_of_bytes); cp_offset += number_of_bytes; // Updates the number of bytes used. - LOG_DEBUG("XVC flush: cp_offset: %d", cp_offset); + LOG_DEBUG("XVC flush: cp_offset: %zu", cp_offset); LOG_DEBUG("XVC flush: used_bits: %d", xvc_used_bits); int written = write_socket(xvc_fd, xvc_send_buf, cp_offset); - if (written != cp_offset) { + if (written != (int)cp_offset) { LOG_ERROR("Error writing socket in %s", __func__); return ERROR_FAIL; } @@ -205,9 +205,10 @@ static int xvc_queue(const uint8_t *tms, unsigned int tms_offset, const uint8_t static int xvc_getinfo(void) { const char *getinfo = "getinfo:"; - int len = strlen(getinfo); + size_t len = strlen(getinfo); int written = write_socket(xvc_fd, getinfo, len); - if (written != len) { + + if (written != (int)len) { LOG_ERROR("%s: write", __func__); return ERROR_FAIL; } @@ -559,11 +560,11 @@ static int xvc_tap_path_move(struct pathmove_command *cmd) return ERROR_OK; } -static unsigned int xvc_tap_stableclocks(int num_cycles) +static unsigned int xvc_tap_stableclocks(unsigned int num_cycles) { uint8_t tms = (tap_get_state() == TAP_RESET ? 0xff : 0); - for (int i = 0; i < num_cycles; i++) + for (unsigned int i = 0; i < num_cycles; i++) xvc_queue(&tms, 0, NULL, 0, NULL, 0, 1); return ERROR_OK; -- |
|
From: <ge...@op...> - 2026-04-19 11:44:19
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9581 -- gerrit commit 946f29ac893641204ea01cad46ec26cf6600235b Author: Marc Schink <de...@za...> Date: Sat Apr 18 14:48:32 2026 +0200 adapters/xvc: Handle return values during initialization Propagate errors from xvc_getinfo() and xvc_set_tck() during adapter initialization instead of silently ignoring them. Change-Id: I8cb86194b8cdbbccb1a49e0e97d50905c62af2ec Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index 3d1c431ce1..8a1bc7c7fd 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -462,16 +462,23 @@ static int xvc_init(void) xvc_tck = 1000; LOG_DEBUG("Initializing XVC driver"); - int err = ERROR_OK; + int ret; + if (!xvc_port) - err = xvc_init_unix(&xvc_fd); + ret = xvc_init_unix(&xvc_fd); else - err = xvc_init_tcp(&xvc_fd); - if (err != ERROR_OK) - return err; + ret = xvc_init_tcp(&xvc_fd); + + if (ret != ERROR_OK) + return ret; + + ret = xvc_getinfo(); + if (ret != ERROR_OK) + return ret; - xvc_getinfo(); - xvc_set_tck(); + ret = xvc_set_tck(); + if (ret != ERROR_OK) + return ret; LOG_DEBUG("XVC driver initialized"); -- |
|
From: <ge...@op...> - 2026-04-19 11:44:19
|
This is an automated email from Gerrit. "zapb <de...@za...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9583 -- gerrit commit ec850335ee40ea22e24f51b241d2736fdafe33b7 Author: Marc Schink <de...@za...> Date: Sun Apr 19 12:01:14 2026 +0200 adapters/xvc: Remove noisy debug output The current debug output clutters the logs while adding little useful information, so remove it. Change-Id: I4b6261520e471194be7807e4205cd1ba05df15bc Signed-off-by: Marc Schink <de...@za...> diff --git a/src/jtag/drivers/xvc.c b/src/jtag/drivers/xvc.c index d5a5810f35..9a38ed1b4c 100644 --- a/src/jtag/drivers/xvc.c +++ b/src/jtag/drivers/xvc.c @@ -149,8 +149,6 @@ static int xvc_flush(void) memcpy(xvc_send_buf + cp_offset, xvc_tdi_buf, number_of_bytes); cp_offset += number_of_bytes; // Updates the number of bytes used. - LOG_DEBUG("XVC flush: cp_offset: %zu", cp_offset); - LOG_DEBUG("XVC flush: used_bits: %d", xvc_used_bits); int written = write_socket(xvc_fd, xvc_send_buf, cp_offset); if (written != (int)cp_offset) { -- |
|
From: <ge...@op...> - 2026-04-17 13:24:15
|
This is an automated email from Gerrit. "Alexandra Kulyatskaya <a.k...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9579 -- gerrit commit ef486bfd76b58a400f46045cf9d8f9afd73f3c36 Author: Kulyatskaya Alexandra <a.k...@sy...> Date: Fri Apr 10 13:20:21 2026 +0300 [src/server] Support x packet Implement the binary memory read GDB packet 'x addr,length'. Change-Id: I7e4aab1c5e9fd26bb03f19f133b9d94aee7f22a1 Signed-off-by: Kulyatskaya Alexandra <a.k...@sy...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index f59eb5029e..a06133bf31 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1532,42 +1532,37 @@ static int gdb_error(struct connection *connection, int retval) return ERROR_OK; } -static int gdb_read_memory_packet(struct connection *connection, - char const *packet, int packet_size) +static bool parse_packet_addr_len(char const *packet, uint64_t *addr, uint32_t *len) { - struct target *target = get_available_target_from_connection(connection); char *separator; - uint64_t addr = 0; - uint32_t len = 0; - - uint8_t *buffer; - char *hex_buffer; - - int retval = ERROR_OK; /* skip command character */ packet++; - addr = strtoull(packet, &separator, 16); + *addr = strtoull(packet, &separator, 16); - if (*separator != ',') { - LOG_ERROR("incomplete read memory packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; + if (*separator != ',') + return false; + + errno = 0; + long signed_len = strtol(separator + 1, NULL, 16); + if (errno == ERANGE || signed_len < 0 || (unsigned long)signed_len > UINT32_MAX) { + return false; } - len = strtoul(separator + 1, NULL, 16); + *len = (uint32_t)signed_len; - if (!len) { - LOG_WARNING("invalid read memory packet received (len == 0)"); - gdb_put_packet(connection, "", 0); - return ERROR_OK; - } + return true; +} - buffer = malloc(len); +static int gdb_read_memory(const struct connection *connection, + uint8_t *buffer, uint64_t addr, uint32_t len) +{ + struct target *target = get_available_target_from_connection(connection); LOG_DEBUG("addr: 0x%16.16" PRIx64 ", len: 0x%8.8" PRIx32, addr, len); - retval = ERROR_NOT_IMPLEMENTED; + int retval = ERROR_NOT_IMPLEMENTED; if (target->rtos) retval = rtos_read_buffer(target, addr, len, buffer); if (retval == ERROR_NOT_IMPLEMENTED) @@ -1591,8 +1586,47 @@ static int gdb_read_memory_packet(struct connection *connection, retval = ERROR_OK; } + return retval; +} + +static int gdb_read_memory_packet(struct connection *connection, + char const *packet, int packet_size) +{ + uint64_t addr; + uint32_t len; + + uint8_t *buffer; + char *hex_buffer; + + int retval; + + if (!parse_packet_addr_len(packet, &addr, &len)) { + LOG_ERROR("incomplete read memory packet received, dropping connection"); + return ERROR_SERVER_REMOTE_CLOSED; + } + if (!len) { + LOG_WARNING("invalid read memory packet received (len == 0)"); + gdb_put_packet(connection, "", 0); + return ERROR_OK; + } + + buffer = malloc(len); + if (!buffer) { + LOG_ERROR("Unable to allocate memory"); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + retval = gdb_read_memory(connection, buffer, addr, len); + if (retval == ERROR_OK) { hex_buffer = malloc(len * 2 + 1); + if (!hex_buffer) { + LOG_ERROR("Unable to allocate memory for hex buffer"); + gdb_send_error(connection, 01); + free(buffer); + return ERROR_OK; + } size_t pkt_len = hexify(hex_buffer, buffer, len, len * 2 + 1); @@ -1607,6 +1641,83 @@ static int gdb_read_memory_packet(struct connection *connection, return retval; } +static size_t escape_binary_data(const uint8_t *data, char *out, size_t data_len) +{ + assert(out); + + size_t out_pos = 1; + out[0] = 'b'; + + for (size_t i = 0; i < data_len; ++i) { + uint8_t c = data[i]; + /* See the logic for escaping binary data here: + * https://sourceware.org/gdb/current/onlinedocs/gdb.html/Overview.html#Binary-Data */ + if (c == 0x23 || c == 0x24 || c == 0x7d || c == 0x2a) { + out[out_pos++] = 0x7d; + out[out_pos++] = c ^ 0x20; + } else { + out[out_pos++] = c; + } + } + + return out_pos; +} + +static int gdb_read_memory_packet_binary(struct connection *connection, + char const *packet, int packet_size) +{ + uint64_t addr; + uint32_t len; + + if (!parse_packet_addr_len(packet, &addr, &len)) { + LOG_ERROR("incomplete read memory packet received, dropping connection"); + return ERROR_SERVER_REMOTE_CLOSED; + } + if (!len) { + LOG_WARNING("invalid read memory packet received (len == 0)"); + gdb_put_packet(connection, "", 0); + return ERROR_OK; + } + + char *out_buffer = NULL; + uint8_t *buffer = malloc(len); + if (!buffer) { + LOG_ERROR("Unable to allocate memory"); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + int retval = gdb_read_memory(connection, buffer, addr, len); + if (retval != ERROR_OK) { + retval = gdb_error(connection, retval); + goto cleanup; + } + + /* len * 2 : each byte may need escaping → 2 bytes max per input byte + * +1 : for 'b' prefix + * +1 : for null terminator */ + out_buffer = malloc(len * 2 + 1 + 1); + if (!out_buffer) { + LOG_ERROR("Unable to allocate memory for output buffer"); + gdb_send_error(connection, 01); + goto cleanup; + } + size_t pkt_len = escape_binary_data(buffer, out_buffer, len); + if (pkt_len < len || INT_MAX <= pkt_len) { + LOG_ERROR("Escape binary data failed: invalid output length %zu " + "(input: %" PRIu32 ", max: %d)", pkt_len, len, INT_MAX); + gdb_send_error(connection, ERANGE); + } else { + retval = gdb_put_packet(connection, out_buffer, pkt_len); + } + +cleanup: + free(out_buffer); + free(buffer); + + return retval; +} + static int gdb_write_memory_packet(struct connection *connection, char const *packet, int packet_size) { @@ -2942,7 +3053,7 @@ static int gdb_query_packet(struct connection *connection, &buffer, &pos, &size, - "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+", + "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+;binary-upload+", GDB_BUFFER_SIZE, (gdb_use_memory_map && (flash_get_bank_count() > 0)) ? '+' : '-', gdb_target_desc_supported ? '+' : '-'); @@ -3735,6 +3846,11 @@ static int gdb_input_inner(struct connection *connection) retval = gdb_write_memory_binary_packet(connection, packet, packet_size); gdb_con->output_flag = GDB_OUTPUT_NO; break; + case 'x': + gdb_con->output_flag = GDB_OUTPUT_NOTIF; + retval = gdb_read_memory_packet_binary(connection, packet, packet_size); + gdb_con->output_flag = GDB_OUTPUT_NO; + break; case 'k': if (gdb_con->extended_protocol) { gdb_con->attached = false; -- |