Skip to content

Commit 03c73b3

Browse files
committed
tools: Adds script to detect Espressif devkits connected to the host
1 parent 858373d commit 03c73b3

File tree

13 files changed

+582
-16
lines changed

13 files changed

+582
-16
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ install(TARGETS openocd DESTINATION ${bindir})
1919
install(DIRECTORY tcl/ DESTINATION ${pkgdatadir}/scripts)
2020
install(FILES contrib/60-openocd.rules DESTINATION ${pkgdatadir}/contrib)
2121
install(DIRECTORY contrib/libdcc DESTINATION ${pkgdatadir}/contrib)
22+
install(FILES tools/esp_detect_config.py DESTINATION ${pkgdatadir}/tools)
2223
get_property(ulink_firmware TARGET ocdjtagdrivers PROPERTY ULINK_FIRMWARE)
2324
if(BUILD_JLINK)
2425
install(FILES ${ulink_firmware} DESTINATION ${pkgdatadir}/OpenULINK)

Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ nobase_dist_pkgdata_DATA = \
1919
contrib/libdcc/README \
2020
contrib/60-openocd.rules
2121

22+
esptoolsdir = $(pkgdatadir)/espressif/tools
23+
dist_esptools_DATA = \
24+
tools/esp_detect_config.py
25+
2226
SUBDIRS =
2327
DIST_SUBDIRS =
2428
bin_PROGRAMS =

src/jtag/adapter.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ static const struct gpio_map {
6666
[ADAPTER_GPIO_IDX_LED] = { "led", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
6767
};
6868

69+
#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
70+
static void adapter_usb_set_location(const char *location);
71+
#endif
72+
6973
bool is_adapter_initialized(void)
7074
{
7175
return adapter_config.adapter_initialized;
@@ -146,6 +150,14 @@ int adapter_init(struct command_context *cmd_ctx)
146150
return ERROR_JTAG_INIT_FAILED;
147151
}
148152

153+
#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
154+
char *loc = getenv("OPENOCD_USB_ADAPTER_LOCATION");
155+
if (loc) {
156+
LOG_INFO("use USB location specified via env var '%s'", loc);
157+
adapter_usb_set_location(loc);
158+
}
159+
#endif
160+
149161
retval = adapter_driver->init();
150162
if (retval != ERROR_OK)
151163
return retval;

src/jtag/drivers/esp_usb_jtag.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -915,11 +915,37 @@ COMMAND_HANDLER(esp_usb_jtag_chip_id)
915915
return ERROR_OK;
916916
}
917917

918-
extern void libusb_list_devices(void);
918+
COMMAND_HANDLER(esp_usb_jtag_get_location)
919+
{
920+
char dev_loc[128];
921+
922+
if (!priv->usb_device) {
923+
command_print(CMD, "Can not get device location! No open device.");
924+
return ERROR_FAIL;
925+
}
926+
927+
if (jtag_libusb_get_dev_location_by_handle(priv->usb_device, dev_loc, sizeof(dev_loc)) != ERROR_OK) {
928+
command_print(CMD, "Cannot get location for open usb device!");
929+
return ERROR_FAIL;
930+
}
931+
932+
command_print(CMD, "%s", dev_loc);
933+
return ERROR_OK;
934+
}
919935

920-
COMMAND_HANDLER(esp_usb_jtag_list)
936+
COMMAND_HANDLER(esp_usb_jtag_dev_list)
921937
{
922-
libusb_list_devices();
938+
const uint16_t vids[] = { esp_usb_vid, 0 }; /* must be null terminated */
939+
const uint16_t pids[] = { esp_usb_pid, 0 }; /* must be null terminated */
940+
int cnt, i;
941+
char **locations;
942+
943+
cnt = jtag_libusb_get_devs_locations(vids, pids, &locations);
944+
for (i = 0; i < cnt; i++)
945+
command_print(CMD, "%s", locations[i]);
946+
947+
jtag_libusb_free_devs_locations(locations, cnt);
948+
923949
return ERROR_OK;
924950
}
925951

