Compare commits
11 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6f2a0cc4c | ||
|
|
b138cd1ba1 | ||
|
|
5b4034b0f9 | ||
|
|
0332ed1117 | ||
|
|
6bfd594148 | ||
|
|
ab3624e73b | ||
|
|
2b71fa7422 | ||
|
|
6d16513e79 | ||
|
|
8045dd5c78 | ||
|
|
0b408468ce | ||
|
|
759bdeb282 |
39 changed files with 7566 additions and 70 deletions
0
examples/Brain/brain_test/.pico_rp2350_tinyusb.test.only
Normal file
0
examples/Brain/brain_test/.pico_rp2350_tinyusb.test.only
Normal file
|
|
@ -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"
|
||||
|
|
|
|||
0
examples/Brain/usbh_test/.pico_rp2350_tinyusb.test.only
Normal file
0
examples/Brain/usbh_test/.pico_rp2350_tinyusb.test.only
Normal file
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name=Adafruit TestBed
|
||||
version=1.13.2
|
||||
version=1.14.2
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Adafruit's internal test bed code library
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ Adafruit_TestBed::Adafruit_TestBed(void) {
|
|||
#if defined(ADAFRUIT_METRO_M0_EXPRESS)
|
||||
neopixelPin = 40;
|
||||
neopixelNum = 1;
|
||||
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
|
||||
neopixelPin = 8;
|
||||
neopixelNum = 1;
|
||||
#endif
|
||||
|
||||
esp32boot = NULL;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include "Wire.h"
|
||||
|
||||
#include "ESP32BootROM.h"
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
|
||||
#define RED 0xFF0000
|
||||
#define YELLOW 0xFFFF00
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef ARDUINO_RASPBERRY_PI_PICO
|
||||
#ifdef ARDUINO_ARCH_RP2040
|
||||
|
||||
#include "SdFat.h"
|
||||
#include "SdFat_Adafruit_Fork.h"
|
||||
#include "pio_usb.h"
|
||||
|
||||
#include "Adafruit_DAP.h"
|
||||
|
|
@ -34,6 +34,12 @@
|
|||
|
||||
#define USBHOST_RHPORT 1
|
||||
|
||||
// Workaround force F_CPU to 240MHz for programming RP2350 due to handshake
|
||||
// timeout
|
||||
#if F_CPU != 120000000L && F_CPU != 240000000L
|
||||
#error "F_CPU must be set to either 120Mhz or 240Mhz for pio-usb host"
|
||||
#endif
|
||||
|
||||
Adafruit_TestBed_Brains Brain;
|
||||
|
||||
volatile bool LCD_semaphore = false;
|
||||
|
|
@ -133,8 +139,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 +152,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 +194,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);
|
||||
|
||||
|
|
@ -475,6 +514,209 @@ bool Adafruit_TestBed_Brains::SD_begin(uint32_t max_clock) {
|
|||
//--------------------------------------------------------------------+
|
||||
// LCD
|
||||
//--------------------------------------------------------------------+
|
||||
#define NOP1 __asm volatile("nop");
|
||||
#define NOP2 NOP1 NOP1
|
||||
#define NOP3 NOP2 NOP1
|
||||
#define NOP4 NOP2 NOP2
|
||||
#define NOP5 NOP4 NOP1
|
||||
#define NOP6 NOP4 NOP2
|
||||
#define NOP7 NOP4 NOP3
|
||||
#define NOP8 NOP4 NOP4
|
||||
#define NOP9 NOP8 NOP1
|
||||
#define NOP10 NOP8 NOP2
|
||||
#define NOP11 NOP8 NOP3
|
||||
#define NOP12 NOP8 NOP4
|
||||
#define NOP13 NOP8 NOP5
|
||||
#define NOP14 NOP8 NOP6
|
||||
#define NOP15 NOP8 NOP7
|
||||
#define NOP16 NOP8 NOP8
|
||||
#define NOP17 NOP16 NOP1
|
||||
#define NOP18 NOP16 NOP2
|
||||
#define NOP19 NOP16 NOP3
|
||||
#define NOP20 NOP16 NOP4
|
||||
#define NOP21 NOP16 NOP5
|
||||
#define NOP22 NOP16 NOP6
|
||||
#define NOP23 NOP16 NOP7
|
||||
#define NOP24 NOP16 NOP8
|
||||
#define NOP25 NOP16 NOP9
|
||||
#define NOP26 NOP16 NOP10
|
||||
#define NOP27 NOP16 NOP11
|
||||
#define NOP28 NOP16 NOP12
|
||||
#define NOP29 NOP16 NOP13
|
||||
#define NOP30 NOP16 NOP14
|
||||
#define NOP31 NOP16 NOP15
|
||||
#define NOP32 NOP16 NOP16
|
||||
#define NOP33 NOP32 NOP1
|
||||
#define NOP34 NOP32 NOP2
|
||||
#define NOP35 NOP32 NOP3
|
||||
#define NOP36 NOP32 NOP4
|
||||
#define NOP37 NOP32 NOP5
|
||||
#define NOP38 NOP32 NOP6
|
||||
#define NOP39 NOP32 NOP7
|
||||
#define NOP40 NOP32 NOP8
|
||||
#define NOP41 NOP32 NOP9
|
||||
#define NOP42 NOP32 NOP10
|
||||
#define NOP43 NOP32 NOP11
|
||||
#define NOP44 NOP32 NOP12
|
||||
#define NOP45 NOP32 NOP13
|
||||
#define NOP46 NOP32 NOP14
|
||||
#define NOP47 NOP32 NOP15
|
||||
#define NOP48 NOP32 NOP16
|
||||
#define NOP49 NOP48 NOP1
|
||||
#define NOP50 NOP48 NOP2
|
||||
#define NOP51 NOP48 NOP3
|
||||
#define NOP52 NOP48 NOP4
|
||||
#define NOP53 NOP48 NOP5
|
||||
#define NOP54 NOP48 NOP6
|
||||
#define NOP55 NOP48 NOP7
|
||||
#define NOP56 NOP48 NOP8
|
||||
#define NOP57 NOP48 NOP9
|
||||
#define NOP58 NOP48 NOP10
|
||||
#define NOP59 NOP48 NOP11
|
||||
#define NOP60 NOP48 NOP12
|
||||
#define NOP61 NOP48 NOP13
|
||||
#define NOP62 NOP48 NOP14
|
||||
#define NOP63 NOP48 NOP15
|
||||
#define NOP64 NOP48 NOP16
|
||||
#define NOP65 NOP64 NOP1
|
||||
#define NOP66 NOP64 NOP2
|
||||
#define NOP67 NOP64 NOP3
|
||||
#define NOP68 NOP64 NOP4
|
||||
#define NOP69 NOP64 NOP5
|
||||
#define NOP70 NOP64 NOP6
|
||||
#define NOP71 NOP64 NOP7
|
||||
#define NOP72 NOP64 NOP8
|
||||
#define NOP73 NOP64 NOP9
|
||||
#define NOP74 NOP64 NOP10
|
||||
#define NOP75 NOP64 NOP11
|
||||
#define NOP76 NOP64 NOP12
|
||||
#define NOP77 NOP64 NOP13
|
||||
#define NOP78 NOP64 NOP14
|
||||
#define NOP79 NOP64 NOP15
|
||||
#define NOP80 NOP64 NOP16
|
||||
#define NOP81 NOP80 NOP1
|
||||
#define NOP82 NOP80 NOP2
|
||||
#define NOP83 NOP80 NOP3
|
||||
#define NOP84 NOP80 NOP4
|
||||
#define NOP85 NOP80 NOP5
|
||||
#define NOP86 NOP80 NOP6
|
||||
#define NOP87 NOP80 NOP7
|
||||
#define NOP88 NOP80 NOP8
|
||||
#define NOP89 NOP80 NOP9
|
||||
#define NOP90 NOP80 NOP10
|
||||
#define NOP91 NOP80 NOP11
|
||||
#define NOP92 NOP80 NOP12
|
||||
#define NOP93 NOP80 NOP13
|
||||
#define NOP94 NOP80 NOP14
|
||||
#define NOP95 NOP80 NOP15
|
||||
#define NOP96 NOP80 NOP16
|
||||
#define NOP97 NOP96 NOP1
|
||||
#define NOP98 NOP96 NOP2
|
||||
#define NOP99 NOP96 NOP3
|
||||
#define NOP100 NOP96 NOP4
|
||||
#define NOP101 NOP100 NOP1
|
||||
#define NOP102 NOP100 NOP2
|
||||
#define NOP103 NOP100 NOP3
|
||||
#define NOP104 NOP100 NOP4
|
||||
#define NOP105 NOP100 NOP5
|
||||
#define NOP106 NOP100 NOP6
|
||||
#define NOP107 NOP100 NOP7
|
||||
#define NOP108 NOP100 NOP8
|
||||
#define NOP109 NOP100 NOP9
|
||||
#define NOP110 NOP100 NOP10
|
||||
#define NOP111 NOP100 NOP11
|
||||
#define NOP112 NOP100 NOP12
|
||||
#define NOP113 NOP100 NOP13
|
||||
#define NOP114 NOP100 NOP14
|
||||
#define NOP115 NOP100 NOP15
|
||||
#define NOP116 NOP100 NOP16
|
||||
#define NOP117 NOP116 NOP1
|
||||
#define NOP118 NOP116 NOP2
|
||||
#define NOP119 NOP116 NOP3
|
||||
#define NOP120 NOP116 NOP4
|
||||
#define NOP121 NOP116 NOP5
|
||||
#define NOP122 NOP116 NOP6
|
||||
#define NOP123 NOP116 NOP7
|
||||
#define NOP124 NOP116 NOP8
|
||||
#define NOP125 NOP116 NOP9
|
||||
#define NOP126 NOP116 NOP10
|
||||
#define NOP127 NOP116 NOP11
|
||||
#define NOP128 NOP116 NOP12
|
||||
#define NOP129 NOP128 NOP1
|
||||
#define NOP130 NOP128 NOP2
|
||||
#define NOP131 NOP128 NOP3
|
||||
#define NOP132 NOP128 NOP4
|
||||
#define NOP133 NOP128 NOP5
|
||||
#define NOP134 NOP128 NOP6
|
||||
#define NOP135 NOP128 NOP7
|
||||
#define NOP136 NOP128 NOP8
|
||||
#define NOP137 NOP128 NOP9
|
||||
#define NOP138 NOP128 NOP10
|
||||
#define NOP139 NOP128 NOP11
|
||||
#define NOP140 NOP128 NOP12
|
||||
#define NOP141 NOP128 NOP13
|
||||
#define NOP142 NOP128 NOP14
|
||||
#define NOP143 NOP128 NOP15
|
||||
#define NOP144 NOP128 NOP16
|
||||
#define NOP145 NOP144 NOP1
|
||||
#define NOP146 NOP144 NOP2
|
||||
#define NOP147 NOP144 NOP3
|
||||
#define NOP148 NOP144 NOP4
|
||||
#define NOP149 NOP144 NOP5
|
||||
#define NOP150 NOP144 NOP6
|
||||
#define NOP151 NOP144 NOP7
|
||||
#define NOP152 NOP144 NOP8
|
||||
#define NOP153 NOP144 NOP9
|
||||
#define NOP154 NOP144 NOP10
|
||||
#define NOP155 NOP144 NOP11
|
||||
#define NOP156 NOP144 NOP12
|
||||
#define NOP157 NOP144 NOP13
|
||||
#define NOP158 NOP144 NOP14
|
||||
#define NOP159 NOP144 NOP15
|
||||
#define NOP160 NOP144 NOP16
|
||||
#define NOP161 NOP160 NOP1
|
||||
#define NOP162 NOP160 NOP2
|
||||
#define NOP163 NOP160 NOP3
|
||||
#define NOP164 NOP160 NOP4
|
||||
#define NOP165 NOP160 NOP5
|
||||
#define NOP166 NOP160 NOP6
|
||||
#define NOP167 NOP160 NOP7
|
||||
#define NOP168 NOP160 NOP8
|
||||
#define NOP169 NOP160 NOP9
|
||||
#define NOP170 NOP160 NOP10
|
||||
#define NOP171 NOP160 NOP11
|
||||
#define NOP172 NOP160 NOP12
|
||||
#define NOP173 NOP160 NOP13
|
||||
#define NOP174 NOP160 NOP14
|
||||
#define NOP175 NOP160 NOP15
|
||||
#define NOP176 NOP160 NOP16
|
||||
#define NOP177 NOP176 NOP1
|
||||
#define NOP178 NOP176 NOP2
|
||||
#define NOP179 NOP176 NOP3
|
||||
#define NOP180 NOP176 NOP4
|
||||
#define NOP181 NOP176 NOP5
|
||||
#define NOP182 NOP176 NOP6
|
||||
#define NOP183 NOP176 NOP7
|
||||
#define NOP184 NOP176 NOP8
|
||||
#define NOP185 NOP176 NOP9
|
||||
#define NOP186 NOP176 NOP10
|
||||
#define NOP187 NOP176 NOP11
|
||||
#define NOP188 NOP176 NOP12
|
||||
#define NOP189 NOP176 NOP13
|
||||
#define NOP190 NOP176 NOP14
|
||||
#define NOP191 NOP176 NOP15
|
||||
#define NOP192 NOP176 NOP16
|
||||
#define NOP193 NOP192 NOP1
|
||||
#define NOP194 NOP192 NOP2
|
||||
#define NOP195 NOP192 NOP3
|
||||
#define NOP196 NOP192 NOP4
|
||||
#define NOP197 NOP192 NOP5
|
||||
#define NOP198 NOP192 NOP6
|
||||
#define NOP199 NOP192 NOP7
|
||||
#define NOP200 NOP192 NOP8
|
||||
|
||||
#define _NOP_COUNT(n) NOP##n
|
||||
#define NOP_COUNT(n) _NOP_COUNT(n)
|
||||
|
||||
void __no_inline_not_in_flash_func(Adafruit_TestBed_Brains::setColor)(
|
||||
uint32_t color) {
|
||||
|
|
@ -515,53 +757,69 @@ void __no_inline_not_in_flash_func(Adafruit_TestBed_Brains::setColor)(
|
|||
|
||||
uint32_t const isr_context = save_and_disable_interrupts();
|
||||
|
||||
// RP2040 is 120 MHz, 120 cycle = 1us = 1000 ns
|
||||
// Neopixel is 800 KHz, 1T = 1.25 us = 150 nop
|
||||
/* Neopixel is 800 KHz, 1T = 1.25 us = 150 nop (120Mhz), 300 nop (240Mhz)
|
||||
- T1H = 0.8 us, T1L = 0.45 us
|
||||
- T0H = 0.4 us, T0L = 0.85 us
|
||||
If F_CPU is 120 MHz: 120 nop = 1us -> 1 nop = 8.33 ns
|
||||
- T1H = 0.8 us = 96 nop, T1L = 0.45 us = 54 nop
|
||||
- T0H = 0.4 us = 48 nop, T0L = 0.85 us = 102 nop
|
||||
If F_CPU is 240 MHz: 240 nop = 1us -> 1 nop = 4.17 ns
|
||||
- T1H = 0.8 us = 192 nop, T1L = 0.45 us = 108 nop
|
||||
- T0H = 0.4 us = 96 nop, T0L = 0.85 us = 204 nop
|
||||
Due to overhead the number of NOP is actually smaller, also M33 run faster
|
||||
(higher IPC) therefore these are hand tuned,
|
||||
*/
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO)
|
||||
// value for rp2040 at 120MHz
|
||||
#define T1H_CYCLE 90
|
||||
#define T1L_CYCLE 39
|
||||
#define T0H_CYCLE 42
|
||||
#define T0L_CYCLE 84
|
||||
#define LOOP_OVERHEAD_CYCLE 10 // overhead for if/else and loop
|
||||
#elif defined(ARDUINO_RASPBERRY_PI_PICO_2)
|
||||
// value for rp2350 at 120MHz
|
||||
#define T1H_CYCLE 190
|
||||
#define T1L_CYCLE 90
|
||||
#define T0H_CYCLE 88
|
||||
#define T0L_CYCLE 180
|
||||
#define LOOP_OVERHEAD_CYCLE 5
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
if (p & bitMask) {
|
||||
// T1H 0,8 us = 96 - 1 = 95 nop
|
||||
// T1H 0.8 us = 96 nop (without overhead)
|
||||
sio_hw->gpio_set = pinMask;
|
||||
__asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
|
||||
NOP_COUNT(T1H_CYCLE);
|
||||
#if F_CPU == 240000000L
|
||||
NOP_COUNT(T1H_CYCLE);
|
||||
#endif
|
||||
|
||||
// T1L 0,45 = 54 - 10 (ifelse) - 5 (overhead) = 44 nop
|
||||
// T1L 0.45 = 54 - 10 (ifelse) - 5 (overhead) = 44 nop
|
||||
sio_hw->gpio_clr = pinMask;
|
||||
__asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop;");
|
||||
NOP_COUNT(T1L_CYCLE);
|
||||
#if F_CPU == 240000000L
|
||||
NOP_COUNT(T1L_CYCLE);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
// T0H 0,4 us = 48 - 1 = 47 nop
|
||||
// T0H 0.4 us = 48 cycles
|
||||
sio_hw->gpio_set = pinMask;
|
||||
__asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop;");
|
||||
NOP_COUNT(T0H_CYCLE);
|
||||
#if F_CPU == 240000000L
|
||||
NOP_COUNT(T0H_CYCLE);
|
||||
#endif
|
||||
|
||||
// T0L 0.85 us = 102 - 10 (ifelse) - 5 (overhead) = 87 nop
|
||||
sio_hw->gpio_clr = pinMask;
|
||||
__asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||
"nop; nop; nop; nop;");
|
||||
NOP_COUNT(T0L_CYCLE);
|
||||
#if F_CPU == 240000000L
|
||||
NOP_COUNT(T0L_CYCLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bitMask >>= 1) {
|
||||
// not full byte, shift to next bit
|
||||
__asm volatile("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
|
||||
NOP_COUNT(LOOP_OVERHEAD_CYCLE);
|
||||
} else {
|
||||
// probably take 10 nops
|
||||
// if a full byte is sent, next to another byte
|
||||
|
|
@ -571,6 +829,9 @@ void __no_inline_not_in_flash_func(Adafruit_TestBed_Brains::setColor)(
|
|||
p = *ptr++;
|
||||
bitMask = 0x80;
|
||||
}
|
||||
#if F_CPU == 240000000L
|
||||
NOP_COUNT(LOOP_OVERHEAD_CYCLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
restore_interrupts(isr_context);
|
||||
|
|
@ -652,15 +913,14 @@ void Adafruit_TestBed_Brains::usbh_setVBus(bool en) {
|
|||
bool Adafruit_TestBed_Brains::usbh_begin(void) {
|
||||
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
|
||||
uint32_t cpu_hz = clock_get_hz(clk_sys);
|
||||
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
|
||||
if (cpu_hz % 12000000UL) {
|
||||
while (!Serial) {
|
||||
delay(10); // wait for native usb
|
||||
}
|
||||
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be "
|
||||
"multiple of 120 Mhz\r\n",
|
||||
"multiple of 12 Mhz\r\n",
|
||||
cpu_hz);
|
||||
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU "
|
||||
"Speed \r\n");
|
||||
Serial.println("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed");
|
||||
while (1) {
|
||||
delay(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef ADAFRUIT_TESTBED_BRAINS_H
|
||||
#define ADAFRUIT_TESTBED_BRAINS_H
|
||||
|
||||
#ifdef ARDUINO_RASPBERRY_PI_PICO
|
||||
#ifdef ARDUINO_ARCH_RP2040
|
||||
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
// https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html
|
||||
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO) || defined(__SAMD51__) || \
|
||||
#if defined(ARDUINO_ARCH_RP2040) || defined(__SAMD51__) || \
|
||||
defined(TARGET_RP2040) || defined(ARDUINO_ARCH_ESP32) || \
|
||||
(defined(ARDUINO_ARCH_SAMD) && defined(ARM_MATH_CM0PLUS))
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ void ESP32BootROMClass::resetBootloader(void) {
|
|||
// IO0 high: done
|
||||
digitalWrite(_gpio0Pin, HIGH);
|
||||
}
|
||||
#if defined(USE_TINYUSB) && defined(ARDUINO_RASPBERRY_PI_PICO)
|
||||
#if defined(USE_TINYUSB) && defined(ARDUINO_ARCH_RP2040)
|
||||
else {
|
||||
// Serial Host using setDtrRts()
|
||||
// - DTR -> IO0
|
||||
|
|
|
|||
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