User avatar
HermannSW
Posts: 5297
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Pico (USB) No-Button-Boot (NBB)

Fri Feb 26, 2021 7:31 pm

This thread is based on the different concepts developed in "Poor Man's Pico No-Button-Boot (NBB)" thread by different people:
viewtopic.php?f=144&t=302144

While signalling over RTS/DTR is nice, I have to agree with @incognitum that special software is needed to do that triggering, while his "tud_cdc_set_wanted_char('\0');" method can be triggered from bash command line easily:
viewtopic.php?f=144&t=302144&start=50#p1827396

Code: Select all

$ printf "\0" > /dev/ttyACM0

The "problem" with that method until this thread was, that each program had to add "tud_cdc_set_wanted_char('\0');" to main() and define a callback function. Why do I say until now? I have resolved that issue -- for code that does use USB, and even for code that does not use USB!

First visual proof that I was successful:
  • on the right side miniterm session is active, with output stating that demo will start
  • next I did "make clean" in pico-examples/build/hello_world/usb
  • and then reverted all changes to pico-examples/hello_world/usb/hello_usb.c
  • the "make" then compiles unmodifed pico-examples demo code hello_usb.c
  • first "flash" does upload (and start) newly compiled "hello_usb.uf2"
  • only the second flash proves that really "hello_usb.uf2" allows for externally bringing into flash mode

Image


I used this "flash" script
https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7
which uses the "printf" command discussed above in order to simulate "bootsel pressed" restart.


So how does this work?
"stdio_init_all()" does call "stdio_usb_init()" if USB is supported.
I just added this command as last statement of "stdio_init_usb()" in "pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c":

Code: Select all

@@ -104,6 +111,9 @@ bool stdio_usb_init(void) {
     if (rc) {
         stdio_set_driver_enabled(&stdio_usb, true);
     }
+
+    tud_cdc_set_wanted_char('\0');
+
     return rc;
 }
 #else

At top of the file this small addition completes the functionality:

Code: Select all

@@ -13,6 +13,13 @@
 #include "pico/binary_info.h"
 #include "hardware/irq.h"
 
+#include "pico/bootrom.h"
+
+void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char)
+{ 
+  reset_usb_boot(0, 0);      // go to flash mode
+}
+
 static_assert(PICO_STDIO_USB_LOW_PRIORITY_IRQ > RTC_IRQ, ""); // note RTC_IRQ i

Since Pico C SDK "make" does not use libraries directly, no library needs to be recompiled(!).


OK, now we have seen how to make use of new "flash" technique from code that uses USB.
These are the simple steps needed to make "hello_serial" demo accepting bring to flash mode command:
  • add this to "pico/pico-examples/hello_world/serial/CMakeLists.txt"

    Code: Select all

     target_link_libraries(hello_serial pico_stdlib)
     
    +pico_enable_stdio_usb(hello_serial 1)
    +
     # create map/bin/hex/uf2 file etc.
    
  • cd ~/pico/pico-examples/build && cmake ..
That is all -- now when you compile hello_serial in "pico/pico-examples/build/hello_world/serial" with "make", the needed USB code will be part of "hello_serial.uf2".



Summary:
  • for code utilizing USB new method just works, not touching anything(*) is needed
  • for code not utilizing USB, one addition to its CMakeLists.txt and one "cmake .." are needed once

(*)
You have to modify "pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c" once as described above.
https://hermann-sw.github.io/planar_graph_playground
https://stamm-wilbrandt.de/en#raspcatbt
https://github.com/Hermann-SW/memrun
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 5297
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: Pico (USB) No-Button-Boot (NBB)

Sat Feb 27, 2021 1:08 pm

I just play with flash_stream demo, and "pico/pico-playground/build/scanvideo/flash_stream/flash_stream.c" does not have a "stdio_init_all()". In addition to adding "pico_enable_stdio_usb(flash_stream 1)" to CMakeLists.txt and executing "cmake .." in "pico/pico-playground/build" I had to add "stdio_init_all()" to "main()". After work is done, all three steps can be undone, but until then programming the Pico with "flash" tool just works.

No activity is required executing "flash" tool, "removable medium" popup appears, but automatically goes away by last "cp" command:
https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7

Code: Select all

#!/bin/bash
printf "\0" > /dev/ttyACM0
echo waiting
while [ ! -d /media/pi/RPI-RP2 ]; do sleep 0.1; done
sleep 0.5
if [ "$*" = "" ]; then echo rebooting; sudo picotool reboot; exit; fi
echo copying
cp $1 /media/pi/RPI-RP2
echo done
https://hermann-sw.github.io/planar_graph_playground
https://stamm-wilbrandt.de/en#raspcatbt
https://github.com/Hermann-SW/memrun
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

