Compare commits
@@ -10,7 +10,7 @@ jobs:
|
||||
|
||||
# Consistent style, spelling
|
||||
astyle:
|
||||
name: Spelling, Style, Boards, Package
|
||||
name: Spelling, Style, Boards, Package, PIO
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -21,11 +21,6 @@ jobs:
|
||||
with:
|
||||
skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib,./libraries/http-parser/lib,./libraries/WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino,./libraries/HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino,./.git,./libraries/FatFS/lib/fatfs,./libraries/FatFS/src/diskio.h,./libraries/FatFS/src/ff.cpp,./libraries/FatFS/src/ffconf.h,./libraries/FatFS/src/ffsystem.cpp,./libraries/FatFS/src/ff.h,./libraries/lwIP_WINC1500/src/driver,./libraries/lwIP_WINC1500/src/common,./libraries/lwIP_WINC1500/src/bus_wrapper,./libraries/lwIP_WINC1500/src/spi_flash
|
||||
ignore_words_list: ser,dout,shiftIn,acount,froms
|
||||
- name: Get submodules for following tests
|
||||
run: git submodule update --init
|
||||
- name: Check package references
|
||||
run: |
|
||||
./tests/ci/pkgrefs_test.sh
|
||||
- name: Check boards.txt was not edited after makeboards.py
|
||||
run: |
|
||||
./tools/makeboards.py
|
||||
@@ -38,6 +33,15 @@ jobs:
|
||||
./tests/restyle.sh
|
||||
# If anything changed, GIT should return an error and fail the test
|
||||
git diff --exit-code
|
||||
- name: Check compiled PIO files
|
||||
run: |
|
||||
(cd ./tools && ./get.py)
|
||||
./tools/makepio.py
|
||||
# If anything changed, GIT should return an error and fail the test
|
||||
git diff -w --exit-code
|
||||
- name: Check package references
|
||||
run: |
|
||||
./tests/ci/pkgrefs_test.sh
|
||||
|
||||
# Build all examples on linux (core and Arduino IDE)
|
||||
build-linux:
|
||||
|
||||
+4
-1
@@ -5,5 +5,8 @@ docs/_build
|
||||
ota/build
|
||||
ota/build-rp2350
|
||||
ota/build-rp2350-riscv
|
||||
tools/libpico/build
|
||||
tools/libpico/boot
|
||||
tools/libpico/build-rp2040
|
||||
tools/libpico/build-rp2350
|
||||
tools/libpico/build-rp2350-riscv
|
||||
platform.local.txt
|
||||
|
||||
@@ -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
|
||||
|
||||
+2529
-1176
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;
|
||||
|
||||
+189
-19
@@ -182,13 +182,16 @@ 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 */ }
|
||||
~RP2040() { /* noop */ }
|
||||
|
||||
void begin() {
|
||||
_epoch = 0;
|
||||
void begin(int cpuid) {
|
||||
_epoch[cpuid] = 0;
|
||||
#if !defined(__riscv) && !defined(__PROFILE)
|
||||
if (!__isFreeRTOS) {
|
||||
// Enable SYSTICK exception
|
||||
@@ -197,43 +200,70 @@ public:
|
||||
systick_hw->rvr = 0x00FFFFFF;
|
||||
} else {
|
||||
#endif
|
||||
int off = 0;
|
||||
_ccountPgm = new PIOProgram(&ccount_program);
|
||||
_ccountPgm->prepare(&_pio, &_sm, &off);
|
||||
ccount_program_init(_pio, _sm, off);
|
||||
pio_sm_set_enabled(_pio, _sm, true);
|
||||
// Only start 1 instance of the PIO SM
|
||||
if (cpuid == 0) {
|
||||
int off = 0;
|
||||
_ccountPgm = new PIOProgram(&ccount_program);
|
||||
_ccountPgm->prepare(&_pio, &_sm, &off);
|
||||
ccount_program_init(_pio, _sm, off);
|
||||
pio_sm_set_enabled(_pio, _sm, true);
|
||||
}
|
||||
#if !defined(__riscv) && !defined(__PROFILE)
|
||||
}
|
||||
#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
|
||||
volatile uint64_t _epoch = 0;
|
||||
/**
|
||||
@brief CPU cycle counter epoch (24-bit cycle). For internal use
|
||||
*/
|
||||
volatile uint64_t _epoch[2] = {};
|
||||
/**
|
||||
@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;
|
||||
do {
|
||||
epoch = (uint32_t)_epoch;
|
||||
epoch = (uint32_t)_epoch[sio_hw->cpuid];
|
||||
ctr = systick_hw->cvr;
|
||||
} while (epoch != (uint32_t)_epoch);
|
||||
} while (epoch != (uint32_t)_epoch[sio_hw->cpuid]);
|
||||
return epoch + (1 << 24) - ctr; /* CTR counts down from 1<<24-1 */
|
||||
} else {
|
||||
#endif
|
||||
@@ -242,16 +272,20 @@ 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) {
|
||||
uint64_t epoch;
|
||||
uint64_t ctr;
|
||||
do {
|
||||
epoch = _epoch;
|
||||
epoch = _epoch[sio_hw->cpuid];
|
||||
ctr = systick_hw->cvr;
|
||||
} while (epoch != _epoch);
|
||||
} while (epoch != _epoch[sio_hw->cpuid]);
|
||||
return epoch + (1LL << 24) - ctr;
|
||||
} else {
|
||||
#endif
|
||||
@@ -261,23 +295,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 +351,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 +365,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 +380,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 +401,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 +415,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 +464,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 +485,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 +564,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 +578,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 +617,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;
|
||||
@@ -499,8 +669,8 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
static void _SystickHandler() {
|
||||
rp2040._epoch += 1LL << 24;
|
||||
static void __no_inline_not_in_flash_func(_SystickHandler)() {
|
||||
rp2040._epoch[sio_hw->cpuid] += 1LL << 24;
|
||||
}
|
||||
PIO _pio;
|
||||
int _sm;
|
||||
|
||||
@@ -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 4
|
||||
#define ARDUINO_PICO_VERSION_STR "4.5.4"
|
||||
|
||||
@@ -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;
|
||||
|
||||
+11
-18
@@ -68,13 +68,10 @@ static PIOProgram *_getRxProgram(int bits) {
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// TODO - this works, but there must be a faster/better way...
|
||||
static int _parity(int bits, int data) {
|
||||
int p = 0;
|
||||
for (int b = 0; b < bits; b++) {
|
||||
p ^= (data & (1 << b)) ? 1 : 0;
|
||||
}
|
||||
return p;
|
||||
static int __not_in_flash_func(_parity)(int data) {
|
||||
data ^= data >> 4;
|
||||
data &= 0xf;
|
||||
return (0x6996 >> data) & 1;
|
||||
}
|
||||
|
||||
// We need to cache generated SerialPIOs so we can add data to them from
|
||||
@@ -98,20 +95,16 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() {
|
||||
}
|
||||
while (!pio_sm_is_rx_fifo_empty(_rxPIO, _rxSM)) {
|
||||
uint32_t decode = _rxPIO->rxf[_rxSM];
|
||||
decode >>= 33 - _rxBits;
|
||||
uint32_t val = 0;
|
||||
for (int b = 0; b < _bits + 1; b++) {
|
||||
val |= (decode & (1 << (b * 2))) ? 1 << b : 0;
|
||||
}
|
||||
uint32_t val = decode >> (32 - _rxBits - 1);
|
||||
if (_parity == UART_PARITY_EVEN) {
|
||||
int p = ::_parity(_bits, val);
|
||||
int p = ::_parity(val);
|
||||
int r = (val & (1 << _bits)) ? 1 : 0;
|
||||
if (p != r) {
|
||||
// TODO - parity error
|
||||
continue;
|
||||
}
|
||||
} else if (_parity == UART_PARITY_ODD) {
|
||||
int p = ::_parity(_bits, val);
|
||||
int p = ::_parity(val);
|
||||
int r = (val & (1 << _bits)) ? 1 : 0;
|
||||
if (p == r) {
|
||||
// TODO - parity error
|
||||
@@ -234,7 +227,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
|
||||
_writer = 0;
|
||||
_reader = 0;
|
||||
|
||||
_rxBits = 2 * (_bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1) - 1;
|
||||
_rxBits = _bits + (_parity != UART_PARITY_NONE ? 1 : 0);
|
||||
_rxPgm = _getRxProgram(_rxBits);
|
||||
int off;
|
||||
if (!_rxPgm->prepare(&_rxPIO, &_rxSM, &off, _rx, 1)) {
|
||||
@@ -249,7 +242,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
|
||||
pio_sm_clear_fifos(_rxPIO, _rxSM); // Remove any existing data
|
||||
|
||||
// Put phase divider into OSR w/o using add'l program memory
|
||||
pio_sm_put_blocking(_rxPIO, _rxSM, clock_get_hz(clk_sys) / (_baud * 2) - 7 /* insns in PIO halfbit loop */);
|
||||
pio_sm_put_blocking(_rxPIO, _rxSM, clock_get_hz(clk_sys) / (_baud * 2) - 3);
|
||||
pio_sm_exec(_rxPIO, _rxSM, pio_encode_pull(false, false));
|
||||
|
||||
// Join the TX FIFO to the RX one now that we don't need it
|
||||
@@ -378,10 +371,10 @@ size_t SerialPIO::write(uint8_t c) {
|
||||
if (_parity == UART_PARITY_NONE) {
|
||||
val |= 7 << _bits; // Set 2 stop bits, the HW will only transmit the required number
|
||||
} else if (_parity == UART_PARITY_EVEN) {
|
||||
val |= ::_parity(_bits, c) << _bits;
|
||||
val |= ::_parity(c) << _bits;
|
||||
val |= 7 << (_bits + 1);
|
||||
} else {
|
||||
val |= (1 ^ ::_parity(_bits, c)) << _bits;
|
||||
val |= (1 ^ ::_parity(c)) << _bits;
|
||||
val |= 7 << (_bits + 1);
|
||||
}
|
||||
val <<= 1; // Start bit = low
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+13
-1
@@ -51,9 +51,14 @@ void initVariant() { }
|
||||
|
||||
// Optional 2nd core setup and loop
|
||||
bool core1_separate_stack __attribute__((weak)) = false;
|
||||
bool core1_disable_systick __attribute__((weak)) = false;
|
||||
extern void setup1() __attribute__((weak));
|
||||
extern void loop1() __attribute__((weak));
|
||||
extern "C" void main1() {
|
||||
if (!core1_disable_systick) {
|
||||
// Don't install the SYSTICK exception handler. rp2040.getCycleCount will not work properly on core1
|
||||
rp2040.begin(1);
|
||||
}
|
||||
rp2040.fifo.registerCore();
|
||||
if (setup1) {
|
||||
setup1();
|
||||
@@ -128,7 +133,7 @@ extern "C" int main() {
|
||||
_REENT_INIT_PTR(_impure_ptr1);
|
||||
}
|
||||
|
||||
rp2040.begin();
|
||||
rp2040.begin(0);
|
||||
|
||||
initVariant();
|
||||
|
||||
@@ -239,3 +244,10 @@ void hexdump(const void* mem, uint32_t len, uint8_t cols) {
|
||||
}
|
||||
|
||||
const String emptyString = "";
|
||||
|
||||
extern "C" void __attribute__((__noreturn__)) __wrap___stack_chk_fail() {
|
||||
while (true) {
|
||||
panic("*** stack smashing detected ***: terminated\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,20 +73,25 @@ static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_t
|
||||
; IN pin 0 and JMP pin are both mapped to the GPIO used as UART RX.
|
||||
|
||||
start:
|
||||
set x, 18 ; Preload bit counter...we'll shift in the start bit and stop bit, and each bit will be double-recorded (to be fixed by RP2040 code)
|
||||
set x, 18 ; Preload bit counter...overwritten by the app
|
||||
wait 0 pin 0 ; Stall until start bit is asserted
|
||||
|
||||
bitloop:
|
||||
; Delay until 1/2 way into the bit time
|
||||
mov y, osr
|
||||
wait_half:
|
||||
jmp y-- wait_half
|
||||
wait_mid_start:
|
||||
jmp y-- wait_mid_start
|
||||
|
||||
; Read in the bit
|
||||
in pins, 1 ; Shift data bit into ISR
|
||||
jmp x-- bitloop ; Loop all bits
|
||||
|
||||
push ; Stuff it and wait for next start
|
||||
bitloop:
|
||||
mov y, osr
|
||||
bitloop1:
|
||||
jmp y-- bitloop1
|
||||
mov y, osr
|
||||
bitloop2:
|
||||
jmp y-- bitloop2
|
||||
|
||||
in pins, 1
|
||||
jmp x-- bitloop
|
||||
push
|
||||
|
||||
% c-sdk {
|
||||
static inline void pio_rx_program_init(PIO pio, uint sm, uint offset, uint pin) {
|
||||
|
||||
@@ -71,7 +71,7 @@ static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_t
|
||||
// ------ //
|
||||
|
||||
#define pio_rx_wrap_target 0
|
||||
#define pio_rx_wrap 6
|
||||
#define pio_rx_wrap 10
|
||||
#define pio_rx_pio_version 0
|
||||
|
||||
static const uint16_t pio_rx_program_instructions[] = {
|
||||
@@ -80,16 +80,20 @@ static const uint16_t pio_rx_program_instructions[] = {
|
||||
0x2020, // 1: wait 0 pin, 0
|
||||
0xa047, // 2: mov y, osr
|
||||
0x0083, // 3: jmp y--, 3
|
||||
0x4001, // 4: in pins, 1
|
||||
0x0042, // 5: jmp x--, 2
|
||||
0x8020, // 6: push block
|
||||
0xa047, // 4: mov y, osr
|
||||
0x0085, // 5: jmp y--, 5
|
||||
0xa047, // 6: mov y, osr
|
||||
0x0087, // 7: jmp y--, 7
|
||||
0x4001, // 8: in pins, 1
|
||||
0x0044, // 9: jmp x--, 4
|
||||
0x8020, // 10: push block
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
static const struct pio_program pio_rx_program = {
|
||||
.instructions = pio_rx_program_instructions,
|
||||
.length = 7,
|
||||
.length = 11,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
#define tone2_pio_version 0
|
||||
|
||||
static const uint16_t tone2_program_instructions[] = {
|
||||
// .wrap_target
|
||||
// .wrap_target
|
||||
0x8080, // 0: pull noblock
|
||||
0xb827, // 1: mov x, osr side 1
|
||||
0xa047, // 2: mov y, osr
|
||||
0x0083, // 3: jmp y--, 3
|
||||
0xb047, // 4: mov y, osr side 0
|
||||
0x0085, // 5: jmp y--, 5
|
||||
// .wrap
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
@@ -32,7 +32,7 @@ static const struct pio_program tone2_program = {
|
||||
.instructions = tone2_program_instructions,
|
||||
.length = 6,
|
||||
.origin = -1,
|
||||
.pio_version = tone2_pio_version,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
|
||||
+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.4'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'4.5.0'
|
||||
release = u'4.5.4'
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
@@ -16,6 +16,25 @@ not necessarily simultaneously!).
|
||||
See the ``Multicore.ino`` example in the ``rp2040`` example directory for a
|
||||
quick introduction.
|
||||
|
||||
Core 1 Operation
|
||||
----------------
|
||||
|
||||
By default, core1 (the second core) has no non-user written code running on it.
|
||||
No interrupts, exceptions, or other background processing is done (but the core
|
||||
is still subject to hardware stalls due to on-die memory resource conflicts).
|
||||
When flash erase or write operations (i.e. ``LittleFS`` or ``EEPROM``) are called
|
||||
from core0, core1 **will** be paused.
|
||||
|
||||
If ``rp2040.getCycleCount`` is needed to operate on the second core, then a
|
||||
periodic (once ever 16M clock cycles) ``SYSTICK`` exception will happen behind
|
||||
the scenes. For extremely time-critical operations this may not be desirable
|
||||
and can be disabled by defining a new ``bool`` variable to ``true`` anywhere
|
||||
in your sketch:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
bool core1_disable_systick = true;
|
||||
|
||||
Stack Sizes
|
||||
-----------
|
||||
|
||||
@@ -67,6 +86,9 @@ void rp2040.restartCore1()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Hard resets Core1 from Core 0 and restarts its operation from ``setup1()``.
|
||||
This can cause unpredictable behavior because globals and the heap
|
||||
are shared between cores and not re-initialized with this call. Use with
|
||||
extreme caution.
|
||||
|
||||
Communicating Between Cores
|
||||
---------------------------
|
||||
|
||||
@@ -67,3 +67,5 @@
|
||||
-Wl,--wrap=cyw43_tcpip_link_status
|
||||
-Wl,--wrap=cyw43_cb_tcpip_init
|
||||
-Wl,--wrap=cyw43_cb_tcpip_deinit
|
||||
|
||||
-Wl,--wrap=__stack_chk_fail
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1
|
||||
-DTARGET_RP2350
|
||||
-DCYW43_LWIP=1
|
||||
-DCYW43_PIO_CLOCK_DIV_DYNAMIC=1
|
||||
-DCFG_TUSB_MCU=OPT_MCU_RP2040
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1
|
||||
-DTARGET_RP2350
|
||||
-DCYW43_LWIP=1
|
||||
-DCYW43_PIO_CLOCK_DIV_DYNAMIC=1
|
||||
-DCFG_TUSB_MCU=OPT_MCU_RP2040
|
||||
|
||||
@@ -49,12 +49,7 @@ bool ADCInput::setBuffers(size_t buffers, size_t bufferWords) {
|
||||
|
||||
int ADCInput::_mask(pin_size_t p) {
|
||||
switch (p) {
|
||||
#if !defined(PICO_RP2350B)
|
||||
case 26: return 1;
|
||||
case 27: return 2;
|
||||
case 28: return 4;
|
||||
case 29: return 8;
|
||||
#else // Starts at 40 and there are 8 of them
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
case 40: return 1;
|
||||
case 41: return 2;
|
||||
case 42: return 4;
|
||||
@@ -63,6 +58,11 @@ int ADCInput::_mask(pin_size_t p) {
|
||||
case 45: return 32;
|
||||
case 46: return 64;
|
||||
case 47: return 128;
|
||||
#else
|
||||
case 26: return 1;
|
||||
case 27: return 2;
|
||||
case 28: return 4;
|
||||
case 29: return 8;
|
||||
#endif
|
||||
default: return 0;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Submodule libraries/Adafruit_TinyUSB_Arduino updated: c92b7fde16...6b772c0ac4
@@ -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,82 @@ 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
|
||||
#define pio_tdm_inout_pio_version 0
|
||||
|
||||
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
|
||||
#define pio_tdm_inout_swap_pio_version 0
|
||||
|
||||
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 +566,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);
|
||||
@@ -555,3 +661,4 @@ static inline void pio_i2s_inout_program_init(PIO pio, uint sm, uint offset, uin
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Submodule libraries/LittleFS/lib/littlefs updated: 0494ce7169...8ed63b27be
@@ -31,7 +31,7 @@ static inline void pdm_pio_program_init(PIO pio, uint sm, uint offset, uint clkP
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, dataPin, 1, false);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, clkPin, 1, true);
|
||||
pio_sm_set_pins_with_mask(pio, sm, 0, (1u << clkPin) );
|
||||
//pio_gpio_init(pio, dataPin);
|
||||
pio_gpio_init(pio, dataPin);
|
||||
pio_gpio_init(pio, clkPin);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
|
||||
@@ -18,8 +18,8 @@ static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 16000, 1}, {11025, 116
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 16625, 1}, {11025, 24127, 2}, {16000, 16625, 2}, {22050, 24127, 4}, {32000, 16625, 4}, {44100, 24127, 8}, {48000, 16625, 6}, {88200, 24127, 16}, {96000, 16625, 12}, {176400, 47500, 63}, {192000, 16625, 24}};
|
||||
#elif F_CPU == 150000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 18750, 1}, {11025, 27211, 2}, {16000, 9375, 1}, {22050, 47619, 7}, {32000, 9375, 2}, {44100, 37415, 11}, {48000, 3125, 1}, {88200, 42517, 25}, {96000, 3125, 2}, {176400, 42517, 50}, {192000, 3125, 4}};
|
||||
#elif F_CPU == 175000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 21875, 1}, {11025, 15873, 1}, {16000, 21875, 2}, {22050, 15873, 2}, {32000, 21875, 4}, {44100, 15873, 4}, {48000, 21875, 6}, {88200, 15873, 8}, {96000, 21875, 12}, {176400, 62500, 63}, {192000, 21875, 24}};
|
||||
#elif F_CPU == 176000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 22000, 1}, {11025, 63855, 4}, {16000, 11000, 1}, {22050, 55873, 7}, {32000, 5500, 1}, {44100, 55873, 14}, {48000, 11000, 3}, {88200, 55873, 28}, {96000, 5500, 3}, {176400, 55873, 56}, {192000, 2750, 3}};
|
||||
#elif F_CPU == 200000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 25000, 1}, {11025, 54422, 3}, {16000, 12500, 1}, {22050, 63492, 7}, {32000, 6250, 1}, {44100, 31746, 7}, {48000, 12500, 3}, {88200, 15873, 7}, {96000, 6250, 3}, {176400, 53288, 47}, {192000, 3125, 3}};
|
||||
#elif F_CPU == 225000000
|
||||
@@ -28,8 +28,8 @@ static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 28125, 1}, {11025, 204
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 30000, 1}, {11025, 65306, 3}, {16000, 15000, 1}, {22050, 32653, 3}, {32000, 7500, 1}, {44100, 59864, 11}, {48000, 5000, 1}, {88200, 62585, 23}, {96000, 2500, 1}, {176400, 62585, 46}, {192000, 1250, 1}};
|
||||
#elif F_CPU == 250000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 31250, 1}, {11025, 45351, 2}, {16000, 15625, 1}, {22050, 56689, 5}, {32000, 15625, 2}, {44100, 62358, 11}, {48000, 15625, 3}, {88200, 42517, 15}, {96000, 15625, 6}, {176400, 42517, 30}, {192000, 15625, 12}};
|
||||
#elif F_CPU == 275000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 34375, 1}, {11025, 49887, 2}, {16000, 34375, 2}, {22050, 37415, 3}, {32000, 34375, 4}, {44100, 37415, 6}, {48000, 34375, 6}, {88200, 37415, 12}, {96000, 34375, 12}, {176400, 35856, 23}, {192000, 34375, 24}};
|
||||
#elif F_CPU == 276000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 34500, 1}, {11025, 25034, 1}, {16000, 17250, 1}, {22050, 12517, 1}, {32000, 8625, 1}, {44100, 12517, 2}, {48000, 5750, 1}, {88200, 12517, 4}, {96000, 2875, 1}, {176400, 12517, 8}, {192000, 2875, 2}};
|
||||
#elif F_CPU == 300000000
|
||||
static const PWMPacerPrecalc __PWMAudio_pacer[] = {{8000, 37500, 1}, {11025, 27211, 1}, {16000, 18750, 1}, {22050, 27211, 2}, {32000, 9375, 1}, {44100, 47619, 7}, {48000, 6250, 1}, {88200, 37415, 11}, {96000, 3125, 1}, {176400, 42517, 25}, {192000, 3125, 2}};
|
||||
#else
|
||||
|
||||
@@ -263,8 +263,8 @@ void SPIClassRP2040::abortAsync() {
|
||||
|
||||
|
||||
bool SPIClassRP2040::setRX(pin_size_t pin) {
|
||||
#ifdef PICO_RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({0, 4, 16, 20, 32, 26}) /* SPI0 */,
|
||||
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
|
||||
constexpr uint64_t valid[2] = { __bitset({0, 4, 16, 20, 32, 36}) /* SPI0 */,
|
||||
__bitset({8, 12, 24, 28, 40, 44}) /* SPI1 */
|
||||
};
|
||||
#else
|
||||
@@ -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);
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified May 2025 by Sven Bruns (Lorandil on GitHub) to support user defined buffer size (inspired by ESP32 code)
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
@@ -46,10 +48,14 @@ TwoWire::TwoWire(i2c_inst_t *i2c, pin_size_t sda, pin_size_t scl) {
|
||||
_running = false;
|
||||
_txBegun = false;
|
||||
_buffLen = 0;
|
||||
|
||||
// allocate buffer memory early, so we don't fragment the heap later
|
||||
_buffSize = WIRE_BUFFER_SIZE;
|
||||
_buff = (uint8_t *)malloc(_buffSize);
|
||||
}
|
||||
|
||||
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 +82,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 */
|
||||
};
|
||||
@@ -158,6 +164,16 @@ void TwoWire::begin(uint8_t addr) {
|
||||
// ERROR
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate buffer if necessary
|
||||
if (!_buff) {
|
||||
_buff = (uint8_t *)malloc(_buffSize);
|
||||
if (!_buff) {
|
||||
// ERROR
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_slave = true;
|
||||
i2c_init(_i2c, _clkHz);
|
||||
i2c_set_slave_mode(_i2c, true, addr);
|
||||
@@ -192,7 +208,7 @@ void TwoWire::onIRQ() {
|
||||
// First, pull off any data available
|
||||
if (irqstat & (1 << 2)) {
|
||||
// RX_FULL
|
||||
if (_buffLen < (int)sizeof(_buff)) {
|
||||
if (_buffLen < int(_buffSize)) {
|
||||
_buff[_buffLen++] = _i2c->hw->data_cmd & 0xff;
|
||||
} else {
|
||||
_i2c->hw->data_cmd;
|
||||
@@ -271,7 +287,7 @@ void TwoWire::beginTransmission(uint8_t addr) {
|
||||
}
|
||||
|
||||
size_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) {
|
||||
if (!_running || _txBegun || !quantity || (quantity > sizeof(_buff))) {
|
||||
if (!_running || _txBegun || !quantity || (quantity > _buffSize)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -448,7 +464,7 @@ size_t TwoWire::write(uint8_t ucData) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!_txBegun || (_buffLen == sizeof(_buff))) {
|
||||
if (!_txBegun || (_buffLen == int(_buffSize))) {
|
||||
return 0;
|
||||
}
|
||||
_buff[_buffLen++] = ucData;
|
||||
@@ -745,6 +761,20 @@ void TwoWire::clearTimeoutFlag() {
|
||||
_timeoutFlag = false;
|
||||
}
|
||||
|
||||
size_t TwoWire::setBufferSize(size_t bSize) {
|
||||
if (_running) {
|
||||
// ERROR - transmission already running. Report back current buffer size
|
||||
return _buffSize;
|
||||
}
|
||||
// only free the buffer, if it already exists and the new size differs from the current one
|
||||
if (_buff && (bSize != _buffSize)) {
|
||||
free(_buff);
|
||||
_buff = nullptr;
|
||||
}
|
||||
_buffSize = max(WIRE_BUFFER_SIZE_MIN, int(bSize)); // enforce minimum buffer size
|
||||
return _buffSize;
|
||||
}
|
||||
|
||||
#ifndef __WIRE0_DEVICE
|
||||
#define __WIRE0_DEVICE i2c0
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified May 2025 by Sven Bruns (Lorandil on GitHub) to support user defined buffer size (inspired by ESP32 code)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -30,8 +32,14 @@
|
||||
// WIRE_HAS_END means Wire has end()
|
||||
#define WIRE_HAS_END 1
|
||||
|
||||
// WIRE_HAS_BUFFER_SIZE means Wire has setBufferSize()
|
||||
#define WIRE_HAS_BUFFER_SIZE 1
|
||||
|
||||
#ifndef WIRE_BUFFER_SIZE
|
||||
#define WIRE_BUFFER_SIZE 256
|
||||
#define WIRE_BUFFER_SIZE 256 // default size, if none is set using Wire::setBuffersize(size_t)
|
||||
#endif
|
||||
#ifndef WIRE_BUFFER_SIZE_MIN
|
||||
#define WIRE_BUFFER_SIZE_MIN 32 // minimum size for safe operation
|
||||
#endif
|
||||
|
||||
class TwoWire : public HardwareI2C {
|
||||
@@ -97,6 +105,8 @@ public:
|
||||
bool getTimeoutFlag(void);
|
||||
void clearTimeoutFlag(void);
|
||||
|
||||
size_t setBufferSize(size_t bSize); // set buffer size (call prior to 'begin()')
|
||||
|
||||
// IRQ callback
|
||||
void onIRQ();
|
||||
|
||||
@@ -115,7 +125,9 @@ private:
|
||||
bool _reset_with_timeout;
|
||||
void _handleTimeout(bool reset);
|
||||
|
||||
uint8_t _buff[WIRE_BUFFER_SIZE];
|
||||
uint8_t *_buff; // pointer to i2c buffer
|
||||
size_t _buffSize; // current buffer size
|
||||
|
||||
int _buffLen;
|
||||
int _buffOff;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#define wiznet_pio_spi_write_read_wrap_target 0
|
||||
#define wiznet_pio_spi_write_read_wrap 8
|
||||
#define wiznet_pio_spi_write_read_pio_version 0
|
||||
|
||||
#define wiznet_pio_spi_write_read_offset_write_bits 0u
|
||||
#define wiznet_pio_spi_write_read_offset_write_end 3u
|
||||
@@ -38,6 +39,10 @@ static const struct pio_program wiznet_pio_spi_write_read_program = {
|
||||
.instructions = wiznet_pio_spi_write_read_program_instructions,
|
||||
.length = 9,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config wiznet_pio_spi_write_read_program_get_default_config(uint offset) {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "framework-arduinopico",
|
||||
"version": "1.40500.0",
|
||||
"version": "1.40504.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"
|
||||
},
|
||||
|
||||
+2
-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.4
|
||||
|
||||
# Required discoveries and monitors
|
||||
# ---------------------------------
|
||||
@@ -203,6 +203,7 @@ tools.uf2conv-network.cmd={runtime.platform.path}/system/python3/python3
|
||||
tools.uf2conv-network.upload.protocol=uf2
|
||||
tools.uf2conv-network.upload.params.verbose=
|
||||
tools.uf2conv-network.upload.params.quiet=
|
||||
tools.uf2conv-network.upload.field.password=Password
|
||||
tools.uf2conv-network.upload.pattern="{cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{upload.port.address}" -p "{upload.port.properties.port}" "--auth={upload.field.password}" -f "{build.path}/{build.project_name}.bin"
|
||||
|
||||
#tools.picotool.cmd={runtime.tools.pqt-picotool.path}
|
||||
|
||||
@@ -30,6 +30,15 @@ as necessary to add any add'l fields or menus required. Used because the
|
||||
`boards.txt` file is very repetitive and it's safer to generate with code
|
||||
than by hand.
|
||||
|
||||
## makepacer.cpp
|
||||
Generates ``libraries/PWMAudio/src/PWMAudioPrecalc.h` which contains the
|
||||
precalculated DMA pacer settings for common audio sample rates and CPU
|
||||
frequencies. Makes setting the frequency for PWMAudio instantaneous.
|
||||
|
||||
## makepio.py
|
||||
Rebuilds all the ``*.pio`` files in the core and libraries using the
|
||||
currently installed pioasm. Use when a new PIOASM is available.
|
||||
|
||||
## makever.py
|
||||
Updates the version info prior to a release in platform.txt, package.json,
|
||||
and the version header. Run from root of the repo.
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
+21
-12
@@ -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]))
|
||||
|
||||
@@ -112,7 +112,7 @@ def BuildStackProtect(name):
|
||||
print("%s.menu.stackprotect.Disabled=Disabled" % (name))
|
||||
print("%s.menu.stackprotect.Disabled.build.flags.stackprotect=" % (name))
|
||||
print("%s.menu.stackprotect.Enabled=Enabled" % (name))
|
||||
print("%s.menu.stackprotect.Enabled.build.flags.stackprotect=-fstack-protector" % (name))
|
||||
print("%s.menu.stackprotect.Enabled.build.flags.stackprotect=-fstack-protector-all" % (name))
|
||||
|
||||
def BuildExceptions(name):
|
||||
print("%s.menu.exceptions.Disabled=Disabled" % (name))
|
||||
@@ -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)
|
||||
@@ -359,7 +364,7 @@ def MakeBoard(name, chip, vendor_name, product_name, vid, pid, pwr, boarddefine,
|
||||
# Optional, user needs to solder themselves
|
||||
BuildPSRAM(name)
|
||||
BuildPSRAMFreq(name)
|
||||
elif name == "adafruit_feather_rp2350_hstx":
|
||||
elif (name == "adafruit_feather_rp2350_hstx") or (name == "adafruit_metro_rp2350"):
|
||||
# Optional, user needs to solder themselves
|
||||
BuildPSRAM(name)
|
||||
else:
|
||||
@@ -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")
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ int main(int argc, char **argv) {
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
int M = 1000000;
|
||||
int fsys[] = {50*M, 100*M, 120*M, 125*M, 128*M, 133*M, 150*M, 175*M, 200*M, 225*M, 240*M, 250*M, 275*M, 300*M};
|
||||
int fsys[] = {50*M, 100*M, 120*M, 125*M, 128*M, 133*M, 150*M, 176*M, 200*M, 225*M, 240*M, 250*M, 276*M, 300*M};
|
||||
int freq[] = {8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000};
|
||||
FILE *f = fopen("../libraries/PWMAudio/src/PWMAudioPrecalc.h", "w");
|
||||
fprintf(f, "// Generated by tools/makepacer.cpp, do not edit\n");
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
PIOASM="system/pioasm/pioasm"
|
||||
|
||||
def recursivepioasm(path):
|
||||
for root, dirs, files in os.walk(path):
|
||||
for f in files:
|
||||
if f.endswith(".pio"):
|
||||
subprocess.run([PIOASM, "-o", "c-sdk", os.path.join(root, f), os.path.join(root, f) + ".h"])
|
||||
print(os.path.join(root, f))
|
||||
|
||||
|
||||
def main():
|
||||
recursivepioasm("cores")
|
||||
recursivepioasm("libraries")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -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)
|
||||
|
||||
@@ -62,8 +64,13 @@
|
||||
#define PIN_SPI0_SS (21u)
|
||||
|
||||
// Wire
|
||||
#define PIN_WIRE0_SDA (16u)
|
||||
#define PIN_WIRE0_SCL (17u)
|
||||
#define __WIRE0_DEVICE i2c0
|
||||
#define PIN_WIRE0_SDA (16u)
|
||||
#define PIN_WIRE0_SCL (17u)
|
||||
|
||||
#define __WIRE1_DEVICE i2c1
|
||||
#define PIN_WIRE1_SDA (31u) // Not used.
|
||||
#define PIN_WIRE1_SCL (31u) // Not used.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1 +1,40 @@
|
||||
#include "../generic/pins_arduino.h"
|
||||
#pragma once
|
||||
|
||||
// Pin definitions taken from:
|
||||
// https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
|
||||
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED (19u)
|
||||
|
||||
// Serial
|
||||
#define PIN_SERIAL1_TX (0u)
|
||||
#define PIN_SERIAL1_RX (1u)
|
||||
|
||||
#define PIN_SERIAL2_TX (8u)
|
||||
#define PIN_SERIAL2_RX (9u)
|
||||
|
||||
// SPI
|
||||
// Default SPI0 pins are used internally and are unavailable on this board. To use SPI0 other peripherals must be sacrificed.
|
||||
#define PIN_SPI0_MISO (2u) // 16u is connected to the buck-boost converted.
|
||||
#define PIN_SPI0_MOSI (3u) // 19u is connected to USERLED, defined as PIN_LED.
|
||||
#define PIN_SPI0_SCK (4u) // 18u is connected to a voltage divider on VBUS.
|
||||
#define PIN_SPI0_SS (5u) // 17u doesn't even show up in the schematics.
|
||||
|
||||
#define PIN_SPI1_MISO (12u)
|
||||
#define PIN_SPI1_MOSI (15u)
|
||||
#define PIN_SPI1_SCK (14u)
|
||||
#define PIN_SPI1_SS (13u)
|
||||
|
||||
// Wire
|
||||
#define PIN_WIRE0_SDA (4u)
|
||||
#define PIN_WIRE0_SCL (5u)
|
||||
|
||||
#define PIN_WIRE1_SDA (26u)
|
||||
#define PIN_WIRE1_SCL (27u)
|
||||
|
||||
#define SERIAL_HOWMANY (3u)
|
||||
#define SPI_HOWMANY (2u)
|
||||
#define WIRE_HOWMANY (2u)
|
||||
|
||||
#include "../generic/common.h"
|
||||
|
||||
Reference in New Issue
Block a user