Skip to content

Commit ae386d4

Browse files
Redo boards menu, separate out upload method, add picotool upload (#1112)
Instead of listing each board three times (normal upload, picoprobe, and pico-debug uploads), list each board once and use a menu to select the actual upload method. Also add in picotool as an upload method for those folks who have trouble with automounting. Fix #1111
1 parent ff9f5d3 commit ae386d4

File tree

8 files changed

+1540
-18792
lines changed

8 files changed

+1540
-18792
lines changed

boards.txt

Lines changed: 1297 additions & 18736 deletions
Large diffs are not rendered by default.

cores/rp2040/RP2040USB.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
#include "hardware/irq.h"
3434
#include "pico/mutex.h"
3535
#include "pico/unique_id.h"
36+
#include "pico/usb_reset_interface.h"
37+
#include "hardware/watchdog.h"
38+
#include "pico/bootrom.h"
39+
#include <device/usbd_pvt.h>
3640

3741
// Big, global USB mutex, shared with all USB devices to make sure we don't
3842
// have multiple cores updating the TUSB state in parallel
@@ -67,13 +71,19 @@ static int __usb_task_irq;
6771
#define USBD_STR_PRODUCT (0x02)
6872
#define USBD_STR_SERIAL (0x03)
6973
#define USBD_STR_CDC (0x04)
74+
#define USBD_STR_RPI_RESET (0x05)
7075

7176
#define EPNUM_HID 0x83
7277

7378
#define USBD_MSC_EPOUT 0x03
7479
#define USBD_MSC_EPIN 0x84
7580
#define USBD_MSC_EPSIZE 64
7681

82+
#define TUD_RPI_RESET_DESCRIPTOR(_itfnum, _stridx) \
83+
/* Interface */\
84+
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_VENDOR_SPECIFIC, RESET_INTERFACE_SUBCLASS, RESET_INTERFACE_PROTOCOL, _stridx,
85+
86+
7787
const uint8_t *tud_descriptor_device_cb(void) {
7888
static tusb_desc_device_t usbd_desc_device = {
7989
.bLength = sizeof(tusb_desc_device_t),
@@ -250,6 +260,14 @@ void __SetupUSBDescriptor() {
250260

251261
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0) + (__USBInstallMassStorage ? sizeof(msd_desc) : 0);
252262

263+
#ifdef ENABLE_PICOTOOL_USB
264+
uint8_t picotool_itf = interface_count++;
265+
uint8_t picotool_desc[] = {
266+
TUD_RPI_RESET_DESCRIPTOR(picotool_itf, USBD_STR_RPI_RESET)
267+
};
268+
usbd_desc_len += sizeof(picotool_desc);
269+
#endif
270+
253271
uint8_t tud_cfg_desc[TUD_CONFIG_DESC_LEN] = {
254272
// Config number, interface count, string index, total length, attribute, power in mA
255273
TUD_CONFIG_DESCRIPTOR(1, interface_count, USBD_STR_0, usbd_desc_len, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA)
@@ -274,6 +292,10 @@ void __SetupUSBDescriptor() {
274292
memcpy(ptr, msd_desc, sizeof(msd_desc));
275293
ptr += sizeof(msd_desc);
276294
}
295+
#ifdef ENABLE_PICOTOOL_USB
296+
memcpy(ptr, picotool_desc, sizeof(picotool_desc));
297+
ptr += sizeof(picotool_desc);
298+
#endif
277299
}
278300
}
279301
}
@@ -291,6 +313,9 @@ const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
291313
[USBD_STR_PRODUCT] = "PicoArduino",
292314
[USBD_STR_SERIAL] = idString,
293315
[USBD_STR_CDC] = "Board CDC",
316+
#ifdef ENABLE_PICOTOOL_USB
317+
[USBD_STR_RPI_RESET] = "Reset",
318+
#endif
294319
};
295320

296321
if (!idString[0]) {
@@ -432,4 +457,84 @@ extern "C" void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t pr
432457
}
433458

434459