hippy
Posts: 12485
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Pico (USB) No-Button-Boot (NBB)

Sun Feb 28, 2021 1:37 pm

HermannSW wrote:
Fri Feb 26, 2021 7:31 pm
While signalling over RTS/DTR is nice, I have to agree with @incognitum that special software is needed to do that triggering, while his "tud_cdc_set_wanted_char('\0');" method can be triggered from bash command line easily:
Using "printf "\0" > /dev/ttyACM0" has never worked for me. No idea why because it does work from within a Python program.

I don't however feel that setting "tud_cdc_set_wanted_char('\0')" is a good general purpose solution because it can't be used by code which may want to receive that "\0". Not a problem for 'Printable ASCII' interfacing but it will be for binary interfacing, could rule out PPP/SLIP over USB, a variety of 'gadget modes' and other possibilities.

It also presents the problem you are trying to resolve here. Good effort and well done, but it's an unnecessary complication when there are other easier solutions.

The RTS/DTR trick is clever but again doesn't work for code which may wish to use those signals, and will be problematic when connected to an interface program which may cause RTS changes as the port is opened and initialised - and that may be out of the programmer's hands.

What is needed is something truly out-of-band. Unless intercepting at a higher level of USB transaction handling, the only viable solution appears to be baud rate change triggering. Few programs need to respond to baud rate changes and, even when they do, requiring going from one baud rate to another, even a whole sequence of changes or having timeouts, should solve that. Selecting 110 baud then 300 or 600 baud is not something which will be very common at all.

That will probably require a separate program or utility to action a Pico reset or bootloader invocation but I don't see that as a practical concern - In Python it should be as simple as opening the port twice -

Code: Select all

ser = serial.Serial("/dev/ttyACM0", 110)
ser.close()
ser = serial.Serial("/dev/ttyACM0", 300)
ser.close()
The other benefit of baud rate changes is it's not limited to triggering just one or two actions, and those are simple to implement with just a 'switch' structure.

So, as much as I appreciate all the effort put into providing No Button Boot capabilities; baud rate change is currently the only non-problematic solution in my view which should be recommended as a general solution for people who don't want 'openocd' or more advanced solutions, just want to be able to kick a Pico into reset or bootloader mode once their code is running.

Baud rate change actioning has been mentioned on the forum, but I couldn't find any code for doing it on a Pico ? Does anyone have such code or a link to it ?

incognitum
Posts: 1043
Joined: Tue Oct 30, 2018 3:34 pm

Re: Pico (USB) No-Button-Boot (NBB)

Sun Feb 28, 2021 3:02 pm

hippy wrote:
Sun Feb 28, 2021 1:37 pm
I don't however feel that setting "tud_cdc_set_wanted_char('\0')" is a good general purpose solution because it can't be used by code which may want to receive that "\0". Not a problem for 'Printable ASCII' interfacing but it will be for binary interfacing, could rule out PPP/SLIP over USB, a variety of 'gadget modes' and other possibilities.
Sounds like a more theoretical problem to me.
Why would one use PPP/SLIP over the CDC ACM interface, when you could let the Pico do CDC Ethernet on a seperate interface as well if there was any need for network communcation?

That will probably require a separate program or utility to action a Pico reset or bootloader invocation but I don't see that as a practical concern - In Python it should be as simple as opening the port twice -

Code: Select all

ser = serial.Serial("/dev/ttyACM0", 110)
ser.close()
ser = serial.Serial("/dev/ttyACM0", 300)
ser.close()
While Python hides the implementation details nicely, be aware that things like setting baudrate is highly platform dependent.
E.g. to see how that is handled under the hood:
https://github.com/pyserial/pyserial/bl ... alposix.py
https://github.com/pyserial/pyserial/bl ... alwin32.py

Not sure whether or not all platforms support baudrates that low either.
E.g. Cygwin only has constants for the higher ones: https://github.com/pyserial/pyserial/bl ... ix.py#L193 ?

Baud rate change actioning has been mentioned on the forum, but I couldn't find any code for doing it on a Pico ? Does anyone have such code or a link to it ?

Here you go: https://github.com/MichaelBell/pico-sdk ... c3bfc1dc29


See also the issue on the main repo: https://github.com/raspberrypi/pico-sdk/issues/112
It is suggesting adding an extra USB interface, and letting picotool send the special command.