@@ -967,11 +993,18 @@ static const struct command_registration esp_usb_jtag_subcommands[] = {
967993
.usage = "chip_id",
968994
},
969995
{
970-
.name = "list",
971-
.handler = &esp_usb_jtag_list,
996+
.name = "list_devs",
997+
.handler = &esp_usb_jtag_dev_list,
998+
.mode = COMMAND_ANY,
999+
.help = "list devices",
1000+
.usage = "list_devs",
1001+
},
1002+
{
1003+
.name = "get_location",
1004+
.handler = &esp_usb_jtag_get_location,
9721005
.mode = COMMAND_ANY,
973-
.help = "list",
974-
.usage = "list",
1006+
.help = "get device location",
1007+
.usage = "get_location",
9751008
},
9761009
COMMAND_REGISTRATION_DONE
9771010
};

src/jtag/drivers/ftdi.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@
7575
/* FTDI access library includes */
7676
#include "mpsse.h"
7777

78+
#include "libusb_helper.h"
79+
7880
#define JTAG_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
7981
#define JTAG_MODE_ALT (LSB_FIRST | NEG_EDGE_IN | NEG_EDGE_OUT)
8082
#define SWD_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
@@ -918,6 +920,39 @@ COMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command)
918920
return ERROR_OK;
919921
}
920922

