Compare commits
@@ -75,12 +75,15 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
|
||||
* Neko Systems BL2040 Mini
|
||||
* Newsan Archi
|
||||
* nullbits Bit-C PRO
|
||||
* Olimex Pico2XL
|
||||
* Olimex Pico2XXL
|
||||
* Olimex RP2040-Pico30
|
||||
* Pimoroni PGA2040
|
||||
* Pimoroni Pico Plus 2
|
||||
* Pimoroni Pico Plus 2W
|
||||
* Pimoroni Plasma2040
|
||||
* Pimoroni Plasma2350
|
||||
* Pimoroni Servo2040
|
||||
* Pimoroni Tiny2040
|
||||
* Pimoroni Tiny2350
|
||||
* Pintronix PinMax
|
||||
|
||||
+2400
-1055
File diff suppressed because it is too large
Load Diff
+14
-1
@@ -27,10 +27,23 @@
|
||||
#include "RP2040Version.h"
|
||||
#include "api/ArduinoAPI.h"
|
||||
#include "api/itoa.h" // ARM toolchain doesn't provide itoa etc, provide them
|
||||
#include <pico.h>
|
||||
#undef PICO_RP2350A // Set in the RP2350 SDK boards file, overridden in the variant pins_arduino.h
|
||||
#include <pins_arduino.h>
|
||||
#include <hardware/gpio.h> // Required for the port*Register macros
|
||||
#include "debug_internal.h"
|
||||
|
||||
// Chip sanity checking. SDK uses interesting way of separating 2350A from 2350B, see https://github.com/raspberrypi/pico-sdk/issues/2364
|
||||
#if (!defined(PICO_RP2040) && !defined(PICO_RP2350)) || defined(PICO_RP2040) && defined(PICO_RP2350)
|
||||
#error Invalid core definition. Either PICO_RP2040 or PICO_RP2350 must be defined.
|
||||
#endif
|
||||
#if defined(PICO_RP2350) && !defined(PICO_RP2350A)
|
||||
#error Invalid RP2350 definition. Need to set PICO_RP2350A=0/1 for A/B variant
|
||||
#endif
|
||||
#if defined(PICO_RP2350B)
|
||||
#error Do not define PICO_RP2350B. Use PICO_RP2350A=0 to indicate RP2350B. See the SDK for more details
|
||||
#endif
|
||||
|
||||
// Try and make the best of the old Arduino abs() macro. When in C++, use
|
||||
// the sane std::abs() call, but for C code use their macro since stdlib abs()
|
||||
// is int but their macro "works" for everything (with potential side effects)
|
||||
@@ -152,7 +165,7 @@ constexpr uint64_t __bitset(const int (&a)[N], size_t i = 0U) {
|
||||
#define PSRAM __attribute__((section("\".psram\"")))
|
||||
|
||||
// General GPIO/ADC layout info
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A
|
||||
#define __GPIOCNT 48
|
||||
#define __FIRSTANALOGGPIO 40
|
||||
#else
|
||||
|
||||
@@ -20,10 +20,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
@brief Wrapper class for polling the BOOTSEL button
|
||||
*/
|
||||
class __Bootsel {
|
||||
public:
|
||||
__Bootsel() { }
|
||||
/**
|
||||
@brief Get state of the BOOTSEL pin
|
||||
|
||||
@returns True if BOOTSEL pushed
|
||||
*/
|
||||
operator bool();
|
||||
};
|
||||
|
||||
/**
|
||||
@brief BOOTSEL accessor instance
|
||||
*/
|
||||
extern __Bootsel BOOTSEL;
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include "api/IPAddress.h"
|
||||
using arduino::IPAddress;
|
||||
|
||||
@@ -182,6 +182,9 @@ extern "C" void loop1() __attribute__((weak));
|
||||
extern "C" bool core1_separate_stack;
|
||||
extern "C" uint32_t* core1_separate_stack_address;
|
||||
|
||||
/**
|
||||
@brief RP2040/RP2350 helper function for HW-specific features
|
||||
*/
|
||||
class RP2040 {
|
||||
public:
|
||||
RP2040() { /* noop */ }
|
||||
@@ -207,26 +210,50 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
// Convert from microseconds to PIO clock cycles
|
||||
/**
|
||||
@brief Convert from microseconds to PIO clock cycles
|
||||
|
||||
@returns the PIO cycles for a given microsecond delay
|
||||
*/
|
||||
static int usToPIOCycles(int us) {
|
||||
// Parenthesis needed to guarantee order of operations to avoid 32bit overflow
|
||||
return (us * (clock_get_hz(clk_sys) / 1'000'000));
|
||||
}
|
||||
|
||||
// Get current clock frequency
|
||||
/**
|
||||
@brief Gets the active CPU speed (may differ from F_CPU
|
||||
|
||||
@returns CPU frequency in Hz
|
||||
*/
|
||||
static int f_cpu() {
|
||||
return clock_get_hz(clk_sys);
|
||||
}
|
||||
|
||||
// Get current CPU core number
|
||||
/**
|
||||
@brief Get the core ID that is currently executing this code
|
||||
|
||||
@returns 0 for Core 0, 1 for Core 1
|
||||
*/
|
||||
static int cpuid() {
|
||||
return sio_hw->cpuid;
|
||||
}
|
||||
|
||||
// Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
|
||||
/**
|
||||
@brief CPU cycle counter epoch (24-bit cycle). For internal use
|
||||
*/
|
||||
volatile uint64_t _epoch = 0;
|
||||
/**
|
||||
@brief Get the count of CPU clock cycles since power on.
|
||||
|
||||
@details
|
||||
The 32-bit count will overflow every 4 billion cycles, so consider using ``getCycleCount64`` for
|
||||
longer measurements
|
||||
|
||||
@returns CPU clock cycles since power up
|
||||
*/
|
||||
inline uint32_t getCycleCount() {
|
||||
#if !defined(__riscv) && !defined(__PROFILE)
|
||||
// Get CPU cycle count. Needs to do magic to extend 24b HW to something longer
|
||||
if (!__isFreeRTOS) {
|
||||
uint32_t epoch;
|
||||
uint32_t ctr;
|
||||
@@ -242,7 +269,11 @@ public:
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
@brief Get the count of CPU clock cycles since power on as a 64-bit quantrity
|
||||
|
||||
@returns CPU clock cycles since power up
|
||||
*/
|
||||
inline uint64_t getCycleCount64() {
|
||||
#if !defined(__riscv) && !defined(__PROFILE)
|
||||
if (!__isFreeRTOS) {
|
||||
@@ -261,23 +292,53 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Gets total unused heap (dynamic memory)
|
||||
|
||||
@details
|
||||
Note that the allocations of the size of the total free heap may fail due to fragmentation.
|
||||
For example, ``getFreeHeap`` can report 100KB available, but an allocation of 90KB may fail
|
||||
because there may not be a contiguous 90KB space available
|
||||
|
||||
@returns Free heap in bytes
|
||||
*/
|
||||
inline int getFreeHeap() {
|
||||
return getTotalHeap() - getUsedHeap();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Gets total used heap (dynamic memory)
|
||||
|
||||
@returns Used heap in bytes
|
||||
*/
|
||||
inline int getUsedHeap() {
|
||||
struct mallinfo m = mallinfo();
|
||||
return m.uordblks;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Gets total heap (dynamic memory) compiled into the program
|
||||
|
||||
@returns Total heap size in bytes
|
||||
*/
|
||||
inline int getTotalHeap() {
|
||||
return &__StackLimit - &__bss_end__;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief On the RP2350, returns the amount of heap (dynamic memory) available in PSRAM
|
||||
|
||||
@returns Total free heap in PSRAM, or 0 if no PSRAM present
|
||||
*/
|
||||
inline int getFreePSRAMHeap() {
|
||||
return getTotalPSRAMHeap() - getUsedPSRAMHeap();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief On the RP2350, returns the total amount of PSRAM heap (dynamic memory) used
|
||||
|
||||
@returns Bytes used in PSRAM, or 0 if no PSRAM present
|
||||
*/
|
||||
inline int getUsedPSRAMHeap() {
|
||||
#if defined(RP2350_PSRAM_CS)
|
||||
extern size_t __psram_total_used();
|
||||
@@ -287,6 +348,11 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@brief On the RP2350, gets total heap (dynamic memory) compiled into the program
|
||||
|
||||
@returns Total PSRAM heap size in bytes, or 0 if no PSRAM present
|
||||
*/
|
||||
inline int getTotalPSRAMHeap() {
|
||||
#if defined(RP2350_PSRAM_CS)
|
||||
extern size_t __psram_total_space();
|
||||
@@ -296,6 +362,11 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Gets the current stack pointer in a ARM/RISC-V safe manner
|
||||
|
||||
@returns Current SP
|
||||
*/
|
||||
inline uint32_t getStackPointer() {
|
||||
uint32_t *sp;
|
||||
#if defined(__riscv)
|
||||
@@ -306,6 +377,14 @@ public:
|
||||
return (uint32_t)sp;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Calculates approximately how much stack space is still available for the running core. Handles multiprocessing and separate stacks.
|
||||
|
||||
@details
|
||||
Not valid in FreeRTOS. Use the FreeRTOS internal functions to access this information.
|
||||
|
||||
@returns Approximation of the amount of stack available for use on the specific core
|
||||
*/
|
||||
inline int getFreeStack() {
|
||||
const unsigned int sp = getStackPointer();
|
||||
uint32_t ref = 0x20040000;
|
||||
@@ -319,6 +398,11 @@ public:
|
||||
return sp - ref;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief On the RP2350, gets the size of attached PSRAM
|
||||
|
||||
@returns PSRAM size in bytes, or 0 if no PSRAM present
|
||||
*/
|
||||
inline size_t getPSRAMSize() {
|
||||
#if defined(RP2350_PSRAM_CS)
|
||||
extern size_t __psram_size;
|
||||
@@ -328,20 +412,48 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Freezes the other core in a flash-write-safe state. Not generally needed by applications
|
||||
|
||||
@details
|
||||
When the external flash chip is erasing or writing, the Pico cannot fetch instructions from it.
|
||||
In this case both the core doing the writing and the other core (if active) need to run from a
|
||||
routine that's contained in RAM. This call forces the other core into a tight, RAM-based loop
|
||||
safe for this operation. When flash erase/write is completed, ``resumeOtherCore`` to return
|
||||
it to operation.
|
||||
|
||||
Be sure to disable any interrupts or task switches before calling to avoid deadlocks.
|
||||
|
||||
If the second core is not started, this is a no-op.
|
||||
*/
|
||||
void idleOtherCore() {
|
||||
fifo.idleOtherCore();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Resumes normal operation of the other core
|
||||
*/
|
||||
void resumeOtherCore() {
|
||||
fifo.resumeOtherCore();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Hard resets the 2nd core (CORE1).
|
||||
|
||||
@details
|
||||
Because core1 will restart with the heap and global variables not in the same state as
|
||||
power-on, this call may not work as desired and a full CPU reset may be necessary in
|
||||
certain cases.
|
||||
*/
|
||||
void restartCore1() {
|
||||
multicore_reset_core1();
|
||||
fifo.clear();
|
||||
multicore_launch_core1(main1);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Warm-reboots the chip in normal mode
|
||||
*/
|
||||
void reboot() {
|
||||
watchdog_reboot(0, 0, 10);
|
||||
while (1) {
|
||||
@@ -349,10 +461,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Warm-reboots the chip in normal mode
|
||||
*/
|
||||
inline void restart() {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Warm-reboots the chip into the USB bootloader mode
|
||||
*/
|
||||
inline void rebootToBootloader() {
|
||||
reset_usb_boot(0, 0);
|
||||
while (1) {
|
||||
@@ -364,16 +482,32 @@ public:
|
||||
static void enableDoubleResetBootloader();
|
||||
#endif
|
||||
|
||||
/**
|
||||
@brief Starts the hardware watchdog timer. The CPU will reset if the watchdog is not fed every delay_ms
|
||||
|
||||
@param [in] delay_ms Milliseconds without a wdt_reset before rebooting
|
||||
*/
|
||||
void wdt_begin(uint32_t delay_ms) {
|
||||
watchdog_enable(delay_ms, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Feeds the watchdog timer, resetting it for another delay_ms countdown
|
||||
*/
|
||||
void wdt_reset() {
|
||||
watchdog_update();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Best-effort reasons for chip reset
|
||||
*/
|
||||
enum resetReason_t {UNKNOWN_RESET, PWRON_RESET, RUN_PIN_RESET, SOFT_RESET, WDT_RESET, DEBUG_RESET, GLITCH_RESET, BROWNOUT_RESET};
|
||||
|
||||
/**
|
||||
@brief Attempts to determine the reason for the last chip reset. May not always be able to determine accurately
|
||||
|
||||
@returns Reason for reset
|
||||
*/
|
||||
resetReason_t getResetReason(void) {
|
||||
io_rw_32 *WD_reason_reg = (io_rw_32 *)(WATCHDOG_BASE + WATCHDOG_REASON_OFFSET);
|
||||
|
||||
@@ -427,6 +561,10 @@ public:
|
||||
return UNKNOWN_RESET;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get unique ID string for the running board
|
||||
@returns String with the unique board ID as determined by the SDK
|
||||
*/
|
||||
const char *getChipID() {
|
||||
static char id[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1] = { 0 };
|
||||
if (!id[0]) {
|
||||
@@ -437,6 +575,17 @@ public:
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
/**
|
||||
@brief Perform a memcpy using a DMA engine for speed
|
||||
|
||||
@details
|
||||
Uses the DMA to copy to and from RAM. Only works on 4-byte aligned, 4-byte multiple length
|
||||
sources and destination (i.e. word-aligned, word-length). Falls back to normal memcpy otherwise.
|
||||
|
||||
@param [out] dest Memcpy destination, 4-byte aligned
|
||||
@param [in] src Memcpy source, 4-byte aligned
|
||||
@param [in] n Count in bytes to transfer (should be a multiple of 4 bytes)
|
||||
*/
|
||||
void *memcpyDMA(void *dest, const void *src, size_t n) {
|
||||
// Allocate a DMA channel on 1st call, reuse it every call after
|
||||
if (memcpyDMAChannel < 1) {
|
||||
@@ -465,14 +614,32 @@ public:
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
// Multicore comms FIFO
|
||||
/**
|
||||
@brief Multicore communications FIFO
|
||||
*/
|
||||
_MFIFO fifo;
|
||||
|
||||
|
||||
/**
|
||||
@brief Return a 32-bit from the hardware random number generator
|
||||
|
||||
@returns Random value using appropriate hardware (RP2350 has true RNG, RP2040 has a less true RNG method)
|
||||
*/
|
||||
uint32_t hwrand32() {
|
||||
return get_rand_32();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Determines if code is running on a Pico or a PicoW
|
||||
|
||||
@details
|
||||
Code compiled for the RP2040 PicoW can run on the RP2040 Pico. This call lets an application
|
||||
identify if the current device is really a Pico or PicoW and handle appropriately. For
|
||||
the RP2350, this runtime detection is not available and the call returns whether it was
|
||||
compiled for the CYW43 WiFi driver
|
||||
|
||||
@returns True if running on a PicoW board with CYW43 WiFi chip.
|
||||
*/
|
||||
bool isPicoW() {
|
||||
#if !defined(PICO_CYW43_SUPPORTED)
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#define ARDUINO_PICO_MAJOR 4
|
||||
#define ARDUINO_PICO_MINOR 5
|
||||
#define ARDUINO_PICO_REVISION 0
|
||||
#define ARDUINO_PICO_VERSION_STR "4.5.0"
|
||||
#define ARDUINO_PICO_REVISION 2
|
||||
#define ARDUINO_PICO_VERSION_STR "4.5.2"
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
|
||||
// Input/output will be handled by OpenOCD
|
||||
|
||||
// From https://developer.arm.com/documentation/dui0471/g/Semihosting/Semihosting-operations?lang=en
|
||||
/**
|
||||
@brief Semihosting host API opcodes, from https://developer.arm.com/documentation/dui0471/g/Semihosting/Semihosting-operations?lang=en
|
||||
*/
|
||||
typedef enum {
|
||||
SEMIHOST_SYS_CLOSE = 0x02,
|
||||
SEMIHOST_SYS_CLOCK = 0x10,
|
||||
@@ -52,7 +54,13 @@ typedef enum {
|
||||
|
||||
#ifdef __arm__
|
||||
|
||||
// From https://github.com/ErichStyger/mcuoneclipse/blob/master/Examples/MCUXpresso/FRDM-K22F/FRDM-K22F_Semihosting/source/McuSemihost.c
|
||||
/**
|
||||
@brief Execute a semihosted request, from https://github.com/ErichStyger/mcuoneclipse/blob/master/Examples/MCUXpresso/FRDM-K22F/FRDM-K22F_Semihosting/source/McuSemihost.c
|
||||
|
||||
@param [in] reason Opcode to execute
|
||||
@param [in] arg Any arguments for the opcode
|
||||
@returns Result of operation
|
||||
*/
|
||||
static inline int __attribute__((always_inline)) Semihost(int reason, void *arg) {
|
||||
int value;
|
||||
__asm volatile(
|
||||
@@ -69,7 +77,13 @@ static inline int __attribute__((always_inline)) Semihost(int reason, void *arg)
|
||||
}
|
||||
#else
|
||||
|
||||
// https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/n-5VQ9PHZ4w/m/KbzH5t9MBgAJ
|
||||
/**
|
||||
@brief Execute a semihosted request, from https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/n-5VQ9PHZ4w/m/KbzH5t9MBgAJ
|
||||
|
||||
@param [in] reason Opcode to execute
|
||||
@param [in] argPack Any arguments for the opcode
|
||||
@returns Result of operation
|
||||
*/
|
||||
static inline int __attribute__((always_inline)) Semihost(int reason, void *argPack) {
|
||||
register int value asm("a0") = reason;
|
||||
register void *ptr asm("a1") = argPack;
|
||||
|
||||
@@ -32,7 +32,7 @@ extern void serialEvent1() __attribute__((weak));
|
||||
extern void serialEvent2() __attribute__((weak));
|
||||
|
||||
bool SerialUART::setRX(pin_size_t pin) {
|
||||
#if defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({1, 3, 13, 15, 17, 19, 29, 31, 33, 35, 45, 47}) /* UART0 */,
|
||||
__bitset({5, 7, 9, 11, 21, 23, 25, 27, 37, 39, 41, 43}) /* UART1 */
|
||||
};
|
||||
@@ -64,7 +64,7 @@ bool SerialUART::setRX(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SerialUART::setTX(pin_size_t pin) {
|
||||
#if defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({0, 2, 12, 14, 16, 18, 28, 30, 32, 34, 44, 46}) /* UART0 */,
|
||||
__bitset({4, 6, 8, 10, 20, 22, 24, 26, 36, 38, 40, 42}) /* UART1 */
|
||||
};
|
||||
@@ -95,7 +95,7 @@ bool SerialUART::setTX(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SerialUART::setRTS(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({3, 15, 19, 31, 35, 47}) /* UART0 */,
|
||||
__bitset({7, 11, 23, 27, 39, 43}) /* UART1 */
|
||||
};
|
||||
@@ -122,7 +122,7 @@ bool SerialUART::setRTS(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SerialUART::setCTS(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({2, 14, 18, 30, 34, 46}) /* UART0 */,
|
||||
__bitset({6, 10, 22, 26, 38, 42}) /* UART1 */
|
||||
};
|
||||
@@ -182,7 +182,7 @@ static void _uart1IRQ();
|
||||
// Does the selected TX/RX need UART_AUX function (rp2350)
|
||||
static gpio_function_t __gpioFunction(int pin) {
|
||||
switch (pin) {
|
||||
#if defined(PICO_RP2350) || defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A
|
||||
case 2:
|
||||
case 3:
|
||||
case 6:
|
||||
|
||||
@@ -22,9 +22,18 @@
|
||||
|
||||
#include "SerialPIO.h"
|
||||
|
||||
/**
|
||||
@brief Implements a UART port using PIO for input and output
|
||||
*/
|
||||
class SoftwareSerial : public SerialPIO {
|
||||
public:
|
||||
// Note the rx/tx pins are swapped in PIO vs SWSerial
|
||||
/**
|
||||
@brief Constructs a PIO-based UART
|
||||
|
||||
@param [in] rx GPIO for RX pin or -1 for transmit-only
|
||||
@param [in] tx GPIO for TX pin or -1 for receive-only
|
||||
@param [in] invert True to invert the receive and transmit lines
|
||||
*/
|
||||
SoftwareSerial(pin_size_t rx, pin_size_t tx, bool invert = false) : SerialPIO(tx, rx) {
|
||||
_invert = invert;
|
||||
}
|
||||
@@ -32,18 +41,37 @@ public:
|
||||
~SoftwareSerial() {
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Starts the PIO UART
|
||||
|
||||
@param [in] baud Serial bit rate
|
||||
*/
|
||||
virtual void begin(unsigned long baud = 115200) override {
|
||||
begin(baud, SERIAL_8N1);
|
||||
};
|
||||
|
||||
/**
|
||||
@brief Starts the PIO UART
|
||||
|
||||
@param [in] baud Serial bit rate
|
||||
@param [in] config Start/Stop/Len configuration (i.e. SERIAL_8N1 or SERIAL_7E2)
|
||||
*/
|
||||
void begin(unsigned long baud, uint16_t config) override {
|
||||
setInvertTX(_invert);
|
||||
setInvertRX(_invert);
|
||||
SerialPIO::begin(baud, config);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief No-op on this core
|
||||
*/
|
||||
void listen() { /* noop */ }
|
||||
|
||||
/**
|
||||
@brief No-op on this core
|
||||
|
||||
@returns True always
|
||||
*/
|
||||
bool isListening() {
|
||||
return true;
|
||||
}
|
||||
|
||||
+7
-6
@@ -12,9 +12,9 @@ need to be periodically sampled to be read by applications, easily, such as:
|
||||
* Light dependent resistors (LDR), etc.
|
||||
|
||||
|
||||
Up to 4 analog samples can be recorded by the hardware (``A0`` ... ``A3``), and all
|
||||
recording is done at 16-bit levels (but be aware that the ADC in the Pico will only
|
||||
ever return values between 0...4095).
|
||||
Up to 4 (or 8 in the case of the RP2350B) analog samples can be recorded by the
|
||||
hardware (``A0`` ... ``A3``), and all recording is done at 16-bit levels (but be
|
||||
aware that the ADC in the Pico will only ever return values between 0...4095).
|
||||
|
||||
The interface for the ``ADCInput`` device is very similar to the ``I2S`` input
|
||||
device, and most code can be ported simply by instantiating a ``ADCInput``
|
||||
@@ -26,11 +26,12 @@ allowed while in use.
|
||||
ADC Input API
|
||||
-------------
|
||||
|
||||
ADCInput(pin0 [, pin1, pin2, pin3])
|
||||
ADCInput(pin0 [, pin1, pin2, pin3[, pin4, pin5, pin6, pin7])
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Creates an ADC input object which will record the pins specified in the code.
|
||||
Only pins ``A0`` ... ``A3`` can be used, and they must be specified in increasing
|
||||
order (i.e. ``ADCInput(A0, A1);`` is valid, but ``ADCInput(A1, A0)`` is not.
|
||||
Only pins ``A0`` ... ``A3`` (``A7`` on RP2350B) can be used, and they must be
|
||||
specified in increasing order (i.e. ``ADCInput(A0, A1);`` is valid,
|
||||
but ``ADCInput(A1, A0)`` is not.
|
||||
|
||||
bool setBuffers(size_t buffers, size_t bufferWords)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
+2
-2
@@ -54,9 +54,9 @@ author = u'Earle F. Philhower, III'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'4.5.0'
|
||||
version = u'4.5.2'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'4.5.0'
|
||||
release = u'4.5.2'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
+2
-2
@@ -112,7 +112,7 @@ For only RP2350A variants (using the compile options, not the onboard ID registe
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#if defined(PICO_RP2350) && !defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2350A) && PICO_RP2350A
|
||||
...RP2350A only code...
|
||||
#endif
|
||||
|
||||
@@ -121,7 +121,7 @@ and not the chip ID register):
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#if defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2350A) && !PICO_RP2350A
|
||||
...48-GPIO version code here
|
||||
#endif
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ bool ADCInput::setBuffers(size_t buffers, size_t bufferWords) {
|
||||
|
||||
int ADCInput::_mask(pin_size_t p) {
|
||||
switch (p) {
|
||||
#if !defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
case 26: return 1;
|
||||
case 27: return 2;
|
||||
case 28: return 4;
|
||||
@@ -106,7 +106,7 @@ bool ADCInput::begin() {
|
||||
// Set up the GPIOs to go to ADC
|
||||
adc_init();
|
||||
int cnt = 0;
|
||||
#if !defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
int startpin = 26;
|
||||
int maxpin = 29;
|
||||
#else
|
||||
|
||||
@@ -178,7 +178,7 @@ bool I2S::setLSBJFormat() {
|
||||
}
|
||||
|
||||
bool I2S::setTDMFormat() {
|
||||
if (_running || !_isOutput || _isInput) {
|
||||
if (_running || !_isOutput) {
|
||||
return false;
|
||||
}
|
||||
_isTDM = true;
|
||||
@@ -186,7 +186,7 @@ bool I2S::setTDMFormat() {
|
||||
}
|
||||
|
||||
bool I2S::setTDMChannels(int channels) {
|
||||
if (_running || !_isOutput || _isInput) {
|
||||
if (_running || !_isOutput) {
|
||||
return false;
|
||||
}
|
||||
_tdmChannels = channels;
|
||||
@@ -255,9 +255,9 @@ bool I2S::begin() {
|
||||
_isHolding = 0;
|
||||
int off = 0;
|
||||
if (!_swapClocks) {
|
||||
_i2s = new PIOProgram(_isOutput ? (_isInput ? &pio_i2s_inout_program : (_isTDM ? &pio_tdm_out_program : (_isLSBJ ? &pio_lsbj_out_program : &pio_i2s_out_program))) : &pio_i2s_in_program);
|
||||
_i2s = new PIOProgram(_isOutput ? (_isInput ? (_isTDM ? &pio_tdm_inout_program : &pio_i2s_inout_program) : (_isTDM ? &pio_tdm_out_program : (_isLSBJ ? &pio_lsbj_out_program : &pio_i2s_out_program))) : &pio_i2s_in_program);
|
||||
} else {
|
||||
_i2s = new PIOProgram(_isOutput ? (_isInput ? &pio_i2s_inout_swap_program : (_isTDM ? &pio_tdm_out_swap_program : (_isLSBJ ? &pio_lsbj_out_swap_program : &pio_i2s_out_swap_program))) : &pio_i2s_in_swap_program);
|
||||
_i2s = new PIOProgram(_isOutput ? (_isInput ? (_isTDM ? &pio_tdm_inout_swap_program : &pio_i2s_inout_swap_program) : (_isTDM ? &pio_tdm_out_swap_program : (_isLSBJ ? &pio_lsbj_out_swap_program : &pio_i2s_out_swap_program))) : &pio_i2s_in_swap_program);
|
||||
}
|
||||
int minpin, maxpin;
|
||||
if (_isOutput && _isInput) {
|
||||
@@ -278,7 +278,11 @@ bool I2S::begin() {
|
||||
}
|
||||
if (_isOutput) {
|
||||
if (_isInput) {
|
||||
pio_i2s_inout_program_init(_pio, _sm, off, _pinDIN, _pinDOUT, _pinBCLK, _bps, _swapClocks);
|
||||
if (_isTDM) {
|
||||
pio_tdm_inout_program_init(_pio, _sm, off, _pinDIN, _pinDOUT, _pinBCLK, _bps, _swapClocks, _tdmChannels);
|
||||
} else {
|
||||
pio_i2s_inout_program_init(_pio, _sm, off, _pinDIN, _pinDOUT, _pinBCLK, _bps, _swapClocks);
|
||||
}
|
||||
} else if (_isTDM) {
|
||||
pio_tdm_out_program_init(_pio, _sm, off, _pinDOUT, _pinBCLK, _bps, _swapClocks, _tdmChannels);
|
||||
} else if (_isLSBJ) {
|
||||
|
||||
@@ -104,6 +104,41 @@ lastbit:
|
||||
; Loop back to the beginning
|
||||
|
||||
|
||||
.program pio_tdm_inout
|
||||
.side_set 2 ; 0 = bclk, 1 = wclk
|
||||
; The C code should place (number of bits * channels - 1) in Y and update SHIFTCTRL
|
||||
; to be 32 (as per the TDM specs)
|
||||
; +----- WCLK
|
||||
; |+---- BCLK
|
||||
mov x, y side 0b01 [1]
|
||||
bitloop:
|
||||
out pins, 1 side 0b00 ; Output changes on falling edge
|
||||
in pins, 1 side 0b00 ; Sample input on falling edge
|
||||
jmp x-- bitloop side 0b11 [1] ; Last bit toggles WCLK to mark frame boundary
|
||||
|
||||
lastbit:
|
||||
in pins, 1 side 0b10
|
||||
out pins, 1 side 0b10
|
||||
; Loop back to the beginning
|
||||
|
||||
|
||||
.program pio_tdm_inout_swap
|
||||
.side_set 2 ; 0 = bclk, 1 = wclk
|
||||
; The C code should place (number of bits * channels - 1) in Y and update SHIFTCTRL
|
||||
; to be 32 (as per the TDM specs)
|
||||
; +----- WCLK
|
||||
; |+---- BCLK
|
||||
mov x, y side 0b10 [1]
|
||||
bitloop:
|
||||
out pins, 1 side 0b00 ; Output changes on falling edge
|
||||
in pins, 1 side 0b00 ; Sample input on falling edge
|
||||
jmp x-- bitloop side 0b11 [1] ; Last bit toggles WCLK to mark frame boundary
|
||||
|
||||
lastbit:
|
||||
in pins, 1 side 0b01
|
||||
out pins, 1 side 0b01
|
||||
; Loop back to the beginning
|
||||
|
||||
|
||||
.program pio_lsbj_out
|
||||
.side_set 2 ; 0 = bclk, 1=wclk
|
||||
@@ -313,6 +348,42 @@ static inline void pio_tdm_out_program_init(PIO pio, uint sm, uint offset, uint
|
||||
pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32));
|
||||
}
|
||||
|
||||
static inline void pio_tdm_inout_program_init(PIO pio, uint sm, uint offset, uint data_in_pin, uint data_out_pin, uint clock_pin_base, uint bits, bool swap, uint channels) {
|
||||
pio_gpio_init(pio, data_in_pin);
|
||||
pio_gpio_init(pio, data_out_pin);
|
||||
pio_gpio_init(pio, clock_pin_base);
|
||||
pio_gpio_init(pio, clock_pin_base + 1);
|
||||
|
||||
pio_sm_config c = swap ? pio_tdm_inout_swap_program_get_default_config(offset) : pio_tdm_inout_program_get_default_config(offset);
|
||||
|
||||
sm_config_set_in_pins(&c, data_in_pin);
|
||||
sm_config_set_out_pins(&c, data_out_pin, 1);
|
||||
sm_config_set_sideset_pins(&c, clock_pin_base);
|
||||
sm_config_set_in_shift(&c, false, true, 32);
|
||||
sm_config_set_out_shift(&c, false, true, 32);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_NONE);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, data_in_pin, 1, false);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true);
|
||||
pio_sm_set_set_pins(pio, sm, data_out_pin, 1);
|
||||
pio_sm_set_set_pins(pio, sm, clock_pin_base, 2);
|
||||
|
||||
// Initialize PIO state for TDM
|
||||
// Can't set constant > 31, so push and pop/mov if needed
|
||||
if (bits * channels - 1 > 31) {
|
||||
pio_sm_put_blocking(pio, sm, bits * channels - 2);
|
||||
pio_sm_exec(pio, sm, pio_encode_pull(false, false));
|
||||
pio_sm_exec(pio, sm, pio_encode_mov(pio_y, pio_osr));
|
||||
} else {
|
||||
pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits * channels - 2));
|
||||
}
|
||||
|
||||
// Need to make OSR believe there's nothing left to shift out
|
||||
pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32));
|
||||
}
|
||||
|
||||
static inline void pio_lsbj_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) {
|
||||
pio_gpio_init(pio, data_pin);
|
||||
|
||||
@@ -193,6 +193,80 @@ static inline pio_sm_config pio_tdm_out_swap_program_get_default_config(uint off
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------- //
|
||||
// pio_tdm_inout //
|
||||
// ------------- //
|
||||
|
||||
#define pio_tdm_inout_wrap_target 0
|
||||
#define pio_tdm_inout_wrap 5
|
||||
|
||||
static const uint16_t pio_tdm_inout_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0xa922, // 0: mov x, y side 1 [1]
|
||||
0x6001, // 1: out pins, 1 side 0
|
||||
0x4001, // 2: in pins, 1 side 0
|
||||
0x1941, // 3: jmp x--, 1 side 3 [1]
|
||||
0x5001, // 4: in pins, 1 side 2
|
||||
0x7001, // 5: out pins, 1 side 2
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
static const struct pio_program pio_tdm_inout_program = {
|
||||
.instructions = pio_tdm_inout_program_instructions,
|
||||
.length = 6,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_tdm_inout_program_get_default_config(uint offset) {
|
||||
pio_sm_config c = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&c, offset + pio_tdm_inout_wrap_target, offset + pio_tdm_inout_wrap);
|
||||
sm_config_set_sideset(&c, 2, false, false);
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------ //
|
||||
// pio_tdm_inout_swap //
|
||||
// ------------------ //
|
||||
|
||||
#define pio_tdm_inout_swap_wrap_target 0
|
||||
#define pio_tdm_inout_swap_wrap 5
|
||||
|
||||
static const uint16_t pio_tdm_inout_swap_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0xb122, // 0: mov x, y side 2 [1]
|
||||
0x6001, // 1: out pins, 1 side 0
|
||||
0x4001, // 2: in pins, 1 side 0
|
||||
0x1941, // 3: jmp x--, 1 side 3 [1]
|
||||
0x4801, // 4: in pins, 1 side 1
|
||||
0x6801, // 5: out pins, 1 side 1
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
static const struct pio_program pio_tdm_inout_swap_program = {
|
||||
.instructions = pio_tdm_inout_swap_program_instructions,
|
||||
.length = 6,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_tdm_inout_swap_program_get_default_config(uint offset) {
|
||||
pio_sm_config c = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&c, offset + pio_tdm_inout_swap_wrap_target, offset + pio_tdm_inout_swap_wrap);
|
||||
sm_config_set_sideset(&c, 2, false, false);
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------ //
|
||||
// pio_lsbj_out //
|
||||
// ------------ //
|
||||
@@ -490,6 +564,36 @@ static inline void pio_tdm_out_program_init(PIO pio, uint sm, uint offset, uint
|
||||
// Need to make OSR believe there's nothing left to shift out, or the 1st word will be the count we just passed in, not a sample
|
||||
pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32));
|
||||
}
|
||||
static inline void pio_tdm_inout_program_init(PIO pio, uint sm, uint offset, uint data_in_pin, uint data_out_pin, uint clock_pin_base, uint bits, bool swap, uint channels) {
|
||||
pio_gpio_init(pio, data_in_pin);
|
||||
pio_gpio_init(pio, data_out_pin);
|
||||
pio_gpio_init(pio, clock_pin_base);
|
||||
pio_gpio_init(pio, clock_pin_base + 1);
|
||||
pio_sm_config c = swap ? pio_tdm_inout_swap_program_get_default_config(offset) : pio_tdm_inout_program_get_default_config(offset);
|
||||
sm_config_set_in_pins(&c, data_in_pin);
|
||||
sm_config_set_out_pins(&c, data_out_pin, 1);
|
||||
sm_config_set_sideset_pins(&c, clock_pin_base);
|
||||
sm_config_set_in_shift(&c, false, true, 32);
|
||||
sm_config_set_out_shift(&c, false, true, 32);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_NONE);
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, data_in_pin, 1, false);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true);
|
||||
pio_sm_set_set_pins(pio, sm, data_out_pin, 1);
|
||||
pio_sm_set_set_pins(pio, sm, clock_pin_base, 2);
|
||||
// Initialize PIO state for TDM
|
||||
// Can't set constant > 31, so push and pop/mov if needed
|
||||
if (bits * channels - 1 > 31) {
|
||||
pio_sm_put_blocking(pio, sm, bits * channels - 2);
|
||||
pio_sm_exec(pio, sm, pio_encode_pull(false, false));
|
||||
pio_sm_exec(pio, sm, pio_encode_mov(pio_y, pio_osr));
|
||||
} else {
|
||||
pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits * channels - 2));
|
||||
}
|
||||
// Need to make OSR believe there's nothing left to shift out
|
||||
pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32));
|
||||
}
|
||||
static inline void pio_lsbj_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) {
|
||||
pio_gpio_init(pio, data_pin);
|
||||
pio_gpio_init(pio, clock_pin_base);
|
||||
|
||||
@@ -263,7 +263,7 @@ void SPIClassRP2040::abortAsync() {
|
||||
|
||||
|
||||
bool SPIClassRP2040::setRX(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({0, 4, 16, 20, 32, 26}) /* SPI0 */,
|
||||
__bitset({8, 12, 24, 28, 40, 44}) /* SPI1 */
|
||||
};
|
||||
@@ -290,7 +290,7 @@ bool SPIClassRP2040::setRX(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SPIClassRP2040::setCS(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({1, 5, 17, 21, 33, 37}) /* SPI0 */,
|
||||
__bitset({9, 13, 25, 29, 41, 45}) /* SPI1 */
|
||||
};
|
||||
@@ -317,7 +317,7 @@ bool SPIClassRP2040::setCS(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SPIClassRP2040::setSCK(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({2, 6, 18, 22, 34, 38}) /* SPI0 */,
|
||||
__bitset({10, 14, 26, 30, 42, 46}) /* SPI1 */
|
||||
};
|
||||
@@ -344,7 +344,7 @@ bool SPIClassRP2040::setSCK(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SPIClassRP2040::setTX(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({3, 7, 19, 23, 35, 39}) /* SPI0 */,
|
||||
__bitset({11, 15, 27, 31, 43, 47}) /* SPI1 */
|
||||
};
|
||||
|
||||
+166
-12
@@ -25,65 +25,219 @@
|
||||
#include <hardware/spi.h>
|
||||
#include "SPIHelper.h"
|
||||
|
||||
/**
|
||||
@brief Implements a hardware-based SPI interface using the Pico's SPI blocks
|
||||
*/
|
||||
class SPIClassRP2040 : public arduino::HardwareSPI {
|
||||
public:
|
||||
/**
|
||||
@brief Create a PIO-based SPI instance, pins can be changed before begin() call
|
||||
|
||||
@param [in] spi SPI hardware instance (spi0/spi1)
|
||||
@param [in] rx MISO GPIO
|
||||
@param [in] cs CS GPIO
|
||||
@param [in] sck SCK GPIO
|
||||
@param [in] tx MOSI GPIO
|
||||
*/
|
||||
SPIClassRP2040(spi_inst_t *spi, pin_size_t rx, pin_size_t cs, pin_size_t sck, pin_size_t tx);
|
||||
|
||||
// Send or receive 8- or 16-bit data. Returns read back value
|
||||
/**
|
||||
@brief Send an 8-bit byte of data and return read-back 8-bit value
|
||||
|
||||
@param [in] data Data to send
|
||||
@returns Read back byte from SPI interface
|
||||
*/
|
||||
byte transfer(uint8_t data) override;
|
||||
|
||||
/**
|
||||
@brief Send a 16-bit quantity over SPI and return read-back 16-bit value under a single CS assertion
|
||||
|
||||
@param [in] data Data to send
|
||||
@returns Read back 16-bit quantity
|
||||
*/
|
||||
uint16_t transfer16(uint16_t data) override;
|
||||
|
||||
// Sends buffer in 8 bit chunks. Overwrites buffer with read data
|
||||
|
||||
/**
|
||||
@brief Sends buffer in 8 bit chunks under a single CS. Overwrites buffer with read data
|
||||
|
||||
@param [in, out] buf Buffer to read and write back into
|
||||
@param [in] count Number of bytes to transmit/read
|
||||
*/
|
||||
void transfer(void *buf, size_t count) override;
|
||||
|
||||
// Sends one buffer and receives into another, much faster! can set rx or txbuf to nullptr
|
||||
/**
|
||||
@brief Sends one buffer and receives into another under a single CS. Can set rx or txbuf to nullptr
|
||||
|
||||
@param [in] txbuf Buffer to transmit or nullptr to send 0s
|
||||
@param [out] rxbuf Buffer to read back into or nullptr to ignore returned data
|
||||
@param [in] count Numbner of bytes to transmit/receive
|
||||
*/
|
||||
void transfer(const void *txbuf, void *rxbuf, size_t count) override;
|
||||
|
||||
// DMA/asynchronous transfers. Do not combime with synchronous runs or bad stuff will happen
|
||||
// All buffers must be valid for entire DMA and not touched until `finished()` returns true.
|
||||
/**
|
||||
@brief Perform a transfer() using DMA in the background. Returns immediately, need to check for completion
|
||||
|
||||
@details
|
||||
Do not combine asynchronous and synchronous transfers. All buffers must be valid until
|
||||
the transfer reports that it is completed (``finished`` returns true).
|
||||
|
||||
@param [in] send Buffer to transmit, must remain valid through entire operation
|
||||
@param [out] recv Buffer to receive, must remain valid through entire operation
|
||||
@param [in] bytes Number of bytes to transfer under single CS
|
||||
*/
|
||||
bool transferAsync(const void *send, void *recv, size_t bytes);
|
||||
bool finishedAsync(); // Call to check if the async operations is completed and the buffer can be reused/read
|
||||
void abortAsync(); // Cancel an outstanding async operation
|
||||
/**
|
||||
@brief Call to check if the async operations is completed and the buffer can be reused/read
|
||||
|
||||
@returns True if the asynchronous SPI operation has completed and ``recv`` buffer is valid
|
||||
*/
|
||||
bool finishedAsync();
|
||||
|
||||
/**
|
||||
@brief Aborts an ongoing asynchronous SPI operation, if one is still operating
|
||||
|
||||
@details
|
||||
Not normally needed, but in the case where a large, long SPI operation needs to be aborted
|
||||
this call allows an application to safely stop the SPI and dispose of the ``recv`` and
|
||||
``send`` buffers
|
||||
*/
|
||||
void abortAsync();
|
||||
|
||||
|
||||
// Call before/after every complete transaction
|
||||
/**
|
||||
@brief Begin an SPI transaction, sets SPI speed and masks necessary interrupts
|
||||
|
||||
@param [in] SPISettings SPI configuration parameters, including the clock speed
|
||||
*/
|
||||
void beginTransaction(SPISettings settings) override;
|
||||
|
||||
/**
|
||||
@brief Ends an SPI transaction, unmasks and masked GPIO interrupts
|
||||
*/
|
||||
void endTransaction(void) override;
|
||||
|
||||
// Assign pins, call before begin()
|
||||
/**
|
||||
@brief Sets the MISO(RX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setRX(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the MISO(RX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
inline bool setMISO(pin_size_t pin) {
|
||||
return setRX(pin);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Sets the CS pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setCS(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the SCK pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setSCK(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the MOSI(TX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setTX(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the MOSI(TX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
inline bool setMOSI(pin_size_t pin) {
|
||||
return setTX(pin);
|
||||
}
|
||||
|
||||
// Call once to init/deinit SPI class, select pins, etc.
|
||||
/**
|
||||
@brief Call once to init/deinit SPI class, select pins, etc.
|
||||
*/
|
||||
virtual void begin() override {
|
||||
begin(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Call once to init/deinit SPI class, select pins, etc.
|
||||
|
||||
@param [in] hwCS Pass in true to enable HW-controlled CS. Otherwise application needs to assert/deassert CS.
|
||||
*/
|
||||
void begin(bool hwCS);
|
||||
|
||||
/**
|
||||
@brief Call to deinit and disable the SPI interface.
|
||||
*/
|
||||
void end() override;
|
||||
|
||||
// Deprecated - do not use!
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
|
||||
@param [in] order Deprecated
|
||||
*/
|
||||
void setBitOrder(BitOrder order) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
|
||||
@param [in] order Deprecated
|
||||
*/
|
||||
void setDataMode(uint8_t uc_mode) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
|
||||
@param [in] order Deprecated
|
||||
*/
|
||||
void setClockDivider(uint8_t uc_div) __attribute__((deprecated));
|
||||
|
||||
// List of GPIO IRQs to disable during a transaction
|
||||
/**
|
||||
@brief Ensure specific GPIO interrupt is disabled during and SPI transaction to protect against re-entrancy. Multiple GPIOs supported by multiple calls.
|
||||
|
||||
@param [in] interruptNumber GPIO pin to mask
|
||||
*/
|
||||
virtual void usingInterrupt(int interruptNumber) override {
|
||||
_helper.usingInterrupt(interruptNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Remove a GPIO from the masked-during-transaction list.
|
||||
|
||||
@param [in] interruptNumber GPIO pin to unmask
|
||||
*/
|
||||
virtual void notUsingInterrupt(int interruptNumber) override {
|
||||
_helper.notUsingInterrupt(interruptNumber);
|
||||
}
|
||||
virtual void attachInterrupt() override { /* noop */ }
|
||||
virtual void detachInterrupt() override { /* noop */ }
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
*/
|
||||
virtual void attachInterrupt() override __attribute__((deprecated)) { /* noop */ }
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
*/
|
||||
virtual void detachInterrupt() override __attribute__((deprecated)) { /* noop */ }
|
||||
|
||||
private:
|
||||
void adjustBuffer(const void *s, void *d, size_t cnt, bool by16);
|
||||
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
return (reverseByte(w & 0xff) << 8) | (reverseByte(w >> 8));
|
||||
}
|
||||
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
static constexpr int GPIOIRQREGS = 6;
|
||||
#else
|
||||
static constexpr int GPIOIRQREGS = 4;
|
||||
|
||||
@@ -79,7 +79,7 @@ inline spi_cpha_t SPISlaveClass::cpha(SPISettings _spis) {
|
||||
}
|
||||
|
||||
bool SPISlaveClass::setRX(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({0, 4, 16, 20, 32, 26}) /* SPI0 */,
|
||||
__bitset({8, 12, 24, 28, 40, 44}) /* SPI1 */
|
||||
};
|
||||
@@ -106,7 +106,7 @@ bool SPISlaveClass::setRX(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SPISlaveClass::setCS(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({1, 5, 17, 21, 33, 37}) /* SPI0 */,
|
||||
__bitset({9, 13, 25, 29, 41, 45}) /* SPI1 */
|
||||
};
|
||||
@@ -133,7 +133,7 @@ bool SPISlaveClass::setCS(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SPISlaveClass::setSCK(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({2, 6, 18, 22, 34, 38}) /* SPI0 */,
|
||||
__bitset({10, 14, 26, 30, 42, 46}) /* SPI1 */
|
||||
};
|
||||
@@ -160,7 +160,7 @@ bool SPISlaveClass::setSCK(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool SPISlaveClass::setTX(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({3, 7, 19, 23, 35, 39}) /* SPI0 */,
|
||||
__bitset({11, 15, 27, 31, 43, 47}) /* SPI1 */
|
||||
};
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <api/HardwareSPI.h>
|
||||
#include <hardware/spi.h>
|
||||
|
||||
/**
|
||||
@brief Implements a PIO-based SPI interface without pin restrictions
|
||||
*/
|
||||
class SoftwareSPI : public arduino::HardwareSPI {
|
||||
public:
|
||||
/**
|
||||
@@ -37,53 +40,170 @@ public:
|
||||
*/
|
||||
SoftwareSPI(pin_size_t sck, pin_size_t miso, pin_size_t mosi, pin_size_t cs = -1);
|
||||
|
||||
// Send or receive 8- or 16-bit data. Returns read back value
|
||||
/**
|
||||
@brief Send an 8-bit byte of data and return read-back 8-bit value
|
||||
|
||||
@param [in] data Data to send
|
||||
@returns Read back byte from SPI interface
|
||||
*/
|
||||
byte transfer(uint8_t data) override;
|
||||
|
||||
/**
|
||||
@brief Send a 16-bit quantity over SPI and return read-back 16-bit value under a single CS assertion
|
||||
|
||||
@param [in] data Data to send
|
||||
@returns Read back 16-bit quantity
|
||||
*/
|
||||
uint16_t transfer16(uint16_t data) override;
|
||||
|
||||
// Sends buffer in 8 bit chunks. Overwrites buffer with read data
|
||||
/**
|
||||
@brief Sends buffer in 8 bit chunks under a single CS. Overwrites buffer with read data
|
||||
|
||||
@param [in, out] buf Buffer to read and write back into
|
||||
@param [in] count Number of bytes to transmit/read
|
||||
*/
|
||||
void transfer(void *buf, size_t count) override;
|
||||
|
||||
// Sends one buffer and receives into another, much faster! can set rx or txbuf to nullptr
|
||||
/**
|
||||
@brief Sends one buffer and receives into another under a single CS. Can set rx or txbuf to nullptr
|
||||
|
||||
@param [in] txbuf Buffer to transmit or nullptr to send 0s
|
||||
@param [out] rxbuf Buffer to read back into or nullptr to ignore returned data
|
||||
@param [in] count Numbner of bytes to transmit/receive
|
||||
*/
|
||||
void transfer(const void *txbuf, void *rxbuf, size_t count) override;
|
||||
|
||||
// Call before/after every complete transaction
|
||||
/**
|
||||
@brief Begin an SPI transaction, sets SPI speed and masks necessary interrupts
|
||||
|
||||
@param [in] SPISettings SPI configuration parameters, including the clock speed
|
||||
*/
|
||||
void beginTransaction(SPISettings settings) override;
|
||||
|
||||
/**
|
||||
@brief Ends an SPI transaction, unmasks and masked GPIO interrupts
|
||||
*/
|
||||
void endTransaction(void) override;
|
||||
|
||||
// Assign pins, call before begin()
|
||||
/**
|
||||
@brief Sets the MISO(RX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setMISO(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the MISO(RX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
inline bool setRX(pin_size_t pin) {
|
||||
return setMISO(pin);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Sets the CS pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setCS(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the SCK pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setSCK(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the MOSI(TX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
bool setMOSI(pin_size_t pin);
|
||||
|
||||
/**
|
||||
@brief Sets the MOSI(TX) pin. Call before begin()
|
||||
|
||||
@param [in] pin The GPIO number to assign to
|
||||
@returns True on success
|
||||
*/
|
||||
inline bool setTX(pin_size_t pin) {
|
||||
return setMOSI(pin);
|
||||
}
|
||||
|
||||
// Call once to init/deinit SPI class, select pins, etc.
|
||||
/**
|
||||
@brief Call once to init/deinit SPI class, select pins, etc.
|
||||
*/
|
||||
virtual void begin() override {
|
||||
begin(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Call once to init/deinit SPI class, select pins, etc.
|
||||
|
||||
@param [in] hwCS Pass in true to enable HW-controlled CS. Otherwise application needs to assert/deassert CS.
|
||||
*/
|
||||
void begin(bool hwCS);
|
||||
|
||||
/**
|
||||
@brief Call to deinit and disable the SPI interface.
|
||||
*/
|
||||
void end() override;
|
||||
|
||||
// Deprecated - do not use!
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
|
||||
@param [in] order Deprecated
|
||||
*/
|
||||
void setBitOrder(BitOrder order) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
|
||||
@param [in] uc_mode Deprecated
|
||||
*/
|
||||
void setDataMode(uint8_t uc_mode) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
|
||||
@param [in] uc_div Deprecated
|
||||
*/
|
||||
void setClockDivider(uint8_t uc_div) __attribute__((deprecated));
|
||||
|
||||
// List of GPIO IRQs to disable during a transaction
|
||||
/**
|
||||
@brief Ensure specific GPIO interrupt is disabled during and SPI transaction to protect against re-entrancy. Multiple GPIOs supported by multiple calls.
|
||||
|
||||
@param [in] interruptNumber GPIO pin to mask
|
||||
*/
|
||||
virtual void usingInterrupt(int interruptNumber) override {
|
||||
_helper.usingInterrupt(interruptNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Remove a GPIO from the masked-during-transaction list.
|
||||
|
||||
@param [in] interruptNumber GPIO pin to unmask
|
||||
*/
|
||||
virtual void notUsingInterrupt(int interruptNumber) override {
|
||||
_helper.notUsingInterrupt(interruptNumber);
|
||||
}
|
||||
virtual void attachInterrupt() override { /* noop */ }
|
||||
virtual void detachInterrupt() override { /* noop */ }
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
*/
|
||||
virtual void attachInterrupt() override __attribute__((deprecated)) { /* noop */ }
|
||||
|
||||
/**
|
||||
@brief Deprecated, do not use
|
||||
*/
|
||||
virtual void detachInterrupt() override __attribute__((deprecated)) { /* noop */ }
|
||||
|
||||
private:
|
||||
void _adjustPIO(int bits);
|
||||
|
||||
@@ -49,7 +49,7 @@ TwoWire::TwoWire(i2c_inst_t *i2c, pin_size_t sda, pin_size_t scl) {
|
||||
}
|
||||
|
||||
bool TwoWire::setSDA(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44}) /* I2C0 */,
|
||||
__bitset({2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46}) /* I2C1 */
|
||||
};
|
||||
@@ -76,7 +76,7 @@ bool TwoWire::setSDA(pin_size_t pin) {
|
||||
}
|
||||
|
||||
bool TwoWire::setSCL(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45}) /* I2C0 */,
|
||||
__bitset({3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47}) /* I2C1 */
|
||||
};
|
||||
|
||||
@@ -75,7 +75,7 @@ void __removeEthernetPacketHandler(int id) {
|
||||
}
|
||||
|
||||
#define GPIOSTACKSIZE 8
|
||||
#ifdef PICO_RP2350B
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
#define GPIOIRQREGS 6
|
||||
#define GPIOIRQREGSINIT 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
|
||||
#else
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
const char* host = "djxmmx.net";
|
||||
const uint16_t port = 17;
|
||||
|
||||
Wiznet55rp20lwIP eth(1 /* chip select */);
|
||||
Wiznet55rp20lwIP eth(20 /* chip select */);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
Constructor that uses the default hardware SPI pins
|
||||
@param cs the Arduino Chip Select / Slave Select pin (default 10)
|
||||
*/
|
||||
Wiznet55rp20(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1);
|
||||
Wiznet55rp20(int8_t cs = WIZNET_PIO_SPI_CS_PIN, SPIClass& spi = SPI, int8_t intr = -1);
|
||||
//Wiznet55rp20();
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "framework-arduinopico",
|
||||
"version": "1.40500.0",
|
||||
"version": "1.40502.0",
|
||||
"description": "Arduino Wiring-based Framework (RPi Pico RP2040, RP2350)",
|
||||
"keywords": [
|
||||
"framework",
|
||||
|
||||
@@ -80,6 +80,9 @@
|
||||
{
|
||||
"name": "Adafruit KB2040"
|
||||
},
|
||||
{
|
||||
"name": "Adafruit Feather RP2350 Adalogger"
|
||||
},
|
||||
{
|
||||
"name": "Adafruit Feather RP2350 HSTX"
|
||||
},
|
||||
@@ -89,6 +92,9 @@
|
||||
{
|
||||
"name": "Adafruit Metro RP2350"
|
||||
},
|
||||
{
|
||||
"name": "Adafruit Fruit Jam RP2350"
|
||||
},
|
||||
{
|
||||
"name": "Amken BunnyBoard"
|
||||
},
|
||||
@@ -237,10 +243,13 @@
|
||||
"name": "nullbits Bit-C PRO"
|
||||
},
|
||||
{
|
||||
"name": "Olimex RP2040-Pico30 2MB"
|
||||
"name": "Olimex Pico2XL"
|
||||
},
|
||||
{
|
||||
"name": "Olimex RP2040-Pico30 16MB"
|
||||
"name": "Olimex Pico2XXL"
|
||||
},
|
||||
{
|
||||
"name": "Olimex RP2040-Pico30"
|
||||
},
|
||||
{
|
||||
"name": "Pimoroni PGA2040"
|
||||
@@ -260,6 +269,9 @@
|
||||
{
|
||||
"name": "Pimoroni Plasma2350"
|
||||
},
|
||||
{
|
||||
"name": "Pimoroni Servo2040"
|
||||
},
|
||||
{
|
||||
"name": "Pimoroni Tiny2040"
|
||||
},
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=Raspberry Pi RP2040/RP2350 Boards
|
||||
version=4.5.0
|
||||
version=4.5.2
|
||||
|
||||
# Required discoveries and monitors
|
||||
# ---------------------------------
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"boot2_source": "none.S",
|
||||
"usb_vid": "0x239A",
|
||||
"usb_pid": "0x816D"
|
||||
}
|
||||
},
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m33",
|
||||
"extra_flags": "-DARDUINO_ADAFRUIT_FEATHER_RP2350_ADALOGGER -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 ",
|
||||
"f_cpu": "150000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x816D"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2350",
|
||||
"variant": "adafruit_feather_rp2350_adalogger"
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2350_0",
|
||||
"openocd_target": "rp2350.cfg",
|
||||
"svd_path": "rp2350.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Feather RP2350 Adalogger",
|
||||
"upload": {
|
||||
"maximum_ram_size": 524288,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"blackmagic",
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"boot2_source": "none.S",
|
||||
"usb_vid": "0x239A",
|
||||
"usb_pid": "0x816B"
|
||||
}
|
||||
},
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m33",
|
||||
"extra_flags": "-DARDUINO_ADAFRUIT_FRUITJAM_RP2350 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 ",
|
||||
"f_cpu": "150000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x816B"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2350",
|
||||
"variant": "adafruit_fruitjam"
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2350_0",
|
||||
"openocd_target": "rp2350.cfg",
|
||||
"svd_path": "rp2350.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Fruit Jam RP2350",
|
||||
"upload": {
|
||||
"maximum_ram_size": 524288,
|
||||
"maximum_size": 16777216,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"blackmagic",
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
],
|
||||
"psram_length": 8388608
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"boot2_source": "none.S",
|
||||
"usb_vid": "0x15BA",
|
||||
"usb_pid": "0x0026"
|
||||
}
|
||||
},
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m33",
|
||||
"extra_flags": "-DARDUINO_OLIMEX_PICO2XL -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 ",
|
||||
"f_cpu": "150000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
],
|
||||
[
|
||||
"0x15BA",
|
||||
"0x0026"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2350",
|
||||
"variant": "olimex_pico2xl"
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2350_0",
|
||||
"openocd_target": "rp2350.cfg",
|
||||
"svd_path": "rp2350.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Pico2XL",
|
||||
"upload": {
|
||||
"maximum_ram_size": 524288,
|
||||
"maximum_size": 2097152,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"blackmagic",
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Olimex"
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"boot2_source": "none.S",
|
||||
"usb_vid": "0x15BA",
|
||||
"usb_pid": "0x0026"
|
||||
}
|
||||
},
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m33",
|
||||
"extra_flags": "-DARDUINO_OLIMEX_PICO2XXL -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500 ",
|
||||
"f_cpu": "150000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
],
|
||||
[
|
||||
"0x15BA",
|
||||
"0x0026"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2350",
|
||||
"variant": "olimex_pico2xxl"
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2350_0",
|
||||
"openocd_target": "rp2350.cfg",
|
||||
"svd_path": "rp2350.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Pico2XXL",
|
||||
"upload": {
|
||||
"maximum_ram_size": 524288,
|
||||
"maximum_size": 16777216,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"blackmagic",
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
],
|
||||
"psram_length": 8388608
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Olimex"
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-DARDUINO_OLIMEX_RP2040_PICO30_2MB -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 ",
|
||||
"extra_flags": "-DARDUINO_OLIMEX_RP2040_PICO30 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 ",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
@@ -22,7 +22,7 @@
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"variant": "olimex_rp2040pico30_2mb"
|
||||
"variant": "olimex_rp2040pico30"
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
@@ -32,7 +32,7 @@
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "RP2040-Pico30 2MB",
|
||||
"name": "RP2040-Pico30",
|
||||
"upload": {
|
||||
"maximum_ram_size": 262144,
|
||||
"maximum_size": 2097152,
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m33",
|
||||
"extra_flags": "-DARDUINO_PIMORONI_PLASMA2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500 ",
|
||||
"extra_flags": "-DARDUINO_PIMORONI_PLASMA2350 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500 ",
|
||||
"f_cpu": "150000000L",
|
||||
"hwids": [
|
||||
[
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x15BA",
|
||||
"usb_pid": "0x0026"
|
||||
"usb_vid": "0x2E8A",
|
||||
"usb_pid": "0x10A5"
|
||||
}
|
||||
},
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-DARDUINO_OLIMEX_RP2040_PICO30_16MB -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 ",
|
||||
"extra_flags": "-DARDUINO_PIMORONI_SERVO2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500 ",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
@@ -17,12 +17,12 @@
|
||||
"0x00C0"
|
||||
],
|
||||
[
|
||||
"0x15BA",
|
||||
"0x0026"
|
||||
"0x2E8A",
|
||||
"0x10A5"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"variant": "olimex_rp2040pico30_16mb"
|
||||
"variant": "pimoroni_servo2040"
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
@@ -32,10 +32,10 @@
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "RP2040-Pico30 16MB",
|
||||
"name": "Servo2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 262144,
|
||||
"maximum_size": 16777216,
|
||||
"maximum_size": 2097152,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
@@ -51,5 +51,5 @@
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Olimex"
|
||||
"vendor": "Pimoroni"
|
||||
}
|
||||
+19
-10
@@ -39,7 +39,7 @@ def BuildDebugLevel(name):
|
||||
|
||||
def BuildFreq(name, defmhz):
|
||||
out = 0
|
||||
for f in [ defmhz, 50, 100, 120, 125, 128, 133, 150, 175, 200, 225, 240, 250, 275, 300]:
|
||||
for f in [ defmhz, 50, 100, 120, 125, 128, 133, 150, 176, 200, 225, 240, 250, 276, 300]:
|
||||
warn = ""
|
||||
if f > defmhz: warn = " (Overclock)"
|
||||
if (out == 1) and (f == defmhz):
|
||||
@@ -85,7 +85,7 @@ def BuildPSRAMFreq(name):
|
||||
print("%s.menu.psramfreq.freq%d.build.psram_freq=-DRP2350_PSRAM_MAX_SCK_HZ=%d" % (name, s, s * 1000000))
|
||||
|
||||
def BuildRP2350Variant(name):
|
||||
for l in [ ("RP2350A", "-DPICO_RP2350A=1"), ("RP2530B", "-DPICO_RP2350B=1") ]:
|
||||
for l in [ ("RP2350A", "-D__PICO_RP2350A=1"), ("RP2530B", "-D__PICO_RP2350A=0") ]:
|
||||
print("%s.menu.variantchip.%s=%s" % (name, l[0], l[0]))
|
||||
print("%s.menu.variantchip.%s.build.variantdefines=%s" % (name, l[0], l[1]))
|
||||
|
||||
@@ -313,7 +313,8 @@ def BuildWifiType(name):
|
||||
print("%s.menu.espwifitype.esp_hosted.build.espwifitype=-DESPHOSTSPI=SPI1" % (name))
|
||||
|
||||
def MakeBoard(name, chip, vendor_name, product_name, vid, pid, pwr, boarddefine, flashsizemb, psramsize, boot2, extra = None, board_url = None):
|
||||
fssizelist = [ 0, 64 * 1024, 128 * 1024, 256 * 1024, 512 * 1024 ]
|
||||
smallfs = [ 0, 64 * 1024, 128 * 1024, 256 * 1024, 512 * 1024 ]
|
||||
fssizelist = list(smallfs)
|
||||
for i in range(1, flashsizemb):
|
||||
fssizelist.append(i * 1024 * 1024)
|
||||
if chip == "rp2040":
|
||||
@@ -329,17 +330,21 @@ def MakeBoard(name, chip, vendor_name, product_name, vid, pid, pwr, boarddefine,
|
||||
raise Exception("Unknown board type " + str(chip));
|
||||
BuildHeader(name, chip, tup, opts, vendor_name, product_name, vid, pid, pwr, boarddefine, name, flashsizemb * 1024 * 1024, psramsize, boot2, extra)
|
||||
if (name == "generic") or (name == "generic_rp2350") or (name == "vccgnd_yd_rp2040"):
|
||||
BuildFlashMenu(name, chip, 2*1024*1024, [0, 1*1024*1024])
|
||||
smfs = [ 0, 64 * 1024, 128 * 1024, 256 * 1024, 512 * 1024 ]
|
||||
BuildFlashMenu(name, chip, 2*1024*1024, [*smallfs, 1024 * 1024])
|
||||
BuildFlashMenu(name, chip, 4*1024*1024, [0, 3*1024*1024, 2*1024*1024])
|
||||
BuildFlashMenu(name, chip, 8*1024*1024, [0, 7*1024*1024, 4*1024*1024, 2*1024*1024])
|
||||
BuildFlashMenu(name, chip, 16*1024*1024, [0, 15*1024*1024, 14*1024*1024, 12*1024*1024, 8*1024*1024, 4*1024*1024, 2*1024*1024])
|
||||
elif name == "pimoroni_tiny2040":
|
||||
BuildFlashMenu(name, chip, 2*1024*1024, fssizelist)
|
||||
BuildFlashMenu(name, chip, 2*1024*1024, [*smallfs, 1024 * 1024])
|
||||
BuildFlashMenu(name, chip, 8*1024*1024, [0, 7*1024*1024, 4*1024*1024, 2*1024*1024])
|
||||
elif name == "akana_r1":
|
||||
BuildFlashMenu(name, chip, 2*1024*1024, [0, 1*1024*1024])
|
||||
BuildFlashMenu(name, chip, 2*1024*1024, [*smallfs, 1024 * 1024])
|
||||
BuildFlashMenu(name, chip, 8*1024*1024, [0, 7*1024*1024, 4*1024*1024, 2*1024*1024])
|
||||
BuildFlashMenu(name, chip, 16*1024*1024, [0, 15*1024*1024, 14*1024*1024, 12*1024*1024, 8*1024*1024, 4*1024*1024, 2*1024*1024])
|
||||
elif name == "olimex_rp2040pico30":
|
||||
BuildFlashMenu(name, chip, 2*1024*1024, [*smallfs, 1024 * 1024])
|
||||
BuildFlashMenu(name, chip, 16*1024*1024, [0, 15*1024*1024, 14*1024*1024, 12*1024*1024, 8*1024*1024, 4*1024*1024, 2*1024*1024])
|
||||
elif (name == "challenger_2350_wifi6_ble5") or (name == "challenger_2040_wifi_ble"):
|
||||
BuildWifiType(name)
|
||||
BuildCountry(name)
|
||||
@@ -372,7 +377,7 @@ def MakeBoard(name, chip, vendor_name, product_name, vid, pid, pwr, boarddefine,
|
||||
BuildDebugPort(name)
|
||||
BuildDebugLevel(name)
|
||||
BuildUSBStack(name)
|
||||
if name in ["rpipicow", "pimoroni_pico_plus_2w", "sparkfun_thingplusrp2350"]:
|
||||
if name in ["rpipicow", "rpipico2w", "pimoroni_pico_plus_2w", "sparkfun_thingplusrp2350"]:
|
||||
BuildCountry(name)
|
||||
BuildIPBTStack(name)
|
||||
if name == "generic":
|
||||
@@ -514,9 +519,11 @@ MakeBoard("adafruit_stemmafriend", "rp2040", "Adafruit", "STEMMA Friend RP2040",
|
||||
MakeBoard("adafruit_trinkeyrp2040qt", "rp2040", "Adafruit", "Trinkey RP2040 QT", "0x239a", "0x8109", 250, "ADAFRUIT_TRINKEYQT_RP2040", 8, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("adafruit_macropad2040", "rp2040", "Adafruit", "MacroPad RP2040", "0x239a", "0x8107", 250, "ADAFRUIT_MACROPAD_RP2040", 8, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("adafruit_kb2040", "rp2040", "Adafruit", "KB2040", "0x239a", "0x8105", 250, "ADAFRUIT_KB2040_RP2040", 8, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("adafruit_feather_rp2350_adalogger", "rp2350", "Adafruit", "Feather RP2350 Adalogger", "0x239a", "0x816D", 250, "ADAFRUIT_FEATHER_RP2350_ADALOGGER", 8, 0, "none")
|
||||
MakeBoard("adafruit_feather_rp2350_hstx", "rp2350", "Adafruit", "Feather RP2350 HSTX", "0x239a", "0x814f", 250, "ADAFRUIT_FEATHER_RP2350_HSTX", 8, 0, "none")
|
||||
MakeBoard("adafruit_floppsy", "rp2040", "Adafruit", "Floppsy", "0x239a", "0x8151", 250, "ADAFRUIT_FLOPPSY_RP2040", 16, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("adafruit_metro_rp2350", "rp2350", "Adafruit", "Metro RP2350", "0x239a", "0x814d", 250, "ADAFRUIT_METRO_RP2350", 16, 0, "none")
|
||||
MakeBoard("adafruit_fruitjam", "rp2350", "Adafruit", "Fruit Jam RP2350", "0x239a", "0x816B", 250, "ADAFRUIT_FRUITJAM_RP2350", 16, 8, "none")
|
||||
# Amken
|
||||
MakeBoard("amken_bunny", "rp2040","Amken","BunnyBoard","0x2770",["0x7303"],250,"AMKEN_BB",128,0,"boot2_w25q128jvxq_4_padded_checksum","","https://www.amken3d.com")
|
||||
MakeBoard("amken_revelop", "rp2040","Amken","Revelop","0x2770",["0x7304"],250,"AMKEN_REVELOP",32,0,"boot2_W25Q32JVxQ_4_padded_checksum","","https://www.amken3d.com")
|
||||
@@ -615,8 +622,9 @@ MakeBoard("newsan_archi", "rp2040", "Newsan", "Archi", "0x2E8A", "0x1043", 250,
|
||||
MakeBoard("nullbits_bit_c_pro", "rp2040", "nullbits", "Bit-C PRO", "0x2e8a", "0x6e61", 500, "NULLBITS_BIT_C_PRO", 4, 0, "boot2_w25x10cl_4_padded_checksum")
|
||||
|
||||
# Olimex
|
||||
MakeBoard("olimex_rp2040pico30_2mb", "rp2040", "Olimex", "RP2040-Pico30 2MB", "0x15ba", "0x0026", 250, "OLIMEX_RP2040_PICO30_2MB", 2, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("olimex_rp2040pico30_16mb", "rp2040", "Olimex", "RP2040-Pico30 16MB", "0x15ba", "0x0026", 250, "OLIMEX_RP2040_PICO30_16MB", 16, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("olimex_pico2xl", "rp2350", "Olimex", "Pico2XL", "0x15ba", "0x0026", 250, "OLIMEX_PICO2XL", 2, 0, "none")
|
||||
MakeBoard("olimex_pico2xxl", "rp2350", "Olimex", "Pico2XXL", "0x15ba", "0x0026", 500, "OLIMEX_PICO2XXL", 16, 8, "none")
|
||||
MakeBoard("olimex_rp2040pico30", "rp2040", "Olimex", "RP2040-Pico30", "0x15ba", "0x0026", 250, "OLIMEX_RP2040_PICO30", 2, 0, "boot2_w25q080_2_padded_checksum")
|
||||
|
||||
# Pimoroni
|
||||
MakeBoard("pimoroni_pga2040", "rp2040", "Pimoroni", "PGA2040", "0x2e8a", "0x1008", 250, "PIMORONI_PGA2040", 8, 0, "boot2_w25q64jv_4_padded_checksum")
|
||||
@@ -624,7 +632,8 @@ MakeBoard("pimoroni_pga2350", "rp2350", "Pimoroni", "PGA2350", "0x2e8a", "0x1018
|
||||
MakeBoard("pimoroni_pico_plus_2", "rp2350", "Pimoroni", "PicoPlus2", "0x2e8a", "0x100a", 500, "PIMORONI_PICO_PLUS_2", 16, 8, "none")
|
||||
MakeBoard("pimoroni_pico_plus_2w", "rp2350", "Pimoroni", "PicoPlus2W", "0x2e8a", "0x100a", 500, "PIMORONI_PICO_PLUS_2W", 16, 8, "none", ["PICO_CYW43_SUPPORTED=1", "CYW43_PIN_WL_DYNAMIC=1"])
|
||||
MakeBoard("pimoroni_plasma2040", "rp2040", "Pimoroni", "Plasma2040", "0x2e8a", "0x100a", 500, "PIMORONI_PLASMA2040", 2, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("pimoroni_plasma2350", "rp2350", "Pimoroni", "Plasma2350", "0x2e8a", "0x10a5", 500, "PIMORONI_PLASMA2040", 2, 0, "none")
|
||||
MakeBoard("pimoroni_plasma2350", "rp2350", "Pimoroni", "Plasma2350", "0x2e8a", "0x10a5", 500, "PIMORONI_PLASMA2350", 2, 0, "none")
|
||||
MakeBoard("pimoroni_servo2040", "rp2040", "Pimoroni", "Servo2040", "0x2e8a", "0x10a5", 500, "PIMORONI_SERVO2040", 2, 0, "boot2_w25q080_2_padded_checksum")
|
||||
MakeBoard("pimoroni_tiny2040", "rp2040", "Pimoroni", "Tiny2040", "0x2e8a", "0x100a", 500, "PIMORONI_TINY2040", 2, 0, "boot2_w25q64jv_4_padded_checksum")
|
||||
MakeBoard("pimoroni_tiny2350", "rp2350", "Pimoroni", "Tiny2350", "0x2e8a", "0x100b", 500, "PIMORONI_TINY2350", 4, 0, "none")
|
||||
|
||||
|
||||
@@ -5,89 +5,96 @@ import sys
|
||||
import time
|
||||
import threading
|
||||
|
||||
|
||||
toolspath = os.path.dirname(os.path.realpath(__file__))
|
||||
try:
|
||||
sys.path.insert(0, os.path.join(toolspath, ".")) # Add pyserial dir to search path
|
||||
sys.path.insert(0, os.path.join(toolspath, ".")) # Add uf2conv dir to search path
|
||||
import uf2conv # If this fails, we can't continue and will bomb below
|
||||
except ImportError:
|
||||
sys.stderr.write("uf2conv not found next to this tool.\n")
|
||||
sys.exit(1)
|
||||
|
||||
scannerStop = threading.Event()
|
||||
dropDead = False
|
||||
|
||||
scannerGo = False
|
||||
class ScannerDarkly(threading.Thread):
|
||||
|
||||
loopTime = 0.0 # Set to 0 for 1st pass to get immediate response for arduino-cli, then bumped to 2.0 for ongoing checks
|
||||
|
||||
# https://stackoverflow.com/questions/12435211/threading-timer-repeat-function-every-n-seconds
|
||||
def __init__(self, event):
|
||||
threading.Thread.__init__(self)
|
||||
self.stopped = event
|
||||
|
||||
def run(self):
|
||||
global dropDead
|
||||
boards = False;
|
||||
while not self.stopped.wait(self.loopTime):
|
||||
if self.stopped.is_set() or dropDead:
|
||||
return
|
||||
self.loopTime = 2.0
|
||||
l = uf2conv.get_drives()
|
||||
if (len(l) > 0) and not boards:
|
||||
boards = True
|
||||
print ("""{
|
||||
"eventType": "add",
|
||||
"port": {
|
||||
"address": "UF2_Board",
|
||||
"label": "UF2 Board",
|
||||
"protocol": "uf2conv",
|
||||
"protocolLabel": "UF2 Devices",
|
||||
"properties": {
|
||||
"mac": "ffffffffffff",
|
||||
"pid" : "0x2e8a",
|
||||
"vid" : "0x000a"
|
||||
}
|
||||
}
|
||||
}""", flush=True)
|
||||
elif (len(l) == 0) and boards:
|
||||
boards = False
|
||||
print("""{
|
||||
"eventType": "remove",
|
||||
"port": {
|
||||
"address": "UF2_Board",
|
||||
"protocol": "uf2conv"
|
||||
}
|
||||
}""", flush = True)
|
||||
|
||||
def scanner():
|
||||
global scannerGo
|
||||
scannerGo = True
|
||||
boards = False
|
||||
while scannerGo:
|
||||
l = uf2conv.get_drives()
|
||||
if (len(l) > 0) and scannerGo and not boards:
|
||||
boards = True
|
||||
print ("""{
|
||||
"eventType": "add",
|
||||
"port": {
|
||||
"address": "UF2_Board",
|
||||
"label": "UF2 Board",
|
||||
"protocol": "uf2conv",
|
||||
"protocolLabel": "UF2 Devices",
|
||||
"properties": {
|
||||
"mac": "ffffffffffff",
|
||||
"pid" : "0x2e8a",
|
||||
"vid" : "0x000a"
|
||||
}
|
||||
}
|
||||
}""", flush=True)
|
||||
elif (len(l) == 0) and scannerGo and boards:
|
||||
boards = False
|
||||
print("""{
|
||||
"eventType": "remove",
|
||||
"port": {
|
||||
"address": "UF2_Board",
|
||||
"protocol": "uf2conv"
|
||||
}
|
||||
}""", flush = True)
|
||||
n = time.time() + 2
|
||||
while scannerGo and (time.time() < n):
|
||||
time.sleep(.1)
|
||||
scannerGo = True
|
||||
|
||||
def main():
|
||||
global scannerGo
|
||||
while True:
|
||||
cmdline = input()
|
||||
cmd = cmdline.split()[0]
|
||||
if cmd == "HELLO":
|
||||
print(""" {
|
||||
global scannerStop
|
||||
global dropDead
|
||||
try:
|
||||
while True:
|
||||
cmdline = input()
|
||||
cmd = cmdline.split()[0]
|
||||
if cmd == "HELLO":
|
||||
print(""" {
|
||||
"eventType": "hello",
|
||||
"message": "OK",
|
||||
"protocolVersion": 1
|
||||
}""", flush = True)
|
||||
elif cmd == "START":
|
||||
print("""{
|
||||
elif cmd == "START":
|
||||
print("""{
|
||||
"eventType": "start",
|
||||
"message": "OK"
|
||||
}""", flush = True);
|
||||
elif cmd == "STOP":
|
||||
scannerGo = False
|
||||
while not scannerGo:
|
||||
time.sleep(.1)
|
||||
print("""{
|
||||
elif cmd == "STOP":
|
||||
scannerStop.set()
|
||||
print("""{
|
||||
"eventType": "stop",
|
||||
"message": "OK"
|
||||
}""", flush = True)
|
||||
elif cmd == "QUIT":
|
||||
scannerGo = False
|
||||
print("""{
|
||||
elif cmd == "QUIT":
|
||||
scannerStop.set()
|
||||
print("""{
|
||||
"eventType": "quit",
|
||||
"message": "OK"
|
||||
}""", flush = True)
|
||||
return
|
||||
elif cmd == "LIST":
|
||||
l = uf2conv.get_drives()
|
||||
if len(l) > 0:
|
||||
print ("""{
|
||||
return
|
||||
elif cmd == "LIST":
|
||||
l = uf2conv.get_drives()
|
||||
if len(l) > 0:
|
||||
print ("""{
|
||||
"eventType": "list",
|
||||
"ports": [
|
||||
{
|
||||
@@ -103,18 +110,19 @@ def main():
|
||||
}
|
||||
]
|
||||
}""", flush=True)
|
||||
else:
|
||||
print ("""{
|
||||
else:
|
||||
print ("""{
|
||||
"eventType": "list",
|
||||
"ports": [ ]
|
||||
}""", flush=True)
|
||||
elif cmd == "START_SYNC":
|
||||
print("""{
|
||||
elif cmd == "START_SYNC":
|
||||
print("""{
|
||||
"eventType": "start_sync",
|
||||
"message": "OK"
|
||||
}""", flush = True)
|
||||
scannerGo = True
|
||||
threading.Thread(target = scanner).start()
|
||||
time.sleep(.5)
|
||||
thread = ScannerDarkly(scannerStop)
|
||||
thread.start()
|
||||
except:
|
||||
dropDead = True
|
||||
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (7u)
|
||||
|
||||
#define PIN_NEOPIXEL (21u)
|
||||
#define NUM_NEOPIXEL (1)
|
||||
|
||||
// SD Card connector
|
||||
#define PIN_CARD_DETECT (13u)
|
||||
#define PIN_SD_CLK (14u)
|
||||
#define PIN_SD_CMD_MOSI (15u)
|
||||
#define PIN_SD_DAT0_MISO (16u)
|
||||
#define PIN_SD_DAT1 (17u)
|
||||
#define PIN_SD_DAT2 (18u)
|
||||
#define PIN_SD_DAT3_CS (19u)
|
||||
|
||||
// UARTs
|
||||
#define PIN_SERIAL1_TX (0u)
|
||||
#define PIN_SERIAL1_RX (1u)
|
||||
#define PIN_SERIAL2_TX (99u) // not pinned out
|
||||
#define PIN_SERIAL2_RX (99u)
|
||||
|
||||
// SPI
|
||||
#define PIN_SPI0_MISO (20u)
|
||||
#define PIN_SPI0_MOSI (23u)
|
||||
#define PIN_SPI0_SCK (22u)
|
||||
#define PIN_SPI0_SS (13u)
|
||||
#define __SPI0_DEVICE spi0
|
||||
|
||||
// SPI1 for SD card
|
||||
#define PIN_SPI1_MISO PIN_SD_DAT0_MISO
|
||||
#define PIN_SPI1_MOSI PIN_SD_CMD_MOSI
|
||||
#define PIN_SPI1_SCK PIN_SD_CLK
|
||||
#define PIN_SPI1_SS PIN_SD_DAT3_CS
|
||||
#define __SPI1_DEVICE spi1
|
||||
|
||||
// Wire
|
||||
#define __WIRE0_DEVICE i2c0
|
||||
#define PIN_WIRE0_SDA (2u)
|
||||
#define PIN_WIRE0_SCL (3u)
|
||||
|
||||
#define __WIRE1_DEVICE i2c1
|
||||
#define PIN_WIRE1_SDA (31u) // not pinned out
|
||||
#define PIN_WIRE1_SCL (31u)
|
||||
|
||||
#define SERIAL_HOWMANY (1u)
|
||||
#define SPI_HOWMANY (2u)
|
||||
#define WIRE_HOWMANY (1u)
|
||||
|
||||
#include "../generic/common.h"
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (7u)
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
#define PICO_RP2350A 0
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (29u)
|
||||
|
||||
#define PIN_NEOPIXEL (32u)
|
||||
#define NUM_NEOPIXEL (5u)
|
||||
|
||||
// 'Boot0' button also on GPIO #0
|
||||
#define PIN_BUTTON (0u)
|
||||
#define PIN_BUTTON1 (4u)
|
||||
#define PIN_BUTTON2 (5u)
|
||||
|
||||
// USB host connector
|
||||
#define PIN_USB_HOST_DP (1u)
|
||||
#define PIN_USB_HOST_DM (2u)
|
||||
#define PIN_5V_EN (11u)
|
||||
#define PIN_5V_EN_STATE (1u)
|
||||
|
||||
// SDIO
|
||||
#define PIN_SD_DETECT (33u)
|
||||
#define PIN_SD_CLK (34u)
|
||||
#define PIN_SD_CMD_MOSI (35u)
|
||||
#define PIN_SD_DAT0_MISO (36u)
|
||||
#define PIN_SD_DAT1 (37u)
|
||||
#define PIN_SD_DAT2 (38u)
|
||||
#define PIN_SD_DAT3_CS (39u)
|
||||
|
||||
// I2S
|
||||
#define PIN_I2S_DATAOUT (24u)
|
||||
#define PIN_I2S_WORDSEL (25u)
|
||||
#define PIN_I2S_BITCLK (26u)
|
||||
#define PIN_I2S_MCLK (27u)
|
||||
|
||||
#define PIN_PERIPHERAL_RESET (22u)
|
||||
|
||||
#define __PIN_A0 (40u)
|
||||
#define __PIN_A1 (41u)
|
||||
#define __PIN_A2 (42u)
|
||||
#define __PIN_A3 (43u)
|
||||
#define __PIN_A4 (44u)
|
||||
#define __PIN_A5 (45u)
|
||||
|
||||
// UARTs
|
||||
#define PIN_SERIAL1_TX (8u)
|
||||
#define PIN_SERIAL1_RX (9u)
|
||||
#define PIN_SERIAL2_TX (99u) // not pinned out
|
||||
#define PIN_SERIAL2_RX (99u)
|
||||
|
||||
// SPI
|
||||
#define __SPI1_DEVICE spi1
|
||||
#define PIN_SPI1_MISO (28u)
|
||||
#define PIN_SPI1_MOSI (31u)
|
||||
#define PIN_SPI1_SCK (30u)
|
||||
#define PIN_SPI1_SS (46u)
|
||||
|
||||
#define __SPI0_DEVICE spi0
|
||||
#define PIN_SPI0_MISO (36u)
|
||||
#define PIN_SPI0_MOSI (35u)
|
||||
#define PIN_SPI0_SCK (34u)
|
||||
#define PIN_SPI0_SS (39u)
|
||||
|
||||
// Wire
|
||||
#define __WIRE0_DEVICE i2c0
|
||||
#define PIN_WIRE0_SDA (20u)
|
||||
#define PIN_WIRE0_SCL (21u)
|
||||
|
||||
#define __WIRE1_DEVICE i2c1
|
||||
#define PIN_WIRE1_SDA (99u) // not pinned out
|
||||
#define PIN_WIRE1_SCL (99u)
|
||||
|
||||
#define SERIAL_HOWMANY (1u)
|
||||
#define SPI_HOWMANY (2u)
|
||||
#define WIRE_HOWMANY (1u)
|
||||
|
||||
// PSRAM
|
||||
#define RP2350_PSRAM_CS (47u)
|
||||
#define RP2350_PSRAM_MAX_SCK_HZ (109*1000*1000)
|
||||
|
||||
// DVI connector
|
||||
#define PIN_CKN (12u)
|
||||
#define PIN_CKP (13u)
|
||||
#define PIN_D0N (14u)
|
||||
#define PIN_D0P (15u)
|
||||
#define PIN_D1N (16u)
|
||||
#define PIN_D1P (17u)
|
||||
#define PIN_D2N (18u)
|
||||
#define PIN_D2P (19u)
|
||||
|
||||
#include "../generic/common.h"
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#define PICO_RP2350B 1
|
||||
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (23u)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
#define PINS_COUNT (30u)
|
||||
#define NUM_DIGITAL_PINS (30u)
|
||||
#define NUM_ANALOG_INPUTS (4u)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
#define PINS_COUNT (30u)
|
||||
#define NUM_DIGITAL_PINS (30u)
|
||||
#define NUM_ANALOG_INPUTS (4u)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (29u)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (2u)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// DatanoiseTV PicoADK v2 - Audio Development Kit with RP2350A
|
||||
// https://github.com/DatanoiseTV/PicoDSP-Hardware
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ static const uint8_t D29 = __PIN_D29;
|
||||
static const uint8_t D29 = (29u);
|
||||
#endif
|
||||
|
||||
#if !defined(PICO_RP2350B)
|
||||
#if defined(PICO_RP2040) || (defined(PICO_RP2350) && PICO_RP2350A)
|
||||
|
||||
#ifdef __PIN_A0
|
||||
static const uint8_t A0 = __PIN_A0;
|
||||
@@ -190,7 +190,7 @@ static const uint8_t A3 = __PIN_A3;
|
||||
static const uint8_t A3 = (29u);
|
||||
#endif
|
||||
|
||||
#elif defined(PICO_RP2350B)
|
||||
#elif defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
|
||||
#ifdef __PIN_D30
|
||||
static const uint8_t D30 = __PIN_D30;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Pin definitions taken from:
|
||||
// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
|
||||
|
||||
#define PICO_RP2350A __PICO_RP2350A
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (25u)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Pin definitions taken from:
|
||||
// https://github.com/Architeuthis-Flux/JumperlessV5/tree/main/Hardware/Jumperless23V50
|
||||
|
||||
#define PICO_RP2350B 1
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (17u)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
#include "../rpipico2/pins_arduino.h"
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
#define RP2350_PSRAM_CS 8
|
||||
#include "../rpipico2/pins_arduino.h"
|
||||
@@ -1,2 +0,0 @@
|
||||
#pragma once
|
||||
#include "../rpipico/pins_arduino.h"
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// Enables external PSRAM
|
||||
#define RP2350_PSRAM_CS 47
|
||||
#define PICO_RP2350B 1
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
|
||||
// This is a bare board with no real predefined pins, so use generic
|
||||
#include "../generic/pins_arduino.h"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#define RP2350_PSRAM_CS (47u)
|
||||
#define RP2350_PSRAM_MAX_SCK_HZ (109*1000*1000)
|
||||
|
||||
#define PICO_RP2350B 1
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
|
||||
/* Pins mappings for marked pins on the board */
|
||||
static const uint8_t D0 = (0u);
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#define RP2350_PSRAM_CS (47u)
|
||||
#define RP2350_PSRAM_MAX_SCK_HZ (109*1000*1000)
|
||||
|
||||
#define PICO_RP2350B 1
|
||||
#define PICO_RP2350A 0 // RP2530B
|
||||
|
||||
/* Pins mappings for marked pins on the board */
|
||||
static const uint8_t D0 = (0u);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// Pin definitions taken from:
|
||||
// https://github.com/rp-rs/rp-hal-boards/blob/main/boards/pimoroni-plasma-2040/src/lib.rs
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
// Pin definitions taken from:
|
||||
// https://github.com/rp-rs/rp-hal-boards/blob/main/boards/pimoroni-servo2040/src/lib.rs
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (18u)
|
||||
#define LED_BUILTIN PIN_LED
|
||||
|
||||
// Digital pins
|
||||
#define SERVO1 (0u)
|
||||
#define SERVO2 (1u)
|
||||
#define SERVO3 (2u)
|
||||
#define SERVO4 (3u)
|
||||
#define SERVO5 (4u)
|
||||
#define SERVO6 (5u)
|
||||
#define SERVO7 (6u)
|
||||
#define SERVO8 (7u)
|
||||
#define SERVO9 (8u)
|
||||
#define SERVO10 (9u)
|
||||
#define SERVO11 (10u)
|
||||
#define SERVO12 (11u)
|
||||
#define SERVO13 (12u)
|
||||
#define SERVO14 (13u)
|
||||
#define SERVO15 (14u)
|
||||
#define SERVO16 (15u)
|
||||
#define SERVO17 (16u)
|
||||
#define SERVO18 (17u)
|
||||
#define USER_SW (22u)
|
||||
|
||||
// Analog pins
|
||||
#define ADC_ADDR_0 (22u)
|
||||
#define ADC_ADDR_1 (24u)
|
||||
#define ADC_ADDR_2 (25u)
|
||||
static const uint8_t A0 = (26u);
|
||||
static const uint8_t A1 = (27u);
|
||||
static const uint8_t A2 = (28u);
|
||||
static const uint8_t A3 = (31u);
|
||||
#define ADC_SHARED A3
|
||||
#define ADC_RESOLUTION 12
|
||||
|
||||
// NeoPixel
|
||||
#define PIN_NEOPIXEL (15u)
|
||||
//#define NEOPIXEL_POWER (11u)
|
||||
|
||||
// Serial1
|
||||
#define PIN_SERIAL1_TX (31u)
|
||||
#define PIN_SERIAL1_RX (31u)
|
||||
|
||||
// Serial2 not pinned out
|
||||
#define PIN_SERIAL2_TX (31u)
|
||||
#define PIN_SERIAL2_RX (31u)
|
||||
|
||||
// SPI
|
||||
#define PIN_SPI0_MISO (31u)
|
||||
#define PIN_SPI0_MOSI (31u)
|
||||
#define PIN_SPI0_SCK (31u)
|
||||
#define PIN_SPI0_SS (31u) // not pinned out
|
||||
//static const uint8_t SS = PIN_SPI0_SS; // SPI Slave SS not used. Set here only for reference.
|
||||
//static const uint8_t MOSI = PIN_SPI0_MOSI;
|
||||
//static const uint8_t MISO = PIN_SPI0_MISO;
|
||||
//static const uint8_t SCK = PIN_SPI0_SCK;
|
||||
|
||||
// Not pinned out
|
||||
#define PIN_SPI1_MISO (31u)
|
||||
#define PIN_SPI1_MOSI (31u)
|
||||
#define PIN_SPI1_SCK (31u)
|
||||
#define PIN_SPI1_SS (31u)
|
||||
//#define SPI_MISO (PIN_SPI1_MISO)
|
||||
//#define SPI_MOSI (PIN_SPI1_MOSI)
|
||||
//#define SPI_SCK (PIN_SPI1_SCK)
|
||||
|
||||
// Wire
|
||||
#define __WIRE0_DEVICE (i2c0)
|
||||
#define PIN_WIRE0_SDA (20u)
|
||||
#define PIN_WIRE0_SCL (21u)
|
||||
#define SDA PIN_WIRE0_SDA
|
||||
#define SCL PIN_WIRE0_SCL
|
||||
#define I2C_SDA (SDA)
|
||||
#define I2C_SCL (SCL)
|
||||
|
||||
// Wire1 not pinned out
|
||||
#define __WIRE1_DEVICE (i2c1)
|
||||
#define PIN_WIRE1_SDA (31u)
|
||||
#define PIN_WIRE1_SCL (31u)
|
||||
|
||||
#define SERIAL_HOWMANY (0u)
|
||||
#define SPI_HOWMANY (0u)
|
||||
#define WIRE_HOWMANY (1u)
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// This is a bare board with few predefined pins, so based on generic
|
||||
|
||||
// Pin definitions taken from:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Pin definitions taken from:
|
||||
// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (25u)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// Pin definitions taken from:
|
||||
// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (64u)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// Pin definitions taken from:
|
||||
// https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// Pin definitions taken from:
|
||||
// https://rp2xxx-stamp-carrier-xl.solder.party/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Pin definitions taken from:
|
||||
// https://rp2xxx-stamp-carrier-xl.solder.party/
|
||||
|
||||
#define PICO_RP2350B 1
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (3u)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (25u)
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cyw43_wrappers.h>
|
||||
|
||||
#define PICO_RP2350B 1
|
||||
#define PICO_RP2350A 0
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
|
||||
#define PINS_COUNT (48u)
|
||||
#define NUM_DIGITAL_PINS (48u)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
// Taken from schematic at https://cdn.sparkfun.com/assets/e/2/7/6/b/ProMicroRP2040_Graphical_Datasheet.pdf
|
||||
|
||||
// LEDs
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 1
|
||||
|
||||
#include <cyw43_wrappers.h>
|
||||
|
||||
// LEDs
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define PICO_RP2350A 0
|
||||
#define PICO_RP2350A 0 // RP2350B
|
||||
|
||||
#include <cyw43_wrappers.h>
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#define PICO_RP2350A 1
|
||||
#include "../generic/pins_arduino.h"
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#define PICO_RP2350A 1
|
||||
#include "../generic/pins_arduino.h"
|
||||
|
||||
Reference in New Issue
Block a user