Personally not a fan of installing extra executables like picotool either, that may need udev rules to get them to work, etc.
Hassle you do not have when using the MSD interface for flashing instead.

hippy
Posts: 12485
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Pico (USB) No-Button-Boot (NBB)

Sun Feb 28, 2021 3:58 pm

incognitum wrote:
Sun Feb 28, 2021 3:02 pm
hippy wrote:
Sun Feb 28, 2021 1:37 pm
I don't however feel that setting "tud_cdc_set_wanted_char('\0')" is a good general purpose solution because it can't be used by code which may want to receive that "\0". Not a problem for 'Printable ASCII' interfacing but it will be for binary interfacing, could rule out PPP/SLIP over USB, a variety of 'gadget modes' and other possibilities.
Sounds like a more theoretical problem to me.
Why would one use PPP/SLIP over the CDC ACM interface, when you could let the Pico do CDC Ethernet on a seperate interface as well if there was any need for network communcation?
For people who don't have a good grasp on how to do things and have to figure it out for themselves it's easier to hook something into what exists rather than try and figure out how to create separate or composite interfaces. I was just thinking of some example where it would be problematic to not just me.

Maybe I should have just left it at 'doesn't work for anyone needing a binary rather than character interface', which is the boat I am in, and I am using RTS signalling as a stop-gap for break signal detection which I haven't been able to figure out how to add.
incognitum wrote:
Sun Feb 28, 2021 3:02 pm
While Python hides the implementation details nicely, be aware that things like setting baudrate is highly platform dependent.
Ultimately a CDC device will get told what baud rate is being used so that shouldn't be a problem.
incognitum wrote:
Sun Feb 28, 2021 3:02 pm
Here you go: https://github.com/MichaelBell/pico-sdk ... c3bfc1dc29
Many thanks for that.
incognitum wrote:
Sun Feb 28, 2021 3:02 pm
See also the issue on the main repo: https://github.com/raspberrypi/pico-sdk/issues/112
It is suggesting adding an extra USB interface, and letting picotool send the special command.
I would probably be happy with a Pico exposing two serial channels, having the second used to respond to reboot sequences and also useful for debugging printf's when the first is tied up for data transfer. Unfortunately it's far beyond my own capabilities for implementing that at present.

User avatar
HermannSW
Posts: 5297
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: Pico (USB) No-Button-Boot (NBB)

Sun Feb 28, 2021 6:00 pm

Thanks @hippy and @incognitum for the good discussion.

My comments on SWD were probably too harsh wrt soldering needed (the Pico right).
Three logic analyzer probes allow easy non-soldering SWD work (the middle Pico):
20210228_170646.10%.part.jpg
20210228_170646.10%.part.jpg
20210228_170646.10%.part.jpg (37.67 KiB) Viewed 3296 times

Besides SWD these methods for triggering "bootsel mode" have been proposed:
  • sending '\0' to /dev/ttyACM0
  • triggering with RTS/DTR
  • triggering via baudrate changes
I buy hippy's argument wrt. binary data transmission, so no '\0' anymore.
baudrate changes convinced me, with python as easy as sending '\0'.

I did change my "flash" gist to allow for rebooting as well as flashing .uf2 files.
So easy with "python -c" and bash function "baud":
https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7

Code: Select all

#!/bin/bash
function baud { python -c "import serial; serial.Serial(\"$1\", $2).close()"; }
if [ "$*" = "" ]; then echo rebooting; baud /dev/ttyACM0 2400; exit; fi
baud /dev/ttyACM0 1200
echo waiting
while [ ! -d /media/pi/RPI-RP2 ]; do sleep 0.1; done
sleep 0.5
echo copying
cp $1 /media/pi/RPI-RP2
echo done

Running "flash" command (~/.local/bin/flash) just reboots the Pico as can be seen.
"flash" with .uf2 argument brings Pico into bootsel mode and then flashes the .uf2.
Minicom session does not know about baudrate change, but does not need to.
The reboot/start in bootsel mode bring the Pico to 115200 default baudrate again:
Peek_2021-02-28_18-35.gif
Peek_2021-02-28_18-35.gif
Peek_2021-02-28_18-35.gif (108.32 KiB) Viewed 3296 times

The minimal change to "pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c" is so small, really that is all:

Code: Select all

@@ -13,6 +13,15 @@
 #include "pico/binary_info.h"
 #include "hardware/irq.h"
 
