Jim's Depository

this code is not yet written
 

NOTE: THIS IS ALL OBSOLETE, DO NOT USE!

Find the reset_usb_boot() function in pico/bootrom.h instead.

But for historical reasons, and maybe you want to render it unbootable…

I want to be able to erase and reprogram my Pi Pico without having to touch it and only having a USB cable to it.

I built my program to use USB for the console. If the console receives a "reset" command then it erases the secondary boot loader from flash and forces a restart. This will make it boot into the UF2 loader.

The function looks like this…

#include "wipe.h"
#include "hardware/watchdog.h"
#include "hardware/flash.h"
#include "hardware/sync.h"
#include "pico/multicore.h"

// Remember: Put hardware_flash and pico_multicore in the CMakeLists.txt target_link_libraries

void wipe(void) {
    const uint8_t blank[256] = {0};

    // Stop core1. We better be core0.                                                                                                
    multicore_reset_core1();

    uint32_t saved = save_and_disable_interrupts();
    // Wipe the secondary boot loader                                                                                                 
    flash_range_program( 0, blank, 256);
    restore_interrupts(saved);

    // this will reset us in 1 millisecond.                                                                                           
    watchdog_enable( 1, false);

    // await our doom                                                                                                                 
    while( true);
}

No more physical access required while developing. Until I do something stupid to hang the CPU.

Subtle Note:

I am using flash_range_program instead of flash_range_erase because I want to do only 256 bytes. Otherwise I clobber the code I'm executing and everything ends in tears. In the world of this flash chip, "erase" means "set to all ones" and "program" means "set the zeros to zero". So I can turn the 256 bytes into all zeros without erasing.

Danger:

If you decide you want to erase the whole flash, there is going to be trouble. You will end up erasing the code you are executing and hang. I would suggest you move the watchdog_enable call above your flash_range_erase (which you will use instead of program so you don't need a buffer) and give it a timeout long enough to accomplish the erase.

Ostensibly you can mark your function as being copied to RAM, but I didn't have success with that. If I used the CMakeLists.txt to make the whole program be in RAM I could erase flash willy nilly without problems.