Skip to content

Commit ed78403

Browse files
committed
Improve handling of RP2040 devices after reboot
Calling GET_INFO when not available sometimes causes issues with forced commands Also improve libusb error messages when debugging
1 parent 08b68b9 commit ed78403

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8762,7 +8762,7 @@ int main(int argc, char **argv) {
87628762
// again is to assume it has the same serial number.
87638763
settings.address = -1;
87648764
settings.bus = -1;
8765-
// also skip vid/pid filtering, as that will typically change in BOOTSEL mode
8765+
// also skip vid/pid filtering, as that will typically change in BOOTSEL mode, and could be white-labelled on RP2350
87668766
settings.pid = -1;
87678767
// still filter for rpi vid/pid if we don't have a serial number, as that is an RP2040 running a no_flash binary, so will
87688768
// have a standard rpi vid/pid in BOOTSEL mode

picoboot_connection/picoboot_connection.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_d
6969
int ret = libusb_get_device_descriptor(device, &desc);
7070
enum picoboot_device_result res = dr_vidpid_unknown;
7171
if (ret && verbose) {
72-
output("Failed to read device descriptor\n");
72+
output("Failed to read device descriptor %s\n", libusb_error_name(ret));
7373
}
7474
if (!ret) {
7575
if (pid >= 0) {
@@ -107,14 +107,14 @@ enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_d
107107
}
108108
ret = libusb_get_active_config_descriptor(device, &config);
109109
if (ret && verbose) {
110-
output("Failed to read config descriptor\n");
110+
output("Failed to read config descriptor %s\n", libusb_error_name(ret));
111111
}
112112
}
113113

114114
if (!ret) {
115115
ret = libusb_open(device, dev_handle);
116116
if (ret && verbose) {
117-
output("Failed to open device %d\n", ret);
117+
output("Failed to open device %s\n", libusb_error_name(ret));
118118
}
119119
if (ret) {
120120
if (vid == 0 || strlen(ser) != 0) {
@@ -169,7 +169,7 @@ enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_d
169169
if (verbose) output("Found PICOBOOT interface\n");
170170
ret = libusb_claim_interface(*dev_handle, interface);
171171
if (ret) {
172-
if (verbose) output("Failed to claim interface\n");
172+
if (verbose) output("Failed to claim interface %s\n", libusb_error_name(ret));
173173
return dr_vidpid_bootrom_no_interface;
174174
}
175175
} else {
@@ -180,16 +180,22 @@ enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_d
180180

181181
if (!ret) {
182182
if (*model == unknown) {
183-
struct picoboot_get_info_cmd info_cmd;
184-
info_cmd.bType = PICOBOOT_GET_INFO_SYS,
185-
info_cmd.dParams[0] = (uint32_t) (SYS_INFO_CHIP_INFO);
186-
uint32_t word_buf[64];
187-
// RP2040 doesn't have this function, so returns non-zero
188-
int info_ret = picoboot_get_info(*dev_handle, &info_cmd, (uint8_t*)word_buf, sizeof(word_buf));
189-
if (info_ret) {
183+
if (desc.idVendor == VENDOR_ID_RASPBERRY_PI && desc.idProduct == PRODUCT_ID_RP2040_USBBOOT) {
184+
// Set model based on bootrom vid/pid for RP2040, as it cannot be white-labelled
190185
*model = rp2040;
191186
} else {
192-
*model = rp2350;
187+
// Otherwise check the chip info
188+
struct picoboot_get_info_cmd info_cmd;
189+
info_cmd.bType = PICOBOOT_GET_INFO_SYS,
190+
info_cmd.dParams[0] = (uint32_t) (SYS_INFO_CHIP_INFO);
191+
uint32_t word_buf[64];
192+
// RP2040 doesn't have this function, so returns non-zero
193+
int info_ret = picoboot_get_info(*dev_handle, &info_cmd, (uint8_t*)word_buf, sizeof(word_buf));
194+
if (info_ret) {
195+
*model = rp2040;
196+
} else {
197+
*model = rp2350;
198+
}
193199
}
194200
}
195201
if (strlen(ser) != 0) {
@@ -301,7 +307,7 @@ int picoboot_cmd(libusb_device_handle *usb_device, struct picoboot_cmd *cmd, uin
301307
ret = libusb_bulk_transfer(usb_device, out_ep, (uint8_t *) cmd, sizeof(struct picoboot_cmd), &sent, 3000);
302308

303309
if (ret != 0 || sent != sizeof(struct picoboot_cmd)) {
304-
output(" ...failed to send command %d\n", ret);
310+
output(" ...failed to send command %s\n", libusb_error_name(ret));
305311
return ret;
306312
}
307313

@@ -321,15 +327,15 @@ int picoboot_cmd(libusb_device_handle *usb_device, struct picoboot_cmd *cmd, uin
321327
int received = 0;
322328
ret = libusb_bulk_transfer(usb_device, in_ep, buffer, cmd->dTransferLength, &received, timeout);
323329
if (ret != 0 || received != (int) cmd->dTransferLength) {
324-
output(" ...failed to receive data %d %d/%d\n", ret, received, cmd->dTransferLength);
330+
output(" ...failed to receive data %s %d/%d\n", libusb_error_name(ret), received, cmd->dTransferLength);
325331
if (!ret) ret = 1;
326332
return ret;
327333
}
328334
} else {
329335
if (verbose) output(" send %d...\n", cmd->dTransferLength);
330336
ret = libusb_bulk_transfer(usb_device, out_ep, buffer, cmd->dTransferLength, &sent, timeout);
331337
if (ret != 0 || sent != (int) cmd->dTransferLength) {
332-
output(" ...failed to send data %d %d/%d\n", ret, sent, cmd->dTransferLength);
338+
output(" ...failed to send data %s %d/%d\n", libusb_error_name(ret), sent, cmd->dTransferLength);
333339
if (!ret) ret = 1;
334340
picoboot_cmd_status_verbose(usb_device, NULL, true);
335341
return ret;

0 commit comments

Comments
 (0)