+#include "pico/bootrom.h"
+#include "hardware/watchdog.h"
+
+void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding)
+{ 
+  if (p_line_coding->bit_rate == 1200)  { reset_usb_boot(0, 0); }
+  if (p_line_coding->bit_rate == 2400)  { watchdog_reboot(0, 0, 0); }
+}
+
 static_assert(PICO_STDIO_USB_LOW_PRIORITY_IRQ > RTC_IRQ, ""); // note RTC_IRQ is currently the last one
https://hermann-sw.github.io/planar_graph_playground
https://stamm-wilbrandt.de/en#raspcatbt
https://github.com/Hermann-SW/memrun
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

hippy
Posts: 12485
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Pico (USB) No-Button-Boot (NBB)

Sun Feb 28, 2021 6:51 pm

HermannSW wrote:
Sun Feb 28, 2021 6:00 pm
The minimal change to "pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c" is so small, really that is all:
Pretty much what I implemented, though in main.c. I also have it that it must be 1200 baud then 2400 or 4800 to prevent issues if opened with those baud rates.

So all three mechanisms working for me, "\0" sent, RTS toggle and baud rate change. Haven't managed to hook BOOTSEL button into the USB task yet which is a fourth method; can't figure out which include files are needed.

Code: Select all

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/bootrom.h"
#include "hardware/watchdog.h"
#include "class/cdc/cdc_device.h"

// Enter MSD Bootloader Mode when "\0" recieved
// Note: Must be enabled in main()
// https://www.raspberrypi.org/forums/viewtopic.php?p=1813953#p1813953
// printf "\0" > /dev/ttyACM0
// ./null-boot.py

void tud_cdc_rx_wanted_cb(uint8_t itf, char c) {
  reset_usb_boot(0, 0);
}

// Enter MSD Bootloader or Reset when RTS line changes
// Note: Enabled by inclusion. Not need to enable in main()
// https://www.raspberrypi.org/forums/viewtopic.php?p=1825646#p1825646
// ./rts-boot.py  - DTR=1  MSD Bootloader
// ./rts-reset.py - DTR=0  Reset

void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
  static int8_t lastRts = -1;
  if ((-1 != lastRts) && (lastRts && !rts)) {
    if (dtr) { reset_usb_boot(0, 0);     }
    else     { watchdog_reboot(0, 0, 0); }
  }
  lastRts = rts;
}

// Enter MSD Bootloader or Reset when baudrate changes
// Note: Enabled by inclusion. No need to enable in main()
// https://github.com/MichaelBell/pico-sdk/commit/d19e44166b4548bfd5b1586e73e3e4c3bfc1dc29
// ./baud-boot.py  - 1200 -> 2400  MSD Bootloader
// ./baud-reset.py - 1200 -> 4800  Reset

void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) {
  static uint32_t lastBaudRate = 0;
  uint32_t baudRate = p_line_coding->bit_rate;
  if ((1200 == lastBaudRate) && (baudRate != lastBaudRate)) {
    switch (baudRate) {
      case 2400 : { reset_usb_boot(0, 0);     }
      case 4800 : { watchdog_reboot(0, 0, 0); }
    }
  }
  lastBaudRate = baudRate;
}

int main()
{
  stdio_init_all();

  // Enable enter MSD Bootloader Mode when "\0" recieved
  tud_cdc_set_wanted_char('\0');

  while(true)
  {
    printf("%d\n", time_us_32());
    busy_wait_us(1000000);
  }
}

User avatar
HermannSW
Posts: 5297
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: Pico (USB) No-Button-Boot (NBB)

Sun Feb 28, 2021 7:01 pm

hippy wrote:
Sun Feb 28, 2021 6:51 pm
Pretty much what I implemented, though in main.c. I also have it that it must be 1200 baud then 2400 or 4800 to prevent issues if opened with those baud rates.
I will never use 1200 or 2400 baudrates for USB other than signalling, so just checking for those baudrates and reflash/reboot is fine.

The most important point for me is to make the change in "pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c", because then automatically all projects get the NBB support compiled in, without any code change in the project!
https://hermann-sw.github.io/planar_graph_playground
https://stamm-wilbrandt.de/en#raspcatbt
https://github.com/Hermann-SW/memrun
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 5297
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: Pico (USB) No-Button-Boot (NBB)

Mon Mar 01, 2021 11:31 am

incognitum wrote:
Sun Feb 28, 2021 3:02 pm
While Python hides the implementation details nicely, be aware that things like setting baudrate is highly platform dependent.
"flash" script is a bash script, so runs on Linux/Raspberry Pi OS.
But for those platforms python is not needed to change baudrate, stty can be utilized:
reboot

Code: Select all