460+
461+
#ifdef ENABLE_PICOTOOL_USB
462+
463+
static uint8_t _picotool_itf_num;
464+
465+
static void resetd_init() {
466+
}
467+
468+
static void resetd_reset(uint8_t rhport) {
469+
(void) rhport;
470+
_picotool_itf_num = 0;
471+
}
472+
473+
static uint16_t resetd_open(uint8_t rhport,
474+
tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
475+
(void) rhport;
476+
TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass &&
477+
RESET_INTERFACE_SUBCLASS == itf_desc->bInterfaceSubClass &&
478+
RESET_INTERFACE_PROTOCOL == itf_desc->bInterfaceProtocol, 0);
479+
480+
uint16_t const drv_len = sizeof(tusb_desc_interface_t);
481+
TU_VERIFY(max_len >= drv_len, 0);
482+
483+
_picotool_itf_num = itf_desc->bInterfaceNumber;
484+
return drv_len;
485+
}
486+
487+
// Support for parameterized reset via vendor interface control request
488+
static bool resetd_control_xfer_cb(uint8_t rhport, uint8_t stage,
489+
tusb_control_request_t const *request) {
490+
(void) rhport;
491+
// nothing to do with DATA & ACK stage
492+
if (stage != CONTROL_STAGE_SETUP) {
493+
return true;
494+
}
495+
496+
if (request->wIndex == _picotool_itf_num) {
497+
if (request->bRequest == RESET_REQUEST_BOOTSEL) {
498+
reset_usb_boot(0, (request->wValue & 0x7f));
499+
// does not return, otherwise we'd return true
500+
}
501+
502+
if (request->bRequest == RESET_REQUEST_FLASH) {
503+
watchdog_reboot(0, 0, 100);
504+
return true;
505+
}
506+
507+
}
508+
return false;
509+
}
510+
511+
static bool resetd_xfer_cb(uint8_t rhport, uint8_t ep_addr,
512+
xfer_result_t result, uint32_t xferred_bytes) {
513+
(void) rhport;
514+
(void) ep_addr;
515+
(void) result;
516+
(void) xferred_bytes;
517+
return true;
518+
}
519+
520+
static usbd_class_driver_t const _resetd_driver = {
521+
#if CFG_TUSB_DEBUG >= 2
522+
.name = "RESET",
523+
#endif
524+
.init = resetd_init,
525+
.reset = resetd_reset,
526+
.open = resetd_open,
527+
.control_xfer_cb = resetd_control_xfer_cb,
528+
.xfer_cb = resetd_xfer_cb,
529+
.sof = NULL
530+
};
531+
532+
// Implement callback to add our custom driver
533+
usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
534+
*driver_count = 1;
535+
return &_resetd_driver;
536+
}
537+
#endif
538+
539+
435540
#endif

docs/install.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,22 @@ For detailed usage information, please check the repo documentation available at
135135

136136
* https://arduino-pico.readthedocs.io/en/latest/fs.html
137137

138+
Uploading Sketches with Picotool
139+
--------------------------------
140+
Because the Picotool uses a custom device driver in the Pico to handle upload, when using the ``Upload Method->Picotool`` mode custom code needs to be run on the Pico which is not included by default for compatibility and code savings.
141+
142+
So for the first sketch you will need to rebuild (with the ``Upload Method->Picotool`` selected in them menus) and then manually hold down BOOTSEL and insert the Pico USB cable to enter the ROM bootloader.
143+
144+
After the initial upload, as long as the running binary was built using the ``Picotool`` upload method, then the normal upload process should work.
145+
146+
Note that for Ubuntu and other Linux operating systems you may need to add the following lines to a new `udev` config file(``99-picotool.rules``) to allow normal users to access the special USB device the Pico exports:
147+
148+
.. code::
149+
150+
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE="660", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-Picotool.rules
151+
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE="660", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-Picotool.rules
152+
sudo udevadm control --reload
153+
138154
Uploading Sketches with Picoprobe
139155
---------------------------------
140156
If you have built a Raspberry Pi Picoprobe, you can use OpenOCD to handle your sketch uploads and for debugging with GDB.

