support programming rp2350, add a new example to program metro rp2350 from firmware.h
rename program_rp2040_uf2.ino to program_rp2_from_sdcard.ino change include SdFat.h to SdFat_Adafruit_Fork.h
This commit is contained in:
parent
1130b8c29d
commit
759bdeb282
23 changed files with 7294 additions and 28 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Testing basic peripherals on Brain
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// - There is no need to connect IO0/Reset since we will use DTR/RTS to reset ESP32
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain TX/RX <-> ESP32 RX/TX
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain's USB host to Target USB
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain's USB host to Target USB
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
BIN
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2
Normal file
BIN
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2
Normal file
Binary file not shown.
7043
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2.h
Normal file
7043
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2.h
Normal file
File diff suppressed because it is too large
Load diff
135
examples/Brain/program_rp2/program_rp2.ino
Normal file
135
examples/Brain/program_rp2/program_rp2.ino
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// This sketch program rp2040 by copying UF2 file from SDCard to
|
||||
// rp2040 bootrom
|
||||
// Hardware wiring:
|
||||
// - Brain's Target GPIO28 to RP2 bootsel
|
||||
// - Brain's Target Reset to RP2 Reset
|
||||
// - Brain's USB host to RP2040 USB interface
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
#include "Adafruit_TinyUSB.h"
|
||||
|
||||
#include "Adafruit_TestBed_Brains.h"
|
||||
|
||||
// firmware.h is converted using tools/file2carray.py e.g
|
||||
// python tools/file2carray.py cdc_msc.uf2
|
||||
// above command will generate cdc_msc.uf2.h with bindata, bindata_len
|
||||
#include "metro_rp2350_cdc_msc.uf2.h"
|
||||
|
||||
// RP2040 Boot VID/PID
|
||||
#define BOOT_VID 0x2e8a
|
||||
#define BOOT_PID_RP2040 0x0003
|
||||
#define BOOT_PID_RP2350 0x000f
|
||||
|
||||
// If USB filesystem is mounted
|
||||
volatile bool is_usbfs_mounted = false;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup and Loop on Core0
|
||||
//--------------------------------------------------------------------+
|
||||
void print_speed(size_t count, uint32_t ms) {
|
||||
Brain.LCD_printf(0, "%.01fKB %.01fs", count/1000.0F, ms / 1000.0F);
|
||||
|
||||
Serial.printf("Completed %u bytes in %.02f seconds.\r\n", count, ms / 1000.0F);
|
||||
Serial.printf("Speed : %.02f KB/s\r\n", (count / 1000.0F) / (ms / 1000.0F));
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) delay(10);
|
||||
Serial.println("Program RP2 by copy UF2 from Internal Flash to Bootloader!");
|
||||
|
||||
// sync: wait for Brain.begin() called in core1 before accessing SD or other peripherals
|
||||
while (!Brain.inited()) delay(10);
|
||||
|
||||
// wait for USB filesystem is mounted. USB host bit-banging and task is
|
||||
// processed on core1
|
||||
while (!is_usbfs_mounted) delay(10);
|
||||
|
||||
// Copy UF2 file
|
||||
Brain.LCD_printf(0, "Copying firmware");
|
||||
Serial.println("Copying UF2 from Flash to USBHFS");
|
||||
|
||||
uint32_t ms = millis();
|
||||
size_t copied_bytes = Brain.rp2_programUF2(bindata, bindata_len);
|
||||
print_speed(copied_bytes, millis() - ms);
|
||||
|
||||
// wait for rp2040 boot rom to reset
|
||||
// while (is_usbfs_mounted) delay(10);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup and Loop on Core1
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// call usbh_begin() here to make pio usb background task run on core1
|
||||
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
||||
void setup1() {
|
||||
Brain.begin();
|
||||
Brain.usbh_begin();
|
||||
|
||||
Brain.LCD_printf(1, "No USB Device");
|
||||
|
||||
// reset rp2040 target into Boot Rom, default bootsel = 28, reset duration = 10 ms
|
||||
Brain.rp2_targetResetBootRom();
|
||||
}
|
||||
|
||||
// core1's loop: process usb host task on core1
|
||||
void loop1() {
|
||||
Brain.USBHost.task();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TinyUSB Host callbacks
|
||||
// Note: running in the same core where Brain.USBHost.task() is called
|
||||
//--------------------------------------------------------------------+
|
||||
bool is_rp2_bootloader(uint16_t vid, uint16_t pid) {
|
||||
return (vid == BOOT_VID && (pid == BOOT_PID_RP2040 || pid == BOOT_PID_RP2350));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Invoked when device is mounted (configured)
|
||||
void tuh_mount_cb(uint8_t dev_addr) {
|
||||
uint16_t vid, pid;
|
||||
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||
|
||||
if (!is_rp2_bootloader(vid, pid)) {
|
||||
Brain.LCD_printf(1, "UnkDev %04x:%04x", vid, pid);
|
||||
}
|
||||
}
|
||||
|
||||
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||
void tuh_umount_cb(uint8_t dev_addr) {
|
||||
(void)dev_addr;
|
||||
Brain.LCD_printf(1, "No USB Device");
|
||||
}
|
||||
|
||||
// Invoked when a device with MassStorage interface is mounted
|
||||
void tuh_msc_mount_cb(uint8_t dev_addr) {
|
||||
uint16_t vid, pid;
|
||||
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||
|
||||
if (is_rp2_bootloader(vid, pid)) {
|
||||
is_usbfs_mounted = Brain.usbh_mountFS(dev_addr);
|
||||
if (is_usbfs_mounted) {
|
||||
uint16_t rp2variant = (pid == BOOT_PID_RP2040 ? 2040 : 2350);
|
||||
Brain.LCD_printf(1, "RP%u Bootldr", rp2variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when a device with MassStorage interface is unmounted
|
||||
void tuh_msc_umount_cb(uint8_t dev_addr) {
|
||||
is_usbfs_mounted = false;
|
||||
Brain.usbh_umountFS(dev_addr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain's USB host to RP2040 USB interface
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
@ -79,7 +79,7 @@ void setup() {
|
|||
Serial.println("Copying from SD to USBHFS: " UF2_FILE_PATH);
|
||||
|
||||
uint32_t ms = millis();
|
||||
size_t copied_bytes = Brain.rp2040_programUF2(UF2_FILE_PATH);
|
||||
size_t copied_bytes = Brain.rp2_programUF2(UF2_FILE_PATH);
|
||||
|
||||
print_speed(copied_bytes, millis() - ms);
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ void setup1() {
|
|||
Brain.LCD_printf(1, "No USB Device");
|
||||
|
||||
// reset rp2040 target into Boot Rom, default bootsel = 28, reset duration = 10 ms
|
||||
Brain.rp2040_targetResetBootRom();
|
||||
Brain.rp2_targetResetBootRom();
|
||||
}
|
||||
|
||||
// core1's loop: process usb host task on core1
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain's USB host to Target USB
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain's USB host to Target USB
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain's USB host to Target USB
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// - Brain's USB host to Target USB
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// to LCD. Also determine if device support MSC or HID
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// to LCD. Also determine if device support MSC or HID
|
||||
|
||||
// required for Host MSC block device
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// required for USB host
|
||||
#include "pio_usb.h"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* from https://github.com/adafruit/nina-fw/releases/tag/1.7.5 in this example directory.
|
||||
*/
|
||||
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
// #include "Adafruit_TinyUSB.h"
|
||||
#include "Adafruit_TestBed.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include "Wire.h"
|
||||
|
||||
#include "ESP32BootROM.h"
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
#define RED 0xFF0000
|
||||
#define YELLOW 0xFFFF00
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#ifdef ARDUINO_RASPBERRY_PI_PICO
|
||||
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
#include "pio_usb.h"
|
||||
|
||||
#include "Adafruit_DAP.h"
|
||||
|
|
@ -133,8 +133,8 @@ bool Adafruit_TestBed_Brains::inited(void) { return _inited; }
|
|||
// RP2040 Target
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void Adafruit_TestBed_Brains::rp2040_targetResetBootRom(int bootsel_pin,
|
||||
uint32_t reset_ms) {
|
||||
void Adafruit_TestBed_Brains::rp2_targetResetBootRom(int bootsel_pin,
|
||||
uint32_t reset_ms) {
|
||||
pinMode(bootsel_pin, OUTPUT);
|
||||
digitalWrite(bootsel_pin, LOW);
|
||||
|
||||
|
|
@ -146,7 +146,41 @@ void Adafruit_TestBed_Brains::rp2040_targetResetBootRom(int bootsel_pin,
|
|||
pinMode(bootsel_pin, INPUT);
|
||||
}
|
||||
|
||||
size_t Adafruit_TestBed_Brains::rp2040_programUF2(const char *fpath) {
|
||||
size_t Adafruit_TestBed_Brains::rp2_programUF2(const uint8_t *buffer,
|
||||
size_t bufsize) {
|
||||
size_t copied_bytes = 0;
|
||||
const char *dst_name = "FIRMWARE.UF2";
|
||||
File32 fdst = USBH_FS.open(dst_name, O_WRONLY | O_CREAT);
|
||||
|
||||
if (!fdst) {
|
||||
Serial.printf("USBH_FS: cannot create file: %s\r\n", dst_name);
|
||||
} else {
|
||||
while (copied_bytes < bufsize) {
|
||||
size_t count = bufsize - copied_bytes;
|
||||
if (count > 4096) {
|
||||
count = 4096; // write 1 sector each
|
||||
}
|
||||
|
||||
setLED(HIGH);
|
||||
size_t wr_count = fdst.write(buffer, count);
|
||||
setLED(LOW);
|
||||
|
||||
buffer += wr_count;
|
||||
copied_bytes += wr_count;
|
||||
|
||||
if (wr_count != count) {
|
||||
Serial.println("USBH_FS: Failed to write file");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fdst.close();
|
||||
|
||||
return copied_bytes;
|
||||
}
|
||||
|
||||
size_t Adafruit_TestBed_Brains::rp2_programUF2(const char *fpath) {
|
||||
File32 fsrc = SD.open(fpath);
|
||||
if (!fsrc) {
|
||||
Serial.printf("SD: cannot open file: %s\r\n", fpath);
|
||||
|
|
@ -154,7 +188,6 @@ size_t Adafruit_TestBed_Brains::rp2040_programUF2(const char *fpath) {
|
|||
}
|
||||
|
||||
size_t copied_bytes = 0;
|
||||
|
||||
const char *dst_name = "FIRMWARE.UF2";
|
||||
File32 fdst = USBH_FS.open(dst_name, O_WRONLY | O_CREAT);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#ifdef ARDUINO_RASPBERRY_PI_PICO
|
||||
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
#include "Adafruit_TestBed.h"
|
||||
#include <LiquidCrystal.h>
|
||||
|
|
@ -49,15 +49,25 @@ public:
|
|||
bool usbh_mountFS(uint8_t dev_addr);
|
||||
bool usbh_umountFS(uint8_t dev_addr);
|
||||
|
||||
//--------------------------------------------------------------------+1
|
||||
// RP2 (rp2040 and rp2350) Target
|
||||
//--------------------------------------------------------------------+
|
||||
// RP2040 Target
|
||||
//--------------------------------------------------------------------+
|
||||
// reset rp2040 target to Boot ROM
|
||||
void rp2040_targetResetBootRom(int bootsel_pin = 28, uint32_t reset_ms = 20);
|
||||
// reset rp2 target to Boot ROM
|
||||
void rp2_targetResetBootRom(int bootsel_pin = 28, uint32_t reset_ms = 20);
|
||||
|
||||
// program rp2040 target by copying UF2 file from SDCard
|
||||
// program rp2 target by copying UF2 file stored in flash
|
||||
size_t rp2_programUF2(const uint8_t *buffer, size_t bufsize);
|
||||
|
||||
// program rp2 target by copying UF2 file from SDCard
|
||||
// return number of copied bytes (typically uf2 file size)
|
||||
size_t rp2040_programUF2(const char *fpath);
|
||||
size_t rp2_programUF2(const char *fpath);
|
||||
|
||||
// backward compatibility
|
||||
void rp2040_targetResetBootRom(int bootsel_pin = 28, uint32_t reset_ms = 20) {
|
||||
rp2_targetResetBootRom(bootsel_pin, reset_ms);
|
||||
}
|
||||
|
||||
size_t rp2040_programUF2(const char *fpath) { return rp2_programUF2(fpath); }
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// DAP (samd21/51, nrf5x, stm32f4 etc..) Target
|
||||
|
|
|
|||
45
tools/file2carray.py
Normal file
45
tools/file2carray.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import random
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from multiprocessing import Pool
|
||||
from weakref import finalize
|
||||
|
||||
|
||||
def print_carray(f, payload):
|
||||
while len(payload) > 0:
|
||||
f.write('\n ')
|
||||
f.write(', '.join('0x{:02x}'.format(x) for x in payload[0:16]))
|
||||
f.write(',')
|
||||
payload = payload[16:]
|
||||
f.write('\n')
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Convert binary files to C array format')
|
||||
parser.add_argument('files', nargs='+', help='Binary files to convert')
|
||||
args = parser.parse_args()
|
||||
|
||||
files = args.files
|
||||
for fin_name in files:
|
||||
if not os.path.isfile(fin_name):
|
||||
print(f"File {fin_name} does not exist")
|
||||
continue
|
||||
|
||||
with open(fin_name, 'rb') as fin:
|
||||
contents = fin.read()
|
||||
fout_name = fin_name + '.h'
|
||||
with open(fout_name, 'w') as fout:
|
||||
print(f"Converting {fin_name} to {fout_name}")
|
||||
fout.write(f'const size_t bindata_len = {len(contents)};\n')
|
||||
fout.write(f'const uint8_t bindata[] __attribute__((aligned(16))) = {{')
|
||||
print_carray(fout, contents)
|
||||
fout.write('};\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Loading…
Reference in a new issue