Compare commits

...

10 commits

Author SHA1 Message Date
Tyeth Gundry
c6f2a0cc4c
Update library.properties - bump version to 1.14.2 2025-08-05 13:32:43 +01:00
Ha Thach
b138cd1ba1
Merge pull request #29 from adafruit/brain-240mhz
Support running brain with rp2350 also support both F_CPU 120Mhz or 240Mhz
2025-07-30 21:38:04 +07:00
hathach
5b4034b0f9
add rp2350 to brain ci build 2025-07-30 21:17:17 +07:00
hathach
0332ed1117
support running rp2350 as testbed brain. Correct nop cycle for both rp2040 and rp2350 (higher IPC). Support both running with 120Mhz and 240Mhz 2025-07-30 21:09:27 +07:00
ladyada
6bfd594148 let run on RP2350 2025-07-29 13:44:15 -04:00
hathach
ab3624e73b
error if F_CPU is not 240Mhz due to pio-usb hanndshake timing issue when working with rp2350 bootrom.
support neopixel with 240Mhz
2025-07-29 21:10:15 +07:00
Tyeth Gundry
2b71fa7422
Update library.properties - 1.14.1 2025-06-26 15:03:33 +01:00
ladyada
6d16513e79 add feather m0's built in neopix 2025-06-22 13:40:48 -04:00
Tyeth Gundry
8045dd5c78
Update library.properties - bump to 1.14.0 2025-03-11 21:21:50 +00:00
Ha Thach
0b408468ce
Merge pull request #28 from adafruit/support-program-rp2350
support programming rp2350
2025-03-07 11:15:37 +07:00
18 changed files with 272 additions and 42 deletions

View file

@ -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

View file

@ -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;

View file

@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#ifdef ARDUINO_RASPBERRY_PI_PICO
#ifdef ARDUINO_ARCH_RP2040
#include "SdFat_Adafruit_Fork.h"
#include "pio_usb.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;
@ -508,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) {
@ -548,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
@ -604,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);
@ -685,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);
}

View file

@ -1,7 +1,7 @@
#ifndef ADAFRUIT_TESTBED_BRAINS_H
#define ADAFRUIT_TESTBED_BRAINS_H
#ifdef ARDUINO_RASPBERRY_PI_PICO
#ifdef ARDUINO_ARCH_RP2040
#include "SdFat_Adafruit_Fork.h"

View file

@ -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