Compare commits
@@ -20,7 +20,7 @@ jobs:
|
||||
- name: Run codespell
|
||||
uses: codespell-project/actions-codespell@master
|
||||
with:
|
||||
skip: ./pico-extras,./ArduinoCore-API,./libraries/SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api
|
||||
skip: ./pico-extras,./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api
|
||||
ignore_words_list: ser,DOUT
|
||||
|
||||
# Consistent style
|
||||
@@ -36,7 +36,9 @@ jobs:
|
||||
./tests/ci/pkgrefs_test.sh
|
||||
- name: Check boards.txt was not edited after makeboards.py
|
||||
run: |
|
||||
./tools/makeboards.py > boards.txt
|
||||
./tools/makeboards.py
|
||||
# If anything changed, GIT should return an error and fail the test
|
||||
git diff --exit-code
|
||||
- name: Run astyle on all code/examples
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -44,10 +46,10 @@ jobs:
|
||||
./tests/restyle.sh
|
||||
# If anything changed, GIT should return an error and fail the test
|
||||
git diff --exit-code
|
||||
- name: Check Arduino API copy is clean
|
||||
run: |
|
||||
git submodule update --init ./ArduinoCore-API
|
||||
diff -r ./cores/rp2040/api ./ArduinoCore-API/api
|
||||
# - name: Check Arduino API copy is clean
|
||||
# run: |
|
||||
# git submodule update --init ./ArduinoCore-API
|
||||
# diff -r ./cores/rp2040/api ./ArduinoCore-API/api
|
||||
|
||||
# Build all examples on linux (core and Arduino IDE)
|
||||
build-linux:
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
path = libraries/LittleFS/lib/littlefs
|
||||
url = https://github.com/littlefs-project/littlefs.git
|
||||
[submodule "libraries/SdFat"]
|
||||
path = libraries/SdFat
|
||||
path = libraries/ESP8266SdFat
|
||||
url = https://github.com/earlephilhower/ESP8266SdFat.git
|
||||
[submodule "pico-extras"]
|
||||
path = pico-extras
|
||||
|
||||
+1
-1
Submodule ArduinoCore-API updated: 9da5373517...ff01bb620e
@@ -13,11 +13,28 @@ See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for m
|
||||
* Raspberry Pi Pico
|
||||
* Adafruit Feather RP2040
|
||||
* Adafruit ItsyBitsy RP2040
|
||||
* Adafruit KB2040
|
||||
* Adafruit Macropad RP2040
|
||||
* Adafruit QTPy RP2040
|
||||
* Adafruit STEMMA Friend RP2040
|
||||
* Adafruit Trinkey RP2040 QT
|
||||
* Arduino Nano RP2040 Connect
|
||||
* Cytron Maker Pi RP2040
|
||||
* Cytron Maker Nano RP2040
|
||||
* DeRuiLab FlyBoard2040 Core
|
||||
* DFRobot Beetle RP2040
|
||||
* Invector Labs Challenger RP2040 WiFi
|
||||
* Invector Labs Challenger NB RP2040 WiFi
|
||||
* Invector Labs Challenger RP2040 LTE
|
||||
* Invector Labs Challenger RP2040 LoRa
|
||||
* Invector Labs RPICO32
|
||||
* Melopero Shake RP2040
|
||||
* Seeed XIAO RP2040
|
||||
* Solder Party RP2040 Stamp
|
||||
* SparkFun ProMicro RP2040
|
||||
* SparkFun Thing Plus RP2040
|
||||
* uPesy RP2040 DevKit
|
||||
* WIZnet W5100S-EVB-Pico
|
||||
* Generic (configurable flash, I/O pins)
|
||||
|
||||
# Installing via Arduino Boards Manager
|
||||
@@ -68,7 +85,7 @@ If you follow Les' step-by-step you will also have a fully functional `CMake`-ba
|
||||
To upload your first sketch, you will need to hold the BOOTSEL button down while plugging in the Pico to your computer.
|
||||
Then hit the upload button and the sketch should be transferred and start to run.
|
||||
|
||||
After the first upload, this should not be necessary as the `arduino-pico` core has auto-reset support.
|
||||
After the first upload, this should not be necessary as the `arduino-pico` core has auto-reset support.
|
||||
Select the appropriate serial port shown in the Arduino Tools->Port->Serial Port menu once (this setting will stick and does not need to be
|
||||
touched for multiple uploads). This selection allows the auto-reset tool to identify the proper device to reset.
|
||||
Them hit the upload button and your sketch should upload and run.
|
||||
@@ -80,8 +97,8 @@ follow the initial procedure of holding the BOOTSEL button down while plugging i
|
||||
The onboard flash filesystem for the Pico, LittleFS, lets you upload a filesystem image from the sketch directory for your sketch to use. Download the needed plugin from
|
||||
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/releases
|
||||
|
||||
To install, follow the directions in
|
||||
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
|
||||
To install, follow the directions in
|
||||
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
|
||||
|
||||
For detailed usage information, please check the ESP8266 repo documentation (ignore SPIFFS related notes) available at
|
||||
* https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html
|
||||
@@ -101,8 +118,25 @@ The first line creates a file with the USB vendor and ID of the Picoprobe and te
|
||||
|
||||
Once Picoprobe permissions are set up properly, then select the board "Raspberry Pi Pico (Picoprobe)" in the Tools menu and upload as normal.
|
||||
|
||||
# Debugging with Picoprobe, OpenOCD, and GDB
|
||||
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation.
|
||||
# Uploading Sketches with pico-debug
|
||||
[pico-debug](https://github.com/majbthrd/pico-debug/) differs from Picoprobe in that pico-debug is a virtual debug pod that runs side-by-side on the same RP2040 that you run your code on; so, you only need one RP2040 board instead of two. pico-debug also differs from Picoprobe in that pico-debug is standards-based; it uses the CMSIS-DAP protocol, which means even software not specially written for the Raspberry Pi Pico can support it. pico-debug uses OpenOCD to handle your sketch uploads, and debugging can be accomplished with CMSIS-DAP capable debuggers including GDB.
|
||||
|
||||
Under Windows and macOS, any user should be able to access pico-debug automatically, but under Linux `udev` must be told about the device and to allow normal users access.
|
||||
|
||||
To set up user-level access to all CMSIS-DAP adapters on Ubuntu (and other OSes which use `udev`):
|
||||
````
|
||||
echo 'ATTRS{product}=="*CMSIS-DAP*", MODE="664", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-CMSIS-DAP.rules
|
||||
sudo udevadm control --reload
|
||||
````
|
||||
|
||||
The first line creates a file that recognizes all CMSIS-DAP adapters and tells UDEV to give users full access to it. The second causes `udev` to load this new rule. Note that you will need to unplug and re-plug in your device the first time you create this file, to allow udev to make the device node properly.
|
||||
|
||||
Once CMSIS-DAP permissions are set up properly, then select the board "Raspberry Pi Pico (pico-debug)" in the Tools menu.
|
||||
|
||||
When first connecting the USB port to your PC, you must copy [pico-debug-gimmecache.uf2](https://github.com/majbthrd/pico-debug/releases/) to the Pi Pico to load pico-debug into RAM; after this, upload as normal.
|
||||
|
||||
# Debugging with Picoprobe/pico-debug, OpenOCD, and GDB
|
||||
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation. For [pico-debug](https://github.com/majbthrd/pico-debug/), replace the raspberrypi-swd and picoprobe example OpenOCD arguments of "-f interface/raspberrypi-swd.cfg -f target/rp2040.cfg" or "-f interface/picoprobe.cfg -f target/rp2040.cfg" respectively in the Pico Getting Started manual with "-f board/pico-debug.cfg".
|
||||
|
||||
# Features
|
||||
* Adafruit TinyUSB Arduino (USB mouse, keyboard, flash drive, generic HID, CDC Serial, MIDI, WebUSB, others)
|
||||
@@ -112,12 +146,13 @@ The installed tools include a version of OpenOCD (in the pqt-openocd directory)
|
||||
* Overclocking and underclocking from the menus
|
||||
* digitalWrite/Read, shiftIn/Out, tone, analogWrite(PWM)/Read, temperature
|
||||
* Peripherals: SPI master, Wire(I2C) master/slave, dual UART, emulated EEPROM, I2S audio output, Servo
|
||||
* printf (i.e. debug) output over USB serial
|
||||
* printf (i.e. debug) output over USB serial
|
||||
|
||||
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
|
||||
* Servos
|
||||
* Tones
|
||||
* I2S Output
|
||||
* Software UARTs (Serial ports)
|
||||
|
||||
# Tutorials from Across the Web
|
||||
Here are some links to coverage and additional tutorials for using `arduino-pico`
|
||||
|
||||
-315
@@ -1,315 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "hardware/regs/m0plus.h"
|
||||
#include "hardware/platform_defs.h"
|
||||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/sio.h"
|
||||
#include "pico/binary_info/defs.h"
|
||||
|
||||
#ifdef NDEBUG
|
||||
#ifndef COLLAPSE_IRQS
|
||||
#define COLLAPSE_IRQS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .vectors, "ax"
|
||||
.align 2
|
||||
|
||||
.global __vectors
|
||||
__vectors:
|
||||
.word __StackTop
|
||||
.word _reset_handler
|
||||
.word isr_nmi
|
||||
.word isr_hardfault
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_svcall
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_invalid // Reserved, should never fire
|
||||
.word isr_pendsv
|
||||
.word isr_systick
|
||||
.word isr_irq0
|
||||
.word isr_irq1
|
||||
.word isr_irq2
|
||||
.word isr_irq3
|
||||
.word isr_irq4
|
||||
.word isr_irq5
|
||||
.word isr_irq6
|
||||
.word isr_irq7
|
||||
.word isr_irq8
|
||||
.word isr_irq9
|
||||
.word isr_irq10
|
||||
.word isr_irq11
|
||||
.word isr_irq12
|
||||
.word isr_irq13
|
||||
.word isr_irq14
|
||||
.word isr_irq15
|
||||
.word isr_irq16
|
||||
.word isr_irq17
|
||||
.word isr_irq18
|
||||
.word isr_irq19
|
||||
.word isr_irq20
|
||||
.word isr_irq21
|
||||
.word isr_irq22
|
||||
.word isr_irq23
|
||||
.word isr_irq24
|
||||
.word isr_irq25
|
||||
.word isr_irq26
|
||||
.word isr_irq27
|
||||
.word isr_irq28
|
||||
.word isr_irq29
|
||||
.word isr_irq30
|
||||
.word isr_irq31
|
||||
|
||||
// Declare a weak symbol for each ISR.
|
||||
// By default, they will fall through to the undefined IRQ handler below (breakpoint),
|
||||
// but can be overridden by C functions with correct name.
|
||||
|
||||
.macro decl_isr_bkpt name
|
||||
.weak \name
|
||||
.type \name,%function
|
||||
.thumb_func
|
||||
\name:
|
||||
bkpt #0
|
||||
.endm
|
||||
|
||||
// these are separated out for clarity
|
||||
decl_isr_bkpt isr_invalid
|
||||
decl_isr_bkpt isr_nmi
|
||||
decl_isr_bkpt isr_hardfault
|
||||
decl_isr_bkpt isr_svcall
|
||||
decl_isr_bkpt isr_pendsv
|
||||
decl_isr_bkpt isr_systick
|
||||
|
||||
.macro decl_isr name
|
||||
.weak \name
|
||||
.type \name,%function
|
||||
.thumb_func
|
||||
\name:
|
||||
.endm
|
||||
|
||||
decl_isr isr_irq0
|
||||
decl_isr isr_irq1
|
||||
decl_isr isr_irq2
|
||||
decl_isr isr_irq3
|
||||
decl_isr isr_irq4
|
||||
decl_isr isr_irq5
|
||||
decl_isr isr_irq6
|
||||
decl_isr isr_irq7
|
||||
decl_isr isr_irq8
|
||||
decl_isr isr_irq9
|
||||
decl_isr isr_irq10
|
||||
decl_isr isr_irq11
|
||||
decl_isr isr_irq12
|
||||
decl_isr isr_irq13
|
||||
decl_isr isr_irq14
|
||||
decl_isr isr_irq15
|
||||
decl_isr isr_irq16
|
||||
decl_isr isr_irq17
|
||||
decl_isr isr_irq18
|
||||
decl_isr isr_irq19
|
||||
decl_isr isr_irq20
|
||||
decl_isr isr_irq21
|
||||
decl_isr isr_irq22
|
||||
decl_isr isr_irq23
|
||||
decl_isr isr_irq24
|
||||
decl_isr isr_irq25
|
||||
decl_isr isr_irq26
|
||||
decl_isr isr_irq27
|
||||
decl_isr isr_irq28
|
||||
decl_isr isr_irq29
|
||||
decl_isr isr_irq30
|
||||
decl_isr isr_irq31
|
||||
|
||||
// All unhandled USER IRQs fall through to here
|
||||
.global __unhandled_user_irq
|
||||
.thumb_func
|
||||
__unhandled_user_irq:
|
||||
bl __get_current_exception
|
||||
subs r0, #16
|
||||
.global unhandled_user_irq_num_in_r0
|
||||
unhandled_user_irq_num_in_r0:
|
||||
bkpt #0
|
||||
|
||||
.section .reset, "ax"
|
||||
|
||||
// This is the beginning of the image, which is entered from stage2 or bootrom USB MSD watchdog reboot
|
||||
|
||||
// note if we are NO_FLASH then start: below is currently identical anyway, so save 4 bytes
|
||||
#if !PICO_NO_FLASH
|
||||
// We simply install our own vector table and redirect through it
|
||||
ldr r0, =__vectors
|
||||
b __vector_entry
|
||||
#endif
|
||||
|
||||
// ELF entry point generally called when we load an ELF via debugger
|
||||
.type _entry_point,%function
|
||||
.thumb_func
|
||||
.global _entry_point
|
||||
_entry_point:
|
||||
|
||||
#if PICO_NO_FLASH
|
||||
// non flash
|
||||
ldr r0, =__vectors
|
||||
#else
|
||||
// todo clear watchdog?
|
||||
// When using flash, we install and use the ROM vector table to go thru regular bootrom/stage2 flash sequence
|
||||
movs r0, #0
|
||||
#endif
|
||||
|
||||
__vector_entry:
|
||||
ldr r1, =(PPB_BASE + M0PLUS_CPUID_OFFSET)
|
||||
str r0, [r1, #8]
|
||||
ldmia r0!, {r1, r2}
|
||||
msr msp, r1
|
||||
bx r2
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset handler:
|
||||
// - initialises .data
|
||||
// - clears .bss
|
||||
// - calls runtime_init
|
||||
// - calls main
|
||||
// - calls exit (which should eventually hang the processor via _exit)
|
||||
|
||||
.type _reset_handler,%function
|
||||
.thumb_func
|
||||
_reset_handler:
|
||||
// Hang all cores except core 0
|
||||
ldr r0, =(SIO_BASE + SIO_CPUID_OFFSET)
|
||||
ldr r0, [r0]
|
||||
cmp r0, #0
|
||||
bne wait_for_vector
|
||||
|
||||
adr r4, data_cpy_table
|
||||
|
||||
// assume there is at least one entry
|
||||
1:
|
||||
ldmia r4!, {r1-r3}
|
||||
cmp r1, #0
|
||||
beq 2f
|
||||
bl data_cpy
|
||||
b 1b
|
||||
2:
|
||||
|
||||
// Zero out the BSS
|
||||
ldr r1, =__bss_start__
|
||||
ldr r2, =__bss_end__
|
||||
movs r0, #0
|
||||
b bss_fill_test
|
||||
bss_fill_loop:
|
||||
stm r1!, {r0}
|
||||
bss_fill_test:
|
||||
cmp r1, r2
|
||||
bne bss_fill_loop
|
||||
|
||||
platform_entry: // symbol for stack traces
|
||||
// Use 32-bit jumps, in case these symbols are moved out of branch range
|
||||
// (e.g. if main is in SRAM and crt0 in flash)
|
||||
ldr r1, =runtime_init
|
||||
blx r1
|
||||
ldr r1, =main
|
||||
blx r1
|
||||
ldr r1, =exit
|
||||
blx r1
|
||||
// exit should not return. If it does, hang the core.
|
||||
// (fall thru into our hang _exit impl
|
||||
.weak _exit
|
||||
.type _exit,%function
|
||||
.thumb_func
|
||||
_exit:
|
||||
1: // separate label because _exit can be moved out of branch range
|
||||
bkpt #0
|
||||
b 1b
|
||||
|
||||
data_cpy_loop:
|
||||
ldm r1!, {r0}
|
||||
stm r2!, {r0}
|
||||
data_cpy:
|
||||
cmp r2, r3
|
||||
blo data_cpy_loop
|
||||
bx lr
|
||||
|
||||
#if !PICO_NO_BINARY_INFO
|
||||
binary_info_header:
|
||||
.word BINARY_INFO_MARKER_START
|
||||
.word __binary_info_start
|
||||
.word __binary_info_end
|
||||
.word data_cpy_table // we may need to decode pointers that are in RAM at runtime.
|
||||
.word BINARY_INFO_MARKER_END
|
||||
#endif
|
||||
|
||||
.align 2
|
||||
data_cpy_table:
|
||||
#if PICO_COPY_TO_RAM
|
||||
.word __ram_text_source__
|
||||
.word __ram_text_start__
|
||||
.word __ram_text_end__
|
||||
#endif
|
||||
.word __etext
|
||||
.word __data_start__
|
||||
.word __data_end__
|
||||
|
||||
.word __scratch_x_source__
|
||||
.word __scratch_x_start__
|
||||
.word __scratch_x_end__
|
||||
|
||||
.word __scratch_y_source__
|
||||
.word __scratch_y_start__
|
||||
.word __scratch_y_end__
|
||||
|
||||
.word 0 // null terminator
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Provide safe defaults for _exit and runtime_init
|
||||
// Full implementations usually provided by platform.c
|
||||
|
||||
.weak runtime_init
|
||||
.type runtime_init,%function
|
||||
.thumb_func
|
||||
runtime_init:
|
||||
bx lr
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// In case core 1's VTOR has already been moved into flash, we need to handle
|
||||
// core 1 reset. However, we do so by just jumping back into bootrom version of
|
||||
// wait_for_vector
|
||||
|
||||
wait_for_vector:
|
||||
ldr r0, = 'W' | ('V' << 8)
|
||||
bl rom_func_lookup
|
||||
bx r0
|
||||
|
||||
.global __get_current_exception
|
||||
.thumb_func
|
||||
__get_current_exception:
|
||||
mrs r0, ipsr
|
||||
uxtb r0, r0
|
||||
bx lr
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Stack/heap dummies to set size
|
||||
|
||||
.section .stack
|
||||
// align to allow for memory protection (although this alignment is pretty much ignored by linker script)
|
||||
.align 5
|
||||
.equ StackSize, PICO_STACK_SIZE
|
||||
.space StackSize
|
||||
|
||||
.section .heap
|
||||
.align 2
|
||||
.equ HeapSize, PICO_HEAP_SIZE
|
||||
.space HeapSize
|
||||
+9812
-56
File diff suppressed because it is too large
Load Diff
@@ -25,11 +25,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "stdlib_noniso.h" // Wacky deprecated AVR compatibility functions
|
||||
#include "RP2040Version.h"
|
||||
#include "api/ArduinoAPI.h"
|
||||
#include "api/itoa.h" // ARM toolchain doesn't provide itoa etc, provide them
|
||||
#include <pins_arduino.h>
|
||||
#include "hardware/gpio.h" // Required for the port*Register macros
|
||||
#include "debug_internal.h"
|
||||
#include <RP2040.h> // CMSIS
|
||||
|
||||
// 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()
|
||||
@@ -69,6 +71,7 @@ void noInterrupts();
|
||||
#define portModeRegister(port) ((volatile uint32_t*) sio_hw->gpio_oe)
|
||||
|
||||
// ADC RP2040-specific calls
|
||||
void analogReadResolution(int bits);
|
||||
float analogReadTemp(); // Returns core temp in Centigrade
|
||||
|
||||
// PWM RP2040-specific calls
|
||||
@@ -95,7 +98,8 @@ void analogWriteResolution(int res);
|
||||
#endif
|
||||
|
||||
#include "SerialUART.h"
|
||||
#include "RP2040.h"
|
||||
#include "RP2040Support.h"
|
||||
#include "SerialPIO.h"
|
||||
#include "Bootsel.h"
|
||||
|
||||
// Template which will evaluate at *compile time* to a single 32b number
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <hardware/clocks.h>
|
||||
#include <hardware/irq.h>
|
||||
#include <hardware/pio.h>
|
||||
#include <hardware/exception.h>
|
||||
#include <hardware/structs/systick.h>
|
||||
#include <pico/multicore.h>
|
||||
#include <pico/util/queue.h>
|
||||
#include <CoreMutex.h>
|
||||
@@ -92,6 +94,18 @@ public:
|
||||
// once otherIdled == false.
|
||||
}
|
||||
|
||||
void clear() {
|
||||
uint32_t val;
|
||||
|
||||
while (queue_try_remove(&_queue[0], &val)) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
|
||||
while (queue_try_remove(&_queue[1], &val)) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static void __no_inline_not_in_flash_func(_irq)() {
|
||||
multicore_fifo_clear_irq();
|
||||
@@ -114,8 +128,23 @@ private:
|
||||
static constexpr int _GOTOSLEEP = 0x66666666;
|
||||
};
|
||||
|
||||
class RP2040;
|
||||
extern RP2040 rp2040;
|
||||
extern "C" void main1();
|
||||
|
||||
class RP2040 {
|
||||
public:
|
||||
RP2040() {
|
||||
_epoch = 0;
|
||||
// Enable SYSTICK exception
|
||||
exception_set_exclusive_handler(SYSTICK_EXCEPTION, _SystickHandler);
|
||||
systick_hw->csr = 0x7;
|
||||
systick_hw->rvr = 0x00FFFFFF;
|
||||
}
|
||||
|
||||
~RP2040() { /* noop */ }
|
||||
|
||||
|
||||
// Convert from microseconds to PIO clock cycles
|
||||
static int usToPIOCycles(int us) {
|
||||
// Parenthesis needed to guarantee order of operations to avoid 32bit overflow
|
||||
@@ -127,18 +156,50 @@ public:
|
||||
return clock_get_hz(clk_sys);
|
||||
}
|
||||
|
||||
// Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
|
||||
volatile uint64_t _epoch = 0;
|
||||
inline uint32_t getCycleCount() {
|
||||
uint32_t epoch;
|
||||
uint32_t ctr;
|
||||
do {
|
||||
epoch = (uint32_t)_epoch;
|
||||
ctr = systick_hw->cvr;
|
||||
} while (epoch != (uint32_t)_epoch);
|
||||
return epoch + (1 << 24) - ctr; /* CTR counts down from 1<<24-1 */
|
||||
}
|
||||
|
||||
inline uint64_t getCycleCount64() {
|
||||
uint64_t epoch;
|
||||
uint64_t ctr;
|
||||
do {
|
||||
epoch = _epoch;
|
||||
ctr = systick_hw->cvr;
|
||||
} while (epoch != _epoch);
|
||||
return epoch + (1LL << 24) - ctr;
|
||||
}
|
||||
|
||||
void idleOtherCore() {
|
||||
fifo.idleOtherCore();
|
||||
}
|
||||
|
||||
void resumeOtherCore() {
|
||||
fifo.resumeOtherCore();
|
||||
}
|
||||
|
||||
void restartCore1() {
|
||||
multicore_reset_core1();
|
||||
fifo.clear();
|
||||
multicore_launch_core1(main1);
|
||||
}
|
||||
|
||||
// Multicore comms FIFO
|
||||
_MFIFO fifo;
|
||||
};
|
||||
|
||||
extern RP2040 rp2040;
|
||||
private:
|
||||
static void _SystickHandler() {
|
||||
rp2040._epoch += 1LL << 24;
|
||||
}
|
||||
};
|
||||
|
||||
// Wrapper class for PIO programs, abstracting common operations out
|
||||
// TODO - Add unload/destructor
|
||||
+51
-33
@@ -19,7 +19,7 @@
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef USE_TINYUSB
|
||||
#if !defined(USE_TINYUSB) && !defined(NO_USB)
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "CoreMutex.h"
|
||||
@@ -52,7 +52,6 @@ mutex_t __usb_mutex;
|
||||
#endif
|
||||
|
||||
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
|
||||
#define USBD_MAX_POWER_MA (250)
|
||||
|
||||
#define USBD_ITF_CDC (0) // needs 2 interfaces
|
||||
#define USBD_ITF_MAX (2)
|
||||
@@ -122,32 +121,48 @@ int __USBGetMouseReportID() {
|
||||
}
|
||||
|
||||
static uint8_t *GetDescHIDReport(int *len) {
|
||||
static uint8_t *report = nullptr;
|
||||
int report_len = 0;
|
||||
|
||||
if (report) {
|
||||
free(report);
|
||||
report = nullptr;
|
||||
}
|
||||
|
||||
if (__USBInstallKeyboard && __USBInstallMouse) {
|
||||
static uint8_t desc_hid_report[] = {
|
||||
uint8_t desc_hid_report[] = {
|
||||
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)),
|
||||
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(2))
|
||||
};
|
||||
if (len) {
|
||||
*len = sizeof(desc_hid_report);
|
||||
report_len = sizeof(desc_hid_report);
|
||||
report = (uint8_t *)malloc(report_len);
|
||||
if (report) {
|
||||
memcpy(report, desc_hid_report, report_len);
|
||||
}
|
||||
return desc_hid_report;
|
||||
} else if (__USBInstallKeyboard && ! __USBInstallMouse) {
|
||||
static uint8_t desc_hid_report[] = {
|
||||
uint8_t desc_hid_report[] = {
|
||||
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1))
|
||||
};
|
||||
if (len) {
|
||||
*len = sizeof(desc_hid_report);
|
||||
report_len = sizeof(desc_hid_report);
|
||||
report = (uint8_t *)malloc(report_len);
|
||||
if (report) {
|
||||
memcpy(report, desc_hid_report, report_len);
|
||||
}
|
||||
return desc_hid_report;
|
||||
} else { // if (!__USBInstallKeyboard && __USBInstallMouse) {
|
||||
static uint8_t desc_hid_report[] = {
|
||||
uint8_t desc_hid_report[] = {
|
||||
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1))
|
||||
};
|
||||
if (len) {
|
||||
*len = sizeof(desc_hid_report);
|
||||
report_len = sizeof(desc_hid_report);
|
||||
report = (uint8_t *)malloc(report_len);
|
||||
if (report) {
|
||||
memcpy(report, desc_hid_report, report_len);
|
||||
}
|
||||
return desc_hid_report;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
*len = report_len;
|
||||
}
|
||||
return report;
|
||||
}
|
||||
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
@@ -161,14 +176,14 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) {
|
||||
|
||||
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
(void)index;
|
||||
static uint8_t *usbd_desc_cfg;
|
||||
static uint8_t *usbd_desc_cfg = nullptr;
|
||||
|
||||
if (!usbd_desc_cfg) {
|
||||
bool hasHID = __USBInstallKeyboard || __USBInstallMouse;
|
||||
|
||||
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0) + (__USBInstallMIDI ? 2 : 0);
|
||||
|
||||
static uint8_t cdc_desc[TUD_CDC_DESC_LEN] = {
|
||||
uint8_t cdc_desc[TUD_CDC_DESC_LEN] = {
|
||||
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
||||
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD, USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE)
|
||||
};
|
||||
@@ -176,40 +191,42 @@ const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
int hid_report_len;
|
||||
GetDescHIDReport(&hid_report_len);
|
||||
uint8_t hid_itf = __USBInstallSerial ? 2 : 0;
|
||||
static uint8_t hid_desc[TUD_HID_DESC_LEN] = {
|
||||
uint8_t hid_desc[TUD_HID_DESC_LEN] = {
|
||||
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(hid_itf, 0, HID_ITF_PROTOCOL_NONE, hid_report_len, EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10)
|
||||
};
|
||||
|
||||
uint8_t midi_itf = hid_itf + (hasHID ? 1 : 0);
|
||||
static uint8_t midi_desc[TUD_MIDI_DESC_LEN] = {
|
||||
uint8_t midi_desc[TUD_MIDI_DESC_LEN] = {
|
||||
// Interface number, string index, EP Out & EP In address, EP size
|
||||
TUD_MIDI_DESCRIPTOR(midi_itf, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 64)
|
||||
};
|
||||
|
||||
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0) + (__USBInstallMIDI ? sizeof(midi_desc) : 0);
|
||||
|
||||
static uint8_t tud_cfg_desc[TUD_CONFIG_DESC_LEN] = {
|
||||
uint8_t tud_cfg_desc[TUD_CONFIG_DESC_LEN] = {
|
||||
// Config number, interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, interface_count, USBD_STR_0, usbd_desc_len, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA)
|
||||
};
|
||||
|
||||
// Combine to one descriptor
|
||||
usbd_desc_cfg = (uint8_t *)malloc(usbd_desc_len);
|
||||
bzero(usbd_desc_cfg, usbd_desc_len);
|
||||
uint8_t *ptr = usbd_desc_cfg;
|
||||
memcpy(ptr, tud_cfg_desc, sizeof(tud_cfg_desc));
|
||||
ptr += sizeof(tud_cfg_desc);
|
||||
if (__USBInstallSerial) {
|
||||
memcpy(ptr, cdc_desc, sizeof(cdc_desc));
|
||||
ptr += sizeof(cdc_desc);
|
||||
}
|
||||
if (hasHID) {
|
||||
memcpy(ptr, hid_desc, sizeof(hid_desc));
|
||||
ptr += sizeof(hid_desc);
|
||||
}
|
||||
if (__USBInstallMIDI) {
|
||||
memcpy(ptr, midi_desc, sizeof(midi_desc));
|
||||
if (usbd_desc_cfg) {
|
||||
bzero(usbd_desc_cfg, usbd_desc_len);
|
||||
uint8_t *ptr = usbd_desc_cfg;
|
||||
memcpy(ptr, tud_cfg_desc, sizeof(tud_cfg_desc));
|
||||
ptr += sizeof(tud_cfg_desc);
|
||||
if (__USBInstallSerial) {
|
||||
memcpy(ptr, cdc_desc, sizeof(cdc_desc));
|
||||
ptr += sizeof(cdc_desc);
|
||||
}
|
||||
if (hasHID) {
|
||||
memcpy(ptr, hid_desc, sizeof(hid_desc));
|
||||
ptr += sizeof(hid_desc);
|
||||
}
|
||||
if (__USBInstallMIDI) {
|
||||
memcpy(ptr, midi_desc, sizeof(midi_desc));
|
||||
}
|
||||
}
|
||||
}
|
||||
return usbd_desc_cfg;
|
||||
@@ -277,6 +294,7 @@ void __USBStart() {
|
||||
}
|
||||
|
||||
mutex_init(&__usb_mutex);
|
||||
|
||||
tusb_init();
|
||||
|
||||
irq_set_exclusive_handler(USB_TASK_IRQ, usb_irq);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#define ARDUINO_PICO_MAJOR 1
|
||||
#define ARDUINO_PICO_MINOR 13
|
||||
#define ARDUINO_PICO_REVISION 2
|
||||
#define ARDUINO_PICO_VERSION_STR "1.13.2"
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
Serial-over-PIO for the Raspberry Pi Pico RP2040
|
||||
|
||||
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include "SerialPIO.h"
|
||||
#include "CoreMutex.h"
|
||||
#include <hardware/gpio.h>
|
||||
#include <map>
|
||||
#include "pio_uart.pio.h"
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// -- Generates a unique program for differing bit lengths
|
||||
static std::map<int, PIOProgram*> _txMap;
|
||||
static std::map<int, PIOProgram*> _rxMap;
|
||||
|
||||
// Duplicate a program and replace the first insn with a "set x, repl"
|
||||
static pio_program_t *pio_make_uart_prog(int repl, const pio_program_t *pg) {
|
||||
pio_program_t *p = new pio_program_t;
|
||||
p->length = pg->length;
|
||||
p->origin = pg->origin;
|
||||
uint16_t *insn = (uint16_t *)malloc(p->length * 2);
|
||||
if (!insn) {
|
||||
delete p;
|
||||
return nullptr;
|
||||
}
|
||||
memcpy(insn, pg->instructions, p->length * 2);
|
||||
insn[0] = pio_encode_set(pio_x, repl);
|
||||
p->instructions = insn;
|
||||
return p;
|
||||
}
|
||||
|
||||
static PIOProgram *_getTxProgram(int bits) {
|
||||
auto f = _txMap.find(bits);
|
||||
if (f == _txMap.end()) {
|
||||
pio_program_t * p = pio_make_uart_prog(bits, &pio_tx_program);
|
||||
_txMap.insert({bits, new PIOProgram(p)});
|
||||
f = _txMap.find(bits);
|
||||
}
|
||||
return f->second;
|
||||
}
|
||||
|
||||
static PIOProgram *_getRxProgram(int bits) {
|
||||
auto f = _rxMap.find(bits);
|
||||
if (f == _rxMap.end()) {
|
||||
pio_program_t * p = pio_make_uart_prog(bits, &pio_rx_program);
|
||||
_rxMap.insert({bits, new PIOProgram(p)});
|
||||
f = _rxMap.find(bits);
|
||||
}
|
||||
return f->second;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// We need to cache generated SerialPIOs so we can add data to them from
|
||||
// the shared handler
|
||||
static SerialPIO *_pioSP[2][4];
|
||||
static void __not_in_flash_func(_fifoIRQ)() {
|
||||
for (int p = 0; p < 2; p++) {
|
||||
for (int sm = 0; sm < 4; sm++) {
|
||||
SerialPIO *s = _pioSP[p][sm];
|
||||
if (s) {
|
||||
s->_handleIRQ();
|
||||
pio_interrupt_clear((p == 0) ? pio0 : pio1, sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __not_in_flash_func(SerialPIO::_handleIRQ)() {
|
||||
if (_rx == NOPIN) {
|
||||
return;
|
||||
}
|
||||
while (!pio_sm_is_rx_fifo_empty(_rxPIO, _rxSM)) {
|
||||
uint32_t decode = _rxPIO->rxf[_rxSM];
|
||||
decode >>= 32 - _rxBits;
|
||||
uint32_t val = 0;
|
||||
for (int b = 0; b < _bits + 1; b++) {
|
||||
val |= (decode & (1 << (b * 2))) ? 1 << b : 0;
|
||||
}
|
||||
if (_parity == UART_PARITY_EVEN) {
|
||||
int p = ::_parity(_bits, 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 r = (val & (1 << _bits)) ? 1 : 0;
|
||||
if (p == r) {
|
||||
// TODO - parity error
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto next_writer = _writer + 1;
|
||||
if (next_writer == _fifoSize) {
|
||||
next_writer = 0;
|
||||
}
|
||||
if (next_writer != _reader) {
|
||||
_queue[_writer] = val & ((1 << _bits) - 1);
|
||||
asm volatile("" ::: "memory"); // Ensure the queue is written before the written count advances
|
||||
_writer = next_writer;
|
||||
} else {
|
||||
// TODO: Overflow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SerialPIO::SerialPIO(pin_size_t tx, pin_size_t rx, size_t fifoSize) {
|
||||
_tx = tx;
|
||||
_rx = rx;
|
||||
_fifoSize = fifoSize + 1; // Always one unused entry
|
||||
_queue = new uint8_t[_fifoSize];
|
||||
mutex_init(&_mutex);
|
||||
}
|
||||
|
||||
SerialPIO::~SerialPIO() {
|
||||
end();
|
||||
delete[] _queue;
|
||||
}
|
||||
|
||||
void SerialPIO::begin(unsigned long baud, uint16_t config) {
|
||||
_baud = baud;
|
||||
switch (config & SERIAL_PARITY_MASK) {
|
||||
case SERIAL_PARITY_EVEN:
|
||||
_parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
case SERIAL_PARITY_ODD:
|
||||
_parity = UART_PARITY_ODD;
|
||||
break;
|
||||
default:
|
||||
_parity = UART_PARITY_NONE;
|
||||
break;
|
||||
}
|
||||
switch (config & SERIAL_STOP_BIT_MASK) {
|
||||
case SERIAL_STOP_BIT_1:
|
||||
_stop = 1;
|
||||
break;
|
||||
default:
|
||||
_stop = 2;
|
||||
break;
|
||||
}
|
||||
switch (config & SERIAL_DATA_MASK) {
|
||||
case SERIAL_DATA_5:
|
||||
_bits = 5;
|
||||
break;
|
||||
case SERIAL_DATA_6:
|
||||
_bits = 6;
|
||||
break;
|
||||
case SERIAL_DATA_7:
|
||||
_bits = 7;
|
||||
break;
|
||||
default:
|
||||
_bits = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((_tx == NOPIN) && (_rx == NOPIN)) {
|
||||
DEBUGCORE("ERROR: No pins specified for SerialPIO\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_tx != NOPIN) {
|
||||
_txBits = _bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1/*start bit*/;
|
||||
_txPgm = _getTxProgram(_txBits);
|
||||
int off;
|
||||
if (!_txPgm->prepare(&_txPIO, &_txSM, &off)) {
|
||||
DEBUGCORE("ERROR: Unable to allocate PIO TX UART, out of PIO resources\n");
|
||||
// ERROR, no free slots
|
||||
return;
|
||||
}
|
||||
|
||||
digitalWrite(_tx, HIGH);
|
||||
pinMode(_tx, OUTPUT);
|
||||
|
||||
pio_tx_program_init(_txPIO, _txSM, off, _tx);
|
||||
pio_sm_clear_fifos(_txPIO, _txSM); // Remove any existing data
|
||||
|
||||
// Put the divider into ISR w/o using up program space
|
||||
pio_sm_put_blocking(_txPIO, _txSM, clock_get_hz(clk_sys) / _baud - 2);
|
||||
pio_sm_exec(_txPIO, _txSM, pio_encode_pull(false, false));
|
||||
pio_sm_exec(_txPIO, _txSM, pio_encode_mov(pio_isr, pio_osr));
|
||||
|
||||
// Start running!
|
||||
pio_sm_set_enabled(_txPIO, _txSM, true);
|
||||
}
|
||||
if (_rx != NOPIN) {
|
||||
_writer = 0;
|
||||
_reader = 0;
|
||||
|
||||
_rxBits = 2 * (_bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1) - 1;
|
||||
_rxPgm = _getRxProgram(_rxBits);
|
||||
int off;
|
||||
if (!_rxPgm->prepare(&_rxPIO, &_rxSM, &off)) {
|
||||
DEBUGCORE("ERROR: Unable to allocate PIO RX UART, out of PIO resources\n");
|
||||
return;
|
||||
}
|
||||
// Stash away the created RX port for the IRQ handler
|
||||
_pioSP[pio_get_index(_rxPIO)][_rxSM] = this;
|
||||
|
||||
pinMode(_rx, INPUT);
|
||||
pio_rx_program_init(_rxPIO, _rxSM, off, _rx);
|
||||
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) - 2);
|
||||
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
|
||||
_rxPIO->sm[_rxSM].shiftctrl |= 0x80000000;
|
||||
|
||||
// Enable interrupts on rxfifo
|
||||
switch (_rxSM) {
|
||||
case 0: pio_set_irq0_source_enabled(_rxPIO, pis_sm0_rx_fifo_not_empty, true); break;
|
||||
case 1: pio_set_irq0_source_enabled(_rxPIO, pis_sm1_rx_fifo_not_empty, true); break;
|
||||
case 2: pio_set_irq0_source_enabled(_rxPIO, pis_sm2_rx_fifo_not_empty, true); break;
|
||||
case 3: pio_set_irq0_source_enabled(_rxPIO, pis_sm3_rx_fifo_not_empty, true); break;
|
||||
}
|
||||
auto irqno = pio_get_index(_rxPIO) == 0 ? PIO0_IRQ_0 : PIO1_IRQ_0;
|
||||
irq_set_exclusive_handler(irqno, _fifoIRQ);
|
||||
irq_set_enabled(irqno, true);
|
||||
|
||||
pio_sm_set_enabled(_rxPIO, _rxSM, true);
|
||||
}
|
||||
|
||||
_running = true;
|
||||
}
|
||||
|
||||
void SerialPIO::end() {
|
||||
if (!_running) {
|
||||
return;
|
||||
}
|
||||
// TODO: Deallocate PIO resources, stop them
|
||||
_pioSP[pio_get_index(_rxPIO)][_rxSM] = nullptr;
|
||||
_running = false;
|
||||
}
|
||||
|
||||
int SerialPIO::peek() {
|
||||
CoreMutex m(&_mutex);
|
||||
if (!_running || !m || (_rx == NOPIN)) {
|
||||
return -1;
|
||||
}
|
||||
// If there's something in the FIFO now, just peek at it
|
||||
if (_writer != _reader) {
|
||||
return _queue[_reader];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SerialPIO::read() {
|
||||
CoreMutex m(&_mutex);
|
||||
if (!_running || !m || (_rx == NOPIN)) {
|
||||
return -1;
|
||||
}
|
||||
if (_writer != _reader) {
|
||||
auto ret = _queue[_reader];
|
||||
asm volatile("" ::: "memory"); // Ensure the value is read before advancing
|
||||
auto next_reader = (_reader + 1) % _fifoSize;
|
||||
asm volatile("" ::: "memory"); // Ensure the reader value is only written once, correctly
|
||||
_reader = next_reader;
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SerialPIO::available() {
|
||||
CoreMutex m(&_mutex);
|
||||
if (!_running || !m || (_rx == NOPIN)) {
|
||||
return 0;
|
||||
}
|
||||
return (_writer - _reader) % _fifoSize;
|
||||
}
|
||||
|
||||
int SerialPIO::availableForWrite() {
|
||||
CoreMutex m(&_mutex);
|
||||
if (!_running || !m || (_tx == NOPIN)) {
|
||||
return 0;
|
||||
}
|
||||
return 8 - pio_sm_get_tx_fifo_level(_txPIO, _txSM);
|
||||
}
|
||||
|
||||
void SerialPIO::flush() {
|
||||
CoreMutex m(&_mutex);
|
||||
if (!_running || !m || (_tx == NOPIN)) {
|
||||
return;
|
||||
}
|
||||
while (!pio_sm_is_tx_fifo_empty(_txPIO, _txSM)) {
|
||||
delay(1); // Wait for all FIFO to be read
|
||||
}
|
||||
// Could have 1 byte being transmitted, so wait for bit times
|
||||
delay((1000 * (_txBits + 1)) / _baud);
|
||||
}
|
||||
|
||||
size_t SerialPIO::write(uint8_t c) {
|
||||
CoreMutex m(&_mutex);
|
||||
if (!_running || !m || (_tx == NOPIN)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t val = 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 |= 7 << (_bits + 1);
|
||||
} else {
|
||||
val |= (1 ^ ::_parity(_bits, c)) << _bits;
|
||||
val |= 7 << (_bits + 1);
|
||||
}
|
||||
val <<= 1; // Start bit = low
|
||||
|
||||
pio_sm_put_blocking(_txPIO, _txSM, val);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
SerialPIO::operator bool() {
|
||||
return _running;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Serial-over-PIO for the Raspberry Pi Pico RP2040
|
||||
|
||||
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "api/HardwareSerial.h"
|
||||
#include <stdarg.h>
|
||||
#include <queue>
|
||||
#include <hardware/uart.h>
|
||||
#include "CoreMutex.h"
|
||||
|
||||
extern "C" typedef struct uart_inst uart_inst_t;
|
||||
|
||||
class SerialPIO : public HardwareSerial {
|
||||
public:
|
||||
static const pin_size_t NOPIN = 0xff; // Use in constructor to disable RX or TX unit
|
||||
SerialPIO(pin_size_t tx, pin_size_t rx, size_t fifoSize = 32);
|
||||
~SerialPIO();
|
||||
|
||||
void begin(unsigned long baud = 115200) override {
|
||||
begin(baud, SERIAL_8N1);
|
||||
};
|
||||
void begin(unsigned long baud, uint16_t config) override;
|
||||
void end() override;
|
||||
|
||||
virtual int peek() override;
|
||||
virtual int read() override;
|
||||
virtual int available() override;
|
||||
virtual int availableForWrite() override;
|
||||
virtual void flush() override;
|
||||
virtual size_t write(uint8_t c) override;
|
||||
using Print::write;
|
||||
operator bool() override;
|
||||
|
||||
// Not to be called by users, only from the IRQ handler. In public so that the C-language IQR callback can access it
|
||||
void _handleIRQ();
|
||||
|
||||
private:
|
||||
bool _running = false;
|
||||
pin_size_t _tx, _rx;
|
||||
int _baud;
|
||||
int _bits;
|
||||
uart_parity_t _parity;
|
||||
int _stop;
|
||||
mutex_t _mutex;
|
||||
|
||||
PIOProgram *_txPgm;
|
||||
PIO _txPIO;
|
||||
int _txSM;
|
||||
int _txBits;
|
||||
|
||||
PIOProgram *_rxPgm;
|
||||
PIO _rxPIO;
|
||||
int _rxSM;
|
||||
int _rxBits;
|
||||
|
||||
// Lockless, IRQ-handled circular queue
|
||||
size_t _fifoSize;
|
||||
uint32_t _writer;
|
||||
uint32_t _reader;
|
||||
uint8_t *_queue;
|
||||
};
|
||||
+227
-22
@@ -65,46 +65,173 @@ bool SerialUART::setTX(pin_size_t pin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SerialUART::SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx) {
|
||||
bool SerialUART::setRTS(pin_size_t pin) {
|
||||
constexpr uint32_t valid[2] = { __bitset({3, 15, 19}) /* UART0 */,
|
||||
__bitset({7, 11, 23, 27}) /* UART1 */
|
||||
};
|
||||
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
|
||||
_rts = pin;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_running) {
|
||||
panic("FATAL: Attempting to set Serial%d.RTS while running", uart_get_index(_uart) + 1);
|
||||
} else {
|
||||
panic("FATAL: Attempting to set Serial%d.RTS to illegal pin %d", uart_get_index(_uart) + 1, pin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SerialUART::setCTS(pin_size_t pin) {
|
||||
constexpr uint32_t valid[2] = { __bitset({2, 14, 18}) /* UART0 */,
|
||||
__bitset({6, 10, 22, 26}) /* UART1 */
|
||||
};
|
||||
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
|
||||
_cts = pin;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_running) {
|
||||
panic("FATAL: Attempting to set Serial%d.CTS while running", uart_get_index(_uart) + 1);
|
||||
} else {
|
||||
panic("FATAL: Attempting to set Serial%d.CTS to illegal pin %d", uart_get_index(_uart) + 1, pin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool SerialUART::setPollingMode(bool mode) {
|
||||
if (_running) {
|
||||
return false;
|
||||
}
|
||||
_polling = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SerialUART::setFIFOSize(size_t size) {
|
||||
if (!size || _running) {
|
||||
return false;
|
||||
}
|
||||
_fifoSize = size + 1; // Always 1 unused entry
|
||||
return true;
|
||||
}
|
||||
|
||||
SerialUART::SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx, pin_size_t rts, pin_size_t cts) {
|
||||
_uart = uart;
|
||||
_tx = tx;
|
||||
_rx = rx;
|
||||
_rts = rts;
|
||||
_cts = cts;
|
||||
mutex_init(&_mutex);
|
||||
mutex_init(&_fifoMutex);
|
||||
}
|
||||
|
||||
static void _uart0IRQ();
|
||||
static void _uart1IRQ();
|
||||
|
||||
void SerialUART::begin(unsigned long baud, uint16_t config) {
|
||||
if (_running) {
|
||||
end();
|
||||
}
|
||||
_queue = new uint8_t[_fifoSize];
|
||||
_baud = baud;
|
||||
uart_init(_uart, baud);
|
||||
int bits, stop;
|
||||
uart_parity_t parity;
|
||||
switch (config & SERIAL_PARITY_MASK) {
|
||||
case SERIAL_PARITY_EVEN: parity = UART_PARITY_EVEN; break;
|
||||
case SERIAL_PARITY_ODD: parity = UART_PARITY_ODD; break;
|
||||
default: parity = UART_PARITY_NONE; break;
|
||||
case SERIAL_PARITY_EVEN:
|
||||
parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
case SERIAL_PARITY_ODD:
|
||||
parity = UART_PARITY_ODD;
|
||||
break;
|
||||
default:
|
||||
parity = UART_PARITY_NONE;
|
||||
break;
|
||||
}
|
||||
switch (config & SERIAL_STOP_BIT_MASK) {
|
||||
case SERIAL_STOP_BIT_1: stop = 1; break;
|
||||
default: stop = 2; break;
|
||||
case SERIAL_STOP_BIT_1:
|
||||
stop = 1;
|
||||
break;
|
||||
default:
|
||||
stop = 2;
|
||||
break;
|
||||
}
|
||||
switch (config & SERIAL_DATA_MASK) {
|
||||
case SERIAL_DATA_5: bits = 5; break;
|
||||
case SERIAL_DATA_6: bits = 6; break;
|
||||
case SERIAL_DATA_7: bits = 7; break;
|
||||
default: bits = 8; break;
|
||||
case SERIAL_DATA_5:
|
||||
bits = 5;
|
||||
break;
|
||||
case SERIAL_DATA_6:
|
||||
bits = 6;
|
||||
break;
|
||||
case SERIAL_DATA_7:
|
||||
bits = 7;
|
||||
break;
|
||||
default:
|
||||
bits = 8;
|
||||
break;
|
||||
}
|
||||
uart_set_format(_uart, bits, stop, parity);
|
||||
gpio_set_function(_tx, GPIO_FUNC_UART);
|
||||
gpio_set_function(_rx, GPIO_FUNC_UART);
|
||||
if (_rts != UART_PIN_NOT_DEFINED) {
|
||||
gpio_set_function(_rts, GPIO_FUNC_UART);
|
||||
}
|
||||
if (_cts != UART_PIN_NOT_DEFINED) {
|
||||
gpio_set_function(_cts, GPIO_FUNC_UART);
|
||||
}
|
||||
uart_set_hw_flow(_uart, _rts != UART_PIN_NOT_DEFINED, _cts != UART_PIN_NOT_DEFINED);
|
||||
_writer = 0;
|
||||
_reader = 0;
|
||||
|
||||
if (!_polling) {
|
||||
if (_uart == uart0) {
|
||||
irq_set_exclusive_handler(UART0_IRQ, _uart0IRQ);
|
||||
irq_set_enabled(UART0_IRQ, true);
|
||||
} else {
|
||||
irq_set_exclusive_handler(UART1_IRQ, _uart1IRQ);
|
||||
irq_set_enabled(UART1_IRQ, true);
|
||||
}
|
||||
// Set the IRQ enables and FIFO level to minimum
|
||||
uart_set_irq_enables(_uart, true, false);
|
||||
} else {
|
||||
// Polling mode has no IRQs used
|
||||
}
|
||||
_running = true;
|
||||
_peek = -1;
|
||||
}
|
||||
|
||||
void SerialUART::end() {
|
||||
if (!_running) {
|
||||
return;
|
||||
}
|
||||
uart_deinit(_uart);
|
||||
_running = false;
|
||||
if (!_polling) {
|
||||
if (_uart == uart0) {
|
||||
irq_set_enabled(UART0_IRQ, false);
|
||||
} else {
|
||||
irq_set_enabled(UART1_IRQ, false);
|
||||
}
|
||||
}
|
||||
// Paranoia - ensure nobody else is using anything here at the same time
|
||||
mutex_enter_blocking(&_mutex);
|
||||
mutex_enter_blocking(&_fifoMutex);
|
||||
uart_deinit(_uart);
|
||||
delete[] _queue;
|
||||
// Reset the mutexes once all is off/cleaned up
|
||||
mutex_exit(&_fifoMutex);
|
||||
mutex_exit(&_mutex);
|
||||
}
|
||||
|
||||
void SerialUART::_pumpFIFO() {
|
||||
// Use the _fifoMutex to guard against the other core potentially
|
||||
// running the IRQ (since we can't disable their IRQ handler).
|
||||
// We guard against this core by disabling the IRQ handler and
|
||||
// re-enabling if it was previously enabled at the end.
|
||||
auto irqno = (_uart == uart0) ? UART0_IRQ : UART1_IRQ;
|
||||
bool enabled = irq_is_enabled(irqno);
|
||||
irq_set_enabled(irqno, false);
|
||||
mutex_enter_blocking(&_fifoMutex);
|
||||
_handleIRQ(false);
|
||||
mutex_exit(&_fifoMutex);
|
||||
irq_set_enabled(irqno, enabled);
|
||||
}
|
||||
|
||||
int SerialUART::peek() {
|
||||
@@ -112,11 +239,15 @@ int SerialUART::peek() {
|
||||
if (!_running || !m) {
|
||||
return -1;
|
||||
}
|
||||
if (_peek >= 0) {
|
||||
return _peek;
|
||||
if (_polling) {
|
||||
_handleIRQ(false);
|
||||
} else {
|
||||
_pumpFIFO();
|
||||
}
|
||||
_peek = uart_getc(_uart);
|
||||
return _peek;
|
||||
if (_writer != _reader) {
|
||||
return _queue[_reader];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SerialUART::read() {
|
||||
@@ -124,12 +255,20 @@ int SerialUART::read() {
|
||||
if (!_running || !m) {
|
||||
return -1;
|
||||
}
|
||||
if (_peek >= 0) {
|
||||
int ret = _peek;
|
||||
_peek = -1;
|
||||
if (_polling) {
|
||||
_handleIRQ(false);
|
||||
} else {
|
||||
_pumpFIFO();
|
||||
}
|
||||
if (_writer != _reader) {
|
||||
auto ret = _queue[_reader];
|
||||
asm volatile("" ::: "memory"); // Ensure the value is read before advancing
|
||||
auto next_reader = (_reader + 1) % _fifoSize;
|
||||
asm volatile("" ::: "memory"); // Ensure the reader value is only written once, correctly
|
||||
_reader = next_reader;
|
||||
return ret;
|
||||
}
|
||||
return uart_getc(_uart);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SerialUART::available() {
|
||||
@@ -137,7 +276,12 @@ int SerialUART::available() {
|
||||
if (!_running || !m) {
|
||||
return 0;
|
||||
}
|
||||
return (uart_is_readable(_uart)) ? 1 : 0;
|
||||
if (_polling) {
|
||||
_handleIRQ(false);
|
||||
} else {
|
||||
_pumpFIFO();
|
||||
}
|
||||
return (_writer - _reader) % _fifoSize;
|
||||
}
|
||||
|
||||
int SerialUART::availableForWrite() {
|
||||
@@ -145,6 +289,9 @@ int SerialUART::availableForWrite() {
|
||||
if (!_running || !m) {
|
||||
return 0;
|
||||
}
|
||||
if (_polling) {
|
||||
_handleIRQ(false);
|
||||
}
|
||||
return (uart_is_writable(_uart)) ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -153,7 +300,10 @@ void SerialUART::flush() {
|
||||
if (!_running || !m) {
|
||||
return;
|
||||
}
|
||||
uart_default_tx_wait_blocking();
|
||||
if (_polling) {
|
||||
_handleIRQ(false);
|
||||
}
|
||||
uart_tx_wait_blocking(_uart);
|
||||
}
|
||||
|
||||
size_t SerialUART::write(uint8_t c) {
|
||||
@@ -161,6 +311,9 @@ size_t SerialUART::write(uint8_t c) {
|
||||
if (!_running || !m) {
|
||||
return 0;
|
||||
}
|
||||
if (_polling) {
|
||||
_handleIRQ(false);
|
||||
}
|
||||
uart_putc_raw(_uart, c);
|
||||
return 1;
|
||||
}
|
||||
@@ -170,6 +323,9 @@ size_t SerialUART::write(const uint8_t *p, size_t len) {
|
||||
if (!_running || !m) {
|
||||
return 0;
|
||||
}
|
||||
if (_polling) {
|
||||
_handleIRQ(false);
|
||||
}
|
||||
size_t cnt = len;
|
||||
while (cnt) {
|
||||
uart_putc_raw(_uart, *p);
|
||||
@@ -183,8 +339,17 @@ SerialUART::operator bool() {
|
||||
return _running;
|
||||
}
|
||||
|
||||
#if defined(PIN_SERIAL1_RTS)
|
||||
SerialUART Serial1(uart0, PIN_SERIAL1_TX, PIN_SERIAL1_RX, PIN_SERIAL1_RTS, PIN_SERIAL1_CTS);
|
||||
#else
|
||||
SerialUART Serial1(uart0, PIN_SERIAL1_TX, PIN_SERIAL1_RX);
|
||||
#endif
|
||||
|
||||
#if defined(PIN_SERIAL2_RTS)
|
||||
SerialUART Serial2(uart1, PIN_SERIAL2_TX, PIN_SERIAL2_RX, PIN_SERIAL2_RTS, PIN_SERIAL2_CTS);
|
||||
#else
|
||||
SerialUART Serial2(uart1, PIN_SERIAL2_TX, PIN_SERIAL2_RX);
|
||||
#endif
|
||||
|
||||
void arduino::serialEvent1Run(void) {
|
||||
if (serialEvent1 && Serial1.available()) {
|
||||
@@ -197,3 +362,43 @@ void arduino::serialEvent2Run(void) {
|
||||
serialEvent2();
|
||||
}
|
||||
}
|
||||
|
||||
// IRQ handler, called when FIFO > 1/8 full or when it had held unread data for >32 bit times
|
||||
void __not_in_flash_func(SerialUART::_handleIRQ)(bool inIRQ) {
|
||||
if (inIRQ) {
|
||||
uint32_t owner;
|
||||
if (!mutex_try_enter(&_fifoMutex, &owner)) {
|
||||
// Main app on the other core has the mutex so it is
|
||||
// in the process of pulling data out of the HW FIFO
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ICR is write-to-clear
|
||||
uart_get_hw(_uart)->icr = UART_UARTICR_RTIC_BITS | UART_UARTICR_RXIC_BITS;
|
||||
while (uart_is_readable(_uart)) {
|
||||
auto val = uart_getc(_uart);
|
||||
auto next_writer = _writer + 1;
|
||||
if (next_writer == _fifoSize) {
|
||||
next_writer = 0;
|
||||
}
|
||||
if (next_writer != _reader) {
|
||||
_queue[_writer] = val;
|
||||
asm volatile("" ::: "memory"); // Ensure the queue is written before the written count advances
|
||||
// Avoid using division or mod because the HW divider could be in use
|
||||
_writer = next_writer;
|
||||
} else {
|
||||
// TODO: Overflow
|
||||
}
|
||||
}
|
||||
if (inIRQ) {
|
||||
mutex_exit(&_fifoMutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void __not_in_flash_func(_uart0IRQ)() {
|
||||
Serial1._handleIRQ();
|
||||
}
|
||||
|
||||
static void __not_in_flash_func(_uart1IRQ)() {
|
||||
Serial2._handleIRQ();
|
||||
}
|
||||
|
||||
@@ -23,22 +23,28 @@
|
||||
#include <Arduino.h>
|
||||
#include "api/HardwareSerial.h"
|
||||
#include <stdarg.h>
|
||||
#include <queue>
|
||||
#include "CoreMutex.h"
|
||||
|
||||
extern "C" typedef struct uart_inst uart_inst_t;
|
||||
|
||||
#define UART_PIN_NOT_DEFINED (255u)
|
||||
class SerialUART : public HardwareSerial {
|
||||
public:
|
||||
SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx);
|
||||
SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx, pin_size_t rts = UART_PIN_NOT_DEFINED, pin_size_t cts = UART_PIN_NOT_DEFINED);
|
||||
|
||||
// Select the pinout. Call before .begin()
|
||||
bool setRX(pin_size_t pin);
|
||||
bool setTX(pin_size_t pin);
|
||||
bool setRTS(pin_size_t pin);
|
||||
bool setCTS(pin_size_t pin);
|
||||
bool setPinout(pin_size_t tx, pin_size_t rx) {
|
||||
bool ret = setRX(rx);
|
||||
ret &= setTX(tx);
|
||||
return ret;
|
||||
}
|
||||
bool setFIFOSize(size_t size);
|
||||
bool setPollingMode(bool mode = true);
|
||||
|
||||
void begin(unsigned long baud = 115200) override {
|
||||
begin(baud, SERIAL_8N1);
|
||||
@@ -56,13 +62,25 @@ public:
|
||||
using Print::write;
|
||||
operator bool() override;
|
||||
|
||||
// Not to be called by users, only from the IRQ handler. In public so that the C-language IQR callback can access it
|
||||
void _handleIRQ(bool inIRQ = true);
|
||||
|
||||
private:
|
||||
bool _running = false;
|
||||
uart_inst_t *_uart;
|
||||
pin_size_t _tx, _rx;
|
||||
pin_size_t _rts, _cts;
|
||||
int _baud;
|
||||
int _peek;
|
||||
mutex_t _mutex;
|
||||
bool _polling = false;
|
||||
|
||||
// Lockless, IRQ-handled circular queue
|
||||
uint32_t _writer;
|
||||
uint32_t _reader;
|
||||
size_t _fifoSize = 32;
|
||||
uint8_t *_queue;
|
||||
mutex_t _fifoMutex; // Only needed when non-IRQ updates _writer
|
||||
void _pumpFIFO(); // User space FIFO transfer
|
||||
};
|
||||
|
||||
extern SerialUART Serial1; // HW UART 0
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef USE_TINYUSB
|
||||
#if !defined(USE_TINYUSB) && !defined(NO_USB)
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "CoreMutex.h"
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018, hathach for Adafruit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// COMMON CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
#ifdef USE_TINYUSB
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#else
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
|
||||
#endif
|
||||
|
||||
//#ifndef CFG_TUSB_MCU
|
||||
// #define CFG_TUSB_MCU OPT_MCU_RP2040
|
||||
//#endif
|
||||
#define CFG_TUSB_OS OPT_OS_PICO
|
||||
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
//#if CFG_TUSB_DEBUG
|
||||
// #define tu_printf serial1_printf
|
||||
// extern int serial1_printf(const char *__restrict __format, ...);
|
||||
//#endif
|
||||
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define CFG_TUD_ENDOINT0_SIZE 64
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_CDC 1
|
||||
#define CFG_TUD_MSC 1
|
||||
#define CFG_TUD_HID 1
|
||||
#define CFG_TUD_MIDI 1
|
||||
#define CFG_TUD_VENDOR 1
|
||||
|
||||
// CDC FIFO size of TX and RX
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE 256
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE 256
|
||||
|
||||
// MSC Buffer size of Device Mass storage
|
||||
#define CFG_TUD_MSC_BUFSIZE 512
|
||||
|
||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
#define CFG_TUD_HID_BUFSIZE 64
|
||||
|
||||
// MIDI FIFO size of TX and RX
|
||||
#define CFG_TUD_MIDI_RX_BUFSIZE 128
|
||||
#define CFG_TUD_MIDI_TX_BUFSIZE 128
|
||||
|
||||
// Vendor FIFO size of TX and RX
|
||||
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
|
||||
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
@@ -20,6 +20,10 @@ typedef enum {
|
||||
OUTPUT = 0x1,
|
||||
INPUT_PULLUP = 0x2,
|
||||
INPUT_PULLDOWN = 0x3,
|
||||
OUTPUT_2MA = 0x4,
|
||||
OUTPUT_4MA = 0x5,
|
||||
OUTPUT_8MA = 0x6,
|
||||
OUTPUT_12MA = 0x7,
|
||||
} PinMode;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -110,11 +110,23 @@ typedef const void* uint_farptr_t;
|
||||
#define pgm_read_ptr(addr) (*(void *const *)(addr))
|
||||
#else
|
||||
// Supports misaligned addresses
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
#define pgm_read_word(addr) ((unsigned short)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8)))
|
||||
#define pgm_read_dword(addr) ((unsigned long)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8)) | \
|
||||
(pgm_read_byte((intptr_t)addr + 2) << 16) | (pgm_read_byte((intptr_t)addr + 3) << 24))
|
||||
#define pgm_read_ptr(addr) ((void *)pgm_read_dword(addr))
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
static inline unsigned char pgm_read_byte(const void *addr) {
|
||||
return *(const unsigned char *)(addr);
|
||||
}
|
||||
static inline unsigned short pgm_read_word(const void *addr) {
|
||||
const unsigned char *a = (const unsigned char *)addr;
|
||||
return pgm_read_byte(a) | ( pgm_read_byte(a + 1) << 8 );
|
||||
}
|
||||
static inline unsigned long pgm_read_dword(const void *addr) {
|
||||
const unsigned char *a = (const unsigned char *)addr;
|
||||
return pgm_read_byte(a) | ( pgm_read_byte(a + 1) << 8 ) | ( pgm_read_byte(a + 2) << 16 ) | ( pgm_read_byte(a + 3) << 24 );
|
||||
}
|
||||
static inline void *pgm_read_ptr(const void *addr) {
|
||||
return (void*) pgm_read_dword(addr);
|
||||
}
|
||||
static inline float pgm_read_float(const void *addr) {
|
||||
union {
|
||||
void *p;
|
||||
@@ -123,6 +135,10 @@ static inline float pgm_read_float(const void *addr) {
|
||||
x.p = pgm_read_ptr(addr);
|
||||
return x.f;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
|
||||
|
||||
@@ -41,7 +41,7 @@ void initVariant() { }
|
||||
// Optional 2nd core setup and loop
|
||||
extern void setup1() __attribute__((weak));
|
||||
extern void loop1() __attribute__((weak));
|
||||
static void main1() {
|
||||
extern "C" void main1() {
|
||||
rp2040.fifo.registerCore();
|
||||
if (setup1) {
|
||||
setup1();
|
||||
@@ -61,6 +61,7 @@ extern "C" int main() {
|
||||
mutex_init(&_pioMutex);
|
||||
initVariant();
|
||||
|
||||
#ifndef NO_USB
|
||||
#ifdef USE_TINYUSB
|
||||
TinyUSB_Device_Init(0);
|
||||
|
||||
@@ -72,11 +73,13 @@ extern "C" int main() {
|
||||
Serial.begin(115200);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined DEBUG_RP2040_PORT
|
||||
DEBUG_RP2040_PORT.begin();
|
||||
#endif
|
||||
|
||||
#if defined DEBUG_RP2040_PORT
|
||||
DEBUG_RP2040_PORT.begin(115200);
|
||||
#endif
|
||||
|
||||
#ifndef NO_USB
|
||||
if (setup1 || loop1) {
|
||||
rp2040.fifo.begin(2);
|
||||
multicore_launch_core1(main1);
|
||||
@@ -84,6 +87,7 @@ extern "C" int main() {
|
||||
rp2040.fifo.begin(1);
|
||||
}
|
||||
rp2040.fifo.registerCore();
|
||||
#endif
|
||||
|
||||
setup();
|
||||
while (true) {
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
; pio_uart for the Raspberry Pi Pico RP2040
|
||||
;
|
||||
; Based loosely off of the uart_rx/_tx examples in the pico-examples repo,
|
||||
; but heavily modified and optimized to not require changing the PIO
|
||||
; clocks so that Tone and Servo won't be affected, and multiple different
|
||||
; PIO ports can be run at different baud at the same time.
|
||||
;
|
||||
; Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||
;
|
||||
; This library is free software; you can redistribute it and/or
|
||||
; modify it under the terms of the GNU Lesser General Public
|
||||
; License as published by the Free Software Foundation; either
|
||||
; version 2.1 of the License, or (at your option) any later version.
|
||||
;
|
||||
; This library is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; Lesser General Public License for more details.
|
||||
;
|
||||
; 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
|
||||
|
||||
|
||||
|
||||
.program pio_tx
|
||||
.side_set 1 opt
|
||||
|
||||
; We shift out the start and stop bit as part of the FIFO
|
||||
set x, 9
|
||||
|
||||
pull side 1 ; Force stop bit
|
||||
|
||||
; Send the bits
|
||||
bitloop:
|
||||
out pins, 1
|
||||
mov y, isr ; ISR is loaded by the setup routine with the period-1 count
|
||||
wait_bit:
|
||||
jmp y-- wait_bit
|
||||
jmp x-- bitloop
|
||||
|
||||
|
||||
|
||||
% c-sdk {
|
||||
|
||||
static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_tx) {
|
||||
// Tell PIO to initially drive output-high on the selected pin, then map PIO
|
||||
// onto that pin with the IO muxes.
|
||||
pio_sm_set_pins_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
|
||||
pio_sm_set_pindirs_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
|
||||
pio_gpio_init(pio, pin_tx);
|
||||
|
||||
pio_sm_config c = pio_tx_program_get_default_config(offset);
|
||||
|
||||
// OUT shifts to right, no autopull
|
||||
sm_config_set_out_shift(&c, true, false, 32);
|
||||
|
||||
// We are mapping both OUT and side-set to the same pin, because sometimes
|
||||
// we need to assert user data onto the pin (with OUT) and sometimes
|
||||
// assert constant values (start/stop bit)
|
||||
sm_config_set_out_pins(&c, pin_tx, 1);
|
||||
sm_config_set_sideset_pins(&c, pin_tx);
|
||||
|
||||
// We only need TX, so get an 8-deep FIFO!
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
|
||||
.program pio_rx
|
||||
|
||||
; 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)
|
||||
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
|
||||
|
||||
; 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
|
||||
|
||||
|
||||
% c-sdk {
|
||||
static inline void pio_rx_program_init(PIO pio, uint sm, uint offset, uint pin) {
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
|
||||
pio_gpio_init(pio, pin);
|
||||
gpio_pull_up(pin);
|
||||
|
||||
pio_sm_config c = pio_rx_program_get_default_config(offset);
|
||||
sm_config_set_in_pins(&c, pin); // for WAIT, IN
|
||||
sm_config_set_jmp_pin(&c, pin); // for JMP
|
||||
// Shift to right, autopull disabled
|
||||
sm_config_set_in_shift(&c, true, false, 32);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
}
|
||||
|
||||
%}
|
||||
@@ -0,0 +1,107 @@
|
||||
// -------------------------------------------------- //
|
||||
// This file is autogenerated by pioasm; do not edit! //
|
||||
// -------------------------------------------------- //
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
#include "hardware/pio.h"
|
||||
#endif
|
||||
|
||||
// ------ //
|
||||
// pio_tx //
|
||||
// ------ //
|
||||
|
||||
#define pio_tx_wrap_target 0
|
||||
#define pio_tx_wrap 5
|
||||
|
||||
static const uint16_t pio_tx_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0xe029, // 0: set x, 9
|
||||
0x98a0, // 1: pull block side 1
|
||||
0x6001, // 2: out pins, 1
|
||||
0xa046, // 3: mov y, isr
|
||||
0x0084, // 4: jmp y--, 4
|
||||
0x0042, // 5: jmp x--, 2
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
static const struct pio_program pio_tx_program = {
|
||||
.instructions = pio_tx_program_instructions,
|
||||
.length = 6,
|
||||
.origin = -1,
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_tx_program_get_default_config(uint offset) {
|
||||
pio_sm_config c = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&c, offset + pio_tx_wrap_target, offset + pio_tx_wrap);
|
||||
sm_config_set_sideset(&c, 2, true, false);
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_tx) {
|
||||
// Tell PIO to initially drive output-high on the selected pin, then map PIO
|
||||
// onto that pin with the IO muxes.
|
||||
pio_sm_set_pins_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
|
||||
pio_sm_set_pindirs_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
|
||||
pio_gpio_init(pio, pin_tx);
|
||||
pio_sm_config c = pio_tx_program_get_default_config(offset);
|
||||
// OUT shifts to right, no autopull
|
||||
sm_config_set_out_shift(&c, true, false, 32);
|
||||
// We are mapping both OUT and side-set to the same pin, because sometimes
|
||||
// we need to assert user data onto the pin (with OUT) and sometimes
|
||||
// assert constant values (start/stop bit)
|
||||
sm_config_set_out_pins(&c, pin_tx, 1);
|
||||
sm_config_set_sideset_pins(&c, pin_tx);
|
||||
// We only need TX, so get an 8-deep FIFO!
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ------ //
|
||||
// pio_rx //
|
||||
// ------ //
|
||||
|
||||
#define pio_rx_wrap_target 0
|
||||
#define pio_rx_wrap 6
|
||||
|
||||
static const uint16_t pio_rx_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0xe032, // 0: set x, 18
|
||||
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
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
static const struct pio_program pio_rx_program = {
|
||||
.instructions = pio_rx_program_instructions,
|
||||
.length = 7,
|
||||
.origin = -1,
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_rx_program_get_default_config(uint offset) {
|
||||
pio_sm_config c = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&c, offset + pio_rx_wrap_target, offset + pio_rx_wrap);
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void pio_rx_program_init(PIO pio, uint sm, uint offset, uint pin) {
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
|
||||
pio_gpio_init(pio, pin);
|
||||
gpio_pull_up(pin);
|
||||
pio_sm_config c = pio_rx_program_get_default_config(offset);
|
||||
sm_config_set_in_pins(&c, pin); // for WAIT, IN
|
||||
sm_config_set_jmp_pin(&c, pin); // for JMP
|
||||
// Shift to right, autopull disabled
|
||||
sm_config_set_in_shift(&c, true, false, 32);
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,8 @@ static uint32_t analogScale = 255;
|
||||
static uint16_t analogFreq = 1000;
|
||||
static bool pwmInitted = false;
|
||||
static bool adcInitted = false;
|
||||
static uint16_t analogWritePseudoScale = 1;
|
||||
static uint16_t analogWriteSlowScale = 1;
|
||||
|
||||
auto_init_mutex(_dacMutex);
|
||||
|
||||
@@ -77,6 +79,21 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
|
||||
return;
|
||||
}
|
||||
if (!pwmInitted) {
|
||||
// For low frequencies, we need to scale the output max value up to achieve lower periods
|
||||
analogWritePseudoScale = 1;
|
||||
while (((clock_get_hz(clk_sys) / (float)(analogScale * analogFreq)) > 255.0) && (analogScale < 32678)) {
|
||||
analogWritePseudoScale++;
|
||||
analogScale *= 2;
|
||||
DEBUGCORE("Adjusting analogWrite values PS=%d, scale=%d\n", analogWritePseudoScale, analogScale);
|
||||
}
|
||||
// For high frequencies, we need to scale the output max value down to actually hit the frequency target
|
||||
analogWriteSlowScale = 1;
|
||||
while (((clock_get_hz(clk_sys) / (float)(analogScale * analogFreq)) < 2.0) && (analogScale > 32)) {
|
||||
analogWriteSlowScale++;
|
||||
analogScale /= 2;
|
||||
DEBUGCORE("Adjusting analogWrite values SS=%d, scale=%d\n", analogWriteSlowScale, analogScale);
|
||||
}
|
||||
|
||||
pwm_config c = pwm_get_default_config();
|
||||
pwm_config_set_clkdiv(&c, clock_get_hz(clk_sys) / (float)(analogScale * analogFreq));
|
||||
pwm_config_set_wrap(&c, analogScale);
|
||||
@@ -86,6 +103,9 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
|
||||
pwmInitted = true;
|
||||
}
|
||||
|
||||
val <<= analogWritePseudoScale;
|
||||
val >>= analogWriteSlowScale;
|
||||
|
||||
if (val < 0) {
|
||||
val = 0;
|
||||
} else if ((uint32_t)val > analogScale) {
|
||||
@@ -97,11 +117,15 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
|
||||
}
|
||||
|
||||
auto_init_mutex(_adcMutex);
|
||||
static int _readBits = 10;
|
||||
|
||||
extern "C" int analogRead(pin_size_t pin) {
|
||||
CoreMutex m(&_adcMutex);
|
||||
|
||||
if ((pin < A0) || (pin > A3) || !m) {
|
||||
pin_size_t maxPin = max(A0, A3);
|
||||
pin_size_t minPin = min(A0, A3);
|
||||
|
||||
if ((pin < minPin) || (pin > maxPin) || !m) {
|
||||
DEBUGCORE("ERROR: Illegal analogRead pin (%d)\n", pin);
|
||||
return 0;
|
||||
}
|
||||
@@ -109,8 +133,8 @@ extern "C" int analogRead(pin_size_t pin) {
|
||||
adc_init();
|
||||
}
|
||||
adc_gpio_init(pin);
|
||||
adc_select_input(pin - A0);
|
||||
return adc_read();
|
||||
adc_select_input(pin - minPin);
|
||||
return (_readBits < 12) ? adc_read() >> (12 - _readBits) : adc_read() << (_readBits - 12);
|
||||
}
|
||||
|
||||
extern "C" float analogReadTemp() {
|
||||
@@ -130,3 +154,10 @@ extern "C" float analogReadTemp() {
|
||||
float t = 27.0f - ((v * 3.3f / 4096.0f) - 0.706f) / 0.001721f; // From the datasheet
|
||||
return t;
|
||||
}
|
||||
|
||||
extern "C" void analogReadResolution(int bits) {
|
||||
CoreMutex m(&_adcMutex);
|
||||
if (m && ((bits > 0) && (bits < 32))) {
|
||||
_readBits = bits;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ extern "C" void pinMode(pin_size_t ulPin, PinMode ulMode) {
|
||||
case INPUT:
|
||||
gpio_init(ulPin);
|
||||
gpio_set_dir(ulPin, false);
|
||||
gpio_disable_pulls(ulPin);
|
||||
break;
|
||||
case INPUT_PULLUP:
|
||||
gpio_init(ulPin);
|
||||
@@ -42,7 +43,24 @@ extern "C" void pinMode(pin_size_t ulPin, PinMode ulMode) {
|
||||
gpio_put(ulPin, 1);
|
||||
break;
|
||||
case OUTPUT:
|
||||
case OUTPUT_4MA:
|
||||
gpio_init(ulPin);
|
||||
gpio_set_drive_strength(ulPin, GPIO_DRIVE_STRENGTH_4MA);
|
||||
gpio_set_dir(ulPin, true);
|
||||
break;
|
||||
case OUTPUT_2MA:
|
||||
gpio_init(ulPin);
|
||||
gpio_set_drive_strength(ulPin, GPIO_DRIVE_STRENGTH_2MA);
|
||||
gpio_set_dir(ulPin, true);
|
||||
break;
|
||||
case OUTPUT_8MA:
|
||||
gpio_init(ulPin);
|
||||
gpio_set_drive_strength(ulPin, GPIO_DRIVE_STRENGTH_8MA);
|
||||
gpio_set_dir(ulPin, true);
|
||||
break;
|
||||
case OUTPUT_12MA:
|
||||
gpio_init(ulPin);
|
||||
gpio_set_drive_strength(ulPin, GPIO_DRIVE_STRENGTH_12MA);
|
||||
gpio_set_dir(ulPin, true);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -38,7 +38,7 @@ extern "C" unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeo
|
||||
}
|
||||
|
||||
// Wait for assert
|
||||
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort));
|
||||
while ((!!gpio_get(pin) != !!state) && (time_us_64() < abort));
|
||||
uint64_t begin = time_us_64();
|
||||
if (begin >= abort) {
|
||||
return 0;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
@@ -20,6 +20,8 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
|
||||
Installation <install>
|
||||
IDE Menus <ide>
|
||||
|
||||
Platform.IO Integration <platformio>
|
||||
|
||||
Pin (Re)Assignment <pins>
|
||||
|
||||
Analog I/O <analog>
|
||||
@@ -27,6 +29,7 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
|
||||
EEPROM <eeprom>
|
||||
I2S Audio <i2s>
|
||||
Serial USB and UARTs <serial>
|
||||
"Software Serial" PIO UART <piouart>
|
||||
Servo <servo>
|
||||
SPI <spi>
|
||||
Wire(I2C) <wire>
|
||||
|
||||
+22
-3
@@ -135,6 +135,25 @@ The first line creates a file with the USB vendor and ID of the Picoprobe and te
|
||||
|
||||
Once Picoprobe permissions are set up properly, then select the board "Raspberry Pi Pico (Picoprobe)" in the Tools menu and upload as normal.
|
||||
|
||||
Debugging with Picoprobe, OpenOCD, and GDB
|
||||
------------------------------------------
|
||||
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation.
|
||||
Uploading Sketches with pico-debug
|
||||
----------------------------------
|
||||
pico-debug differs from Picoprobe in that pico-debug is a virtual debug pod that runs side-by-side on the same RP2040 that you run your code on; so, you only need one RP2040 board instead of two. pico-debug also differs from Picoprobe in that pico-debug is standards-based; it uses the CMSIS-DAP protocol, which means even software not specially written for the Raspberry Pi Pico can support it. pico-debug uses OpenOCD to handle your sketch uploads, and debugging can be accomplished with CMSIS-DAP capable debuggers including GDB.
|
||||
|
||||
Under Windows and macOS, any user should be able to access pico-debug automatically, but under Linux `udev` must be told about the device and to allow normal users access.
|
||||
|
||||
To set up user-level access to all CMSIS-DAP adapters on Ubuntu (and other OSes which use `udev`):
|
||||
|
||||
.. code::
|
||||
|
||||
echo 'ATTRS{product}=="*CMSIS-DAP*", MODE="664", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-CMSIS-DAP.rules
|
||||
sudo udevadm control --reload
|
||||
|
||||
The first line creates a file that recognizes all CMSIS-DAP adapters and tells UDEV to give users full access to it. The second causes `udev` to load this new rule. Note that you will need to unplug and re-plug in your device the first time you create this file, to allow udev to make the device node properly.
|
||||
|
||||
Once CMSIS-DAP permissions are set up properly, then select the board "Raspberry Pi Pico (pico-debug)" in the Tools menu.
|
||||
|
||||
When first connecting the USB port to your PC, you must copy pico-debug-gimmecache.uf2 to the Pi Pico to load pico-debug into RAM; after this, upload as normal.
|
||||
|
||||
Debugging with Picoprobe/pico-debug, OpenOCD, and GDB
|
||||
-----------------------------------------------------
|
||||
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation. For pico-debug, replace the raspberrypi-swd and picoprobe example OpenOCD arguments of "-f interface/raspberrypi-swd.cfg -f target/rp2040.cfg" or "-f interface/picoprobe.cfg -f target/rp2040.cfg" respectively in the Pico Getting Started manual with "-f board/pico-debug.cfg".
|
||||
|
||||
+10
-4
@@ -41,6 +41,12 @@ void rp2040.resumeOtherCore()
|
||||
|
||||
Resumes processing in the other core, where it left off.
|
||||
|
||||
|
||||
void rp2040.restartCore1()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Hard resets Core1 from Core 0 and restarts its operation from ``setup1()``.
|
||||
|
||||
Communicating Between Cores
|
||||
---------------------------
|
||||
|
||||
@@ -50,23 +56,23 @@ use the following functions to access a software-managed, multicore safe
|
||||
FIFO.
|
||||
|
||||
void rp2040.fifo.push(uint32_t)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Pushes a value to the other core. Will block if the FIFO is full.
|
||||
|
||||
bool rp2040.fifo.push_nb(uint32_t)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Pushes a value to the other core. If the FIFO is full, returns ``false``
|
||||
immediately and doesn't block. If the push is successful, returns ``true``.
|
||||
|
||||
uint32_t rp2040.fifo.pop()
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Reads a value from this core's FIFO. Blocks until one is available.
|
||||
|
||||
bool rp2040.fifo.pop_nb(uint32_t *dest)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Reads a value from this core's FIFO and places it in dest. Will return
|
||||
``true`` if successful, or ``false`` if the pop would block.
|
||||
|
||||
@@ -26,6 +26,8 @@ Serial1 (UART0), Serial2 (UART1)
|
||||
|
||||
::setRX(pin)
|
||||
::setTX(pin)
|
||||
::setRTS(pin)
|
||||
::setCTS(pin)
|
||||
|
||||
SPI (SPI0), SPI1 (SPI1)
|
||||
-----------------------
|
||||
@@ -33,6 +35,7 @@ SPI (SPI0), SPI1 (SPI1)
|
||||
.. code:: cpp
|
||||
|
||||
::setSCK(pin)
|
||||
::setCS(pin)
|
||||
::setRX(pin)
|
||||
::setTX(pin)
|
||||
|
||||
@@ -58,3 +61,7 @@ it use a non-default pinout with a simple call
|
||||
SD.begin(5);
|
||||
}
|
||||
|
||||
Pad Strength
|
||||
============
|
||||
|
||||
The Raspberry Pi Pico has the ability to set the current that a pin (actually the pad associated with it) is capable of supplying. The current can be set to values of 2mA, 4mA, 8mA and 12mA. By default, on a reset, the setting is 4mA. A `pinMode(x, OUTPUT)`, where `x` is the pin number, is also the default setting. 4 settings have been added for use with `pinMode`: `OUTPUT_2MA`, `OUTPUT_4MA`, which has the same behavior as `OUTPUT`, `OUTPUT_8MA` and `OUTPUT_12MA`.
|
||||
@@ -0,0 +1,23 @@
|
||||
"SoftwareSerial" PIO-based UART
|
||||
================================
|
||||
|
||||
Equivalent to the Arduino SoftwareSerial library, an emulated UART using
|
||||
one or two PIO state machines is included in the Arduino-Pico core. This
|
||||
allows for up to 8 additional serial ports to be run from the RP2040 without
|
||||
requiring additional CPU resources.
|
||||
|
||||
Instantiate a ``SerialPIO(txpin, rxpin, fifosize)`` object in your sketch and then
|
||||
use it the same as any other serial port. Even, odd, and no parity modes
|
||||
are supported, as well as data sizes from 5- to 8-bits. Fifosize, if not
|
||||
specified, defaults to 32 bytes.
|
||||
|
||||
To instantiate only a serial transmit or receive unit, pass in
|
||||
``SerialPIO::NOPIN`` as the ``txpin`` or ``rxpin``.
|
||||
|
||||
For example, to make a transmit-only port on GP16
|
||||
.. code:: cpp
|
||||
|
||||
SerialPIO transmitter( 16, SerialPIO::NOPIN );
|
||||
|
||||
For detailed information about the Serial ports, see the
|
||||
Arduino `Serial Reference <https://www.arduino.cc/reference/en/language/functions/communication/serial/>`_ .
|
||||
@@ -0,0 +1,219 @@
|
||||
Using this core with PlatformIO
|
||||
===============================
|
||||
|
||||
What is PlatformIO?
|
||||
-------------------
|
||||
|
||||
`PlatformIO <https://platformio.org/>`__ is a free, open-source build-tool written in Python, which also integrates into VSCode code as an extension.
|
||||
|
||||
PlatformIO significantly simplifies writing embedded software by offering a unified build system, yet being able to create project files for many different IDEs, including VSCode, Eclipse, CLion, etc.
|
||||
Through this, PlatformIO can offer extensive features such as IntelliSense (autocomplete), debugging, unit testing etc., which not available in the standard Arduino IDE.
|
||||
|
||||
The Arduino IDE experience:
|
||||
|
||||
.. image:: images/the_arduinoide_experience.png
|
||||
|
||||
The PlatformIO experience:
|
||||
|
||||
.. image:: images/the_platformio_experience.png
|
||||
|
||||
Refer to the general documentation at https://docs.platformio.org/.
|
||||
|
||||
Especially useful is the `Getting started with VSCode + PlatformIO <https://docs.platformio.org/en/latest/integration/ide/vscode.html#installation), [CLI reference](https://docs.platformio.org/en/latest/core/index.html) and [platformio.ini options](https://docs.platformio.org/en/latest/projectconf/index.html)>`__ page.
|
||||
|
||||
Hereafter it is assumed that you have a basic understanding of PlatformIO in regards to project creation, project file structure and building and uploading PlatformIO projects, through reading the above pages.
|
||||
|
||||
Current state of development
|
||||
----------------------------
|
||||
|
||||
At the time of writing, PlatformIO integration for this core is a work-in-progress and not yet merged into mainline PlatformIO. This is subject to change soon.
|
||||
|
||||
If you want to use the PlatformIO integration right now, make sure you first create a standard Raspberry Pi Pico + Arduino project within PlatformIO.
|
||||
This will give you a project with the ``platformio.ini``
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[env:pico]
|
||||
platform = raspberrypi
|
||||
board = pico
|
||||
framework = arduino
|
||||
|
||||
Here, you need to change the `platform` to take advantage of the features described hereunder.
|
||||
You *also* need to inject two PlatformIO packages, one for the compiler toolchain and one for the Arduino core package.
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[env:pico]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
board = pico
|
||||
framework = arduino
|
||||
; note that download link for toolchain is specific for OS. see https://github.com/earlephilhower/pico-quick-toolchain/releases.
|
||||
platform_packages =
|
||||
maxgerhardt/framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git
|
||||
maxgerhardt/toolchain-pico@https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.1-a/x86_64-w64-mingw32.arm-none-eabi-7855b0c.210706.zip
|
||||
|
||||
When the support for this core has been merged into mainline PlatformIO, this notice will be removed and a standard `platformio.ini` as shown above will work as a base.
|
||||
|
||||
Selecting the new core
|
||||
----------------------
|
||||
|
||||
Prerequisite for using this core is to tell PlatformIO to switch to it.
|
||||
There will be board definition files where the Earle-Philhower core will
|
||||
be the default since it's a board that only exists in this core (and not
|
||||
the other https://github.com/arduino/ArduinoCore-mbed). To switch boards
|
||||
for which this is not the default core (e.g. the standard
|
||||
``board = pico``), the directive
|
||||
|
||||
.. code:: ini
|
||||
|
||||
board_build.core = earlephilhower
|
||||
|
||||
must be added to the ``platformio.ini``. This controls the `core
|
||||
switching
|
||||
logic <https://github.com/maxgerhardt/platform-raspberrypi/blob/77e0d3a29d1dbf00fd3ec3271104e3bf4820869c/builder/frameworks/arduino/arduino.py#L27-L32>`__.
|
||||
|
||||
Flash size
|
||||
----------
|
||||
|
||||
Controlled via specifying the size allocated for the filesystem.
|
||||
Available sketch size is calculated accordingly by using (as in
|
||||
``makeboards.py``) that number and the (constant) EEPROM size (4096
|
||||
bytes) and the total flash size as known to PlatformIO via the board
|
||||
definition file. The expression on the right can involve "b","k","m"
|
||||
(bytes/kilobytes/megabytes) and floating point numbers. This makes it
|
||||
actually more flexible than in the Arduino IDE where there is a finite
|
||||
list of choices. Calculations happen in `the
|
||||
platform <https://github.com/maxgerhardt/platform-raspberrypi/blob/77e0d3a29d1dbf00fd3ec3271104e3bf4820869c/builder/main.py#L118-L184>`__.
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; in reference to a board = pico config (2MB flash)
|
||||
; Flash Size: 2MB (Sketch: 1MB, FS:1MB)
|
||||
board_build.filesystem_size = 1m
|
||||
; Flash Size: 2MB (No FS)
|
||||
board_build.filesystem_size = 0m
|
||||
; Flash Size: 2MB (Sketch: 0.5MB, FS:1.5MB)
|
||||
board_build.filesystem_size = 1.5m
|
||||
|
||||
CPU Speed
|
||||
---------
|
||||
|
||||
As for all other PlatformIO platforms, the ``f_cpu`` macro value (which
|
||||
is passed to the core) can be changed as
|
||||
`documented <https://docs.platformio.org/en/latest/boards/raspberrypi/pico.html#configuration>`__
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; 133MHz
|
||||
board_build.f_cpu = 133000000L
|
||||
|
||||
Debug Port
|
||||
----------
|
||||
|
||||
Via
|
||||
`build_flags <https://docs.platformio.org/en/latest/projectconf/section_env_build.html#build-flags>`__
|
||||
as done for many other cores
|
||||
(`example <https://docs.platformio.org/en/latest/platforms/ststm32.html#configuration>`__).
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Debug Port: Serial
|
||||
build_flags = -DDEBUG_RP2040_PORT=Serial
|
||||
; Debug Port: Serial 1
|
||||
build_flags = -DDEBUG_RP2040_PORT=Serial1
|
||||
; Debug Port: Serial 2
|
||||
build_flags = -DDEBUG_RP2040_PORT=Serial2
|
||||
|
||||
Debug Level
|
||||
-----------
|
||||
|
||||
Done again by directly adding the needed `build
|
||||
flags <https://github.com/earlephilhower/arduino-pico/blob/05356da2c5552413a442f742e209c6fa92823666/boards.txt#L104-L114>`__.
|
||||
When wanting to define multiple build flags, they must be accumulated in
|
||||
either a sing line or a newline-separated expression.
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Debug level: Core
|
||||
build_flags = -DDEBUG_RP2040_CORE
|
||||
; Debug level: SPI
|
||||
build_flags = -DDEBUG_RP2040_SPI
|
||||
; Debug level: Wire
|
||||
build_flags = -DDEBUG_RP2040_WIRE
|
||||
; Debug level: All
|
||||
build_flags = -DDEBUG_RP2040_WIRE -DDEBUG_RP2040_SPI -DDEBUG_RP2040_CORE
|
||||
; Debug level: NDEBUG
|
||||
build_flags = -DNDEBUG
|
||||
|
||||
; example: Debug port on serial 2 and all debug output
|
||||
build_flags = -DDEBUG_RP2040_WIRE -DDEBUG_RP2040_SPI -DDEBUG_RP2040_CORE -DDEBUG_RP2040_PORT=Serial2
|
||||
; equivalent to above
|
||||
build_flags =
|
||||
-DDEBUG_RP2040_WIRE
|
||||
-DDEBUG_RP2040_SPI
|
||||
-DDEBUG_RP2040_CORE
|
||||
-DDEBUG_RP2040_PORT=Serial2
|
||||
|
||||
USB Stack
|
||||
---------
|
||||
|
||||
Not specifying any special build flags regarding this gives one the
|
||||
default Pico SDK USB stack. To change it, add
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Adafruit TinyUSB
|
||||
build_flags = -DUSE_TINYUSB
|
||||
; No USB stack
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB
|
||||
|
||||
Note that the special "No USB" setting is also supported, through the
|
||||
shortcut-define ``PIO_FRAMEWORK_ARDUINO_NO_USB``.
|
||||
|
||||
|
||||
Selecting a different core version
|
||||
----------------------------------
|
||||
|
||||
If you wish to use a different version of the core, e.g., the latest git
|
||||
``master`` version, you can use a
|
||||
`platform_packages <https://docs.platformio.org/en/latest/projectconf/section_env_platform.html#platform-packages>`__
|
||||
directive to do so. Simply specify that the framework package
|
||||
(``framework-arduinopico``) comes from a different source.
|
||||
|
||||
.. code:: ini
|
||||
|
||||
platform_packages =
|
||||
framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#master
|
||||
|
||||
Whereas the ``#master`` can also be replaced by a ``#branchname`` or a
|
||||
``#commithash``. If left out, it will pull the default branch, which is ``master``.
|
||||
|
||||
The ``file://`` pseudo-protocol can also be used instead of ``https://`` to point to a
|
||||
local copy of the core (with e.g. some modifications) on disk.
|
||||
|
||||
Note that this can only be done for versions that have the PlatformIO
|
||||
builder script it in, so versions before 1.9.2 are not supported.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
The following example ``platformio.ini`` can be used for a Raspberry Pi Pico
|
||||
and 0.5MByte filesystem.
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[env:pico]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
board = pico
|
||||
framework = arduino
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
; note that download link for toolchain is specific for OS. see https://github.com/earlephilhower/pico-quick-toolchain/releases.
|
||||
platform_packages =
|
||||
maxgerhardt/framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git
|
||||
maxgerhardt/toolchain-pico@https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.1-a/x86_64-w64-mingw32.arm-none-eabi-7855b0c.210706.zip
|
||||
|
||||
|
||||
The initial project structure should be generated just creating a new
|
||||
project for the Pico and the Arduino framework, after which the
|
||||
auto-generated ``platformio.ini`` can be adapted per above.
|
||||
@@ -24,5 +24,23 @@ Configure their pins using the ``setXXX`` calls prior to calling ``begin()``
|
||||
Serial1.setTX(pin);
|
||||
Serial1.begin(baud);
|
||||
|
||||
The size of the receive FIFO may also be adjusted from the default 32 bytes by
|
||||
using the ``setFIFOSize`` call prior to calling ``begin()``
|
||||
|
||||
.. code:: cpp
|
||||
Serial1.setFIFOSize(128);
|
||||
Serial1.begin(baud);
|
||||
|
||||
The FIFO is normally handled via an interrupt, which reduced CPU load and
|
||||
makes it less likely to lose characters. However, the FIFO introduces up
|
||||
to 32 bit-times of delay before serial data is available to the application.
|
||||
|
||||
For applications where this is an issue (i.e. very low baud), use
|
||||
``setPollingMode(true)`` before calling ``begin()``
|
||||
|
||||
.. code:: cpp
|
||||
Serial1.setPollingMode(true);
|
||||
Serial1.begin(110)
|
||||
|
||||
For detailed information about the Serial ports, see the
|
||||
Arduino `Serial Reference <https://www.arduino.cc/reference/en/language/functions/communication/serial/>`_ .
|
||||
|
||||
+29
-6
@@ -9,12 +9,35 @@
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
setup1 KEYWORD2
|
||||
loop2 KEYWORD2
|
||||
|
||||
setup1 KEYWORD2
|
||||
loop1 KEYWORD2
|
||||
|
||||
analogWriteFreq KEYWORD2
|
||||
analogWriteRange KEYWORD2
|
||||
analogWriteResolution KEYWORD2
|
||||
analogWriteResolution KEYWORD2
|
||||
|
||||
######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
push KEYWORD2
|
||||
push_nb KEYWORD2
|
||||
pop KEYWORD2
|
||||
pop_nb KEYWORD2
|
||||
|
||||
rp2040 KEYWORD2
|
||||
RP2040 KEYWORD2
|
||||
usToPIOCycles KEYWORD2
|
||||
f_cpu KEYWORD2
|
||||
getCycleCount KEYWORD2
|
||||
getCycleCount64 KEYWORD2
|
||||
idleOtherCore KEYWORD2
|
||||
resumeOtherCore KEYWORD2
|
||||
|
||||
PIOProgram KEYWORD2
|
||||
prepare KEYWORD2
|
||||
SerialPIO KEYWORD2
|
||||
setFIFOSize KEYWORD2
|
||||
setPollingMode KEYWORD2
|
||||
|
||||
OUTPUT_2MA LITERAL1
|
||||
OUTPUT_4MA LITERAL1
|
||||
OUTPUT_8MA LITERAL1
|
||||
OUTPUT_12MA LITERAL1
|
||||
|
||||
Binary file not shown.
@@ -24,7 +24,7 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = __FLASH_LENGTH__
|
||||
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
|
||||
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = __RAM_LENGTH__
|
||||
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
|
||||
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#define _PICO_VERSION_H
|
||||
|
||||
#define PICO_SDK_VERSION_MAJOR 1
|
||||
#define PICO_SDK_VERSION_MINOR 2
|
||||
#define PICO_SDK_VERSION_MINOR 3
|
||||
#define PICO_SDK_VERSION_REVISION 0
|
||||
#define PICO_SDK_VERSION_STRING "1.2.0"
|
||||
#define PICO_SDK_VERSION_STRING "1.3.0"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
-iwithprefixbefore/cores/rp2040/api/deprecated-avr-comp/
|
||||
-iwithprefixbefore/lib/pico_base/
|
||||
-iwithprefixbefore/pico-examples/build/generated/pico_base
|
||||
-iwithprefixbefore/pico-extras/src/common/pico_audio/include
|
||||
-iwithprefixbefore/pico-extras/src/common/pico_util_buffer/include
|
||||
-iwithprefixbefore/pico-extras/src/rp2_common/pico_audio_i2s/include
|
||||
-iwithprefixbefore/pico-sdk/lib/tinyusb/src/
|
||||
-iwithprefixbefore/pico-sdk/src/boards/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_base/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_base/include/
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_binary_info/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_bit_ops/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_divider/include
|
||||
@@ -16,19 +14,23 @@
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_time/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_util/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_regs/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_regs/include/
|
||||
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_regs/include/
|
||||
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_structs/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/cmsis/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/cmsis/stub/CMSIS/Device/RaspberryPi/RP2040/Include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_adc/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_base/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_claim/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_clocks/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_divider/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_dma/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_exception/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_flash/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_gpio/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_i2c/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_interp/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_irq/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_rtc/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_pio/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_pll/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_pwm/include
|
||||
@@ -36,7 +38,6 @@
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_spi/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_sync/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_timer/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_timer/include/
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_uart/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_vreg/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_watchdog/include
|
||||
@@ -46,12 +47,9 @@
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_float/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_int64_ops/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_multicore/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_multicore/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_platform/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_platform/include/
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_printf/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_runtime/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_stdio/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_stdio_uart/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_stdio_usb/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_unique_id/include
|
||||
|
||||
Submodule libraries/Adafruit_TinyUSB_Arduino updated: d26aa1bbd2...4f2c0ab42a
Submodule
+1
Submodule libraries/ESP8266SdFat added at 43a65b42d5
+1
-1
Submodule libraries/Keyboard updated: dcc1a556bf...a6498d6228
@@ -13,6 +13,25 @@
|
||||
// How large of a file to test
|
||||
#define TESTSIZEKB 256
|
||||
|
||||
// Format speed in bytes/second. Static buffer so not re-entrant safe
|
||||
const char *rate(unsigned long start, unsigned long stop, unsigned long bytes) {
|
||||
static char buff[64];
|
||||
if (stop == start) {
|
||||
strcpy_P(buff, PSTR("Inf b/s"));
|
||||
} else {
|
||||
unsigned long delta = stop - start;
|
||||
float r = 1000.0 * (float)bytes / (float)delta;
|
||||
if (r >= 1000000.0) {
|
||||
sprintf_P(buff, PSTR("%0.2f MB/s"), r / 1000000.0);
|
||||
} else if (r >= 1000.0) {
|
||||
sprintf_P(buff, PSTR("%0.2f KB/s"), r / 1000.0);
|
||||
} else {
|
||||
sprintf_P(buff, PSTR("%d bytes/s"), (int)r);
|
||||
}
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
|
||||
void DoTest(FS *fs) {
|
||||
if (!fs->format()) {
|
||||
Serial.printf("Unable to format(), aborting\n");
|
||||
@@ -29,7 +48,7 @@ void DoTest(FS *fs) {
|
||||
}
|
||||
|
||||
Serial.printf("Creating %dKB file, may take a while...\n", TESTSIZEKB);
|
||||
long start = millis();
|
||||
unsigned long start = millis();
|
||||
File f = fs->open("/testwrite.bin", "w");
|
||||
if (!f) {
|
||||
Serial.printf("Unable to open file for writing, aborting\n");
|
||||
@@ -41,11 +60,11 @@ void DoTest(FS *fs) {
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
long stop = millis();
|
||||
Serial.printf("==> Time to write %dKB in 256b chunks = %ld milliseconds\n", TESTSIZEKB, stop - start);
|
||||
unsigned long stop = millis();
|
||||
Serial.printf("==> Time to write %dKB in 256b chunks = %lu milliseconds\n", TESTSIZEKB, stop - start);
|
||||
|
||||
f = fs->open("/testwrite.bin", "r");
|
||||
Serial.printf("==> Created file size = %d\n", f.size());
|
||||
Serial.printf("==> Created file size = %zu\n", f.size());
|
||||
f.close();
|
||||
|
||||
Serial.printf("Reading %dKB file sequentially in 256b chunks\n", TESTSIZEKB);
|
||||
@@ -58,7 +77,7 @@ void DoTest(FS *fs) {
|
||||
}
|
||||
f.close();
|
||||
stop = millis();
|
||||
Serial.printf("==> Time to read %dKB sequentially in 256b chunks = %ld milliseconds = %ld bytes/s\n", TESTSIZEKB, stop - start, TESTSIZEKB * 1024 / (stop - start) * 1000);
|
||||
Serial.printf("==> Time to read %dKB sequentially in 256b chunks = %lu milliseconds = %s\n", TESTSIZEKB, stop - start, rate(start, stop, TESTSIZEKB * 1024));
|
||||
|
||||
Serial.printf("Reading %dKB file MISALIGNED in flash and RAM sequentially in 256b chunks\n", TESTSIZEKB);
|
||||
start = millis();
|
||||
@@ -71,8 +90,7 @@ void DoTest(FS *fs) {
|
||||
}
|
||||
f.close();
|
||||
stop = millis();
|
||||
Serial.printf("==> Time to read %dKB sequentially MISALIGNED in flash and RAM in 256b chunks = %ld milliseconds = %ld bytes/s\n", TESTSIZEKB, stop - start, TESTSIZEKB * 1024 / (stop - start) * 1000);
|
||||
|
||||
Serial.printf("==> Time to read %dKB sequentially MISALIGNED in flash and RAM in 256b chunks = %lu milliseconds = %s\n", TESTSIZEKB, stop - start, rate(start, stop, TESTSIZEKB * 1024));
|
||||
|
||||
Serial.printf("Reading %dKB file in reverse by 256b chunks\n", TESTSIZEKB);
|
||||
start = millis();
|
||||
@@ -91,8 +109,7 @@ void DoTest(FS *fs) {
|
||||
}
|
||||
f.close();
|
||||
stop = millis();
|
||||
Serial.printf("==> Time to read %dKB in reverse in 256b chunks = %ld milliseconds = %ld bytes/s\n", TESTSIZEKB, stop - start, TESTSIZEKB * 1024 / (stop - start) * 1000);
|
||||
|
||||
Serial.printf("==> Time to read %dKB in reverse in 256b chunks = %lu milliseconds = %s\n", TESTSIZEKB, stop - start, rate(start, stop, TESTSIZEKB * 1024));
|
||||
|
||||
Serial.printf("Writing 64K file in 1-byte chunks\n");
|
||||
start = millis();
|
||||
@@ -102,7 +119,7 @@ void DoTest(FS *fs) {
|
||||
}
|
||||
f.close();
|
||||
stop = millis();
|
||||
Serial.printf("==> Time to write 64KB in 1b chunks = %ld milliseconds = %ld bytes/s\n", stop - start, 65536 / (stop - start) * 1000);
|
||||
Serial.printf("==> Time to write 64KB in 1b chunks = %lu milliseconds = %s\n", stop - start, rate(start, stop, 65536));
|
||||
|
||||
Serial.printf("Reading 64K file in 1-byte chunks\n");
|
||||
start = millis();
|
||||
@@ -113,9 +130,7 @@ void DoTest(FS *fs) {
|
||||
}
|
||||
f.close();
|
||||
stop = millis();
|
||||
Serial.printf("==> Time to read 64KB in 1b chunks = %ld milliseconds = %ld bytes/s\n", stop - start, 65536 / (stop - start) * 1000);
|
||||
|
||||
|
||||
Serial.printf("==> Time to read 64KB in 1b chunks = %lu milliseconds = %s\n", stop - start, rate(start, stop, 65536));
|
||||
}
|
||||
|
||||
void setup() {
|
||||
@@ -124,6 +139,7 @@ void setup() {
|
||||
Serial.printf("Beginning test\n");
|
||||
Serial.flush();
|
||||
DoTest(&TESTFS);
|
||||
Serial.println("done");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
Submodule libraries/LittleFS/lib/littlefs updated: 1863dc7883...ead50807f1
@@ -176,6 +176,9 @@ public:
|
||||
}
|
||||
|
||||
bool begin() override {
|
||||
if (_mounted) {
|
||||
return true;
|
||||
}
|
||||
if (_size <= 0) {
|
||||
DEBUGV("LittleFS size is <= zero");
|
||||
return false;
|
||||
|
||||
+1
-1
Submodule libraries/Mouse updated: 1b39fd21e5...be7395a597
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
This example reads audio data from the on-board PDM microphones, and prints
|
||||
out the samples to the Serial console. The Serial Plotter built into the
|
||||
Arduino IDE can be used to plot the audio data (Tools -> Serial Plotter)
|
||||
|
||||
Circuit:
|
||||
- Arduino Nano 33 BLE board, or
|
||||
- Arduino Nano RP2040 Connect, or
|
||||
- Arduino Portenta H7 board plus Portenta Vision Shield
|
||||
|
||||
This example code is in the public domain.
|
||||
*/
|
||||
|
||||
#include <PDM.h>
|
||||
|
||||
// default number of output channels
|
||||
static const char channels = 1;
|
||||
|
||||
// default PCM output frequency
|
||||
static const int frequency = 16000;
|
||||
|
||||
// Buffer to read samples into, each sample is 16-bits
|
||||
short sampleBuffer[512];
|
||||
|
||||
// Number of audio samples read
|
||||
volatile int samplesRead;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while (!Serial);
|
||||
|
||||
// Configure the data receive callback
|
||||
PDM.onReceive(onPDMdata);
|
||||
|
||||
// Optionally set the gain
|
||||
// Defaults to 20 on the BLE Sense and -10 on the Portenta Vision Shield
|
||||
// PDM.setGain(30);
|
||||
|
||||
// Initialize PDM with:
|
||||
// - one channel (mono mode)
|
||||
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
|
||||
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
|
||||
if (!PDM.begin(channels, frequency)) {
|
||||
Serial.println("Failed to start PDM!");
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Wait for samples to be read
|
||||
if (samplesRead) {
|
||||
|
||||
// Print samples to the serial monitor or plotter
|
||||
for (int i = 0; i < samplesRead; i++) {
|
||||
if(channels == 2) {
|
||||
Serial.print("L:");
|
||||
Serial.print(sampleBuffer[i]);
|
||||
Serial.print(" R:");
|
||||
i++;
|
||||
}
|
||||
Serial.println(sampleBuffer[i]);
|
||||
}
|
||||
|
||||
// Clear the read count
|
||||
samplesRead = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to process the data from the PDM microphone.
|
||||
* NOTE: This callback is executed as part of an ISR.
|
||||
* Therefore using `Serial` to print messages inside this function isn't supported.
|
||||
* */
|
||||
void onPDMdata() {
|
||||
// Query the number of available bytes
|
||||
int bytesAvailable = PDM.available();
|
||||
|
||||
// Read into the sample buffer
|
||||
PDM.read(sampleBuffer, bytesAvailable);
|
||||
|
||||
// 16-bit, 2 bytes per sample
|
||||
samplesRead = bytesAvailable / 2;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map PDM
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
PDM KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
begin KEYWORD2
|
||||
end KEYWORD2
|
||||
|
||||
available KEYWORD2
|
||||
read KEYWORD2
|
||||
|
||||
onReceive KEYWORD2
|
||||
|
||||
setGain KEYWORD2
|
||||
setBufferSize KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
@@ -0,0 +1,9 @@
|
||||
name=PDM
|
||||
version=1.0
|
||||
author=Arduino
|
||||
maintainer=Arduino <info@arduino.cc>
|
||||
sentence=Enables the communication with devices that use the PDM Bus. Specific implementation for nRF52.
|
||||
paragraph=
|
||||
category=Communication
|
||||
url=
|
||||
architectures=rp2040
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (c) 2019 Arduino LLC. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _PDM_H_INCLUDED
|
||||
#define _PDM_H_INCLUDED
|
||||
|
||||
#include <Arduino.h>
|
||||
//#include <pinDefinitions.h>
|
||||
|
||||
#include "utility/PDMDoubleBuffer.h"
|
||||
|
||||
class PDMClass
|
||||
{
|
||||
public:
|
||||
PDMClass(int dinPin, int clkPin, int pwrPin);
|
||||
virtual ~PDMClass();
|
||||
|
||||
int begin(int channels, int sampleRate);
|
||||
void end();
|
||||
|
||||
virtual int available();
|
||||
virtual int read(void* buffer, size_t size);
|
||||
|
||||
void onReceive(void(*)(void));
|
||||
|
||||
//PORTENTA_H7 min -12 max 51
|
||||
//NANO 33 BLE SENSe min 0 max 80
|
||||
void setGain(int gain);
|
||||
void setBufferSize(int bufferSize);
|
||||
size_t getBufferSize();
|
||||
|
||||
// private:
|
||||
void IrqHandler(bool halftranfer);
|
||||
|
||||
private:
|
||||
int _dinPin;
|
||||
int _clkPin;
|
||||
int _pwrPin;
|
||||
|
||||
int _channels;
|
||||
int _samplerate;
|
||||
|
||||
int _gain;
|
||||
int _init;
|
||||
|
||||
// Hardware peripherals used
|
||||
uint _dmaChannel;
|
||||
PIO _pio;
|
||||
int _smIdx;
|
||||
int _pgmOffset;
|
||||
|
||||
PDMDoubleBuffer _doubleBuffer;
|
||||
|
||||
void (*_onReceive)(void);
|
||||
};
|
||||
#ifdef PIN_PDM_DIN
|
||||
extern PDMClass PDM;
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,313 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OpenPDMFilter.c
|
||||
* @author CL
|
||||
* @version V1.0.0
|
||||
* @date 9-September-2015
|
||||
* @brief Open PDM audio software decoding Library.
|
||||
* This Library is used to decode and reconstruct the audio signal
|
||||
* produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
|
||||
*******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2018 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "OpenPDMFilter.h"
|
||||
|
||||
|
||||
/* Variables -----------------------------------------------------------------*/
|
||||
|
||||
uint32_t div_const = 0;
|
||||
int64_t sub_const = 0;
|
||||
uint32_t sinc[DECIMATION_MAX * SINCN];
|
||||
uint32_t sinc1[DECIMATION_MAX];
|
||||
uint32_t sinc2[DECIMATION_MAX * 2];
|
||||
uint32_t coef[SINCN][DECIMATION_MAX];
|
||||
#ifdef USE_LUT
|
||||
int32_t lut[256][DECIMATION_MAX / 8][SINCN];
|
||||
#endif
|
||||
|
||||
|
||||
/* Functions -----------------------------------------------------------------*/
|
||||
|
||||
#ifdef USE_LUT
|
||||
int32_t filter_table_mono_64(uint8_t *data, uint8_t sincn)
|
||||
{
|
||||
return (int32_t)
|
||||
lut[data[0]][0][sincn] +
|
||||
lut[data[1]][1][sincn] +
|
||||
lut[data[2]][2][sincn] +
|
||||
lut[data[3]][3][sincn] +
|
||||
lut[data[4]][4][sincn] +
|
||||
lut[data[5]][5][sincn] +
|
||||
lut[data[6]][6][sincn] +
|
||||
lut[data[7]][7][sincn];
|
||||
}
|
||||
int32_t filter_table_stereo_64(uint8_t *data, uint8_t sincn)
|
||||
{
|
||||
return (int32_t)
|
||||
lut[data[0]][0][sincn] +
|
||||
lut[data[2]][1][sincn] +
|
||||
lut[data[4]][2][sincn] +
|
||||
lut[data[6]][3][sincn] +
|
||||
lut[data[8]][4][sincn] +
|
||||
lut[data[10]][5][sincn] +
|
||||
lut[data[12]][6][sincn] +
|
||||
lut[data[14]][7][sincn];
|
||||
}
|
||||
int32_t filter_table_mono_128(uint8_t *data, uint8_t sincn)
|
||||
{
|
||||
return (int32_t)
|
||||
lut[data[0]][0][sincn] +
|
||||
lut[data[1]][1][sincn] +
|
||||
lut[data[2]][2][sincn] +
|
||||
lut[data[3]][3][sincn] +
|
||||
lut[data[4]][4][sincn] +
|
||||
lut[data[5]][5][sincn] +
|
||||
lut[data[6]][6][sincn] +
|
||||
lut[data[7]][7][sincn] +
|
||||
lut[data[8]][8][sincn] +
|
||||
lut[data[9]][9][sincn] +
|
||||
lut[data[10]][10][sincn] +
|
||||
lut[data[11]][11][sincn] +
|
||||
lut[data[12]][12][sincn] +
|
||||
lut[data[13]][13][sincn] +
|
||||
lut[data[14]][14][sincn] +
|
||||
lut[data[15]][15][sincn];
|
||||
}
|
||||
int32_t filter_table_stereo_128(uint8_t *data, uint8_t sincn)
|
||||
{
|
||||
return (int32_t)
|
||||
lut[data[0]][0][sincn] +
|
||||
lut[data[2]][1][sincn] +
|
||||
lut[data[4]][2][sincn] +
|
||||
lut[data[6]][3][sincn] +
|
||||
lut[data[8]][4][sincn] +
|
||||
lut[data[10]][5][sincn] +
|
||||
lut[data[12]][6][sincn] +
|
||||
lut[data[14]][7][sincn] +
|
||||
lut[data[16]][8][sincn] +
|
||||
lut[data[18]][9][sincn] +
|
||||
lut[data[20]][10][sincn] +
|
||||
lut[data[22]][11][sincn] +
|
||||
lut[data[24]][12][sincn] +
|
||||
lut[data[26]][13][sincn] +
|
||||
lut[data[28]][14][sincn] +
|
||||
lut[data[30]][15][sincn];
|
||||
}
|
||||
int32_t (* filter_tables_64[2]) (uint8_t *data, uint8_t sincn) = {filter_table_mono_64, filter_table_stereo_64};
|
||||
int32_t (* filter_tables_128[2]) (uint8_t *data, uint8_t sincn) = {filter_table_mono_128, filter_table_stereo_128};
|
||||
#else
|
||||
int32_t filter_table(uint8_t *data, uint8_t sincn, TPDMFilter_InitStruct *param)
|
||||
{
|
||||
uint8_t c, i;
|
||||
uint16_t data_index = 0;
|
||||
uint32_t *coef_p = &coef[sincn][0];
|
||||
int32_t F = 0;
|
||||
uint8_t decimation = param->Decimation;
|
||||
uint8_t channels = param->In_MicChannels;
|
||||
|
||||
for (i = 0; i < decimation; i += 8) {
|
||||
c = data[data_index];
|
||||
F += ((c >> 7) ) * coef_p[i ] +
|
||||
((c >> 6) & 0x01) * coef_p[i + 1] +
|
||||
((c >> 5) & 0x01) * coef_p[i + 2] +
|
||||
((c >> 4) & 0x01) * coef_p[i + 3] +
|
||||
((c >> 3) & 0x01) * coef_p[i + 4] +
|
||||
((c >> 2) & 0x01) * coef_p[i + 5] +
|
||||
((c >> 1) & 0x01) * coef_p[i + 6] +
|
||||
((c ) & 0x01) * coef_p[i + 7];
|
||||
data_index += channels;
|
||||
}
|
||||
return F;
|
||||
}
|
||||
#endif
|
||||
|
||||
void convolve(uint32_t Signal[/* SignalLen */], unsigned short SignalLen,
|
||||
uint32_t Kernel[/* KernelLen */], unsigned short KernelLen,
|
||||
uint32_t Result[/* SignalLen + KernelLen - 1 */])
|
||||
{
|
||||
uint16_t n;
|
||||
|
||||
for (n = 0; n < SignalLen + KernelLen - 1; n++)
|
||||
{
|
||||
unsigned short kmin, kmax, k;
|
||||
|
||||
Result[n] = 0;
|
||||
|
||||
kmin = (n >= KernelLen - 1) ? n - (KernelLen - 1) : 0;
|
||||
kmax = (n < SignalLen - 1) ? n : SignalLen - 1;
|
||||
|
||||
for (k = kmin; k <= kmax; k++) {
|
||||
Result[n] += Signal[k] * Kernel[n - k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param)
|
||||
{
|
||||
uint16_t i, j;
|
||||
int64_t sum = 0;
|
||||
|
||||
uint8_t decimation = Param->Decimation;
|
||||
|
||||
for (i = 0; i < SINCN; i++) {
|
||||
Param->Coef[i] = 0;
|
||||
Param->bit[i] = 0;
|
||||
}
|
||||
for (i = 0; i < decimation; i++) {
|
||||
sinc1[i] = 1;
|
||||
}
|
||||
|
||||
Param->OldOut = Param->OldIn = Param->OldZ = 0;
|
||||
Param->LP_ALFA = (Param->LP_HZ != 0 ? (uint16_t) (Param->LP_HZ * 256 / (Param->LP_HZ + Param->Fs / (2 * 3.14159))) : 0);
|
||||
Param->HP_ALFA = (Param->HP_HZ != 0 ? (uint16_t) (Param->Fs * 256 / (2 * 3.14159 * Param->HP_HZ + Param->Fs)) : 0);
|
||||
|
||||
Param->FilterLen = decimation * SINCN;
|
||||
sinc[0] = 0;
|
||||
sinc[decimation * SINCN - 1] = 0;
|
||||
convolve(sinc1, decimation, sinc1, decimation, sinc2);
|
||||
convolve(sinc2, decimation * 2 - 1, sinc1, decimation, &sinc[1]);
|
||||
for(j = 0; j < SINCN; j++) {
|
||||
for (i = 0; i < decimation; i++) {
|
||||
coef[j][i] = sinc[j * decimation + i];
|
||||
sum += sinc[j * decimation + i];
|
||||
}
|
||||
}
|
||||
|
||||
sub_const = sum >> 1;
|
||||
div_const = sub_const * Param->MaxVolume / 32768 / Param->filterGain;
|
||||
div_const = (div_const == 0 ? 1 : div_const);
|
||||
|
||||
#ifdef USE_LUT
|
||||
/* Look-Up Table. */
|
||||
uint16_t c, d, s;
|
||||
for (s = 0; s < SINCN; s++)
|
||||
{
|
||||
uint32_t *coef_p = &coef[s][0];
|
||||
for (c = 0; c < 256; c++)
|
||||
for (d = 0; d < decimation / 8; d++)
|
||||
lut[c][d][s] = ((c >> 7) ) * coef_p[d * 8 ] +
|
||||
((c >> 6) & 0x01) * coef_p[d * 8 + 1] +
|
||||
((c >> 5) & 0x01) * coef_p[d * 8 + 2] +
|
||||
((c >> 4) & 0x01) * coef_p[d * 8 + 3] +
|
||||
((c >> 3) & 0x01) * coef_p[d * 8 + 4] +
|
||||
((c >> 2) & 0x01) * coef_p[d * 8 + 5] +
|
||||
((c >> 1) & 0x01) * coef_p[d * 8 + 6] +
|
||||
((c ) & 0x01) * coef_p[d * 8 + 7];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Open_PDM_Filter_64(uint8_t* data, int16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param)
|
||||
{
|
||||
uint8_t i, data_out_index;
|
||||
uint8_t channels = Param->In_MicChannels;
|
||||
uint8_t data_inc = ((DECIMATION_MAX >> 4) * channels);
|
||||
int64_t Z, Z0, Z1, Z2;
|
||||
int64_t OldOut, OldIn, OldZ;
|
||||
|
||||
OldOut = Param->OldOut;
|
||||
OldIn = Param->OldIn;
|
||||
OldZ = Param->OldZ;
|
||||
|
||||
#ifdef USE_LUT
|
||||
uint8_t j = channels - 1;
|
||||
#endif
|
||||
|
||||
for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) {
|
||||
#ifdef USE_LUT
|
||||
Z0 = filter_tables_64[j](data, 0);
|
||||
Z1 = filter_tables_64[j](data, 1);
|
||||
Z2 = filter_tables_64[j](data, 2);
|
||||
#else
|
||||
Z0 = filter_table(data, 0, Param);
|
||||
Z1 = filter_table(data, 1, Param);
|
||||
Z2 = filter_table(data, 2, Param);
|
||||
#endif
|
||||
|
||||
Z = Param->Coef[1] + Z2 - sub_const;
|
||||
Param->Coef[1] = Param->Coef[0] + Z1;
|
||||
Param->Coef[0] = Z0;
|
||||
|
||||
OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
|
||||
OldIn = Z;
|
||||
OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
|
||||
|
||||
Z = OldZ * volume;
|
||||
Z = RoundDiv(Z, div_const);
|
||||
Z = SaturaLH(Z, -32700, 32700);
|
||||
|
||||
dataOut[data_out_index] = Z;
|
||||
data += data_inc;
|
||||
}
|
||||
|
||||
Param->OldOut = OldOut;
|
||||
Param->OldIn = OldIn;
|
||||
Param->OldZ = OldZ;
|
||||
}
|
||||
|
||||
void Open_PDM_Filter_128(uint8_t* data, int16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param)
|
||||
{
|
||||
uint8_t i, data_out_index;
|
||||
uint8_t channels = Param->In_MicChannels;
|
||||
uint8_t data_inc = ((DECIMATION_MAX >> 3) * channels);
|
||||
int64_t Z, Z0, Z1, Z2;
|
||||
int64_t OldOut, OldIn, OldZ;
|
||||
|
||||
OldOut = Param->OldOut;
|
||||
OldIn = Param->OldIn;
|
||||
OldZ = Param->OldZ;
|
||||
|
||||
#ifdef USE_LUT
|
||||
uint8_t j = channels - 1;
|
||||
#endif
|
||||
|
||||
for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) {
|
||||
#ifdef USE_LUT
|
||||
Z0 = filter_tables_128[j](data, 0);
|
||||
Z1 = filter_tables_128[j](data, 1);
|
||||
Z2 = filter_tables_128[j](data, 2);
|
||||
#else
|
||||
Z0 = filter_table(data, 0, Param);
|
||||
Z1 = filter_table(data, 1, Param);
|
||||
Z2 = filter_table(data, 2, Param);
|
||||
#endif
|
||||
|
||||
Z = Param->Coef[1] + Z2 - sub_const;
|
||||
Param->Coef[1] = Param->Coef[0] + Z1;
|
||||
Param->Coef[0] = Z0;
|
||||
|
||||
OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
|
||||
OldIn = Z;
|
||||
OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
|
||||
|
||||
Z = OldZ * volume;
|
||||
Z = RoundDiv(Z, div_const);
|
||||
Z = SaturaLH(Z, -32700, 32700);
|
||||
|
||||
dataOut[data_out_index] = Z;
|
||||
data += data_inc;
|
||||
}
|
||||
|
||||
Param->OldOut = OldOut;
|
||||
Param->OldIn = OldIn;
|
||||
Param->OldZ = OldZ;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OpenPDMFilter.h
|
||||
* @author CL
|
||||
* @version V1.0.0
|
||||
* @date 9-September-2015
|
||||
* @brief Header file for Open PDM audio software decoding Library.
|
||||
* This Library is used to decode and reconstruct the audio signal
|
||||
* produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
|
||||
*******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2018 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __OPENPDMFILTER_H
|
||||
#define __OPENPDMFILTER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/* Definitions ---------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Enable to use a Look-Up Table to improve performances while using more FLASH
|
||||
* and RAM memory.
|
||||
* Note: Without Look-Up Table up to stereo@16KHz configuration is supported.
|
||||
*/
|
||||
#define USE_LUT
|
||||
|
||||
#define SINCN 3
|
||||
#define DECIMATION_MAX 128
|
||||
|
||||
#define HTONS(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
|
||||
(((uint16_t)(A) & 0x00ff) << 8))
|
||||
#define RoundDiv(a, b) (((a)>0)?(((a)+(b)/2)/(b)):(((a)-(b)/2)/(b)))
|
||||
#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
|
||||
|
||||
|
||||
/* Types ---------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
/* Public */
|
||||
float LP_HZ;
|
||||
float HP_HZ;
|
||||
uint16_t Fs;
|
||||
unsigned int nSamples;
|
||||
uint8_t In_MicChannels;
|
||||
uint8_t Out_MicChannels;
|
||||
uint8_t Decimation;
|
||||
uint8_t MaxVolume;
|
||||
/* Private */
|
||||
uint32_t Coef[SINCN];
|
||||
uint16_t FilterLen;
|
||||
int64_t OldOut, OldIn, OldZ;
|
||||
uint16_t LP_ALFA;
|
||||
uint16_t HP_ALFA;
|
||||
uint16_t bit[5];
|
||||
uint16_t byte;
|
||||
uint16_t filterGain;
|
||||
} TPDMFilter_InitStruct;
|
||||
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void Open_PDM_Filter_Init(TPDMFilter_InitStruct *init_struct);
|
||||
void Open_PDM_Filter_64(uint8_t* data, int16_t* data_out, uint16_t mic_gain, TPDMFilter_InitStruct *init_struct);
|
||||
void Open_PDM_Filter_128(uint8_t* data, int16_t* data_out, uint16_t mic_gain, TPDMFilter_InitStruct *init_struct);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __OPENPDMFILTER_H
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,211 @@
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "PDM.h"
|
||||
#include "OpenPDMFilter.h"
|
||||
|
||||
extern "C" {
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/dma.h"
|
||||
#include "hardware/clocks.h"
|
||||
}
|
||||
#include "hardware/sync.h"
|
||||
#include "pdm.pio.h"
|
||||
static PIOProgram _pdmPgm(&pdm_pio_program);
|
||||
|
||||
// raw buffers contain PDM data
|
||||
#define RAW_BUFFER_SIZE 512 // should be a multiple of (decimation / 8)
|
||||
uint8_t rawBuffer0[RAW_BUFFER_SIZE];
|
||||
uint8_t rawBuffer1[RAW_BUFFER_SIZE];
|
||||
uint8_t* rawBuffer[2] = {rawBuffer0, rawBuffer1};
|
||||
volatile int rawBufferIndex = 0;
|
||||
|
||||
int decimation = 64;
|
||||
|
||||
// final buffer is the one to be filled with PCM data
|
||||
int16_t* volatile finalBuffer;
|
||||
|
||||
// OpenPDM filter used to convert PDM into PCM
|
||||
#define FILTER_GAIN 16
|
||||
TPDMFilter_InitStruct filter;
|
||||
|
||||
extern "C" {
|
||||
__attribute__((__used__)) void dmaHandler(void)
|
||||
{
|
||||
PDM.IrqHandler(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) :
|
||||
_dinPin(dinPin),
|
||||
_clkPin(clkPin),
|
||||
_pwrPin(pwrPin),
|
||||
_onReceive(NULL),
|
||||
_gain(-1),
|
||||
_channels(-1),
|
||||
_samplerate(-1),
|
||||
_init(-1),
|
||||
_dmaChannel(0),
|
||||
_pio(nullptr),
|
||||
_smIdx(-1),
|
||||
_pgmOffset(-1)
|
||||
{
|
||||
}
|
||||
|
||||
PDMClass::~PDMClass()
|
||||
{
|
||||
}
|
||||
|
||||
int PDMClass::begin(int channels, int sampleRate)
|
||||
{
|
||||
//_channels = channels; // only one channel available
|
||||
|
||||
// clear the final buffers
|
||||
_doubleBuffer.reset();
|
||||
finalBuffer = (int16_t*)_doubleBuffer.data();
|
||||
int finalBufferLength = _doubleBuffer.availableForWrite() / sizeof(int16_t);
|
||||
_doubleBuffer.swap(0);
|
||||
|
||||
int rawBufferLength = RAW_BUFFER_SIZE / (decimation / 8);
|
||||
// Saturate number of samples. Remaining bytes are dropped.
|
||||
if (rawBufferLength > finalBufferLength) {
|
||||
rawBufferLength = finalBufferLength;
|
||||
}
|
||||
|
||||
/* Initialize Open PDM library */
|
||||
filter.Fs = sampleRate;
|
||||
filter.nSamples = rawBufferLength;
|
||||
filter.LP_HZ = sampleRate/2;
|
||||
filter.HP_HZ = 10;
|
||||
filter.In_MicChannels = 1;
|
||||
filter.Out_MicChannels = 1;
|
||||
filter.Decimation = decimation;
|
||||
if(_gain == -1) {
|
||||
_gain = FILTER_GAIN;
|
||||
}
|
||||
filter.filterGain = _gain;
|
||||
Open_PDM_Filter_Init(&filter);
|
||||
|
||||
// Configure PIO state machine
|
||||
float clkDiv = (float)clock_get_hz(clk_sys) / sampleRate / decimation / 2;
|
||||
|
||||
if (!_pdmPgm.prepare(&_pio, &_smIdx, &_pgmOffset)) {
|
||||
// ERROR, no free slots
|
||||
return -1;
|
||||
}
|
||||
pdm_pio_program_init(_pio, _smIdx, _pgmOffset, _clkPin, _dinPin, clkDiv);
|
||||
|
||||
// Wait for microphone
|
||||
delay(100);
|
||||
|
||||
// Configure DMA for transferring PIO rx buffer to raw buffers
|
||||
_dmaChannel = dma_claim_unused_channel(false);
|
||||
dma_channel_config c = dma_channel_get_default_config(_dmaChannel);
|
||||
channel_config_set_read_increment(&c, false);
|
||||
channel_config_set_write_increment(&c, true);
|
||||
channel_config_set_dreq(&c, pio_get_dreq(_pio, _smIdx, false));
|
||||
channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
|
||||
|
||||
// Clear DMA interrupts
|
||||
dma_hw->ints0 = 1u << _dmaChannel;
|
||||
// Enable DMA interrupts
|
||||
dma_channel_set_irq0_enabled(_dmaChannel, true);
|
||||
// Share but allocate a high priority to the interrupt
|
||||
irq_add_shared_handler(DMA_IRQ_0, dmaHandler, 0);
|
||||
irq_set_enabled(DMA_IRQ_0, true);
|
||||
|
||||
dma_channel_configure(_dmaChannel, &c,
|
||||
rawBuffer[rawBufferIndex], // Destinatinon pointer
|
||||
&_pio->rxf[_smIdx], // Source pointer
|
||||
RAW_BUFFER_SIZE, // Number of transfers
|
||||
true // Start immediately
|
||||
);
|
||||
|
||||
_init = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void PDMClass::end()
|
||||
{
|
||||
dma_channel_abort(_dmaChannel);
|
||||
pinMode(_clkPin, INPUT);
|
||||
}
|
||||
|
||||
int PDMClass::available()
|
||||
{
|
||||
//NVIC_DisableIRQ(DMA_IRQ_0n);
|
||||
//uint32_t interrupts = save_and_disable_interrupts();
|
||||
irq_set_enabled(DMA_IRQ_0, false);
|
||||
size_t avail = _doubleBuffer.available();
|
||||
irq_set_enabled(DMA_IRQ_0, true);
|
||||
//restore_interrupts(interrupts);
|
||||
//NVIC_EnableIRQ(DMA_IRQ_0n);
|
||||
return avail;
|
||||
}
|
||||
|
||||
int PDMClass::read(void* buffer, size_t size)
|
||||
{
|
||||
irq_set_enabled(DMA_IRQ_0, false);
|
||||
int read = _doubleBuffer.read(buffer, size);
|
||||
irq_set_enabled(DMA_IRQ_0, true);
|
||||
return read;
|
||||
}
|
||||
|
||||
void PDMClass::onReceive(void(*function)(void))
|
||||
{
|
||||
_onReceive = function;
|
||||
}
|
||||
|
||||
void PDMClass::setGain(int gain)
|
||||
{
|
||||
_gain = gain;
|
||||
if(_init == 1) {
|
||||
filter.filterGain = _gain;
|
||||
Open_PDM_Filter_Init(&filter);
|
||||
}
|
||||
}
|
||||
|
||||
void PDMClass::setBufferSize(int bufferSize)
|
||||
{
|
||||
_doubleBuffer.setSize(bufferSize);
|
||||
}
|
||||
|
||||
void PDMClass::IrqHandler(bool halftranfer)
|
||||
{
|
||||
static int cutSamples = 100;
|
||||
|
||||
// Clear the interrupt request.
|
||||
dma_hw->ints0 = 1u << _dmaChannel;
|
||||
// Restart dma pointing to the other buffer
|
||||
int shadowIndex = rawBufferIndex ^ 1;
|
||||
dma_channel_set_write_addr(_dmaChannel, rawBuffer[shadowIndex], true);
|
||||
|
||||
if (_doubleBuffer.available()) {
|
||||
// buffer overflow, stop
|
||||
return end();
|
||||
}
|
||||
|
||||
// fill final buffer with PCM samples
|
||||
Open_PDM_Filter_64(rawBuffer[rawBufferIndex], finalBuffer, 1, &filter);
|
||||
|
||||
if (cutSamples) {
|
||||
memset(finalBuffer, 0, cutSamples);
|
||||
cutSamples = 0;
|
||||
}
|
||||
|
||||
// swap final buffer and raw buffers' indexes
|
||||
finalBuffer = (int16_t*)_doubleBuffer.data();
|
||||
_doubleBuffer.swap(filter.nSamples * sizeof(int16_t));
|
||||
rawBufferIndex = shadowIndex;
|
||||
|
||||
if (_onReceive) {
|
||||
_onReceive();
|
||||
}
|
||||
}
|
||||
#ifdef PIN_PDM_DIN
|
||||
PDMClass PDM(PIN_PDM_DIN, PIN_PDM_CLK, -1);
|
||||
#endif // PIN_PDM_DIN
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
.program pdm_pio
|
||||
.side_set 1
|
||||
.wrap_target
|
||||
|
||||
; prova a cambiare edge
|
||||
|
||||
;sample on falling edge
|
||||
push iffull noblock side 1
|
||||
;nop side 1
|
||||
;nop side 0
|
||||
in pins, 1 side 0
|
||||
;nop side 0
|
||||
|
||||
.wrap
|
||||
|
||||
% c-sdk {
|
||||
#include "hardware/gpio.h"
|
||||
|
||||
static inline void pdm_pio_program_init(PIO pio, uint sm, uint offset, uint clkPin, uint dataPin, float clkDiv) {
|
||||
pio_sm_config c = pdm_pio_program_get_default_config(offset);
|
||||
sm_config_set_sideset(&c, 1, false, false);
|
||||
//sm_config_set_in_shift(&c, false, true, 8);
|
||||
sm_config_set_in_shift(&c, false, false, 8);
|
||||
|
||||
sm_config_set_in_pins(&c, dataPin);
|
||||
sm_config_set_sideset_pins(&c, clkPin);
|
||||
sm_config_set_clkdiv(&c, clkDiv);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
|
||||
|
||||
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, clkPin);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
|
||||
|
||||
%}
|
||||
@@ -0,0 +1,57 @@
|
||||
// -------------------------------------------------- //
|
||||
// This file is autogenerated by pioasm; do not edit! //
|
||||
// -------------------------------------------------- //
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
#include "hardware/pio.h"
|
||||
#endif
|
||||
|
||||
// ------- //
|
||||
// pdm_pio //
|
||||
// ------- //
|
||||
|
||||
#define pdm_pio_wrap_target 0
|
||||
#define pdm_pio_wrap 1
|
||||
|
||||
static const uint16_t pdm_pio_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x9040, // 0: push iffull noblock side 1
|
||||
0x4001, // 1: in pins, 1 side 0
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
static const struct pio_program pdm_pio_program = {
|
||||
.instructions = pdm_pio_program_instructions,
|
||||
.length = 2,
|
||||
.origin = -1,
|
||||
};
|
||||
|
||||
static inline pio_sm_config pdm_pio_program_get_default_config(uint offset) {
|
||||
pio_sm_config c = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&c, offset + pdm_pio_wrap_target, offset + pdm_pio_wrap);
|
||||
sm_config_set_sideset(&c, 1, false, false);
|
||||
return c;
|
||||
}
|
||||
|
||||
#include "hardware/gpio.h"
|
||||
static inline void pdm_pio_program_init(PIO pio, uint sm, uint offset, uint clkPin, uint dataPin, float clkDiv) {
|
||||
pio_sm_config c = pdm_pio_program_get_default_config(offset);
|
||||
sm_config_set_sideset(&c, 1, false, false);
|
||||
//sm_config_set_in_shift(&c, false, true, 8);
|
||||
sm_config_set_in_shift(&c, false, false, 8);
|
||||
sm_config_set_in_pins(&c, dataPin);
|
||||
sm_config_set_sideset_pins(&c, clkPin);
|
||||
sm_config_set_clkdiv(&c, clkDiv);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
|
||||
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, clkPin);
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright (c) 2016 Arduino LLC. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "PDMDoubleBuffer.h"
|
||||
|
||||
PDMDoubleBuffer::PDMDoubleBuffer() :
|
||||
_size(DEFAULT_PDM_BUFFER_SIZE)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
PDMDoubleBuffer::~PDMDoubleBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void PDMDoubleBuffer::setSize(int size)
|
||||
{
|
||||
_size = size;
|
||||
reset();
|
||||
}
|
||||
|
||||
size_t PDMDoubleBuffer::getSize()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
void PDMDoubleBuffer::reset()
|
||||
{
|
||||
_buffer[0] = (uint8_t*)realloc(_buffer[0], _size);
|
||||
_buffer[1] = (uint8_t*)realloc(_buffer[1], _size);
|
||||
|
||||
memset(_buffer[0], 0x00, _size);
|
||||
memset(_buffer[1], 0x00, _size);
|
||||
|
||||
_index = 0;
|
||||
_length[0] = 0;
|
||||
_length[1] = 0;
|
||||
_readOffset[0] = 0;
|
||||
_readOffset[1] = 0;
|
||||
}
|
||||
|
||||
size_t PDMDoubleBuffer::availableForWrite()
|
||||
{
|
||||
return (_size - (_length[_index] - _readOffset[_index]));
|
||||
}
|
||||
|
||||
size_t PDMDoubleBuffer::write(const void *buffer, size_t size)
|
||||
{
|
||||
size_t space = availableForWrite();
|
||||
|
||||
if (size > space) {
|
||||
size = space;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&_buffer[_index][_length[_index]], buffer, size);
|
||||
|
||||
_length[_index] += size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t PDMDoubleBuffer::read(void *buffer, size_t size)
|
||||
{
|
||||
size_t avail = available();
|
||||
|
||||
if (size > avail) {
|
||||
size = avail;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buffer, &_buffer[_index][_readOffset[_index]], size);
|
||||
_readOffset[_index] += size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t PDMDoubleBuffer::peek(void *buffer, size_t size)
|
||||
{
|
||||
size_t avail = available();
|
||||
|
||||
if (size > avail) {
|
||||
size = avail;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buffer, &_buffer[_index][_readOffset[_index]], size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void* PDMDoubleBuffer::data()
|
||||
{
|
||||
return (void*)_buffer[_index];
|
||||
}
|
||||
|
||||
size_t PDMDoubleBuffer::available()
|
||||
{
|
||||
return _length[_index] - _readOffset[_index];
|
||||
}
|
||||
|
||||
void PDMDoubleBuffer::swap(int length)
|
||||
{
|
||||
if (_index == 0) {
|
||||
_index = 1;
|
||||
} else {
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
_length[_index] = length;
|
||||
_readOffset[_index] = 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2016 Arduino LLC. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#ifndef _PDM_DOUBLE_BUFFER_H_INCLUDED
|
||||
#define _PDM_DOUBLE_BUFFER_H_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DEFAULT_PDM_BUFFER_SIZE 512
|
||||
|
||||
class PDMDoubleBuffer
|
||||
{
|
||||
public:
|
||||
PDMDoubleBuffer();
|
||||
virtual ~PDMDoubleBuffer();
|
||||
|
||||
void setSize(int size);
|
||||
size_t getSize();
|
||||
|
||||
void reset();
|
||||
|
||||
size_t availableForWrite();
|
||||
size_t write(const void *buffer, size_t size);
|
||||
size_t read(void *buffer, size_t size);
|
||||
size_t peek(void *buffer, size_t size);
|
||||
void* data();
|
||||
size_t available();
|
||||
void swap(int length = 0);
|
||||
|
||||
private:
|
||||
uint8_t* _buffer[2] __attribute__((aligned (16)));
|
||||
int _size;
|
||||
volatile int _length[2];
|
||||
volatile int _readOffset[2];
|
||||
volatile int _index;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -135,8 +135,8 @@ public:
|
||||
size_t size() {
|
||||
uint64_t sz = size64();
|
||||
#ifdef DEBUG_ESP_PORT
|
||||
if (sz > (uint64_t)SIZE_MAX) {
|
||||
DEBUG_ESP_PORT.printf_P(PSTR("WARNING: SD card size overflow (%lld>= 4GB). Please update source to use size64().\n"), sz);
|
||||
if (sz > std::numeric_limits<uint32_t>::max()) {
|
||||
DEBUG_ESP_PORT.printf_P(PSTR("WARNING: SD card size overflow (%lld >= 4GB). Please update source to use size64().\n"), (long long)sz);
|
||||
}
|
||||
#endif
|
||||
return (size_t)sz;
|
||||
@@ -191,9 +191,6 @@ private:
|
||||
|
||||
|
||||
// Expose FatStructs.h helpers for MS-DOS date/time for use with dateTimeCallback
|
||||
static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
|
||||
return (year - 1980) << 9 | month << 5 | day;
|
||||
}
|
||||
static inline uint16_t FAT_YEAR(uint16_t fatDate) {
|
||||
return 1980 + (fatDate >> 9);
|
||||
}
|
||||
@@ -203,9 +200,6 @@ static inline uint8_t FAT_MONTH(uint16_t fatDate) {
|
||||
static inline uint8_t FAT_DAY(uint16_t fatDate) {
|
||||
return fatDate & 0X1F;
|
||||
}
|
||||
static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
|
||||
return hour << 11 | minute << 5 | second >> 1;
|
||||
}
|
||||
static inline uint8_t FAT_HOUR(uint16_t fatTime) {
|
||||
return fatTime >> 11;
|
||||
}
|
||||
|
||||
@@ -64,13 +64,13 @@ FileImplPtr SDFSImpl::open(const char* path, OpenMode openMode, AccessMode acces
|
||||
}
|
||||
free(pathStr);
|
||||
}
|
||||
sdfat::File32 fd = _fs.open(path, flags);
|
||||
File32 fd = _fs.open(path, flags);
|
||||
if (!fd) {
|
||||
DEBUGV("SDFSImpl::openFile: fd=%p path=`%s` openMode=%d accessMode=%d",
|
||||
&fd, path, openMode, accessMode);
|
||||
return FileImplPtr();
|
||||
}
|
||||
auto sharedFd = std::make_shared<sdfat::File32>(fd);
|
||||
auto sharedFd = std::make_shared<File32>(fd);
|
||||
return std::make_shared<SDFSFileImpl>(this, sharedFd, path);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ DirImplPtr SDFSImpl::openDir(const char* path)
|
||||
}
|
||||
// At this point we have a name of "/blah/blah/blah" or "blah" or ""
|
||||
// If that references a directory, just open it and we're done.
|
||||
sdfat::File32 dirFile;
|
||||
File32 dirFile;
|
||||
const char *filter = "";
|
||||
if (!pathStr[0]) {
|
||||
// openDir("") === openDir("/")
|
||||
@@ -135,7 +135,7 @@ DirImplPtr SDFSImpl::openDir(const char* path)
|
||||
DEBUGV("SDFSImpl::openDir: path=`%s`\n", path);
|
||||
return DirImplPtr();
|
||||
}
|
||||
auto sharedDir = std::make_shared<sdfat::File32>(dirFile);
|
||||
auto sharedDir = std::make_shared<File32>(dirFile);
|
||||
auto ret = std::make_shared<SDFSDirImpl>(filter, this, sharedDir, pathStr);
|
||||
free(pathStr);
|
||||
return ret;
|
||||
@@ -145,12 +145,12 @@ bool SDFSImpl::format() {
|
||||
if (_mounted) {
|
||||
return false;
|
||||
}
|
||||
sdfat::SdCardFactory cardFactory;
|
||||
sdfat::SdCard* card = cardFactory.newCard(sdfat::SdSpiConfig(_cfg._csPin, DEDICATED_SPI, _cfg._spiSettings));
|
||||
SdCardFactory cardFactory;
|
||||
SdCard* card = cardFactory.newCard(SdSpiConfig(_cfg._csPin, DEDICATED_SPI, _cfg._spiSettings));
|
||||
if (!card || card->errorCode()) {
|
||||
return false;
|
||||
}
|
||||
sdfat::FatFormatter fatFormatter;
|
||||
FatFormatter fatFormatter;
|
||||
uint8_t *sectorBuffer = new uint8_t[512];
|
||||
bool ret = fatFormatter.format(card, sectorBuffer, nullptr);
|
||||
delete[] sectorBuffer;
|
||||
|
||||
+36
-35
@@ -96,11 +96,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
info.maxOpenFiles = 999; // TODO - not valid
|
||||
info.blockSize = _fs.vol()->sectorsPerCluster() * _fs.vol()->bytesPerSector();
|
||||
info.blockSize = _fs.vol()->bytesPerCluster();
|
||||
info.pageSize = 0; // TODO ?
|
||||
info.maxPathLength = 255; // TODO ?
|
||||
info.totalBytes =_fs.vol()->clusterCount() * info.blockSize;
|
||||
info.usedBytes = info.totalBytes - (_fs.vol()->freeClusterCount() * _fs.vol()->sectorsPerCluster() * _fs.vol()->bytesPerSector());
|
||||
info.usedBytes = info.totalBytes - (_fs.vol()->freeClusterCount() * _fs.vol()->bytesPerCluster());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -114,9 +114,9 @@ public:
|
||||
info.maxOpenFiles = i.maxOpenFiles;
|
||||
info.maxPathLength = i.maxPathLength;
|
||||
#ifdef DEBUG_ESP_PORT
|
||||
if (i.totalBytes > (uint64_t)SIZE_MAX) {
|
||||
if (i.totalBytes > std::numeric_limits<uint32_t>::max()) {
|
||||
// This catches both total and used cases, since used must always be < total.
|
||||
DEBUG_ESP_PORT.printf_P(PSTR("WARNING: SD card size overflow (%lld>= 4GB). Please update source to use info64().\n"), i.totalBytes);
|
||||
DEBUG_ESP_PORT.printf_P(PSTR("WARNING: SD card size overflow (%lld >= 4GB). Please update source to use info64().\n"), (long long)i.totalBytes);
|
||||
}
|
||||
#endif
|
||||
info.totalBytes = (size_t)i.totalBytes;
|
||||
@@ -148,14 +148,14 @@ public:
|
||||
|
||||
bool begin() override {
|
||||
if (_mounted) {
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
_mounted = _fs.begin(_cfg._csPin, _cfg._spiSettings);
|
||||
if (!_mounted && _cfg._autoFormat) {
|
||||
format();
|
||||
_mounted = _fs.begin(_cfg._csPin, _cfg._spiSettings);
|
||||
}
|
||||
sdfat::FsDateTime::setCallback(dateTimeCB);
|
||||
FsDateTime::setCallback(dateTimeCB);
|
||||
return _mounted;
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
return (totalClusters() / blocksPerCluster());
|
||||
}
|
||||
size_t clusterSize() {
|
||||
return blocksPerCluster() * _fs.vol()->bytesPerSector();
|
||||
return _fs.vol()->bytesPerCluster();
|
||||
}
|
||||
size_t size() {
|
||||
return (clusterSize() * totalClusters());
|
||||
@@ -228,14 +228,14 @@ protected:
|
||||
friend class SDFileImpl;
|
||||
friend class SDFSDirImpl;
|
||||
|
||||
sdfat::SdFat* getFs()
|
||||
SdFat* getFs()
|
||||
{
|
||||
return &_fs;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t _getFlags(OpenMode openMode, AccessMode accessMode) {
|
||||
uint8_t mode = 0;
|
||||
static int _getFlags(OpenMode openMode, AccessMode accessMode) {
|
||||
int mode = 0;
|
||||
if (openMode & OM_CREATE) {
|
||||
mode |= O_CREAT;
|
||||
}
|
||||
@@ -245,16 +245,17 @@ protected:
|
||||
if (openMode & OM_TRUNCATE) {
|
||||
mode |= O_TRUNC;
|
||||
}
|
||||
if (accessMode & AM_READ) {
|
||||
if ((accessMode & (AM_READ | AM_WRITE)) == (AM_READ | AM_WRITE)) {
|
||||
mode |= O_RDWR;
|
||||
} else if (accessMode & AM_READ) {
|
||||
mode |= O_READ;
|
||||
}
|
||||
if (accessMode & AM_WRITE) {
|
||||
} else if (accessMode & AM_WRITE) {
|
||||
mode |= O_WRITE;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
sdfat::SdFat _fs;
|
||||
SdFat _fs;
|
||||
SDFSConfig _cfg;
|
||||
bool _mounted;
|
||||
};
|
||||
@@ -263,7 +264,7 @@ protected:
|
||||
class SDFSFileImpl : public FileImpl
|
||||
{
|
||||
public:
|
||||
SDFSFileImpl(SDFSImpl *fs, std::shared_ptr<sdfat::File32> fd, const char *name)
|
||||
SDFSFileImpl(SDFSImpl *fs, std::shared_ptr<File32> fd, const char *name)
|
||||
: _fs(fs), _fd(fd), _opened(true)
|
||||
{
|
||||
_name = std::shared_ptr<char>(new char[strlen(name) + 1], std::default_delete<char[]>());
|
||||
@@ -379,7 +380,7 @@ public:
|
||||
time_t getLastWrite() override {
|
||||
time_t ftime = 0;
|
||||
if (_opened && _fd) {
|
||||
sdfat::DirFat_t tmp;
|
||||
DirFat_t tmp;
|
||||
if (_fd.get()->dirEntry(&tmp)) {
|
||||
ftime = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.modifyDate, *(uint16_t*)tmp.modifyTime);
|
||||
}
|
||||
@@ -390,7 +391,7 @@ public:
|
||||
time_t getCreationTime() override {
|
||||
time_t ftime = 0;
|
||||
if (_opened && _fd) {
|
||||
sdfat::DirFat_t tmp;
|
||||
DirFat_t tmp;
|
||||
if (_fd.get()->dirEntry(&tmp)) {
|
||||
ftime = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.createDate, *(uint16_t*)tmp.createTime);
|
||||
}
|
||||
@@ -399,16 +400,16 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
SDFSImpl* _fs;
|
||||
std::shared_ptr<sdfat::File32> _fd;
|
||||
std::shared_ptr<char> _name;
|
||||
bool _opened;
|
||||
SDFSImpl* _fs;
|
||||
std::shared_ptr<File32> _fd;
|
||||
std::shared_ptr<char> _name;
|
||||
bool _opened;
|
||||
};
|
||||
|
||||
class SDFSDirImpl : public DirImpl
|
||||
{
|
||||
public:
|
||||
SDFSDirImpl(const String& pattern, SDFSImpl* fs, std::shared_ptr<sdfat::File32> dir, const char *dirPath = nullptr)
|
||||
SDFSDirImpl(const String& pattern, SDFSImpl* fs, std::shared_ptr<File32> dir, const char *dirPath = nullptr)
|
||||
: _pattern(pattern), _fs(fs), _dir(dir), _valid(false), _dirPath(nullptr)
|
||||
{
|
||||
if (dirPath) {
|
||||
@@ -483,14 +484,14 @@ public:
|
||||
{
|
||||
const int n = _pattern.length();
|
||||
do {
|
||||
sdfat::File32 file;
|
||||
File32 file;
|
||||
file.openNext(_dir.get(), O_READ);
|
||||
if (file) {
|
||||
_valid = 1;
|
||||
_size = file.fileSize();
|
||||
_isFile = file.isFile();
|
||||
_isDirectory = file.isDir();
|
||||
sdfat::DirFat_t tmp;
|
||||
DirFat_t tmp;
|
||||
if (file.dirEntry(&tmp)) {
|
||||
_time = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.modifyDate, *(uint16_t*)tmp.modifyTime);
|
||||
_creation = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.createDate, *(uint16_t*)tmp.createTime);
|
||||
@@ -515,17 +516,17 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
String _pattern;
|
||||
SDFSImpl* _fs;
|
||||
std::shared_ptr<sdfat::File32> _dir;
|
||||
bool _valid;
|
||||
char _lfn[64];
|
||||
time_t _time;
|
||||
time_t _creation;
|
||||
std::shared_ptr<char> _dirPath;
|
||||
uint32_t _size;
|
||||
bool _isFile;
|
||||
bool _isDirectory;
|
||||
String _pattern;
|
||||
SDFSImpl* _fs;
|
||||
std::shared_ptr<File32> _dir;
|
||||
bool _valid;
|
||||
char _lfn[64];
|
||||
time_t _time;
|
||||
time_t _creation;
|
||||
std::shared_ptr<char> _dirPath;
|
||||
uint32_t _size;
|
||||
bool _isFile;
|
||||
bool _isDirectory;
|
||||
};
|
||||
|
||||
}; // namespace sdfs
|
||||
|
||||
+16
-12
@@ -179,23 +179,22 @@ void SPIClassRP2040::transfer(void *txbuf, void *rxbuf, size_t count) {
|
||||
|
||||
void SPIClassRP2040::beginTransaction(SPISettings settings) {
|
||||
DEBUGSPI("SPI::beginTransaction(clk=%d, bo=%s\n", _spis.getClockFreq(), (_spis.getBitOrder() == MSBFIRST) ? "MSB" : "LSB");
|
||||
_spis = settings;
|
||||
if (_initted) {
|
||||
DEBUGSPI("SPI: deinitting currently active SPI\n");
|
||||
spi_deinit(_spi);
|
||||
if (_initted && settings == _spis) {
|
||||
DEBUGSPI("SPI: Reusing existing initted SPI\n");
|
||||
} else {
|
||||
_spis = settings;
|
||||
if (_initted) {
|
||||
DEBUGSPI("SPI: deinitting currently active SPI\n");
|
||||
spi_deinit(_spi);
|
||||
}
|
||||
DEBUGSPI("SPI: initting SPI\n");
|
||||
spi_init(_spi, _spis.getClockFreq());
|
||||
_initted = true;
|
||||
}
|
||||
DEBUGSPI("SPI: initting SPI\n");
|
||||
spi_init(_spi, _spis.getClockFreq());
|
||||
_initted = true;
|
||||
}
|
||||
|
||||
void SPIClassRP2040::endTransaction(void) {
|
||||
DEBUGSPI("SPI::endTransaction()\n");
|
||||
if (_initted) {
|
||||
DEBUGSPI("SPI: deinitting currently active SPI\n");
|
||||
spi_deinit(_spi);
|
||||
}
|
||||
_initted = false;
|
||||
}
|
||||
|
||||
bool SPIClassRP2040::setRX(pin_size_t pin) {
|
||||
@@ -281,6 +280,11 @@ void SPIClassRP2040::begin(bool hwCS) {
|
||||
|
||||
void SPIClassRP2040::end() {
|
||||
DEBUGSPI("SPI::end()\n");
|
||||
if (_initted) {
|
||||
DEBUGSPI("SPI: deinitting currently active SPI\n");
|
||||
_initted = false;
|
||||
spi_deinit(_spi);
|
||||
}
|
||||
gpio_set_function(_RX, GPIO_FUNC_SIO);
|
||||
if (_hwCS) {
|
||||
gpio_set_function(_CS, GPIO_FUNC_SIO);
|
||||
|
||||
Submodule libraries/SdFat deleted from 3f50e5547d
@@ -83,6 +83,9 @@ bool TwoWire::setSCL(pin_size_t pin) {
|
||||
|
||||
void TwoWire::setClock(uint32_t hz) {
|
||||
_clkHz = hz;
|
||||
if (_running) {
|
||||
i2c_set_baudrate(_i2c, hz);
|
||||
}
|
||||
}
|
||||
|
||||
// Master mode
|
||||
@@ -123,7 +126,7 @@ void TwoWire::begin(uint8_t addr) {
|
||||
i2c_set_slave_mode(_i2c, true, addr);
|
||||
|
||||
// Our callback IRQ
|
||||
_i2c->hw->intr_mask = (1 << 10) | (1 << 9) | (1 << 5) | (1 << 2);
|
||||
_i2c->hw->intr_mask = (1 << 10) | (1 << 9) | (1 << 6) | (1 << 5) | (1 << 2);
|
||||
|
||||
int irqNo = I2C0_IRQ + i2c_hw_index(_i2c);
|
||||
irq_set_exclusive_handler(irqNo, i2c_hw_index(_i2c) == 0 ? _handler0 : _handler1);
|
||||
@@ -146,7 +149,7 @@ void TwoWire::onIRQ() {
|
||||
_i2c->hw->clr_start_det;
|
||||
}
|
||||
if (_i2c->hw->intr_stat & (1 << 9)) {
|
||||
if (_onReceiveCallback) {
|
||||
if (_onReceiveCallback && _buffLen) {
|
||||
_onReceiveCallback(_buffLen);
|
||||
}
|
||||
_buffLen = 0;
|
||||
@@ -154,6 +157,10 @@ void TwoWire::onIRQ() {
|
||||
_slaveStartDet = false;
|
||||
_i2c->hw->clr_stop_det;
|
||||
}
|
||||
if (_i2c->hw->intr_stat & (1 << 6)) {
|
||||
// TX_ABRT
|
||||
_i2c->hw->clr_tx_abrt;
|
||||
}
|
||||
if (_i2c->hw->intr_stat & (1 << 5)) {
|
||||
// RD_REQ
|
||||
if (_onRequestCallback) {
|
||||
@@ -177,6 +184,8 @@ void TwoWire::end() {
|
||||
return;
|
||||
}
|
||||
i2c_deinit(_i2c);
|
||||
pinMode(_sda, INPUT);
|
||||
pinMode(_scl, INPUT);
|
||||
_running = false;
|
||||
_txBegun = false;
|
||||
}
|
||||
@@ -188,6 +197,7 @@ void TwoWire::beginTransmission(uint8_t addr) {
|
||||
}
|
||||
_addr = addr;
|
||||
_buffLen = 0;
|
||||
_buffOff = 0;
|
||||
_txBegun = true;
|
||||
}
|
||||
|
||||
@@ -196,7 +206,10 @@ size_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_buffLen = i2c_read_blocking_until(_i2c, address, _buff, quantity, !stopBit, make_timeout_time_ms(50));
|
||||
_buffLen = i2c_read_blocking_until(_i2c, address, _buff, quantity, !stopBit, make_timeout_time_ms(_timeout));
|
||||
if (_buffLen == PICO_ERROR_GENERIC) {
|
||||
_buffLen = 0;
|
||||
}
|
||||
_buffOff = 0;
|
||||
return _buffLen;
|
||||
}
|
||||
@@ -284,7 +297,7 @@ uint8_t TwoWire::endTransmission(bool stopBit) {
|
||||
return _probe(_addr, _sda, _scl, _clkHz) ? 0 : 2;
|
||||
} else {
|
||||
auto len = _buffLen;
|
||||
auto ret = i2c_write_blocking_until(_i2c, _addr, _buff, _buffLen, !stopBit, make_timeout_time_ms(50));
|
||||
auto ret = i2c_write_blocking_until(_i2c, _addr, _buff, _buffLen, !stopBit, make_timeout_time_ms(_timeout));
|
||||
_buffLen = 0;
|
||||
return (ret == len) ? 0 : 4;
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
#define WIRE_HAS_END 1
|
||||
|
||||
#ifndef WIRE_BUFFER_SIZE
|
||||
#define WIRE_BUFFER_SIZE 128
|
||||
#define WIRE_BUFFER_SIZE 256
|
||||
#endif
|
||||
|
||||
class TwoWire : public HardwareI2C {
|
||||
@@ -0,0 +1,21 @@
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(3000);
|
||||
Serial.println("High precision timing measurements/delays can be built using");
|
||||
Serial.println("rp2040.getCycleCount() and rp2040.getCycleCount64().\n");
|
||||
uint32_t a = rp2040.getCycleCount();
|
||||
delay(1000);
|
||||
uint32_t b = rp2040.getCycleCount();
|
||||
Serial.printf("There are %d cycles in one second.\n\n\n", b - a);
|
||||
|
||||
delay(3000);
|
||||
|
||||
Serial.println("Note that the (32-bit) getCycleCount() will wraparound in ~30 seconds.");
|
||||
Serial.println("Using the 64-bit getCycleCount64() makes it practically infinite.");
|
||||
Serial.printf("\n%15s - %15s\n", "getCycleCount", "getCycleCount64");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.printf("%15u - %15llu\n", rp2040.getCycleCount(), rp2040.getCycleCount64());
|
||||
delay(1500);
|
||||
}
|
||||
+15
-4
@@ -1,6 +1,17 @@
|
||||
{
|
||||
"name": "framework-arduinopico",
|
||||
"description": "Arduino Wiring-based Framework (RPi Pico RP2040)",
|
||||
"url": "https://github.com/esrlephilhower/arduino-pico",
|
||||
"version": "0.9.2"
|
||||
"name": "framework-arduinopico",
|
||||
"version": "1.11302.0",
|
||||
"description": "Arduino Wiring-based Framework (RPi Pico RP2040)",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"arduino",
|
||||
"Cortex-M",
|
||||
"Raspberry Pi",
|
||||
"RP2040"
|
||||
],
|
||||
"homepage": "https://arduino-pico.readthedocs.io/en/latest/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/earlephilhower/arduino-pico"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
Publishing New Releases
|
||||
=======================
|
||||
|
||||
First, update the version number throughout the repo and push the change:
|
||||
|
||||
./tools/makever.py --version X.Y.Z
|
||||
git commit -a -m "Update version"
|
||||
git push
|
||||
|
||||
GitHub CI Actions are used to automatically build a draft package whenever a tag is pushed to repo:
|
||||
|
||||
git tag X.Y.Z
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
{
|
||||
"name": "Adafruit ItsyBitsy RP2040"
|
||||
},
|
||||
{
|
||||
"name": "Adafruit KB2040"
|
||||
},
|
||||
{
|
||||
"name": "Adafruit Macropad RP2040"
|
||||
},
|
||||
@@ -38,9 +41,57 @@
|
||||
{
|
||||
"name": "Adafruit Trinkey RP2040 QT"
|
||||
},
|
||||
{
|
||||
"name": "Arduino Nano RP2040 Connect"
|
||||
},
|
||||
{
|
||||
"name": "Cytron Maker Nano RP2040"
|
||||
},
|
||||
{
|
||||
"name": "Cytron Maker Pi RP2040"
|
||||
},
|
||||
{
|
||||
"name": "DeRuiLab FlyBoard2040 Core"
|
||||
},
|
||||
{
|
||||
"name": "DFRobot Beetle RP2040"
|
||||
},
|
||||
{
|
||||
"name": "Invector Labs Challenger RP2040 WiFi"
|
||||
},
|
||||
{
|
||||
"name": "Invector Labs Challenger NB RP2040 WiFi"
|
||||
},
|
||||
{
|
||||
"name": "Invector Labs Challenger RP2040 LTE"
|
||||
},
|
||||
{
|
||||
"name": "Invector Labs Challenger RP2040 LoRa"
|
||||
},
|
||||
{
|
||||
"name": "Invector Labs RPICO32"
|
||||
},
|
||||
{
|
||||
"name": "Seeed XIAO RP2040"
|
||||
},
|
||||
{
|
||||
"name": "Solder Party RP2040 Stamp"
|
||||
},
|
||||
{
|
||||
"name": "SparkFun ProMicro RP2040"
|
||||
},
|
||||
{
|
||||
"name": "SparkFun Thing Plus RP2040"
|
||||
},
|
||||
{
|
||||
"name": "Melopero Shake RP2040"
|
||||
},
|
||||
{
|
||||
"name": "uPesy RP2040 DevKit"
|
||||
},
|
||||
{
|
||||
"name": "WIZnet W5100S-EVB-Pico"
|
||||
},
|
||||
{
|
||||
"name": "Generic RP2040 Module"
|
||||
}
|
||||
@@ -48,22 +99,22 @@
|
||||
"toolsDependencies": [
|
||||
{
|
||||
"packager": "rp2040",
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-gcc"
|
||||
},
|
||||
{
|
||||
"packager": "rp2040",
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-mklittlefs"
|
||||
},
|
||||
{
|
||||
"packager": "rp2040",
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-elf2uf2"
|
||||
},
|
||||
{
|
||||
"packager": "rp2040",
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-pioasm"
|
||||
},
|
||||
{
|
||||
@@ -73,7 +124,7 @@
|
||||
},
|
||||
{
|
||||
"packager": "rp2040",
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-openocd"
|
||||
}
|
||||
],
|
||||
@@ -84,57 +135,57 @@
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-openocd",
|
||||
"systems": [
|
||||
{
|
||||
"host": "aarch64-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/aarch64-linux-gnu.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"checksum": "SHA-256:a85f1df05614ac0bba3742df0aa36b0a87b9bbef0fbadd4d0ccfa1938801ae98",
|
||||
"size": "6144933"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/aarch64-linux-gnu.openocd-e3428fadb.220212.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.openocd-e3428fadb.220212.tar.gz",
|
||||
"checksum": "SHA-256:d1d95978101c69c3bc777e61ba70077bf9dc4b3245aa7dd93171acaec4d29fb1",
|
||||
"size": "5607214"
|
||||
},
|
||||
{
|
||||
"host": "arm-linux-gnueabihf",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/arm-linux-gnueabihf.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"checksum": "SHA-256:f79ffe70110512ce41c61477910e33fa5ef986fbc142aedfd89f7009f132b237",
|
||||
"size": "5849262"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/arm-linux-gnueabihf.openocd-e3428fadb.220212.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.openocd-e3428fadb.220212.tar.gz",
|
||||
"checksum": "SHA-256:81373c1e12a88e382a587688343c2e2f2f1f999d38334b7b6ded174929cc9b88",
|
||||
"size": "5344032"
|
||||
},
|
||||
{
|
||||
"host": "i686-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-linux-gnu.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"checksum": "SHA-256:b4a8af73539ae2e2a653f8fbe029a5b52db80580c942f0399cafb7d3829498c0",
|
||||
"size": "5651754"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-linux-gnu.openocd-e3428fadb.220212.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.openocd-e3428fadb.220212.tar.gz",
|
||||
"checksum": "SHA-256:6a4dd98422a187c7725fc349b045b55e4742166c65461847d1bd59537242b0be",
|
||||
"size": "5168258"
|
||||
},
|
||||
{
|
||||
"host": "i686-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-w64-mingw32.openocd-d58c2ef5e.210607.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.openocd-d58c2ef5e.210607.zip",
|
||||
"checksum": "SHA-256:7156af6e650df6fc4bfc8541f2f1fd05bfe136b3547b4a0aef91668af88f8b6d",
|
||||
"size": "8330281"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-w64-mingw32.openocd-e3428fadb.220212.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.openocd-e3428fadb.220212.zip",
|
||||
"checksum": "SHA-256:0643903fcd887a8423cb4ba5329565b499c206921f77ad2e59ae32c472a26dd7",
|
||||
"size": "2156820"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-apple-darwin",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-apple-darwin14.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"checksum": "SHA-256:965e35faf4a93396c4f4a22a504fd6b4f639752922996447d5c1e0e65d7329de",
|
||||
"size": "1981786"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-apple-darwin14.openocd-e3428fadb.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.openocd-e3428fadb.220212.tar.gz",
|
||||
"checksum": "SHA-256:913b65baeeef1b60caf202e69cde4cd5a3ba0ed2f75f2600adfb3dcf4b3899ef",
|
||||
"size": "2002482"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-linux-gnu.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.openocd-d58c2ef5e.210607.tar.gz",
|
||||
"checksum": "SHA-256:c54390c9464bcf2a32265ecbafaec6d68cdd41471fa14ba4afabe43fe0a11645",
|
||||
"size": "6076479"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-linux-gnu.openocd-e3428fadb.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.openocd-e3428fadb.220212.tar.gz",
|
||||
"checksum": "SHA-256:63b2be48c1438d2a09f4ed65d89e555176f18753886555cf48f861e9288d7dc1",
|
||||
"size": "5540524"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-w64-mingw32.openocd-d58c2ef5e.210607.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.openocd-d58c2ef5e.210607.zip",
|
||||
"checksum": "SHA-256:4b481449371b39b4e0e87bd5e5a247f99c025b97ccd186c3b1ca58ff2cb44875",
|
||||
"size": "8719676"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-w64-mingw32.openocd-e3428fadb.220212.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.openocd-e3428fadb.220212.zip",
|
||||
"checksum": "SHA-256:0643903fcd887a8423cb4ba5329565b499c206921f77ad2e59ae32c472a26dd7",
|
||||
"size": "2156820"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -201,222 +252,222 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-gcc",
|
||||
"systems": [
|
||||
{
|
||||
"host": "aarch64-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/aarch64-linux-gnu.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"checksum": "SHA-256:fc30b07b98fe965db814178b71f368895790f6789d503d71c8af70ff92451d5c",
|
||||
"size": "103186508"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/aarch64-linux-gnu.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"checksum": "SHA-256:7773b43b9c0bf5b7cdb2299e9d1b151df97e0a2ded4428809ec68264ac9818a9",
|
||||
"size": "102741416"
|
||||
},
|
||||
{
|
||||
"host": "arm-linux-gnueabihf",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/arm-linux-gnueabihf.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"checksum": "SHA-256:4a6ecfaf485ab428e233cc06e853b91dc272146ca0200fbbcdcb87f1930239b8",
|
||||
"size": "95858053"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/arm-linux-gnueabihf.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"checksum": "SHA-256:c422910ef0e29528939e037ea3c518a532726111604b85b27f3f245820680ccb",
|
||||
"size": "95383443"
|
||||
},
|
||||
{
|
||||
"host": "i686-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-linux-gnu.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"checksum": "SHA-256:8f97c67d20077c551b13344c1a96a9f51dd3a91b178a4731cd9dcc27a19217e6",
|
||||
"size": "105954517"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-linux-gnu.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"checksum": "SHA-256:6306791b43de955c4a4d0a1b8972e0f696206591a810eefc16b906b157322bd3",
|
||||
"size": "105350371"
|
||||
},
|
||||
{
|
||||
"host": "i686-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-w64-mingw32.arm-none-eabi-407f016.210607.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.arm-none-eabi-407f016.210607.zip",
|
||||
"checksum": "SHA-256:c30e8b67d16ae6f29bcca84c166ecc3fced209d73b1b8925d5dd0e79b850f923",
|
||||
"size": "105487629"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-w64-mingw32.arm-none-eabi-ed6d983.220212.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.arm-none-eabi-ed6d983.220212.zip",
|
||||
"checksum": "SHA-256:b00aa3594d1911bea07c1dbf31b9a63430f4dcb91c7b3b1341f8551d361d405f",
|
||||
"size": "105568357"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-apple-darwin",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-apple-darwin14.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"checksum": "SHA-256:5c617ffcf86518a6451701bd5756e28f9b7587acc0cb2cd503b6c600b8cf417d",
|
||||
"size": "107365915"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-apple-darwin14.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"checksum": "SHA-256:e93b967d1fb6ed0fc7cf6a5161e22a597dd05080c1353ac74e2a42ddf8dfe98d",
|
||||
"size": "107429038"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-linux-gnu.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.arm-none-eabi-407f016.210607.tar.gz",
|
||||
"checksum": "SHA-256:0a2b7d03f79f723d62255595f9af862807feee601456bb0e2477ce188a4a975f",
|
||||
"size": "107847587"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-linux-gnu.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.arm-none-eabi-ed6d983.220212.tar.gz",
|
||||
"checksum": "SHA-256:047c4d482cf77e09bd8069fc9d5b28b1e0c76440ad81583a0fc3a8e809959bb8",
|
||||
"size": "106740897"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-w64-mingw32.arm-none-eabi-407f016.210607.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.arm-none-eabi-407f016.210607.zip",
|
||||
"checksum": "SHA-256:675ee78477afc5f2daf1e25f3c0560a3adbaa7f2d73d99059e549835b4022bf8",
|
||||
"size": "110334002"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-w64-mingw32.arm-none-eabi-ed6d983.220212.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.arm-none-eabi-ed6d983.220212.zip",
|
||||
"checksum": "SHA-256:5c15725628a3dbd47a8fa8f9a9aab7a2221815ec9bf85dc2080ce19166316ae6",
|
||||
"size": "110420777"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-elf2uf2",
|
||||
"systems": [
|
||||
{
|
||||
"host": "aarch64-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/aarch64-linux-gnu.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:59f6c2f08f1809987bf40df51808f848146a00c626dff06d3cabafb726db8830",
|
||||
"size": "79850"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/aarch64-linux-gnu.elf2uf2-2062372.220212.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.elf2uf2-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:8cb7ce703b0fa6f2fce6b124ae6f34ad0b866aa4a58096f22b66b1251c1b11c0",
|
||||
"size": "79853"
|
||||
},
|
||||
{
|
||||
"host": "arm-linux-gnueabihf",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/arm-linux-gnueabihf.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:fb6d4270aaa017b5fa60937f82674e5e55cf12da392fd23cc5d1f6de279bcd04",
|
||||
"size": "54220"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/arm-linux-gnueabihf.elf2uf2-2062372.220212.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.elf2uf2-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:790d46b411c16a4a210a91436eb4bdc81fb34f0119148a8f9c4b09489489a54d",
|
||||
"size": "54244"
|
||||
},
|
||||
{
|
||||
"host": "i686-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-linux-gnu.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:b55b823e59b7fa4d1ea130621c6144d84a96f3cb9571109f878472fecbcda7f8",
|
||||
"size": "87882"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-linux-gnu.elf2uf2-2062372.220212.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.elf2uf2-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:7c05c70f761bb6caa986d24ac1065367fe906ff7f0434cf4b0112ace331f74bc",
|
||||
"size": "87891"
|
||||
},
|
||||
{
|
||||
"host": "i686-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-w64-mingw32.elf2uf2-fc10a97.210607.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.elf2uf2-fc10a97.210607.zip",
|
||||
"checksum": "SHA-256:e66f3959fcdc2874dd4074d6e5205715235551062d5283da22906e369dc24bf0",
|
||||
"size": "70429"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-w64-mingw32.elf2uf2-2062372.220212.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.elf2uf2-2062372.220212.zip",
|
||||
"checksum": "SHA-256:e6f0578ea781b160390994d3e95bedfec01e212d47243b1adb84f910a06bcba4",
|
||||
"size": "70405"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-apple-darwin",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-apple-darwin14.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:f85403c39741498547448f40fa6ae323519452af7ab0118c4cf7408340c20e07",
|
||||
"size": "81920"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-apple-darwin14.elf2uf2-2062372.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.elf2uf2-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:d65de7218eaf01c9bf58fa22bd9e1e7c10c054213948b4b62f648a058d09b4de",
|
||||
"size": "81981"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-linux-gnu.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.elf2uf2-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:5e9155cea5639b3716f5149e5a98fa864fe3abd9281f53f1dec65fdbe24d8f28",
|
||||
"size": "79515"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-linux-gnu.elf2uf2-2062372.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.elf2uf2-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:ba7795ed49c54f3f52caee675b0fd078f6fb8498a47bf7e5d7457065271df338",
|
||||
"size": "79585"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-w64-mingw32.elf2uf2-fc10a97.210607.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.elf2uf2-fc10a97.210607.zip",
|
||||
"checksum": "SHA-256:e48b9e8d1c238f29e078056f6fedce715b773b042e52bf63df3759822fa66e64",
|
||||
"size": "78298"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-w64-mingw32.elf2uf2-2062372.220212.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.elf2uf2-2062372.220212.zip",
|
||||
"checksum": "SHA-256:02c7684ed1aea4e18216ec6bbbcedeb482c5f23ad7d5eb9dcb942b8ae6cad5ae",
|
||||
"size": "78279"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-pioasm",
|
||||
"systems": [
|
||||
{
|
||||
"host": "aarch64-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/aarch64-linux-gnu.pioasm-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.pioasm-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:6076ec3624c40cb59c456b501450621c57097bd83af4ebcbd03e3b46333fa745",
|
||||
"size": "453301"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/aarch64-linux-gnu.pioasm-2062372.220212.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.pioasm-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:9ea17ecf0e492bc6a971f6a78780c3b3c6ee644d52e056cba08a708ac225add2",
|
||||
"size": "453558"
|
||||
},
|
||||
{
|
||||
"host": "arm-linux-gnueabihf",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/arm-linux-gnueabihf.pioasm-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.pioasm-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:a6fe07241fb913e846c74855165e038b327705d75d2ca576dd714b42e17749c4",
|
||||
"size": "360370"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/arm-linux-gnueabihf.pioasm-2062372.220212.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.pioasm-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:c7af69227a3b3c54ccf87122b18842460a263bd711abf93336794ce5f905c284",
|
||||
"size": "360559"
|
||||
},
|
||||
{
|
||||
"host": "i686-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-linux-gnu.pioasm-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.pioasm-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:47808419d4a6019e527a0aec8c13b5a8bad7d838547fbb97abcddca866f3fc6b",
|
||||
"size": "511410"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-linux-gnu.pioasm-2062372.220212.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.pioasm-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:f66b9bde3d6859d43049b019fb639dd0bfafcd43f1389ffc499d18949bcf1808",
|
||||
"size": "511397"
|
||||
},
|
||||
{
|
||||
"host": "i686-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-w64-mingw32.pioasm-fc10a97.210607.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.pioasm-fc10a97.210607.zip",
|
||||
"checksum": "SHA-256:c815d6845d374133c346e3ae3e40746217be3a6313190a9b4cdc43a4cd2e2bea",
|
||||
"size": "385662"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-w64-mingw32.pioasm-2062372.220212.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.pioasm-2062372.220212.zip",
|
||||
"checksum": "SHA-256:89cfa44101dade30000cfaa5985de7f0e7aba93d03dc45ba962f97226ae4e41f",
|
||||
"size": "385748"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-apple-darwin",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-apple-darwin14.pioasm-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.pioasm-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:cd19c8ff52ebed430e039b18fd5bf5bfa33f60727a51ca1c81ad3bbcbb6ec763",
|
||||
"size": "480403"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-apple-darwin14.pioasm-2062372.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.pioasm-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:d531c911e6eba0333379af04dd807917659bd4d34be9f4bd6792aeff55ab15a9",
|
||||
"size": "480495"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-linux-gnu.pioasm-fc10a97.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.pioasm-fc10a97.210607.tar.gz",
|
||||
"checksum": "SHA-256:9b8d778a2b3dd5b6bc110dac86e4f9a8321e0bd43f8149bd2722b992b3684515",
|
||||
"size": "458642"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-linux-gnu.pioasm-2062372.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.pioasm-2062372.220212.tar.gz",
|
||||
"checksum": "SHA-256:2cd4aa8af98558461cb7b85b21830ea854a430a3e57668d618c5f1cd5e389809",
|
||||
"size": "458730"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-w64-mingw32.pioasm-fc10a97.210607.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.pioasm-fc10a97.210607.zip",
|
||||
"checksum": "SHA-256:87b5f6cd9c760e5091d1d6e6383028a4255c07d054e6eab0583590dbdc05de69",
|
||||
"size": "408341"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-w64-mingw32.pioasm-2062372.220212.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.pioasm-2062372.220212.zip",
|
||||
"checksum": "SHA-256:ba586e67f4b309690a51fca70fdd26f38b68951b0fee4dc8333183ef6429833a",
|
||||
"size": "408649"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.2.0-a-407f016",
|
||||
"version": "1.3.3-a-ed6d983",
|
||||
"name": "pqt-mklittlefs",
|
||||
"systems": [
|
||||
{
|
||||
"host": "aarch64-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/aarch64-linux-gnu.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"checksum": "SHA-256:6475b7cb24ba165fa97e5ae9e66e56901e3609b57b0edb359b75c810b8267d73",
|
||||
"size": "44791"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/aarch64-linux-gnu.mklittlefs-affa497.220212.tar.gz",
|
||||
"archiveFileName": "aarch64-linux-gnu.mklittlefs-affa497.220212.tar.gz",
|
||||
"checksum": "SHA-256:2455f5ca6cb1f7b73ed1cb55d4d2261d249c1b24915bd4e66e28f037a0a13116",
|
||||
"size": "47271"
|
||||
},
|
||||
{
|
||||
"host": "arm-linux-gnueabihf",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/arm-linux-gnueabihf.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"checksum": "SHA-256:39bfd76f25b5da89244f708de856a5e9548db37eec7c5a88e4832dc5c3d0ee1f",
|
||||
"size": "38247"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/arm-linux-gnueabihf.mklittlefs-affa497.220212.tar.gz",
|
||||
"archiveFileName": "arm-linux-gnueabihf.mklittlefs-affa497.220212.tar.gz",
|
||||
"checksum": "SHA-256:f4b71138f1469e4b9ce82b3b21252aca265a88d56a5d48513dbb5c6d58b19841",
|
||||
"size": "40807"
|
||||
},
|
||||
{
|
||||
"host": "i686-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-linux-gnu.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"checksum": "SHA-256:9b6841d1c5070fb1f2b4a5b6c6850395740ac997aa3fbf888f8cd6e7628200e8",
|
||||
"size": "48240"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-linux-gnu.mklittlefs-affa497.220212.tar.gz",
|
||||
"archiveFileName": "i686-linux-gnu.mklittlefs-affa497.220212.tar.gz",
|
||||
"checksum": "SHA-256:ed1011230c75447dad3d912b7b5607ddcc59e093ee7ebd653fb05274bc876f4c",
|
||||
"size": "50909"
|
||||
},
|
||||
{
|
||||
"host": "i686-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/i686-w64-mingw32.mklittlefs-6b5c62d.210607.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.mklittlefs-6b5c62d.210607.zip",
|
||||
"checksum": "SHA-256:9b6d7ab130c1f07d63a045e987f69496bfc5e3bb4bf6edc9bf4cd04d363c2ac4",
|
||||
"size": "332804"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/i686-w64-mingw32.mklittlefs-affa497.220212.zip",
|
||||
"archiveFileName": "i686-w64-mingw32.mklittlefs-affa497.220212.zip",
|
||||
"checksum": "SHA-256:1289f51c674ebdc568843b82c88db21eb4c295f3b15c26398d31266b9da63b4c",
|
||||
"size": "334050"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-apple-darwin",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-apple-darwin14.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"checksum": "SHA-256:538c30d2a072845873d2e3552ac725dcef022f9ac9a873925c218d5564615321",
|
||||
"size": "362807"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-apple-darwin14.mklittlefs-affa497.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-apple-darwin14.mklittlefs-affa497.220212.tar.gz",
|
||||
"checksum": "SHA-256:0c0d7d8c80739ed79bc5a41e831d0229b6378e87f4c58f148d884814f1ad46d2",
|
||||
"size": "365757"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-pc-linux-gnu",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-linux-gnu.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.mklittlefs-6b5c62d.210607.tar.gz",
|
||||
"checksum": "SHA-256:f2b4d849a2146e54fec52abdfc4391894addfbf1e904094424fb5a2a22873e58",
|
||||
"size": "46918"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-linux-gnu.mklittlefs-affa497.220212.tar.gz",
|
||||
"archiveFileName": "x86_64-linux-gnu.mklittlefs-affa497.220212.tar.gz",
|
||||
"checksum": "SHA-256:c504429c24cfea9bf841cbf0caa29bbe0115e72c94c18f949451ffa540d6cacc",
|
||||
"size": "49766"
|
||||
},
|
||||
{
|
||||
"host": "x86_64-mingw32",
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.2.0-a/x86_64-w64-mingw32.mklittlefs-6b5c62d.210607.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.mklittlefs-6b5c62d.210607.zip",
|
||||
"checksum": "SHA-256:c1105383c2c694978aee521dc1d921fb2e2c3452015c5456f323ffad09595725",
|
||||
"size": "345250"
|
||||
"url": "https://github.com/earlephilhower/pico-quick-toolchain/releases/download/1.3.3-a/x86_64-w64-mingw32.mklittlefs-affa497.220212.zip",
|
||||
"archiveFileName": "x86_64-w64-mingw32.mklittlefs-affa497.220212.zip",
|
||||
"checksum": "SHA-256:4ada867888513596fa51bf78c98d9e970de9b8f1eec4f88d85e6e7621704fb91",
|
||||
"size": "347602"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+1
-1
Submodule pico-extras updated: ccd88d320f...77eae28366
+1
-1
Submodule pico-sdk updated: bfcbefafc5...2062372d20
+32
-20
@@ -20,7 +20,8 @@
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=Raspberry Pi RP2040 Boards
|
||||
version=0.9.9
|
||||
version=1.13.2
|
||||
|
||||
runtime.tools.pqt-gcc.path={runtime.platform.path}/system/arm-none-eabi
|
||||
runtime.tools.pqt-python3.path={runtime.platform.path}/system/python3
|
||||
runtime.tools.pqt-mklittlefs.path={runtime.platform.path}/system/mklittlefs
|
||||
@@ -29,29 +30,32 @@ runtime.tools.pqt-elf2uf2.path={runtime.platform.path}/system/elf2uf2
|
||||
|
||||
compiler.path={runtime.tools.pqt-gcc.path}/bin/
|
||||
|
||||
compiler.libraries.ldflags=
|
||||
|
||||
# Compile variables
|
||||
# -----------------
|
||||
|
||||
compiler.warning_flags=-w
|
||||
compiler.warning_flags.none=-w
|
||||
compiler.warning_flags.default=
|
||||
compiler.warning_flags.more=-Wall
|
||||
compiler.warning_flags.all=-Wall -Wextra
|
||||
compiler.warning_flags=-Werror=return-type
|
||||
compiler.warning_flags.none=-Werror=return-type
|
||||
compiler.warning_flags.default=-Werror=return-type
|
||||
compiler.warning_flags.more=-Wall -Werror=return-type -Wno-ignored-qualifiers
|
||||
compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-ignored-qualifiers
|
||||
|
||||
compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
|
||||
compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/platform_inc.txt"
|
||||
compiler.flags=-Os -march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -fno-exceptions
|
||||
compiler.flags=-march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -fno-exceptions
|
||||
compiler.wrap="@{runtime.platform.path}/lib/platform_wrap.txt"
|
||||
compiler.libpico="{runtime.platform.path}/lib/libpico.a"
|
||||
compiler.libstdcpp="-lstdc++"
|
||||
|
||||
compiler.c.cmd=arm-none-eabi-gcc
|
||||
compiler.c.flags=-c {compiler.defines} {compiler.flags} {compiler.includes} -std=gnu17 -g
|
||||
compiler.c.flags=-c {compiler.warning_flags} {compiler.defines} {compiler.flags} {compiler.includes} -std=gnu17 -g
|
||||
compiler.c.elf.cmd=arm-none-eabi-g++
|
||||
compiler.c.elf.flags={compiler.defines} {compiler.flags} -u _printf_float -u _scanf_float
|
||||
compiler.c.elf.flags={compiler.warning_flags} {compiler.defines} {compiler.flags} {build.flags.optimize} -u _printf_float -u _scanf_float
|
||||
compiler.S.cmd=arm-none-eabi-gcc
|
||||
compiler.S.flags=-c -g -x assembler-with-cpp -MMD {compiler.includes} -g
|
||||
compiler.S.flags=-c {compiler.warning_flags} -g -x assembler-with-cpp -MMD {compiler.includes} -g
|
||||
compiler.cpp.cmd=arm-none-eabi-g++
|
||||
compiler.cpp.flags=-c {compiler.defines} {compiler.flags} {compiler.includes} -fno-rtti -std=gnu++17 -g
|
||||
compiler.cpp.flags=-c {compiler.warning_flags} {compiler.defines} {compiler.flags} {compiler.includes} {build.flags.rtti} -std=gnu++17 -g
|
||||
|
||||
compiler.ar.cmd=arm-none-eabi-ar
|
||||
compiler.ar.flags=rcs
|
||||
@@ -79,6 +83,8 @@ compiler.elf2hex.extra_flags=
|
||||
# Board configuration, set in boards.txt. Present here to ensure substitution works
|
||||
build.flash_length=
|
||||
build.eeprom_start=
|
||||
build.flags.optimize=-Os
|
||||
build.flags.rtti=-fno-rtti
|
||||
build.fs_start=
|
||||
build.fs_end=
|
||||
build.usbstack_flags=
|
||||
@@ -86,20 +92,20 @@ build.usbstack_flags=
|
||||
build.boot2=boot2_generic_03h_4_padded_checksum
|
||||
|
||||
# Allow Pico boards do be auto-discovered by the IDE
|
||||
discovery.rp2040.pattern="{runtime.tools.pqt-python3.path}/python3" "{runtime.platform.path}/tools/discovery.py"
|
||||
discovery.rp2040.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/discovery.py"
|
||||
|
||||
|
||||
# Compile patterns
|
||||
# ----------------
|
||||
|
||||
## Compile c files
|
||||
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
|
||||
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {build.flags.optimize} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile c++ files
|
||||
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
|
||||
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {build.flags.optimize} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile S files
|
||||
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
|
||||
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Create archives
|
||||
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
|
||||
@@ -107,13 +113,13 @@ archive_file_path={build.path}/{archive_file}
|
||||
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
|
||||
|
||||
## Generate the linker map with specific flash sizes/locations
|
||||
recipe.hooks.linking.prelink.1.pattern="{runtime.tools.pqt-python3.path}/python3" "{runtime.platform.path}/tools/simplesub.py" --input "{runtime.platform.path}/lib/memmap_default.ld" --out "{build.path}/memmap_default.ld" --sub __FLASH_LENGTH__ {build.flash_length} --sub __EEPROM_START__ {build.eeprom_start} --sub __FS_START__ {build.fs_start} --sub __FS_END__ {build.fs_end}
|
||||
recipe.hooks.linking.prelink.1.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/simplesub.py" --input "{runtime.platform.path}/lib/memmap_default.ld" --out "{build.path}/memmap_default.ld" --sub __FLASH_LENGTH__ {build.flash_length} --sub __EEPROM_START__ {build.eeprom_start} --sub __FS_START__ {build.fs_start} --sub __FS_END__ {build.fs_end} --sub __RAM_LENGTH__ {build.ram_length}
|
||||
|
||||
## Compile the boot stage 2 blob
|
||||
recipe.hooks.linking.prelink.2.pattern="{compiler.path}{compiler.S.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -c "{runtime.platform.path}/assembly/{build.boot2}.S" "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" -o "{build.path}/boot2.o"
|
||||
recipe.hooks.linking.prelink.2.pattern="{compiler.path}{compiler.S.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -c "{runtime.platform.path}/boot2/{build.boot2}.S" "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" -o "{build.path}/boot2.o"
|
||||
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {compiler.ldflags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" "{build.path}/boot2.o" {compiler.libpico} -lm -lc -lstdc++ -lc -Wl,--end-group
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {compiler.ldflags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" "{build.path}/boot2.o" {compiler.libraries.ldflags} {compiler.libpico} -lm -lc {compiler.libstdcpp} -lc -Wl,--end-group
|
||||
|
||||
## Create output (UF2 file)
|
||||
recipe.objcopy.uf2.pattern="{runtime.tools.pqt-elf2uf2.path}/elf2uf2" "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.uf2"
|
||||
@@ -138,7 +144,7 @@ tools.uf2conv.cmd={runtime.platform.path}/system/python3/python3
|
||||
tools.uf2conv.upload.protocol=uf2
|
||||
tools.uf2conv.upload.params.verbose=
|
||||
tools.uf2conv.upload.params.quiet=
|
||||
tools.uf2conv.upload.pattern="{cmd}" "{runtime.platform.path}/tools/uf2conv.py" --serial "{serial.port}" --family RP2040 --deploy "{build.path}/{build.project_name}.uf2"
|
||||
tools.uf2conv.upload.pattern="{cmd}" -I "{runtime.platform.path}/tools/uf2conv.py" --serial "{serial.port}" --family RP2040 --deploy "{build.path}/{build.project_name}.uf2"
|
||||
|
||||
|
||||
#tools.picoprobe.cmd={runtime.tools.pqt-openocd.path}
|
||||
@@ -146,4 +152,10 @@ tools.picoprobe.cmd={runtime.platform.path}/system/openocd
|
||||
tools.picoprobe.upload.protocol=picoprobe
|
||||
tools.picoprobe.upload.params.verbose=
|
||||
tools.picoprobe.upload.params.quiet=
|
||||
tools.picoprobe.upload.pattern="{cmd}/bin/openocd" -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -s "{cmd}/share/openocd/scripts" -c "program {build.path}/{build.project_name}.elf verify reset exit"
|
||||
tools.picoprobe.upload.pattern="{cmd}/bin/openocd" -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -s "{cmd}/share/openocd/scripts" -c "program {{build.path}/{build.project_name}.elf} verify reset exit"
|
||||
|
||||
tools.picodebug.cmd={runtime.platform.path}/system/openocd
|
||||
tools.picodebug.upload.protocol=pico-debug
|
||||
tools.picodebug.upload.params.verbose=
|
||||
tools.picodebug.upload.params.quiet=
|
||||
tools.picodebug.upload.pattern="{cmd}/bin/openocd" -f "board/pico-debug.cfg" -s "{cmd}/share/openocd/scripts" -c "program {{build.path}/{build.project_name}.elf} verify reset exit"
|
||||
|
||||
@@ -19,8 +19,9 @@ function skip_ino()
|
||||
/hid_keyboard/
|
||||
/msc_external_flash/
|
||||
/msc_external_flash_sdcard/
|
||||
/msc_sdfat/
|
||||
/msc_internal_flash_samd/
|
||||
/msc_sd/
|
||||
/msc_sdfat/
|
||||
/midi_pizza_box_dj/
|
||||
EOL
|
||||
echo $ino | grep -q -F "$skiplist"
|
||||
|
||||
+3
-5
@@ -9,16 +9,13 @@ function skip_ino()
|
||||
read -d '' skiplist << EOL || true
|
||||
/#attic/
|
||||
/AvrAdcLogger/
|
||||
/BackwardCompatibility/
|
||||
/examplesV1/
|
||||
/ExFatFormatter/
|
||||
/ExFatLogger/
|
||||
/ExFatUnicodeTest/
|
||||
/RtcTimestampTest/
|
||||
/SoftwareSpi/
|
||||
/STM32Test/
|
||||
/TeensyDmaAdcLogger/
|
||||
/TeensyRtcTimestamp/
|
||||
/TeensySdioDemo/
|
||||
/TeensySdioLogger/
|
||||
/UserChipSelectFunction/
|
||||
/UserSPIDriver/
|
||||
/Adafruit_TinyUSB_Arduino/
|
||||
@@ -26,6 +23,7 @@ function skip_ino()
|
||||
/p08_DigitalHourglass/
|
||||
/p13_TouchSensorLamp/
|
||||
/StringComparisonOperators/
|
||||
/PDMSerialPlotter/
|
||||
EOL
|
||||
echo $ino | grep -q -F "$skiplist"
|
||||
echo $(( 1 - $? ))
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S \
|
||||
./libraries/LittleFS/src ./libraries/LittleFS/examples \
|
||||
./libraries/rp2040 ./libraries/SD ./libraries/SdFat \
|
||||
./libraries/rp2040 ./libraries/SD ./libraries/ESP8266SdFat \
|
||||
./libraries/Servo ./libraries/SPI ./libraries/Wire; do
|
||||
find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
|
||||
find $dir -type f -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \;
|
||||
|
||||
+5
-1
@@ -25,11 +25,15 @@ rely on existence of `sed` command.
|
||||
|
||||
## makeboards.py
|
||||
Generates `boards.txt` programmatically. Never edit the `boards.txt` file
|
||||
manually, use `python3 tools/makeboards.py > boards.py`. Change the script
|
||||
manually, use `python3 tools/makeboards.py`. Change the script
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
## libpico/make-libpico.sh
|
||||
Builds the libpico.a file as well as the bootloader stage2 binaries.
|
||||
Run whenever the pico-sdk is updated.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
This directory contains JSON board definitions for use with Platform.IO
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_ADAFRUIT_FEATHER_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "adafruit_feather",
|
||||
"boot2_source": "boot2_w25x10cl_4_padded_checksum.S",
|
||||
"usb_vid": "0x239a",
|
||||
"usb_pid": "0x80f1",
|
||||
"usb_manufacturer": "Adafruit",
|
||||
"usb_product": "Feather RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Feather RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_ADAFRUIT_ITSYBITSY_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "adafruit_itsybitsy",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x239a",
|
||||
"usb_pid": "0x80fd",
|
||||
"usb_manufacturer": "Adafruit",
|
||||
"usb_product": "ItsyBitsy RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "ItsyBitsy RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_ADAFRUIT_KB2040_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "adafruit_kb2040",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x239a",
|
||||
"usb_pid": "0x8105",
|
||||
"usb_manufacturer": "Adafruit",
|
||||
"usb_product": "KB2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "KB2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_ADAFRUIT_MACROPAD_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "adafruit_macropad2040",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x239a",
|
||||
"usb_pid": "0x8107",
|
||||
"usb_manufacturer": "Adafruit",
|
||||
"usb_product": "MacroPad RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "MacroPad RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_ADAFRUIT_QTPY_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "adafruit_qtpy",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x239a",
|
||||
"usb_pid": "0x80f7",
|
||||
"usb_manufacturer": "Adafruit",
|
||||
"usb_product": "QT Py RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "QT Py RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_ADAFRUIT_STEMMAFRIEND_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "adafruit_stemmafriend",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x239a",
|
||||
"usb_pid": "0x80e3",
|
||||
"usb_manufacturer": "Adafruit",
|
||||
"usb_product": "STEMMA Friend RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "STEMMA Friend RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_ADAFRUIT_TRINKEYQT_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "adafruit_trinkeyrp2040qt",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x239a",
|
||||
"usb_pid": "0x8109",
|
||||
"usb_manufacturer": "Adafruit",
|
||||
"usb_product": "Trinkey RP2040 QT"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Trinkey RP2040 QT",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Adafruit"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_NANO_RP2040_CONNECT -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "arduino_nano_connect",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x2341",
|
||||
"usb_pid": "0x0058",
|
||||
"usb_manufacturer": "Arduino",
|
||||
"usb_product": "Nano RP2040 Connect"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Nano RP2040 Connect",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 16777216,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Arduino"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_CHALLENGER_2040_LORA_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "challenger_2040_lora",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0x1023",
|
||||
"usb_manufacturer": "iLabs",
|
||||
"usb_product": "Challenger 2040 LoRa"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Challenger 2040 LoRa",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "iLabs"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_CHALLENGER_2040_LTE_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "challenger_2040_lte",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0x100b",
|
||||
"usb_manufacturer": "iLabs",
|
||||
"usb_product": "Challenger 2040 LTE"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Challenger 2040 LTE",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "iLabs"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_CHALLENGER_2040_WIFI_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "challenger_2040_wifi",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0x1006",
|
||||
"usb_manufacturer": "iLabs",
|
||||
"usb_product": "Challenger 2040 WiFi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Challenger 2040 WiFi",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "iLabs"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_CHALLENGER_NB_2040_WIFI_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "challenger_nb_2040_wifi",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0x100b",
|
||||
"usb_manufacturer": "iLabs",
|
||||
"usb_product": "Challenger NB 2040 WiFi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Challenger NB 2040 WiFi",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "iLabs"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_CYTRON_MAKER_NANO_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "cytron_maker_nano_rp2040",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0x100f",
|
||||
"usb_manufacturer": "Cytron",
|
||||
"usb_product": "Maker Nano RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Maker Nano RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 2097152,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Cytron"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_CYTRON_MAKER_PI_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "cytron_maker_pi_rp2040",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0x1000",
|
||||
"usb_manufacturer": "Cytron",
|
||||
"usb_product": "Maker Pi RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Maker Pi RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 2097152,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Cytron"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_DFROBOT_BEETLE_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "dfrobot_beetle_rp2040",
|
||||
"boot2_source": "boot2_w25q080_2_padded_checksum.S",
|
||||
"usb_vid": "0x3343",
|
||||
"usb_pid": "0x4253",
|
||||
"usb_manufacturer": "DFRobot",
|
||||
"usb_product": "Beetle RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Beetle RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 2097152,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "DFRobot"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_FLYBOARD2040_CORE -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=500",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "flyboard2040_core",
|
||||
"boot2_source": "boot2_generic_03h_4_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0x008a",
|
||||
"usb_manufacturer": "DeRuiLab",
|
||||
"usb_product": "FlyBoard2040Core"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "FlyBoard2040Core",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "DeRuiLab"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "earlephilhower",
|
||||
"cpu": "cortex-m0plus",
|
||||
"extra_flags": "-D ARDUINO_GENERIC_RP2040 -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250",
|
||||
"f_cpu": "133000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x2E8A",
|
||||
"0x00C0"
|
||||
]
|
||||
],
|
||||
"mcu": "rp2040",
|
||||
"arduino": {
|
||||
"earlephilhower": {
|
||||
"variant": "generic",
|
||||
"boot2_source": "boot2_generic_03h_4_padded_checksum.S",
|
||||
"usb_vid": "0x2e8a",
|
||||
"usb_pid": "0xf00a",
|
||||
"usb_manufacturer": "Generic",
|
||||
"usb_product": "RP2040"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"jlink_device": "RP2040_M0_0",
|
||||
"openocd_target": "rp2040.cfg",
|
||||
"svd_path": "rp2040.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "RP2040",
|
||||
"upload": {
|
||||
"maximum_ram_size": 270336,
|
||||
"maximum_size": 16777216,
|
||||
"require_upload_port": true,
|
||||
"native_usb": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": false,
|
||||
"protocol": "picotool",
|
||||
"protocols": [
|
||||
"cmsis-dap",
|
||||
"jlink",
|
||||
"raspberrypi-swd",
|
||||
"picotool",
|
||||
"picoprobe"
|
||||
]
|
||||
},
|
||||
"url": "https://www.raspberrypi.org/products/raspberry-pi-pico/",
|
||||
"vendor": "Generic"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user