923+
COMMAND_HANDLER(ftdi_handle_get_location)
924+
{
925+
char dev_loc[128];
926+
927+
struct libusb_device_handle *usb_dev = mpsse_get_usb_device(mpsse_ctx);
928+
if (!usb_dev) {
929+
command_print(CMD, "Can not get device location! No open device.");
930+
return ERROR_FAIL;
931+
}
932+
933+
if (jtag_libusb_get_dev_location_by_handle(usb_dev, dev_loc, sizeof(dev_loc)) != ERROR_OK) {
934+
command_print(CMD, "Cannot get location for open usb device!");
935+
return ERROR_FAIL;
936+
}
937+
938+
command_print(CMD, "%s", dev_loc);
939+
return ERROR_OK;
940+
}
941+
942+
COMMAND_HANDLER(ftdi_handle_dev_list)
943+
{
944+
int cnt, i;
945+
char **locations;
946+
947+
cnt = jtag_libusb_get_devs_locations(ftdi_vid, ftdi_pid, &locations);
948+
for (i = 0; i < cnt; i++)
949+
command_print(CMD, "%s", locations[i]);
950+
951+
jtag_libusb_free_devs_locations(locations, cnt);
952+
953+
return ERROR_OK;
954+
}
955+
921956
static const struct command_registration ftdi_subcommand_handlers[] = {
922957
{
923958
.name = "device_desc",
@@ -979,6 +1014,20 @@ static const struct command_registration ftdi_subcommand_handlers[] = {
9791014
"allow signalling speed increase)",
9801015
.usage = "(rising|falling)",
9811016
},
1017+
{
1018+
.name = "list_devs",
1019+
.handler = &ftdi_handle_dev_list,
1020+
.mode = COMMAND_ANY,
1021+
.help = "list devices",
1022+
.usage = "list_devs",
1023+
},
1024+
{
1025+
.name = "get_location",
1026+
.handler = &ftdi_handle_get_location,
1027+
.mode = COMMAND_ANY,
1028+
.help = "get device location",
1029+
.usage = "get_location",
1030+
},
9821031
COMMAND_REGISTRATION_DONE
9831032
};
9841033

src/jtag/drivers/libusb_helper.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,104 @@ static bool jtag_libusb_match_serial(struct libusb_device_handle *device,
145145
return match;
146146
}
147147

148+
static int jtag_libusb_get_dev_location(struct libusb_device *dev, char *loc, int loc_len)
149+
{
150+
int k, len, wr;
151+
uint8_t dev_bus = 0;
152+
uint8_t port_path[MAX_USB_PORTS];
153+
int path_len = 0;
154+
155+
#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
156+
path_len = libusb_get_port_numbers(dev, port_path, MAX_USB_PORTS);
157+
if (path_len == LIBUSB_ERROR_OVERFLOW) {
158+
LOG_WARNING("cannot determine path to usb device! (more than %i ports in path)", MAX_USB_PORTS);
159+
return ERROR_FAIL;
160+
}
161+
dev_bus = libusb_get_bus_number(dev);
162+
#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
163+
164+
len = snprintf(loc, loc_len, "%d", dev_bus);
165+
if (len < 0 || len >= (loc_len - len)) {
166+
*loc = 0;
167+
return ERROR_FAIL;
168+
}
169+
170+
for (k = 0; k < path_len; k++) {
171+
wr = snprintf(&loc[len], loc_len - len, k == 0 ? "-%d" : ".%d", port_path[k]);
172+
if (wr < 0 || wr >= (loc_len - len)) {
173+
*loc = 0;
174+
return ERROR_FAIL;
175+
}
176+
len += wr;
177+
}
178+
return ERROR_OK;
179+
}
180+
181+
int jtag_libusb_get_dev_location_by_handle(struct libusb_device_handle *dev, char *loc, int loc_len)
182+
{
183+
return jtag_libusb_get_dev_location(libusb_get_device(dev), loc, loc_len);
184+
}
185+
186+
int jtag_libusb_get_devs_locations(const uint16_t vids[], const uint16_t pids[], char ***locations)
187+
{
188+
int cnt, idx, devs_cnt = 0;
189+
struct libusb_device **list;
190+
struct libusb_device_descriptor desc;
191+
char **locs;
192+
/* <bus>-<port>[.<port>]... */
193+
#define MAX_DEV_LOCATION_LEN 128
194+
195+
cnt = libusb_get_device_list(jtag_libusb_context, &list);
196+
if (cnt <= 0) {
197+
LOG_WARNING("Cannot get devices list (%d)!", cnt);
198+
return 0;
199+
}
200+
201+
locs = calloc(cnt, sizeof(char *));
202+
if (!locs) {
203+
LOG_ERROR("Unable to allocate space USB devices list!");
204+
libusb_free_device_list(list, 1);
205+
return 0;
206+
}
207+
for (idx = 0; idx < cnt; idx++) {
208+
if (libusb_get_device_descriptor(list[idx], &desc) != 0)
209+
continue;
210+
if (!jtag_libusb_match_ids(&desc, vids, pids))
211+
continue;
212+
213+
locs[devs_cnt] = calloc(1, MAX_DEV_LOCATION_LEN);
214+
if (!locs[devs_cnt]) {
215+
LOG_ERROR("Unable to allocate space USB device location!");
216+
jtag_libusb_free_devs_locations(locs, devs_cnt);
217+
libusb_free_device_list(list, true);
218+
return 0;
219+
}
220+
if (jtag_libusb_get_dev_location(list[idx], locs[devs_cnt], MAX_DEV_LOCATION_LEN) != ERROR_OK)
221+
LOG_WARNING("Cannot get location for usb device!");
222+
223+
devs_cnt++;
224+
}
225+
*locations = locs;
226+
227+
libusb_free_device_list(list, true);
228+
229+
return devs_cnt;
230+
}
231+
232+
void jtag_libusb_free_devs_locations(char *locations[], int cnt)
233+
{
234+
int i;
235+
236+
if (!locations || cnt == 0)
237+
return;
238+
239+
for (i = 0; i < cnt; i++) {
240+
if (locations[i])
241+
free(locations[i]);
242+
}
243+
free(locations);
244+
}
245+
148246
int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
149247
const char *product, struct libusb_device_handle **out,
150248
adapter_get_alternate_serial_fn adapter_get_alternate_serial)