sudo stty -F /dev/ttyACM0 2400
reflash

Code: Select all

sudo stty -F /dev/ttyACM0 2400

I just updated the gist, since requiring stty is more lightweight than requiring python.
And bash function "baud" is not needed anymore:
https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7
https://hermann-sw.github.io/planar_graph_playground
https://stamm-wilbrandt.de/en#raspcatbt
https://github.com/Hermann-SW/memrun
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 5297
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: Pico (USB) No-Button-Boot (NBB)

Fri Mar 05, 2021 5:03 pm

I often switch between flashing C code .uf2 files and Micropython .uf2 files.

The instructions for builing Micropython show that tinyusb is included as a submodule:

Code: Select all

$ cd micropython
$ git submodule update --init -- lib/pico-sdk lib/tinyusb

And micropython/ports/rps/main.c does call "tusb_init()" instead of "stdio_init_all()" or "stdio_init_usb()" which included the 8 lines of C code that allow for reflash/reboot withpout pressing bootsel switch. So the 8 lines have to just go to another file, "pico/micropython/lib/tinyusb/src/tusb.c":

Code: Select all

@@ -30,6 +30,15 @@
 
 #include "tusb.h"
 
+#include "pico/bootrom.h"
+#include "hardware/watchdog.h"
+
+void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding)
+{ 
+  if (p_line_coding->bit_rate == 1200)  { reset_usb_boot(0, 0); }
+  if (p_line_coding->bit_rate == 2400)  { watchdog_reboot(0, 0, 0); }
+}
+
 static bool _initialized = false;

With those lines added and flashing rebuilt Micropython, "flash" tool can be used to flash something else over Micropython, or to just reboot ("flash" without arguments):
https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7


This little change for Micropython allows for a different feature as well, external reboot.
Micropython can call "machine.reset()" for reboot, but a running loop would need to be stopped first, "machine" to be imported and "machine.reset()" to be called, after having a Micropython session opened.
Added 8 lines allow to reboot Pico Micropython externally, with either "flash" tool called without argument , or just this command:

Code: Select all

sudo stty -F /dev/ttyACM0 2400
Peek_2021-03-05_17-58.gif
Peek_2021-03-05_17-58.gif
Peek_2021-03-05_17-58.gif (72.25 KiB) Viewed 3074 times
https://hermann-sw.github.io/planar_graph_playground
https://stamm-wilbrandt.de/en#raspcatbt
https://github.com/Hermann-SW/memrun
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 5297
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany

Re: Pico (USB) No-Button-Boot (NBB)

Tue Mar 09, 2021 2:33 pm

Last weekend V1.1.0 pico-sdk was published.
It contains builtin support for baudrate change (1200) to enter "bootsel pressed" mode.

While there is a vendor specific command to reset Pico as well over USB, it is far too complicate to reinvent the wheel.
Why reinvent? picotool allows to reboot, if device is already in bootsel mode. And baudrate change can get there.

So I updated "flash" gist to use baudrate change as well as "picotool reboot":
https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7

Code: Select all

#!/bin/bash
sudo stty -F /dev/ttyACM0 1200
echo waiting
while [ ! -d /media/pi/RPI-RP2 ]; do sleep 0.1; done
sleep 0.5
if [ "$*" = "" ]; then echo rebooting; sudo picotool reboot; exit; fi
echo copying
cp $1 /media/pi/RPI-RP2
echo done
@Hermann-SW

Here you can see that even software that does not ustilize USB can be enabled for "flash" tool usage, by just enabling usb in projects CMakeLists.txt, here for hello_serial.c example from pico-examples:
Peek_2021-03-09_14-25.gif
Peek_2021-03-09_14-25.gif
Peek_2021-03-09_14-25.gif (208.02 KiB) Viewed 2970 times

The last call of "flash" without arguments, that does reboot the Pico, would not work without usb enabled.


So this is what you need to do:
  1. install "flash" tool: https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7
  2. install picotool: https://github.com/raspberrypi/picotool

With new flash tool you can flash new .uf2 files and reset the Pico over USB.
And for projects using USB no change is needed (besides using >= 1.1.0 version of SDK)!


P.S:
If you update micropython/lib/pico-sdk and build and flash your own Micropython, your Micropython Pico can be flashed/rebooted with "flash" tool as well (reboot is same as "machine.reset()", without the need to stop running code and enter that command in REPL).
https://hermann-sw.github.io/planar_graph_playground
https://stamm-wilbrandt.de/en#raspcatbt
https://github.com/Hermann-SW/memrun
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

Return to “SDK”