lib/platform_inc.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
-iwithprefixbefore/pico-sdk/src/common/pico_stdlib/include
1010
-iwithprefixbefore/pico-sdk/src/common/pico_sync/include
1111
-iwithprefixbefore/pico-sdk/src/common/pico_time/include
12+
-iwithprefixbefore/pico-sdk/src/common/pico_usb_reset_interface/include
1213
-iwithprefixbefore/pico-sdk/src/common/pico_util/include
1314
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_regs/include
1415
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_structs/include

package/build_boards_manager_package.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ sed 's/^tools.uf2conv.network_cmd=.*//g' | \
111111
sed 's/^#tools.uf2conv.network_cmd=/tools.uf2conv.network_cmd=/g' | \
112112
sed 's/^tools.picoprobe.cmd=.*//g' | \
113113
sed 's/^#tools.picoprobe.cmd=/tools.picoprobe.cmd=/g' | \
114+
sed 's/^tools.picotool.cmd=.*//g' | \
115+
sed 's/^#tools.picotool.cmd=/tools.picotool.cmd=/g' | \
114116
sed 's/^tools.picodebug.cmd=.*//g' | \
115117
sed 's/^#tools.picodebug.cmd=/tools.picodebug.cmd=/g' | \
116118
sed 's/^discovery.rp2040.pattern=.*//g' | \