src/jtag/drivers/libusb_helper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,9 @@ uint8_t *oocd_libusb_dev_mem_alloc(libusb_device_handle *devh,
9393
int oocd_libusb_dev_mem_free(libusb_device_handle *devh,
9494
uint8_t *buffer, size_t length);
9595

96+
int jtag_libusb_get_dev_location_by_handle(struct libusb_device_handle *dev, char *loc, int loc_len);
97+
int jtag_libusb_get_devs_locations(const uint16_t vids[], const uint16_t pids[], char ***locations);
98+
void jtag_libusb_free_devs_locations(char *locations[], int cnt);
99+
100+
96101
#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H */

src/jtag/drivers/mpsse.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,11 @@ bool mpsse_is_high_speed(struct mpsse_ctx *ctx)
421421
return ctx->type != TYPE_FT2232C;
422422
}
423423

424+
struct libusb_device_handle *mpsse_get_usb_device(struct mpsse_ctx *ctx)
425+
{
426+
return ctx->usb_dev;
427+
}
428+
424429
void mpsse_purge(struct mpsse_ctx *ctx)
425430
{
426431
int err;

src/jtag/drivers/mpsse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const cha
4040
const char *serial, const char *location, int channel);
4141
void mpsse_close(struct mpsse_ctx *ctx);
4242
bool mpsse_is_high_speed(struct mpsse_ctx *ctx);
43+
struct libusb_device_handle *mpsse_get_usb_device(struct mpsse_ctx *ctx);
4344

4445
/* Command queuing. These correspond to the MPSSE commands with the same names, but no need to care
4546
* about bit/byte transfer or data length limitation. Read data is guaranteed to be available only

tcl/esp-config-schema.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
"$ref": "#/definitions/targetsInfo"
1717
}
1818
},
19+
"interfaces": {
20+
"description": "List of debug interfaces",
21+
"type": "array",
22+
"items": {
23+
"$ref": "#/definitions/interfacesInfo"
24+
}
25+
},
1926
"boards": {
2027
"description": "List of boards",
2128
"type": "array",
@@ -49,13 +56,39 @@
4956
"name": {
5057
"description": "Name of the target e.g. 'ESP32'",
5158
"type": "string"
59+
},
60+
"idcode": {
61+
"description": "JTAG IDCODE of the chip",
62+
"type": "string"
63+
},
64+
"ocdid": {
65+
"description": "OCDID of Xtensa chip",
66+
"type": "string"
5267
}
5368
},
5469
"required": [
5570
"id",
5671
"name"
5772
]
5873
},
74+
"interfacesInfo": {
75+
"type": "object",
76+
"description": "Information about debug interface",
77+
"properties": {
78+
"id": {
79+
"description": "Interface ID. Actually this is OpenOCD debug adapter driver name.",
80+
"type": "string"
81+
},
82+
"config_file": {
83+
"description": "Config file of debug interface e.g. 'ftdi/esp32_devkitj_v1.cfg'. Path relative to 'interface' sub-dir.",
84+
"type": "string"
85+
},
86+
"command": {
87+
"description": "Command for the debug interface driver, e.g. 'ftdi'",
88+
"type": "string"
89+
}
90+
}
91+
},
5992
"boardsInfo": {
6093
"type": "object",
6194
"description": "Information about a board",
@@ -78,6 +111,15 @@
78111
"items": {
79112
"type": "string"
80113
}
114+
},
115+
"interface": {
116+
"description": "Interface ID. Actually this is OpenOCD debug adapter driver name.",
117+
"type": "string",
118+
"$ref": "#/definitions/interfacesInfo/properties/id"
119+
},
120+
"location": {
121+
"description": "Location of the board, e.g. for USB it will look like 'usb://<bus>-<port>[.<port>]...'.",
122+
"type": "string"
81123
}
82124
},
83125
"required": [

0 commit comments

Comments
 (0)