package/package_pico_index.template.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@
192192
"packager": "rp2040",
193193
"version": "1.5.0-a-5007782",
194194
"name": "pqt-openocd"
195+
},
196+
{
197+
"packager": "rp2040",
198+
"version": "1.5.0-a-03f2812",
199+
"name": "pqt-picotool"
195200
}
196201
],
197202
"help": {
@@ -200,6 +205,61 @@
200205
}
201206
],
202207
"tools": [
208+
{
209+
"version": "1.5.0-a-03f2812",
210+
"name": "pqt-picotool",
211+
"systems": [
212+
{
213+
"host": "aarch64-linux-gnu",
214+
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.5.0-a/aarch64-linux-gnu.picotool-03f2812.230113.tar.gz",
215+
"archiveFileName": "aarch64-linux-gnu.picotool-03f2812.230113.tar.gz",
216+
"checksum": "SHA-256:3816240a6aef8da61895227df3b1b5d7a7f95456a9e7737e25252886f649d2f3",
217+
"size": "171807"
218+
},
219+
{
220+
"host": "arm-linux-gnueabihf",
221+
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.5.0-a/arm-linux-gnueabihf.picotool-03f2812.230113.tar.gz",
222+
"archiveFileName": "arm-linux-gnueabihf.picotool-03f2812.230113.tar.gz",
223+
"checksum": "SHA-256:454e1a0ce9a546626bca73cdff74dfb0e06bf6603b13d5a3a4a4f0c0968fd65d",
224+
"size": "152809"
225+
},
226+
{
227+
"host": "i686-pc-linux-gnu",
228+
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.5.0-a/i686-linux-gnu.picotool-03f2812.230113.tar.gz",
229+
"archiveFileName": "i686-linux-gnu.picotool-03f2812.230113.tar.gz",
230+
"checksum": "SHA-256:fee7f93d65bb3db42a9fcf5683e2b038ab13875b1d5bedb304facb92e6469a37",
231+
"size": "183571"
232+
},
233+
{
234+
"host": "i686-mingw32",
235+
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.5.0-a/i686-w64-mingw32.picotool-03f2812.230112.zip",
236+
"archiveFileName": "i686-w64-mingw32.picotool-03f2812.230112.zip",
237+
"checksum": "SHA-256:8a37063d44e306b9315618962cd8dc14b815e998ba960a38099e45bb14bcda90",
238+
"size": "352766"
239+
},
240+
{
241+
"host": "x86_64-apple-darwin",
242+
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.5.0-a/x86_64-apple-darwin14.picotool-03f2812.230112.tar.gz",
243+
"archiveFileName": "x86_64-apple-darwin14.picotool-03f2812.230112.tar.gz",
244+
"checksum": "SHA-256:5b2f77ee33a7a757546ab526d3e477300bf01e787e645f64aa86daac6b19a510",
245+
"size": "852449"
246+
},
247+
{
248+
"host": "x86_64-pc-linux-gnu",
249+
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.5.0-a/x86_64-linux-gnu.picotool-03f2812.230113.tar.gz",
250+
"archiveFileName": "x86_64-linux-gnu.picotool-03f2812.230113.tar.gz",
251+
"checksum": "SHA-256:c6168c6948ec781ead9637ecddc357004aa0fbaca19a634a48fbfc4e48860d1a",
252+
"size": "131509"
253+
},
254+
{
255+
"host": "x86_64-mingw32",
256+
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.5.0-a/x86_64-w64-mingw32.picotool-03f2812.230112.zip",
257+
"archiveFileName": "x86_64-w64-mingw32.picotool-03f2812.230112.zip",
258+
"checksum": "SHA-256:a5bded215b886bc8dc35520d2ae696c56e370ef6e92ca7d3a47fe82db362afa7",
259+
"size": "337118"
260+
}
261+
]
262+
},
203263
{
204264
"version": "1.5.0-a-5007782",
205265
"name": "pqt-openocd",

platform.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ runtime.tools.pqt-mklittlefs.path={runtime.platform.path}/system/mklittlefs
2828
runtime.tools.pqt-pioasm.path={runtime.platform.path}/system/pioasm
2929
runtime.tools.pqt-elf2uf2.path={runtime.platform.path}/system/elf2uf2
3030
runtime.tools.pqt-openocd.path={runtime.platform.path}/system/openocd
31+
runtime.tools.pqt-picotool.path={runtime.platform.path}/system/picotool
3132
compiler.path={runtime.tools.pqt-gcc.path}/bin/
3233

3334
compiler.libraries.ldflags=
@@ -44,7 +45,7 @@ compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-ignored-qualif
4445
compiler.netdefines=-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=0 {build.lwipdefs} -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1
4546
compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines} -DARDUINO_VARIANT="{build.variant}" -DTARGET_RP2040
4647
compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/platform_inc.txt" "-I{runtime.platform.path}/include"
47-
compiler.flags=-march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections {build.flags.exceptions} {build.flags.stackprotect} {build.flags.cmsis}
48+
compiler.flags=-march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections {build.flags.exceptions} {build.flags.stackprotect} {build.flags.cmsis} {build.picodebugflags}
4849
compiler.wrap="@{runtime.platform.path}/lib/platform_wrap.txt"
4950
compiler.libbearssl="{runtime.platform.path}/lib/libbearssl.a"
5051

@@ -97,6 +98,7 @@ build.boot2=boot2_generic_03h_4_padded_checksum
9798
build.lwipdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1
9899
build.wificc=-DWIFICC=CYW43_COUNTRY_WORLDWIDE
99100
build.debugscript=picoprobe.tcl
101+
build.picodebugflags=
100102

101103
# Allow Pico boards do be auto-discovered by the IDE
102104
#discovery.rp2040.pattern={runtime.tools.pqt-python3.path}/python3 -I "{runtime.platform.path}/tools/pluggable_discovery.py"
@@ -187,6 +189,12 @@ tools.uf2conv-network.upload.params.verbose=
187189
tools.uf2conv-network.upload.params.quiet=
188190
tools.uf2conv-network.upload.pattern="{cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{upload.port.address}" -p "{upload.port.properties.port}" "--auth={upload.field.password}" -f "{build.path}/{build.project_name}.bin"
189191

192+
#tools.picotool.cmd={runtime.tools.pqt-picotool.path}
193+
tools.picotool.cmd={runtime.platform.path}/system/picotool
194+
tools.picotool.upload.protocol=picotool
195+
tools.picotool.upload.params.verbose=
196+
tools.picotool.upload.params.quiet=
197+
tools.picotool.upload.pattern="{cmd}/picotool" load "{build.path}/{build.project_name}.uf2" -f
190198

191199
#tools.picoprobe.cmd={runtime.tools.pqt-openocd.path}
192200
tools.picoprobe.cmd={runtime.platform.path}/system/openocd

0 commit comments

Comments
 (0)