Compare commits
@@ -6,35 +6,23 @@ name: Arduino-Pico CI
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
TRAVIS_BUILD_DIR: ${{ github.workspace }}
|
||||
TRAVIS_TAG: ${{ github.ref }}
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
# Me no spell so good
|
||||
code-spell:
|
||||
name: Check spelling
|
||||
# Consistent style, spelling
|
||||
astyle:
|
||||
name: Spelling, Style, Boards, Package
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: false
|
||||
- name: Run codespell
|
||||
uses: codespell-project/actions-codespell@master
|
||||
with:
|
||||
skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib,./libraries/http-parser/lib,./libraries/WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino,./libraries/HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino,./.git
|
||||
ignore_words_list: ser,dout
|
||||
|
||||
# Consistent style
|
||||
astyle:
|
||||
name: Style, Boards, Package
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib,./libraries/http-parser/lib,./libraries/WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino,./libraries/HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino,./.git,./libraries/FatFS/lib/fatfs,./libraries/FatFS/src/diskio.h,./libraries/FatFS/src/ff.cpp,./libraries/FatFS/src/ffconf.h,./libraries/FatFS/src/ffsystem.cpp,./libraries/FatFS/src/ff.h,./libraries/lwIP_WINC1500/src/driver,./libraries/lwIP_WINC1500/src/common,./libraries/lwIP_WINC1500/src/bus_wrapper,./libraries/lwIP_WINC1500/src/spi_flash
|
||||
ignore_words_list: ser,dout,shiftIn,acount
|
||||
- name: Get submodules for following tests
|
||||
run: git submodule update --init
|
||||
- name: Check package references
|
||||
run: |
|
||||
./tests/ci/pkgrefs_test.sh
|
||||
@@ -59,15 +47,15 @@ jobs:
|
||||
matrix:
|
||||
chunk: [0, 1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Cache Linux toolchain
|
||||
id: cache-linux
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./tools/dist
|
||||
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
|
||||
@@ -82,20 +70,51 @@ jobs:
|
||||
cd ..
|
||||
bash ./tests/build.sh
|
||||
|
||||
# Build all rp2350 examples on linux (core and Arduino IDE)
|
||||
build-rp2350-linux:
|
||||
name: Build RP2350 ${{ matrix.chunk }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
chunk: [0, 1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Cache Linux toolchain
|
||||
id: cache-linux
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./tools/dist
|
||||
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
|
||||
- name: Build Sketches
|
||||
env:
|
||||
BUILD_PARITY: custom
|
||||
mod: 6
|
||||
rem: ${{ matrix.chunk }}
|
||||
run: |
|
||||
cd pico-sdk
|
||||
git submodule update --init
|
||||
cd ..
|
||||
bash ./tests/build-rp2350.sh
|
||||
|
||||
# Build TinyUSB examples, requires custom build command line
|
||||
build-tinyusb:
|
||||
name: Build TinyUSB Examples
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Cache Linux toolchain
|
||||
id: cache-linux
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./tools/dist
|
||||
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
|
||||
@@ -113,15 +132,15 @@ jobs:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Cache Windows toolchain
|
||||
id: cache-windows
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./tools/dist
|
||||
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
|
||||
@@ -144,17 +163,20 @@ jobs:
|
||||
# Single build under macOS to ensure the Mac toolchain is good.
|
||||
build-mac:
|
||||
name: Mac
|
||||
runs-on: macOS-12
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macOS-12, macOS-14]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Cache Mac toolchain
|
||||
id: cache-mac
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./tools/dist
|
||||
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
|
||||
@@ -165,6 +187,7 @@ jobs:
|
||||
mod: 500
|
||||
rem: 1
|
||||
run: |
|
||||
uname -a
|
||||
cd pico-sdk
|
||||
git submodule update --init
|
||||
cd ..
|
||||
@@ -175,7 +198,7 @@ jobs:
|
||||
name: Build PlatformIO Examples
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Initialize needed submodules
|
||||
@@ -186,19 +209,19 @@ jobs:
|
||||
git submodule update --init
|
||||
cd ../..
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install PlatformIO
|
||||
@@ -207,8 +230,9 @@ jobs:
|
||||
pip install --upgrade platformio
|
||||
pio pkg install --global --platform https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
pio pkg install --global --tool symlink://.
|
||||
cp -f /home/runner/work/arduino-pico/arduino-pico/tools/json/*.json /home/runner/.platformio/platforms/raspberrypi/boards/.
|
||||
- name: Build Multicore Example
|
||||
run: pio ci --board=rpipico --board=adafruit_feather -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Multicore/Multicore.ino
|
||||
run: pio ci -v --board=rpipico --board=rpipico2 --board=adafruit_feather -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Multicore/Multicore.ino
|
||||
- name: Build Fade Example
|
||||
run: pio ci --board=rpipico --board=adafruit_feather -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Fade/Fade.ino
|
||||
- name: Build TinyUSB Example
|
||||
@@ -219,3 +243,55 @@ jobs:
|
||||
run: pio ci --board=rpipicow -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/ArduinoOTA/examples/SignedOTA/SignedOTA.ino
|
||||
- name: Build Bluetooth Example
|
||||
run: pio ci --board=rpipicow -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" -O "build_flags=-DPIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH" libraries/MouseBLE/examples/BLECircle/BLECircle.ino
|
||||
|
||||
# Build every variant using PIO for simplicity
|
||||
build-variants:
|
||||
name: Build Every Variant ${{ matrix.chunk }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
chunk: [0, 1]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Initialize needed submodules
|
||||
run: |
|
||||
cd pico-sdk
|
||||
git submodule update --init
|
||||
cd ../libraries/Adafruit_TinyUSB_Arduino
|
||||
git submodule update --init
|
||||
cd ../..
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install PlatformIO
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade platformio
|
||||
pio pkg install --global --platform https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
pio pkg install --global --tool symlink://.
|
||||
cp -f /home/runner/work/arduino-pico/arduino-pico/tools/json/*.json /home/runner/.platformio/platforms/raspberrypi/boards/.
|
||||
- name: Build Every Variant
|
||||
run: |
|
||||
cnt=0
|
||||
for b in $(cut -f1 -d. /home/runner/work/arduino-pico/arduino-pico/boards.txt | sed 's/#.*//' | sed 's/^menu$//' | sort -u); do
|
||||
cnt=$((cnt + 1))
|
||||
rem=$((cnt % 2))
|
||||
if [ $rem == ${{ matrix.chunk }} ]; then
|
||||
pio ci --board=$b -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Bootsel/Bootsel.ino
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -9,21 +9,21 @@ jobs:
|
||||
name: Update master JSON file
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
# - name: Cache PlatformIO
|
||||
# uses: actions/cache@v3
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: ~/.platformio
|
||||
# key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
@@ -33,7 +33,6 @@ jobs:
|
||||
# pip install --upgrade platformio
|
||||
- name: Deploy updated JSON
|
||||
env:
|
||||
TRAVIS_BUILD_DIR: ${{ github.workspace }}
|
||||
BUILD_TYPE: package
|
||||
CI_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
|
||||
PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }}
|
||||
|
||||
@@ -15,16 +15,15 @@ jobs:
|
||||
name: Package
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build package JSON
|
||||
env:
|
||||
TRAVIS_BUILD_DIR: ${{ github.workspace }}
|
||||
BUILD_TYPE: package
|
||||
CI_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
|
||||
@@ -37,3 +37,12 @@
|
||||
[submodule "libraries/http_parser/lib/http-parser"]
|
||||
path = libraries/http-parser/lib/http-parser
|
||||
url = https://github.com/nodejs/http-parser.git
|
||||
[submodule "libraries/FatFS/lib/SPIFTL"]
|
||||
path = libraries/FatFS/lib/SPIFTL
|
||||
url = https://github.com/earlephilhower/SPIFTL.git
|
||||
[submodule "libraries/AsyncUDP"]
|
||||
path = libraries/AsyncUDP
|
||||
url = https://github.com/earlephilhower/AsyncUDP.git
|
||||
[submodule "cores/rp2040/tlsf"]
|
||||
path = lib/tlsf
|
||||
url = https://github.com/earlephilhower/tlsf.git
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
[](https://github.com/earlephilhower/arduino-pico/releases)
|
||||
[](https://gitter.im/arduino-pico/community)
|
||||
|
||||
Raspberry Pi Pico Arduino core, for all RP2040 boards
|
||||
Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards
|
||||
|
||||
This is a port of the RP2040 (Raspberry Pi Pico processor) to the Arduino ecosystem. It uses the bare Raspberry Pi Pico SDK and a custom GCC 12.3/Newlib 4.0 toolchain.
|
||||
This is a port of Arduino to the RP2040 (Raspberry Pi Pico processor) anr RP2350 (Raspberry Pi Pico 2 processor). It uses the bare Raspberry Pi Pico SDK and a custom GCC 12.3/Newlib 4.0 toolchain.
|
||||
|
||||
# Documentation
|
||||
See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for more detailed usage information.
|
||||
@@ -15,6 +15,7 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
|
||||
# Supported Boards
|
||||
* Raspberry Pi Pico
|
||||
* Raspberry Pi Pico W
|
||||
* Raspberry Pi Pico 2
|
||||
* 0xCB Helios
|
||||
* Adafruit Feather RP2040
|
||||
* Adafruit Feather RP2040 SCORPIO
|
||||
@@ -25,16 +26,26 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
|
||||
* Adafruit QTPy RP2040
|
||||
* Adafruit STEMMA Friend RP2040
|
||||
* Adafruit Trinkey RP2040 QT
|
||||
* Amken Bunny
|
||||
* Amken Revelop
|
||||
* Amken Revelop Plus
|
||||
* Amken Revelop eS
|
||||
* Arduino Nano RP2040 Connect
|
||||
* ArtronShop RP2 Nano
|
||||
* Breadstick Raspberry
|
||||
* BridgeTek IDM2040-7A
|
||||
* BridgeTek IDM2040-43A
|
||||
* Cytron Maker Pi RP2040
|
||||
* Cytron Maker Nano RP2040
|
||||
* Cytron Maker Uno RP2040
|
||||
* DatanoiseTV PicoADK+
|
||||
* Degz Suibo RP2040
|
||||
* DeRuiLab FlyBoard2040 Core
|
||||
* DFRobot Beetle RP2040
|
||||
* ElectronicCats Hunter Cat NFC
|
||||
* EVN Alpha
|
||||
* ExtremeElectronics RC2040
|
||||
* GroundStudio Marble Pico
|
||||
* Invector Labs Challenger RP2040 WiFi
|
||||
* Invector Labs Challenger RP2040 WiFi/BLE
|
||||
* Invector Labs Challenger RP2040 WiFi6/BLE
|
||||
@@ -44,19 +55,33 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
|
||||
* Invector Labs Challenger RP2040 SubGHz
|
||||
* Invector Labs Challenger RP2040 SD/RTC
|
||||
* Invector Labs Challenger RP2040 UWB
|
||||
* Invector Labs Challenger RP2350 BConnect
|
||||
* Invector Labs Challenger RP2350 WiFi/BLE
|
||||
* Invector Labs RPICO32
|
||||
* Melopero Cookie RP2040
|
||||
* Melopero Shake RP2040
|
||||
* METE HOCA Akana R1
|
||||
* Neko Systems BL2040 Mini
|
||||
* Olimex RP2040-Pico30
|
||||
* Newsan Archi
|
||||
* nullbits Bit-C PRO
|
||||
* Pimoroni PGA2040
|
||||
* Pimoroni Plasma2040
|
||||
* Pimoroni Tiny2040
|
||||
* Pintronix PinMax
|
||||
* RAKwireless RAK11300
|
||||
* Redscorp RP2040-Eins
|
||||
* Redscorp RP2040-ProMini
|
||||
* Sea-Picro
|
||||
* Seeed Indicator RP2040
|
||||
* Seeed XIAO RP2040
|
||||
* Silicognition RP2040-Shim
|
||||
* Solder Party RP2040 Stamp
|
||||
* Solder Party RP2350 Stamp
|
||||
* Solder Party RP2350 Stamp XL
|
||||
* SparkFun MicroMod RP2040
|
||||
* SparkFun ProMicro RP2040
|
||||
* SparkFun ProMicro RP2350
|
||||
* SparkFun Thing Plus RP2040
|
||||
* uPesy RP2040 DevKit
|
||||
* VCC-GND YD-RP2040
|
||||
@@ -66,11 +91,44 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
|
||||
* Waveshare RP2040 Plus
|
||||
* Waveshare RP2040 LCD 0.96
|
||||
* Waveshare RP2040 LCD 1.28
|
||||
* Waveshare RP2040 Matrix
|
||||
* Waveshare RP2040 PiZero
|
||||
* WIZnet W5100S-EVB-Pico
|
||||
* WIZnet W5500-EVB-Pico
|
||||
* WIZnet WizFi360-EVB-Pico
|
||||
* Redscorp RP2040-ProMini
|
||||
* Generic (configurable flash, I/O pins)
|
||||
* Generic RP2040 (configurable flash, I/O pins)
|
||||
* Generic RP2350 (configurable flash, I/O pins)
|
||||
|
||||
# Features
|
||||
* Transparent use of PSRAM globals and heap (RP2350 only)
|
||||
* Adafruit TinyUSB Arduino (USB mouse, keyboard, flash drive, generic HID, CDC Serial, MIDI, WebUSB, others)
|
||||
* Bluetooth on the PicoW (Classic and BLE) with Keyboard, Mouse, Joystick, and Virtual Serial
|
||||
* Bluetooth Classic and BLE HID master mode (connect to BT keyboard, mouse, or joystick)
|
||||
* Generic Arduino USB Serial, Keyboard, Joystick, and Mouse emulation
|
||||
* WiFi (Pico W, ESP32-based ESPHost, Atmel WINC1500)
|
||||
* Ethernet (Wired WizNet W6100, WizNet W5500, WizNet W5100, ENC28J60)
|
||||
* HTTP client and server (WebServer)
|
||||
* SSL/TLS/HTTPS
|
||||
* Over-the-Air (OTA) upgrades
|
||||
* Filesystems (LittleFS and SD/SDFS)
|
||||
* Multicore support (setup1() and loop1())
|
||||
* FreeRTOS SMP support
|
||||
* Overclocking and underclocking from the menus
|
||||
* digitalWrite/Read, shiftIn/Out, tone, analogWrite(PWM)/Read, temperature
|
||||
* Analog stereo audio in using DMA and the built-in ADC
|
||||
* Analog stereo audio out using PWM hardware
|
||||
* Bluetooth A2DP audio source (output) and sink (input) on the PicoW
|
||||
* USB drive mode for data loggers (SingleFileDrive, FatFSUSB)
|
||||
* Peripherals: SPI master/slave, Wire(I2C) master/slave, dual UART, emulated EEPROM, I2S audio input/output, Servo
|
||||
* printf (i.e. debug) output over USB serial
|
||||
|
||||
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
|
||||
* Servos
|
||||
* Tones
|
||||
* I2S Input
|
||||
* I2S Output
|
||||
* Software UARTs (Serial ports)
|
||||
|
||||
|
||||
# Installing via Arduino Boards Manager
|
||||
## Windows-specific Notes
|
||||
@@ -169,11 +227,16 @@ Under Windows a local admin user should be able to access the Picoprobe port aut
|
||||
|
||||
To set up user-level access to Picoprobes on Ubuntu (and other OSes which use `udev`):
|
||||
````
|
||||
echo 'SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", GROUP="users", MODE="0666"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
|
||||
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE="660", GROUP-"plugdev"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
|
||||
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE="660", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
|
||||
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000f", MODE="660", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
|
||||
sudo udevadm control --reload
|
||||
sudo udevadm trigger -w -s usb
|
||||
````
|
||||
|
||||
The first line creates a file with the USB vendor and ID of the Picoprobe 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.
|
||||
The first line creates a device file in `/dev` matching the USB vendor and product ID of the Picoprobe, and it enables global read+write permissions. The second line causes `udev` to load this new rule. The third line requests the kernel generate "device change" events that will cause our new `udev` rule to run.
|
||||
|
||||
If for some reason the device file does not appear, manually unplug and re-plug the USB connection and check again. The output from `dmesg` can reveal useful diagnostics if the device file remains absent.
|
||||
|
||||
Once Picoprobe permissions are set up properly, then select the board "Raspberry Pi Pico (Picoprobe)" in the Tools menu and upload as normal.
|
||||
|
||||
@@ -182,13 +245,16 @@ Once Picoprobe permissions are set up properly, then select the board "Raspberry
|
||||
|
||||
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`):
|
||||
To set up group-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
|
||||
sudo udevadm trigger -w -s usb
|
||||
````
|
||||
|
||||
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.
|
||||
The first line creates a device file in `/dev` that matches all CMSIS-DAP adapters, and it enables read+write permissions for members of the `plugdev` group. The second line causes `udev` to load this new rule. The third line requests the kernel generate "device change" events that will cause our new `udev` rule to run.
|
||||
|
||||
If for some reason the device file does not appear, manually unplug and re-plug the USB connection and check again. The output from `dmesg` can reveal useful diagnostics if the device file remains absent.
|
||||
|
||||
Once CMSIS-DAP permissions are set up properly, then select the board "Raspberry Pi Pico (pico-debug)" in the Tools menu.
|
||||
|
||||
@@ -197,48 +263,6 @@ When first connecting the USB port to your PC, you must copy [pico-debug-gimmeca
|
||||
# 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)
|
||||
* Bluetooth on the PicoW (Classic and BLE) with Keyboard, Mouse, Joystick, and Virtual Serial
|
||||
* Generic Arduino USB Serial, Keyboard, Joystick, and Mouse emulation
|
||||
* WiFi (Pico W)
|
||||
* Ethernet (Wired W5500, W5100, ENC28J60)
|
||||
* HTTP client and server (WebServer)
|
||||
* SSL/TLS/HTTPS
|
||||
* Over-the-Air (OTA) upgrades
|
||||
* Filesystems (LittleFS and SD/SDFS)
|
||||
* Multicore support (setup1() and loop1())
|
||||
* FreeRTOS SMP support
|
||||
* Overclocking and underclocking from the menus
|
||||
* digitalWrite/Read, shiftIn/Out, tone, analogWrite(PWM)/Read, temperature
|
||||
* Analog stereo audio in using DMA and the built-in ADC
|
||||
* Analog stereo audio out using PWM hardware
|
||||
* USB drive mode for data loggers (SingleFileDrive)
|
||||
* Peripherals: SPI master/slave, Wire(I2C) master/slave, dual UART, emulated EEPROM, I2S audio input/output, Servo
|
||||
* printf (i.e. debug) output over USB serial
|
||||
|
||||
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
|
||||
* Servos
|
||||
* Tones
|
||||
* I2S Input
|
||||
* I2S Output
|
||||
* Software UARTs (Serial ports)
|
||||
|
||||
# Tutorials from Across the Web
|
||||
Here are some links to coverage and additional tutorials for using `arduino-pico`
|
||||
* The File:: class is taken from the ESP8266. See https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html
|
||||
* Arduino Support for the Pi Pico available! And how fast is the Pico? - https://youtu.be/-XHh17cuH5E
|
||||
* Pre-release Adafruit QT Py RP2040 - https://www.youtube.com/watch?v=sfC1msqXX0I
|
||||
* Adafruit Feather RP2040 running LCD + TMP117 - https://www.youtube.com/watch?v=fKDeqZiIwHg
|
||||
* Demonstration of Servos and I2C in Korean - https://cafe.naver.com/arduinoshield/1201
|
||||
* Home Assistant Pico W integration starter project using Arduino - https://github.com/daniloc/PicoW_HomeAssistant_Starter
|
||||
* Tutorials for the Raspberry Pi Pico / uPesy RP2040 DevKit board
|
||||
- English version: https://www.upesy.com/blogs/tutorials/best-tutorials-for-rpi-pi-pico-with-arduino-code
|
||||
- French version: https://www.upesy.fr/blogs/tutorials/best-tutorials-for-rpi-pi-pico-with-arduino-code
|
||||
|
||||
# Contributing
|
||||
If you want to contribute or have bugfixes, drop me a note at <earlephilhower@yahoo.com> or open an issue/PR here.
|
||||
|
||||
# Licensing and Credits
|
||||
* The [Arduino IDE and ArduinoCore-API](https://arduino.cc) are developed and maintained by the Arduino team. The IDE is licensed under GPL.
|
||||
* The [RP2040 GCC-based toolchain](https://github.com/earlephilhower/pico-quick-toolchain) is licensed under under the GPL.
|
||||
@@ -248,14 +272,16 @@ If you want to contribute or have bugfixes, drop me a note at <earlephilhower@ya
|
||||
* [UF2CONV.PY](https://github.com/microsoft/uf2) is by Microsoft Corporation and licensed under the MIT license.
|
||||
* Networking and filesystem code taken from the [ESP8266 Arduino Core](https://github.com/esp8266/Arduino) and licensed under the LGPL.
|
||||
* DHCP server for AP host mode from the [Micropython Project](https://micropython.org), distributed under the MIT License.
|
||||
* [FreeRTOS](https://freertos.org) is Copyright Amazon.com, Inc. or its affiliates, and distributed under the MIT license.
|
||||
* [FreeRTOS](https://freertos.org) is copyright Amazon.com, Inc. or its affiliates, and distributed under the MIT license.
|
||||
* [lwIP](https://savannah.nongnu.org/projects/lwip/) is (c) the Swedish Institute of Computer Science and licenced under the BSD license.
|
||||
* [BearSSL](https://bearssl.org) library written by Thomas Pornin, is distributed under the [MIT License](https://bearssl.org/#legal-details).
|
||||
* [UZLib](https://github.com/pfalcon/uzlib) is copyright (c) 2003 Joergen Ibsen and distributed under the zlib license.
|
||||
* [LEAmDNS](https://github.com/LaborEtArs/ESP8266mDNS) is copyright multiple authors and distributed under the MIT license.
|
||||
* [http-parser](https://github.com/nodejs/http-parser) is copyright Joyent, Inc. and other Node contributors.
|
||||
* WebServer code modified from the [ESP32 WebServer](https://github.com/espressif/arduino-esp32/tree/master/libraries/WebServer) and is copyright (c) 2015 Ivan Grokhotkov and others
|
||||
|
||||
* WebServer code modified from the [ESP32 WebServer](https://github.com/espressif/arduino-esp32/tree/master/libraries/WebServer) and is copyright (c) 2015 Ivan Grokhotkov and others.
|
||||
* [Xoshiro-cpp](https://github.com/Reputeless/Xoshiro-cpp) is copyright (c) 2020 Ryo Suzuki and distributed under the MIT license.
|
||||
* [FatFS low-level filesystem](http://elm-chan.org/fsw/ff/) code is Copyright (C) 2024, ChaN, all rights reserved.
|
||||
* [TLSF memory manager for PSRAM from Espressif fork](https://github.com/espressif/tlsf) of [original](https://github.com/mattconte/tlsf) by Matthew Conte is copyright Matthew Conte and licensed under the MIT license.
|
||||
|
||||
-Earle F. Philhower, III
|
||||
earlephilhower@yahoo.com
|
||||
|
||||
+12977
-1258
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
// Padded and checksummed version of: generated\Winbond\W25Q32JVxQ\boot2.bin
|
||||
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .boot2, "ax"
|
||||
|
||||
.byte 0xf7, 0xb5, 0x73, 0x46, 0x21, 0x22, 0x02, 0x25, 0x01, 0x93, 0x29, 0x4b, 0xc0, 0x24, 0x5a, 0x60
|
||||
.byte 0x9a, 0x68, 0x01, 0x26, 0xaa, 0x43, 0xda, 0x60, 0x9a, 0x60, 0x1a, 0x61, 0x5a, 0x61, 0x00, 0x23
|
||||
.byte 0x64, 0x05, 0xa3, 0x60, 0x04, 0x33, 0x63, 0x61, 0x22, 0x4b, 0x28, 0x00, 0x1e, 0x60, 0xe0, 0x23
|
||||
.byte 0xdb, 0x02, 0x23, 0x60, 0x35, 0x23, 0xa6, 0x60, 0x23, 0x66, 0x23, 0x66, 0x00, 0xf0, 0x4a, 0xf8
|
||||
.byte 0xc0, 0xb2, 0xa8, 0x42, 0x12, 0xd0, 0x06, 0x23, 0x30, 0x00, 0x23, 0x66, 0x00, 0xf0, 0x42, 0xf8
|
||||
.byte 0x31, 0x23, 0x28, 0x00, 0x23, 0x66, 0x25, 0x66, 0x00, 0xf0, 0x3c, 0xf8, 0x03, 0x35, 0x25, 0x66
|
||||
.byte 0x02, 0x20, 0x25, 0x66, 0x00, 0xf0, 0x36, 0xf8, 0x30, 0x42, 0xf8, 0xd1, 0x00, 0x25, 0x12, 0x4b
|
||||
.byte 0xa5, 0x60, 0x12, 0x4f, 0x23, 0x60, 0x12, 0x4b, 0x65, 0x60, 0x01, 0x26, 0x3b, 0x60, 0xeb, 0x23
|
||||
.byte 0xa6, 0x60, 0x23, 0x66, 0x4b, 0x3b, 0x23, 0x66, 0x02, 0x20, 0x00, 0xf0, 0x23, 0xf8, 0x0d, 0x4b
|
||||
.byte 0xa5, 0x60, 0x3b, 0x60, 0xa6, 0x60, 0x01, 0x9b, 0xab, 0x42, 0x08, 0xd1, 0x0a, 0x4b, 0x0b, 0x4a
|
||||
.byte 0x13, 0x60, 0x1b, 0x68, 0x83, 0xf3, 0x08, 0x88, 0x09, 0x4b, 0x1b, 0x68, 0x18, 0x47, 0xf7, 0xbd
|
||||
.byte 0x00, 0x00, 0x02, 0x40, 0xf0, 0x00, 0x00, 0x18, 0x00, 0x03, 0x5f, 0x00, 0xf4, 0x00, 0x00, 0x18
|
||||
.byte 0x21, 0x22, 0x00, 0x00, 0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0
|
||||
.byte 0x04, 0x01, 0x00, 0x10, 0xc0, 0x23, 0x02, 0x00, 0x04, 0x21, 0x5b, 0x05, 0x98, 0x6a, 0x08, 0x42
|
||||
.byte 0xfc, 0xd0, 0x01, 0x21, 0x98, 0x6a, 0x08, 0x42, 0xfc, 0xd1, 0x18, 0x6e, 0x01, 0x2a, 0x00, 0xd0
|
||||
.byte 0x18, 0x6e, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x2d, 0x68, 0xca
|
||||
@@ -0,0 +1,25 @@
|
||||
// Padded and checksummed version of: boot2_generic_03h.2.bin
|
||||
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .boot2, "ax"
|
||||
|
||||
.global __boot2_entry_point
|
||||
__boot2_entry_point:
|
||||
.byte 0x00, 0xb5, 0x05, 0x4b, 0x05, 0x48, 0xd8, 0x60, 0x4f, 0xf0, 0x03, 0x00, 0x58, 0x61, 0x4f, 0xf4
|
||||
.byte 0x80, 0x50, 0x18, 0x61, 0x00, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x40, 0x02, 0x01, 0x00, 0x40
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
@@ -0,0 +1,25 @@
|
||||
// Padded and checksummed version of: boot2_generic_03h.4.bin
|
||||
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .boot2, "ax"
|
||||
|
||||
.global __boot2_entry_point
|
||||
__boot2_entry_point:
|
||||
.byte 0x00, 0xb5, 0x05, 0x4b, 0x05, 0x48, 0xd8, 0x60, 0x4f, 0xf0, 0x03, 0x00, 0x58, 0x61, 0x4f, 0xf4
|
||||
.byte 0x80, 0x50, 0x18, 0x61, 0x00, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x40, 0x04, 0x01, 0x00, 0x40
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
@@ -0,0 +1,25 @@
|
||||
// Padded and checksummed version of: boot2_w25q080.2.bin
|
||||
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .boot2, "ax"
|
||||
|
||||
.global __boot2_entry_point
|
||||
__boot2_entry_point:
|
||||
.byte 0x00, 0xb5, 0x24, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x13, 0xf5, 0x40, 0x53, 0x02, 0x20, 0x98, 0x60
|
||||
.byte 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x13, 0xf5, 0x0d, 0x23, 0x1f, 0x49, 0x19, 0x60, 0x18, 0x68
|
||||
.byte 0x10, 0xf0, 0x02, 0x0f, 0xfb, 0xd1, 0x35, 0x20, 0x00, 0xf0, 0x2c, 0xf8, 0x02, 0x28, 0x14, 0xd0
|
||||
.byte 0x06, 0x20, 0x58, 0x60, 0x00, 0xf0, 0x22, 0xf8, 0x98, 0x68, 0x01, 0x20, 0x58, 0x60, 0x00, 0x20
|
||||
.byte 0x58, 0x60, 0x02, 0x20, 0x58, 0x60, 0x00, 0xf0, 0x19, 0xf8, 0x98, 0x68, 0x98, 0x68, 0x98, 0x68
|
||||
.byte 0x05, 0x20, 0x00, 0xf0, 0x17, 0xf8, 0x40, 0x08, 0xfa, 0xd2, 0x31, 0xf0, 0x01, 0x01, 0x19, 0x60
|
||||
.byte 0x0e, 0x48, 0xd8, 0x60, 0x4a, 0xf2, 0xeb, 0x00, 0x58, 0x61, 0x0d, 0x48, 0x18, 0x61, 0x4f, 0xf0
|
||||
.byte 0xa0, 0x51, 0x09, 0x78, 0x20, 0xf4, 0x80, 0x50, 0x18, 0x61, 0x00, 0xbd, 0x18, 0x68, 0x80, 0x08
|
||||
.byte 0xfc, 0xd2, 0x70, 0x47, 0x00, 0xb5, 0x58, 0x60, 0x58, 0x60, 0xff, 0xf7, 0xf7, 0xff, 0x98, 0x68
|
||||
.byte 0x98, 0x68, 0x00, 0xbd, 0x00, 0x00, 0x04, 0x40, 0x41, 0x00, 0x80, 0x07, 0x02, 0x02, 0x00, 0x40
|
||||
.byte 0xa8, 0x92, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
@@ -0,0 +1,25 @@
|
||||
// Padded and checksummed version of: boot2_w25q080.4.bin
|
||||
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
.section .boot2, "ax"
|
||||
|
||||
.global __boot2_entry_point
|
||||
__boot2_entry_point:
|
||||
.byte 0x00, 0xb5, 0x24, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x13, 0xf5, 0x40, 0x53, 0x02, 0x20, 0x98, 0x60
|
||||
.byte 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x13, 0xf5, 0x0d, 0x23, 0x1f, 0x49, 0x19, 0x60, 0x18, 0x68
|
||||
.byte 0x10, 0xf0, 0x02, 0x0f, 0xfb, 0xd1, 0x35, 0x20, 0x00, 0xf0, 0x2c, 0xf8, 0x02, 0x28, 0x14, 0xd0
|
||||
.byte 0x06, 0x20, 0x58, 0x60, 0x00, 0xf0, 0x22, 0xf8, 0x98, 0x68, 0x01, 0x20, 0x58, 0x60, 0x00, 0x20
|
||||
.byte 0x58, 0x60, 0x02, 0x20, 0x58, 0x60, 0x00, 0xf0, 0x19, 0xf8, 0x98, 0x68, 0x98, 0x68, 0x98, 0x68
|
||||
.byte 0x05, 0x20, 0x00, 0xf0, 0x17, 0xf8, 0x40, 0x08, 0xfa, 0xd2, 0x31, 0xf0, 0x01, 0x01, 0x19, 0x60
|
||||
.byte 0x0e, 0x48, 0xd8, 0x60, 0x4a, 0xf2, 0xeb, 0x00, 0x58, 0x61, 0x0d, 0x48, 0x18, 0x61, 0x4f, 0xf0
|
||||
.byte 0xa0, 0x51, 0x09, 0x78, 0x20, 0xf4, 0x80, 0x50, 0x18, 0x61, 0x00, 0xbd, 0x18, 0x68, 0x80, 0x08
|
||||
.byte 0xfc, 0xd2, 0x70, 0x47, 0x00, 0xb5, 0x58, 0x60, 0x58, 0x60, 0xff, 0xf7, 0xf7, 0xff, 0x98, 0x68
|
||||
.byte 0x98, 0x68, 0x00, 0xbd, 0x00, 0x00, 0x04, 0x40, 0x41, 0x00, 0x80, 0x07, 0x04, 0x02, 0x00, 0x40
|
||||
.byte 0xa8, 0x92, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
+11
-5
@@ -30,7 +30,6 @@
|
||||
#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()
|
||||
@@ -59,15 +58,21 @@ extern "C" {
|
||||
void interrupts();
|
||||
void noInterrupts();
|
||||
|
||||
#ifdef RP2350_PSRAM_CS
|
||||
void *pmalloc(size_t size);
|
||||
void *pcalloc(size_t count, size_t size);
|
||||
#endif
|
||||
|
||||
|
||||
// AVR compatibility macros...naughty and accesses the HW directly
|
||||
#define digitalPinToPort(pin) (0)
|
||||
#define digitalPinToBitMask(pin) (1UL << (pin))
|
||||
#define digitalPinToTimer(pin) (0)
|
||||
#define digitalPinToInterrupt(pin) (pin)
|
||||
#define NOT_AN_INTERRUPT (-1)
|
||||
#define portOutputRegister(port) ((volatile uint32_t*) sio_hw->gpio_out)
|
||||
#define portInputRegister(port) ((volatile uint32_t*) sio_hw->gpio_in)
|
||||
#define portModeRegister(port) ((volatile uint32_t*) sio_hw->gpio_oe)
|
||||
#define portOutputRegister(port) ((volatile uint32_t *)&(sio_hw->gpio_out))
|
||||
#define portInputRegister(port) ((volatile uint32_t *)&(sio_hw->gpio_in))
|
||||
#define portModeRegister(port) ((volatile uint32_t *)&(sio_hw->gpio_oe))
|
||||
#define digitalWriteFast(pin, val) (val ? sio_hw->gpio_set = (1 << pin) : sio_hw->gpio_clr = (1 << pin))
|
||||
#define digitalReadFast(pin) ((1 << pin) & sio_hw->gpio_in)
|
||||
#define sei() interrupts()
|
||||
@@ -139,4 +144,5 @@ constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) {
|
||||
#undef stdio_usb_init
|
||||
#define stdio_usb_init(...) static_assert(0, "stdio_usb_init is not supported or needed. Either use Serial.printf() or set the debug port in the IDE to Serial/1/2 and use printf(). See https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1540354673 and https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1546783109")
|
||||
|
||||
|
||||
// PSRAM decorator
|
||||
#define PSRAM __attribute__((section("\".psram\"")))
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Enable BTStack debugging to a Print-able object
|
||||
|
||||
Copyright (c) 2023 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
|
||||
*/
|
||||
|
||||
#if defined(ENABLE_CLASSIC) || defined(ENABLE_BLE)
|
||||
#include <Arduino.h>
|
||||
#include <btstack.h>
|
||||
#include <hci_dump.h>
|
||||
|
||||
static Print *_print;
|
||||
|
||||
static void _log_packet(uint8_t packet_type, uint8_t in, uint8_t *packet, uint16_t len) {
|
||||
if (!_print) {
|
||||
return;
|
||||
}
|
||||
_print->printf("[BT @%lu] ", millis());
|
||||
|
||||
switch (packet_type) {
|
||||
case HCI_COMMAND_DATA_PACKET:
|
||||
_print->printf("CMD => ");
|
||||
break;
|
||||
case HCI_EVENT_PACKET:
|
||||
_print->printf("EVT <= ");
|
||||
break;
|
||||
case HCI_ACL_DATA_PACKET:
|
||||
_print->printf("ACL %s ", in ? "<=" : "=>");
|
||||
break;
|
||||
case HCI_SCO_DATA_PACKET:
|
||||
_print->printf("SCO %s ", in ? "<=" : "=>");
|
||||
break;
|
||||
case HCI_ISO_DATA_PACKET:
|
||||
_print->printf("ISO %s ", in ? "<=" : "=>");
|
||||
break;
|
||||
case LOG_MESSAGE_PACKET:
|
||||
_print->printf("LOG -- %s\n", (char*) packet);
|
||||
return;
|
||||
default:
|
||||
_print->printf("UNK(%x) %s ", packet_type, in ? "<=" : "=>");
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
_print->printf("%02X ", packet[i]);
|
||||
}
|
||||
_print->printf("\n");
|
||||
}
|
||||
|
||||
static void _log_message(int log_level, const char * format, va_list argptr) {
|
||||
(void)log_level;
|
||||
char log_message_buffer[HCI_DUMP_MAX_MESSAGE_LEN];
|
||||
if (!_print) {
|
||||
return;
|
||||
}
|
||||
vsnprintf(log_message_buffer, sizeof(log_message_buffer), format, argptr);
|
||||
_print->printf("[BT @%lu] LOG -- %s\n", millis(), log_message_buffer);
|
||||
}
|
||||
|
||||
|
||||
static const hci_dump_t hci_dump_instance = {
|
||||
NULL,
|
||||
_log_packet,
|
||||
_log_message
|
||||
};
|
||||
|
||||
|
||||
void __EnableBluetoothDebug(Print &print) {
|
||||
_print = &print;
|
||||
hci_dump_init(&hci_dump_instance);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -39,7 +39,12 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
|
||||
|
||||
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
|
||||
// Note the button pulls the pin *low* when pressed.
|
||||
bool button_state = !(sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX));
|
||||
#if PICO_RP2040
|
||||
#define CS_BIT (1u << 1)
|
||||
#else
|
||||
#define CS_BIT SIO_GPIO_HI_IN_QSPI_CSN_BITS
|
||||
#endif
|
||||
bool button_state = !(sio_hw->gpio_hi_in & CS_BIT);
|
||||
|
||||
// Need to restore the state of chip select, else we are going to have a
|
||||
// bad time when we return to code in flash!
|
||||
|
||||
+26
-7
@@ -225,6 +225,21 @@ void File::setTimeCallback(time_t (*cb)(void)) {
|
||||
_timeCallback = cb;
|
||||
}
|
||||
|
||||
bool File::stat(FSStat *st) {
|
||||
if (!_p) {
|
||||
return false;
|
||||
}
|
||||
size_t pos = position();
|
||||
seek(0, SeekEnd);
|
||||
st->size = position() - pos;
|
||||
seek(pos, SeekSet);
|
||||
st->blocksize = 0; // Not set here
|
||||
st->ctime = getCreationTime();
|
||||
st->atime = getLastWrite();
|
||||
st->isDir = isDirectory();
|
||||
return true;
|
||||
}
|
||||
|
||||
File Dir::openFile(const char* mode) {
|
||||
if (!_impl) {
|
||||
return File();
|
||||
@@ -366,13 +381,6 @@ bool FS::info(FSInfo& info) {
|
||||
return _impl->info(info);
|
||||
}
|
||||
|
||||
bool FS::info64(FSInfo64& info) {
|
||||
if (!_impl) {
|
||||
return false;
|
||||
}
|
||||
return _impl->info64(info);
|
||||
}
|
||||
|
||||
File FS::open(const String& path, const char* mode) {
|
||||
return open(path.c_str(), mode);
|
||||
}
|
||||
@@ -462,6 +470,17 @@ bool FS::rename(const String& pathFrom, const String& pathTo) {
|
||||
return rename(pathFrom.c_str(), pathTo.c_str());
|
||||
}
|
||||
|
||||
bool FS::stat(const char *path, FSStat *st) {
|
||||
if (!_impl) {
|
||||
return false;
|
||||
}
|
||||
return _impl->stat(path, st);
|
||||
}
|
||||
|
||||
bool FS::stat(const String& path, FSStat *st) {
|
||||
return stat(path.c_str(), st);
|
||||
}
|
||||
|
||||
time_t FS::getCreationTime() {
|
||||
if (!_impl) {
|
||||
return 0;
|
||||
|
||||
+14
-13
@@ -48,6 +48,14 @@ enum SeekMode {
|
||||
SeekEnd = 2
|
||||
};
|
||||
|
||||
struct FSStat {
|
||||
size_t size;
|
||||
size_t blocksize;
|
||||
time_t ctime;
|
||||
time_t atime;
|
||||
bool isDir;
|
||||
};
|
||||
|
||||
class File : public Stream {
|
||||
public:
|
||||
File(FileImplPtr p = FileImplPtr(), FS *baseFS = nullptr) : _p(p), _fakeDir(nullptr), _baseFS(baseFS) {
|
||||
@@ -119,6 +127,8 @@ public:
|
||||
time_t getCreationTime();
|
||||
void setTimeCallback(time_t (*cb)(void));
|
||||
|
||||
bool stat(FSStat *st);
|
||||
|
||||
protected:
|
||||
FileImplPtr _p;
|
||||
time_t (*_timeCallback)(void) = nullptr;
|
||||
@@ -152,18 +162,8 @@ protected:
|
||||
time_t (*_timeCallback)(void) = nullptr;
|
||||
};
|
||||
|
||||
// Backwards compatible, <4GB filesystem usage
|
||||
struct FSInfo {
|
||||
size_t totalBytes;
|
||||
size_t usedBytes;
|
||||
size_t blockSize;
|
||||
size_t pageSize;
|
||||
size_t maxOpenFiles;
|
||||
size_t maxPathLength;
|
||||
};
|
||||
|
||||
// Support > 4GB filesystems (SD, etc.)
|
||||
struct FSInfo64 {
|
||||
struct FSInfo {
|
||||
uint64_t totalBytes;
|
||||
uint64_t usedBytes;
|
||||
size_t blockSize;
|
||||
@@ -172,7 +172,6 @@ struct FSInfo64 {
|
||||
size_t maxPathLength;
|
||||
};
|
||||
|
||||
|
||||
class FSConfig {
|
||||
public:
|
||||
static constexpr uint32_t FSId = 0x00000000;
|
||||
@@ -201,7 +200,6 @@ public:
|
||||
|
||||
bool format();
|
||||
bool info(FSInfo& info);
|
||||
bool info64(FSInfo64& info);
|
||||
|
||||
File open(const char* path, const char* mode);
|
||||
File open(const String& path, const char* mode);
|
||||
@@ -224,6 +222,9 @@ public:
|
||||
bool rmdir(const char* path);
|
||||
bool rmdir(const String& path);
|
||||
|
||||
bool stat(const char *path, FSStat *st);
|
||||
bool stat(const String& path, FSStat *st);
|
||||
|
||||
// Low-level FS routines, not needed by most applications
|
||||
bool gc();
|
||||
bool check();
|
||||
|
||||
@@ -119,7 +119,6 @@ public:
|
||||
virtual void end() = 0;
|
||||
virtual bool format() = 0;
|
||||
virtual bool info(FSInfo& info) = 0;
|
||||
virtual bool info64(FSInfo64& info) = 0;
|
||||
virtual FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) = 0;
|
||||
virtual bool exists(const char* path) = 0;
|
||||
virtual DirImplPtr openDir(const char* path) = 0;
|
||||
@@ -127,6 +126,7 @@ public:
|
||||
virtual bool remove(const char* path) = 0;
|
||||
virtual bool mkdir(const char* path) = 0;
|
||||
virtual bool rmdir(const char* path) = 0;
|
||||
virtual bool stat(const char *path, FSStat *st) = 0;
|
||||
virtual bool gc() {
|
||||
return true; // May not be implemented in all file systems.
|
||||
}
|
||||
|
||||
@@ -22,9 +22,16 @@
|
||||
#include "PIOProgram.h"
|
||||
#include <map>
|
||||
|
||||
static std::map<const pio_program_t *, int> __pioMap[2];
|
||||
auto_init_mutex(_pioMutex);
|
||||
#if defined(PICO_RP2350)
|
||||
#define PIOS pio0, pio1, pio2
|
||||
#define PIOCNT 3
|
||||
#elif defined(PICO_RP2040)
|
||||
#define PIOS pio0, pio1
|
||||
#define PIOCNT 2
|
||||
#endif
|
||||
|
||||
static std::map<const pio_program_t *, int> __pioMap[PIOCNT];
|
||||
auto_init_mutex(_pioMutex);
|
||||
|
||||
PIOProgram::PIOProgram(const pio_program_t *pgm) {
|
||||
_pgm = pgm;
|
||||
@@ -42,10 +49,10 @@ PIOProgram::~PIOProgram() {
|
||||
// Possibly load into a PIO and allocate a SM
|
||||
bool PIOProgram::prepare(PIO *pio, int *sm, int *offset) {
|
||||
CoreMutex m(&_pioMutex);
|
||||
PIO pi[2] = { pio0, pio1 };
|
||||
PIO pi[PIOCNT] = { PIOS };
|
||||
|
||||
// If it's already loaded into PIO IRAM, try and allocate in that specific PIO
|
||||
for (int o = 0; o < 2; o++) {
|
||||
for (int o = 0; o < PIOCNT; o++) {
|
||||
auto p = __pioMap[o].find(_pgm);
|
||||
if (p != __pioMap[o].end()) {
|
||||
int idx = pio_claim_unused_sm(pi[o], false);
|
||||
@@ -61,7 +68,7 @@ bool PIOProgram::prepare(PIO *pio, int *sm, int *offset) {
|
||||
}
|
||||
|
||||
// Not in any PIO IRAM, so try and add
|
||||
for (int o = 0; o < 2; o++) {
|
||||
for (int o = 0; o < PIOCNT; o++) {
|
||||
if (pio_can_add_program(pi[o], _pgm)) {
|
||||
int idx = pio_claim_unused_sm(pi[o], false);
|
||||
if (idx >= 0) {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <hardware/structs/rosc.h>
|
||||
#include <hardware/structs/systick.h>
|
||||
#include <pico/multicore.h>
|
||||
#include <hardware/dma.h>
|
||||
#include <pico/rand.h>
|
||||
#include <pico/util/queue.h>
|
||||
#include <pico/bootrom.h>
|
||||
@@ -59,8 +60,13 @@ public:
|
||||
void registerCore() {
|
||||
if (!__isFreeRTOS) {
|
||||
multicore_fifo_clear_irq();
|
||||
#ifdef PICO_RP2350
|
||||
irq_set_exclusive_handler(SIO_IRQ_FIFO, _irq);
|
||||
irq_set_enabled(SIO_IRQ_FIFO, true);
|
||||
#else
|
||||
irq_set_exclusive_handler(SIO_IRQ_PROC0 + get_core_num(), _irq);
|
||||
irq_set_enabled(SIO_IRQ_PROC0 + get_core_num(), true);
|
||||
#endif
|
||||
}
|
||||
// FreeRTOS port.c will handle the IRQ hooking
|
||||
}
|
||||
@@ -157,6 +163,10 @@ extern RP2040 rp2040;
|
||||
extern "C" void main1();
|
||||
extern "C" char __StackLimit;
|
||||
extern "C" char __bss_end__;
|
||||
extern "C" void setup1() __attribute__((weak));
|
||||
extern "C" void loop1() __attribute__((weak));
|
||||
extern "C" bool core1_separate_stack;
|
||||
extern "C" uint32_t* core1_separate_stack_address;
|
||||
|
||||
class RP2040 {
|
||||
public:
|
||||
@@ -238,6 +248,56 @@ public:
|
||||
return &__StackLimit - &__bss_end__;
|
||||
}
|
||||
|
||||
inline int getFreePSRAMHeap() {
|
||||
return getTotalPSRAMHeap() - getUsedPSRAMHeap();
|
||||
}
|
||||
|
||||
inline int getUsedPSRAMHeap() {
|
||||
#if defined(PICO_RP2350)
|
||||
extern size_t __psram_total_used();
|
||||
return __psram_total_used();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int getTotalPSRAMHeap() {
|
||||
#if defined(PICO_RP2350)
|
||||
extern size_t __psram_total_space();
|
||||
return __psram_total_space();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t getStackPointer() {
|
||||
uint32_t *sp;
|
||||
asm volatile("mov %0, sp" : "=r"(sp));
|
||||
return (uint32_t)sp;
|
||||
}
|
||||
|
||||
inline int getFreeStack() {
|
||||
const unsigned int sp = getStackPointer();
|
||||
uint32_t ref = 0x20040000;
|
||||
if (setup1 || loop1) {
|
||||
if (core1_separate_stack) {
|
||||
ref = cpuid() ? (unsigned int)core1_separate_stack_address : 0x20040000;
|
||||
} else {
|
||||
ref = cpuid() ? 0x20040000 : 0x20041000;
|
||||
}
|
||||
}
|
||||
return sp - ref;
|
||||
}
|
||||
|
||||
inline size_t getPSRAMSize() {
|
||||
#if defined(PICO_RP2350)
|
||||
extern size_t __psram_size;
|
||||
return __psram_size;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void idleOtherCore() {
|
||||
fifo.idleOtherCore();
|
||||
}
|
||||
@@ -288,6 +348,36 @@ public:
|
||||
return id;
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
void *memcpyDMA(void *dest, const void *src, size_t n) {
|
||||
// Allocate a DMA channel on 1st call, reuse it every call after
|
||||
if (memcpyDMAChannel < 1) {
|
||||
memcpyDMAChannel = dma_claim_unused_channel(true);
|
||||
dma_channel_config c = dma_channel_get_default_config(memcpyDMAChannel);
|
||||
channel_config_set_transfer_data_size(&c, DMA_SIZE_32);
|
||||
channel_config_set_read_increment(&c, true);
|
||||
channel_config_set_write_increment(&c, true);
|
||||
channel_config_set_irq_quiet(&c, true);
|
||||
dma_channel_set_config(memcpyDMAChannel, &c, false);
|
||||
}
|
||||
// If there's any misalignment or too small, use regular memcpy which can handle it
|
||||
if ((n < 64) || (((uint32_t)dest) | ((uint32_t)src) | n) & 3) {
|
||||
return memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
int words = n / 4;
|
||||
dma_channel_set_read_addr(memcpyDMAChannel, src, false);
|
||||
dma_channel_set_write_addr(memcpyDMAChannel, dest, false);
|
||||
dma_channel_set_trans_count(memcpyDMAChannel, words, false);
|
||||
dma_channel_start(memcpyDMAChannel);
|
||||
while (dma_channel_is_busy(memcpyDMAChannel)) {
|
||||
/* busy wait dma */
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
// Multicore comms FIFO
|
||||
_MFIFO fifo;
|
||||
|
||||
@@ -313,4 +403,5 @@ private:
|
||||
PIO _pio;
|
||||
int _sm;
|
||||
PIOProgram *_ccountPgm;
|
||||
int memcpyDMAChannel = -1;
|
||||
};
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <pico/usb_reset_interface.h>
|
||||
#include <hardware/watchdog.h>
|
||||
#include <pico/bootrom.h>
|
||||
#include "sdkoverride/tusb_absmouse.h"
|
||||
#include "sdkoverride/tusb_gamepad16.h"
|
||||
#include <device/usbd_pvt.h>
|
||||
|
||||
// Big, global USB mutex, shared with all USB devices to make sure we don't
|
||||
@@ -83,6 +83,8 @@ static int __usb_task_irq;
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_VENDOR_SPECIFIC, RESET_INTERFACE_SUBCLASS, RESET_INTERFACE_PROTOCOL, _stridx,
|
||||
|
||||
|
||||
int usb_hid_poll_interval __attribute__((weak)) = 10;
|
||||
|
||||
const uint8_t *tud_descriptor_device_cb(void) {
|
||||
static tusb_desc_device_t usbd_desc_device = {
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
@@ -157,7 +159,7 @@ void __SetupDescHIDReport() {
|
||||
//allocate memory for the HID report descriptors. We don't use them, but need the size here.
|
||||
uint8_t desc_hid_report_mouse[] = { TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1)) };
|
||||
uint8_t desc_hid_report_absmouse[] = { TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(1)) };
|
||||
uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(1)) };
|
||||
uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD16(HID_REPORT_ID(1)) };
|
||||
uint8_t desc_hid_report_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)), TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(2)) };
|
||||
int size = 0;
|
||||
|
||||
@@ -227,7 +229,7 @@ void __SetupDescHIDReport() {
|
||||
reportid++;
|
||||
offset += sizeof(desc_hid_report_absmouse);
|
||||
}
|
||||
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(reportid)) };
|
||||
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD16(HID_REPORT_ID(reportid)) };
|
||||
memcpy(__hid_report + offset, desc_local, sizeof(desc_local));
|
||||
}
|
||||
}
|
||||
@@ -263,7 +265,7 @@ void __SetupUSBDescriptor() {
|
||||
uint8_t hid_itf = __USBInstallSerial ? 2 : 0;
|
||||
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)
|
||||
TUD_HID_DESCRIPTOR(hid_itf, 0, HID_ITF_PROTOCOL_NONE, hid_report_len, EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, (uint8_t)usb_hid_poll_interval)
|
||||
};
|
||||
|
||||
uint8_t msd_itf = interface_count - 1;
|
||||
@@ -400,7 +402,7 @@ bool __USBHIDReady() {
|
||||
|
||||
while (((millis() - start) < timeout) && tud_ready() && !tud_hid_ready()) {
|
||||
tud_task();
|
||||
delay(1);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
return tud_hid_ready();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#define ARDUINO_PICO_MAJOR 3
|
||||
#define ARDUINO_PICO_MINOR 6
|
||||
#define ARDUINO_PICO_REVISION 0
|
||||
#define ARDUINO_PICO_VERSION_STR "3.6.0"
|
||||
#define ARDUINO_PICO_MAJOR 4
|
||||
#define ARDUINO_PICO_MINOR 0
|
||||
#define ARDUINO_PICO_REVISION 1
|
||||
#define ARDUINO_PICO_VERSION_STR "4.0.1"
|
||||
|
||||
@@ -53,7 +53,7 @@ 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
|
||||
// Not to be called by users, only from the IRQ handler. In public so that the C-language IRQ callback can access it
|
||||
void _handleIRQ();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -201,7 +201,7 @@ void SerialUART::begin(unsigned long baud, uint16_t config) {
|
||||
break;
|
||||
}
|
||||
uart_set_format(_uart, bits, stop, parity);
|
||||
uart_set_hw_flow(_uart, _rts != UART_PIN_NOT_DEFINED, _cts != UART_PIN_NOT_DEFINED);
|
||||
uart_set_hw_flow(_uart, _cts != UART_PIN_NOT_DEFINED, _rts != UART_PIN_NOT_DEFINED);
|
||||
_writer = 0;
|
||||
_reader = 0;
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
uart_inst_t *_uart;
|
||||
pin_size_t _tx, _rx;
|
||||
pin_size_t _rts, _cts;
|
||||
enum gpio_function _fcnTx, _fcnRx, _fcnRts, _fcnCts;
|
||||
gpio_function_t _fcnTx, _fcnRx, _fcnRts, _fcnCts;
|
||||
int _baud;
|
||||
mutex_t _mutex;
|
||||
bool _polling = false;
|
||||
|
||||
@@ -197,6 +197,14 @@ static void CheckSerialReset() {
|
||||
}
|
||||
}
|
||||
|
||||
bool SerialUSB::dtr() {
|
||||
return _dtr;
|
||||
}
|
||||
|
||||
bool SerialUSB::rts() {
|
||||
return _rts;
|
||||
}
|
||||
|
||||
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
|
||||
(void) itf;
|
||||
_dtr = dtr ? true : false;
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
virtual size_t write(const uint8_t *p, size_t len) override;
|
||||
using Print::write;
|
||||
operator bool() override;
|
||||
bool dtr();
|
||||
bool rts();
|
||||
|
||||
void ignoreFlowControl(bool ignore = true);
|
||||
|
||||
|
||||
@@ -0,0 +1,474 @@
|
||||
|
||||
// autogenerated from https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv
|
||||
// by script <rp2040 arduino core>/tools/tzupdate.sh
|
||||
// Sat 20 Jan 2024 08:54:45 PM UTC
|
||||
//
|
||||
// This database is autogenerated from IANA timezone database
|
||||
// https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv
|
||||
// (using https://www.iana.org/time-zones)
|
||||
// and can be updated on demand in this repository
|
||||
// or by yourself using the above script
|
||||
|
||||
#pragma once
|
||||
|
||||
#define TZ_Africa_Abidjan ("GMT0")
|
||||
#define TZ_Africa_Accra ("GMT0")
|
||||
#define TZ_Africa_Addis_Ababa ("EAT-3")
|
||||
#define TZ_Africa_Algiers ("CET-1")
|
||||
#define TZ_Africa_Asmara ("EAT-3")
|
||||
#define TZ_Africa_Bamako ("GMT0")
|
||||
#define TZ_Africa_Bangui ("WAT-1")
|
||||
#define TZ_Africa_Banjul ("GMT0")
|
||||
#define TZ_Africa_Bissau ("GMT0")
|
||||
#define TZ_Africa_Blantyre ("CAT-2")
|
||||
#define TZ_Africa_Brazzaville ("WAT-1")
|
||||
#define TZ_Africa_Bujumbura ("CAT-2")
|
||||
#define TZ_Africa_Cairo ("EET-2EEST,M4.5.5/0,M10.5.4/24")
|
||||
#define TZ_Africa_Casablanca ("<+01>-1")
|
||||
#define TZ_Africa_Ceuta ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Africa_Conakry ("GMT0")
|
||||
#define TZ_Africa_Dakar ("GMT0")
|
||||
#define TZ_Africa_Dar_es_Salaam ("EAT-3")
|
||||
#define TZ_Africa_Djibouti ("EAT-3")
|
||||
#define TZ_Africa_Douala ("WAT-1")
|
||||
#define TZ_Africa_El_Aaiun ("<+01>-1")
|
||||
#define TZ_Africa_Freetown ("GMT0")
|
||||
#define TZ_Africa_Gaborone ("CAT-2")
|
||||
#define TZ_Africa_Harare ("CAT-2")
|
||||
#define TZ_Africa_Johannesburg ("SAST-2")
|
||||
#define TZ_Africa_Juba ("CAT-2")
|
||||
#define TZ_Africa_Kampala ("EAT-3")
|
||||
#define TZ_Africa_Khartoum ("CAT-2")
|
||||
#define TZ_Africa_Kigali ("CAT-2")
|
||||
#define TZ_Africa_Kinshasa ("WAT-1")
|
||||
#define TZ_Africa_Lagos ("WAT-1")
|
||||
#define TZ_Africa_Libreville ("WAT-1")
|
||||
#define TZ_Africa_Lome ("GMT0")
|
||||
#define TZ_Africa_Luanda ("WAT-1")
|
||||
#define TZ_Africa_Lubumbashi ("CAT-2")
|
||||
#define TZ_Africa_Lusaka ("CAT-2")
|
||||
#define TZ_Africa_Malabo ("WAT-1")
|
||||
#define TZ_Africa_Maputo ("CAT-2")
|
||||
#define TZ_Africa_Maseru ("SAST-2")
|
||||
#define TZ_Africa_Mbabane ("SAST-2")
|
||||
#define TZ_Africa_Mogadishu ("EAT-3")
|
||||
#define TZ_Africa_Monrovia ("GMT0")
|
||||
#define TZ_Africa_Nairobi ("EAT-3")
|
||||
#define TZ_Africa_Ndjamena ("WAT-1")
|
||||
#define TZ_Africa_Niamey ("WAT-1")
|
||||
#define TZ_Africa_Nouakchott ("GMT0")
|
||||
#define TZ_Africa_Ouagadougou ("GMT0")
|
||||
#define TZ_Africa_PortomNovo ("WAT-1")
|
||||
#define TZ_Africa_Sao_Tome ("GMT0")
|
||||
#define TZ_Africa_Tripoli ("EET-2")
|
||||
#define TZ_Africa_Tunis ("CET-1")
|
||||
#define TZ_Africa_Windhoek ("CAT-2")
|
||||
#define TZ_America_Adak ("HST10HDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Anchorage ("AKST9AKDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Anguilla ("AST4")
|
||||
#define TZ_America_Antigua ("AST4")
|
||||
#define TZ_America_Araguaina ("<-03>3")
|
||||
#define TZ_America_Argentina_Buenos_Aires ("<-03>3")
|
||||
#define TZ_America_Argentina_Catamarca ("<-03>3")
|
||||
#define TZ_America_Argentina_Cordoba ("<-03>3")
|
||||
#define TZ_America_Argentina_Jujuy ("<-03>3")
|
||||
#define TZ_America_Argentina_La_Rioja ("<-03>3")
|
||||
#define TZ_America_Argentina_Mendoza ("<-03>3")
|
||||
#define TZ_America_Argentina_Rio_Gallegos ("<-03>3")
|
||||
#define TZ_America_Argentina_Salta ("<-03>3")
|
||||
#define TZ_America_Argentina_San_Juan ("<-03>3")
|
||||
#define TZ_America_Argentina_San_Luis ("<-03>3")
|
||||
#define TZ_America_Argentina_Tucuman ("<-03>3")
|
||||
#define TZ_America_Argentina_Ushuaia ("<-03>3")
|
||||
#define TZ_America_Aruba ("AST4")
|
||||
#define TZ_America_Asuncion ("<-04>4<-03>,M10.1.0/0,M3.4.0/0")
|
||||
#define TZ_America_Atikokan ("EST5")
|
||||
#define TZ_America_Bahia ("<-03>3")
|
||||
#define TZ_America_Bahia_Banderas ("CST6")
|
||||
#define TZ_America_Barbados ("AST4")
|
||||
#define TZ_America_Belem ("<-03>3")
|
||||
#define TZ_America_Belize ("CST6")
|
||||
#define TZ_America_BlancmSablon ("AST4")
|
||||
#define TZ_America_Boa_Vista ("<-04>4")
|
||||
#define TZ_America_Bogota ("<-05>5")
|
||||
#define TZ_America_Boise ("MST7MDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Cambridge_Bay ("MST7MDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Campo_Grande ("<-04>4")
|
||||
#define TZ_America_Cancun ("EST5")
|
||||
#define TZ_America_Caracas ("<-04>4")
|
||||
#define TZ_America_Cayenne ("<-03>3")
|
||||
#define TZ_America_Cayman ("EST5")
|
||||
#define TZ_America_Chicago ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Chihuahua ("CST6")
|
||||
#define TZ_America_Costa_Rica ("CST6")
|
||||
#define TZ_America_Creston ("MST7")
|
||||
#define TZ_America_Cuiaba ("<-04>4")
|
||||
#define TZ_America_Curacao ("AST4")
|
||||
#define TZ_America_Danmarkshavn ("GMT0")
|
||||
#define TZ_America_Dawson ("MST7")
|
||||
#define TZ_America_Dawson_Creek ("MST7")
|
||||
#define TZ_America_Denver ("MST7MDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Detroit ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Dominica ("AST4")
|
||||
#define TZ_America_Edmonton ("MST7MDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Eirunepe ("<-05>5")
|
||||
#define TZ_America_El_Salvador ("CST6")
|
||||
#define TZ_America_Fortaleza ("<-03>3")
|
||||
#define TZ_America_Fort_Nelson ("MST7")
|
||||
#define TZ_America_Glace_Bay ("AST4ADT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Godthab ("<-02>2<-01>,M3.5.0/-1,M10.5.0/0")
|
||||
#define TZ_America_Goose_Bay ("AST4ADT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Grand_Turk ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Grenada ("AST4")
|
||||
#define TZ_America_Guadeloupe ("AST4")
|
||||
#define TZ_America_Guatemala ("CST6")
|
||||
#define TZ_America_Guayaquil ("<-05>5")
|
||||
#define TZ_America_Guyana ("<-04>4")
|
||||
#define TZ_America_Halifax ("AST4ADT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Havana ("CST5CDT,M3.2.0/0,M11.1.0/1")
|
||||
#define TZ_America_Hermosillo ("MST7")
|
||||
#define TZ_America_Indiana_Indianapolis ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Indiana_Knox ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Indiana_Marengo ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Indiana_Petersburg ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Indiana_Tell_City ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Indiana_Vevay ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Indiana_Vincennes ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Indiana_Winamac ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Inuvik ("MST7MDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Iqaluit ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Jamaica ("EST5")
|
||||
#define TZ_America_Juneau ("AKST9AKDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Kentucky_Louisville ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Kentucky_Monticello ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Kralendijk ("AST4")
|
||||
#define TZ_America_La_Paz ("<-04>4")
|
||||
#define TZ_America_Lima ("<-05>5")
|
||||
#define TZ_America_Los_Angeles ("PST8PDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Lower_Princes ("AST4")
|
||||
#define TZ_America_Maceio ("<-03>3")
|
||||
#define TZ_America_Managua ("CST6")
|
||||
#define TZ_America_Manaus ("<-04>4")
|
||||
#define TZ_America_Marigot ("AST4")
|
||||
#define TZ_America_Martinique ("AST4")
|
||||
#define TZ_America_Matamoros ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Mazatlan ("MST7")
|
||||
#define TZ_America_Menominee ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Merida ("CST6")
|
||||
#define TZ_America_Metlakatla ("AKST9AKDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Mexico_City ("CST6")
|
||||
#define TZ_America_Miquelon ("<-03>3<-02>,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Moncton ("AST4ADT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Monterrey ("CST6")
|
||||
#define TZ_America_Montevideo ("<-03>3")
|
||||
#define TZ_America_Montreal ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Montserrat ("AST4")
|
||||
#define TZ_America_Nassau ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_New_York ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Nipigon ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Nome ("AKST9AKDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Noronha ("<-02>2")
|
||||
#define TZ_America_North_Dakota_Beulah ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_North_Dakota_Center ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_North_Dakota_New_Salem ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Nuuk ("<-02>2<-01>,M3.5.0/-1,M10.5.0/0")
|
||||
#define TZ_America_Ojinaga ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Panama ("EST5")
|
||||
#define TZ_America_Pangnirtung ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Paramaribo ("<-03>3")
|
||||
#define TZ_America_Phoenix ("MST7")
|
||||
#define TZ_America_PortmaumPrince ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Port_of_Spain ("AST4")
|
||||
#define TZ_America_Porto_Velho ("<-04>4")
|
||||
#define TZ_America_Puerto_Rico ("AST4")
|
||||
#define TZ_America_Punta_Arenas ("<-03>3")
|
||||
#define TZ_America_Rainy_River ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Rankin_Inlet ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Recife ("<-03>3")
|
||||
#define TZ_America_Regina ("CST6")
|
||||
#define TZ_America_Resolute ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Rio_Branco ("<-05>5")
|
||||
#define TZ_America_Santarem ("<-03>3")
|
||||
#define TZ_America_Santiago ("<-04>4<-03>,M9.1.6/24,M4.1.6/24")
|
||||
#define TZ_America_Santo_Domingo ("AST4")
|
||||
#define TZ_America_Sao_Paulo ("<-03>3")
|
||||
#define TZ_America_Scoresbysund ("<-01>1<+00>,M3.5.0/0,M10.5.0/1")
|
||||
#define TZ_America_Sitka ("AKST9AKDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_St_Barthelemy ("AST4")
|
||||
#define TZ_America_St_Johns ("NST3:30NDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_St_Kitts ("AST4")
|
||||
#define TZ_America_St_Lucia ("AST4")
|
||||
#define TZ_America_St_Thomas ("AST4")
|
||||
#define TZ_America_St_Vincent ("AST4")
|
||||
#define TZ_America_Swift_Current ("CST6")
|
||||
#define TZ_America_Tegucigalpa ("CST6")
|
||||
#define TZ_America_Thule ("AST4ADT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Thunder_Bay ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Tijuana ("PST8PDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Toronto ("EST5EDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Tortola ("AST4")
|
||||
#define TZ_America_Vancouver ("PST8PDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Whitehorse ("MST7")
|
||||
#define TZ_America_Winnipeg ("CST6CDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Yakutat ("AKST9AKDT,M3.2.0,M11.1.0")
|
||||
#define TZ_America_Yellowknife ("MST7MDT,M3.2.0,M11.1.0")
|
||||
#define TZ_Antarctica_Casey ("<+11>-11")
|
||||
#define TZ_Antarctica_Davis ("<+07>-7")
|
||||
#define TZ_Antarctica_DumontDUrville ("<+10>-10")
|
||||
#define TZ_Antarctica_Macquarie ("AEST-10AEDT,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Antarctica_Mawson ("<+05>-5")
|
||||
#define TZ_Antarctica_McMurdo ("NZST-12NZDT,M9.5.0,M4.1.0/3")
|
||||
#define TZ_Antarctica_Palmer ("<-03>3")
|
||||
#define TZ_Antarctica_Rothera ("<-03>3")
|
||||
#define TZ_Antarctica_Syowa ("<+03>-3")
|
||||
#define TZ_Antarctica_Troll ("<+00>0<+02>-2,M3.5.0/1,M10.5.0/3")
|
||||
#define TZ_Antarctica_Vostok ("<+06>-6")
|
||||
#define TZ_Arctic_Longyearbyen ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Asia_Aden ("<+03>-3")
|
||||
#define TZ_Asia_Almaty ("<+06>-6")
|
||||
#define TZ_Asia_Amman ("<+03>-3")
|
||||
#define TZ_Asia_Anadyr ("<+12>-12")
|
||||
#define TZ_Asia_Aqtau ("<+05>-5")
|
||||
#define TZ_Asia_Aqtobe ("<+05>-5")
|
||||
#define TZ_Asia_Ashgabat ("<+05>-5")
|
||||
#define TZ_Asia_Atyrau ("<+05>-5")
|
||||
#define TZ_Asia_Baghdad ("<+03>-3")
|
||||
#define TZ_Asia_Bahrain ("<+03>-3")
|
||||
#define TZ_Asia_Baku ("<+04>-4")
|
||||
#define TZ_Asia_Bangkok ("<+07>-7")
|
||||
#define TZ_Asia_Barnaul ("<+07>-7")
|
||||
#define TZ_Asia_Beirut ("EET-2EEST,M3.5.0/0,M10.5.0/0")
|
||||
#define TZ_Asia_Bishkek ("<+06>-6")
|
||||
#define TZ_Asia_Brunei ("<+08>-8")
|
||||
#define TZ_Asia_Chita ("<+09>-9")
|
||||
#define TZ_Asia_Choibalsan ("<+08>-8")
|
||||
#define TZ_Asia_Colombo ("<+0530>-5:30")
|
||||
#define TZ_Asia_Damascus ("<+03>-3")
|
||||
#define TZ_Asia_Dhaka ("<+06>-6")
|
||||
#define TZ_Asia_Dili ("<+09>-9")
|
||||
#define TZ_Asia_Dubai ("<+04>-4")
|
||||
#define TZ_Asia_Dushanbe ("<+05>-5")
|
||||
#define TZ_Asia_Famagusta ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Asia_Gaza ("EET-2EEST,M3.4.4/50,M10.4.4/50")
|
||||
#define TZ_Asia_Hebron ("EET-2EEST,M3.4.4/50,M10.4.4/50")
|
||||
#define TZ_Asia_Ho_Chi_Minh ("<+07>-7")
|
||||
#define TZ_Asia_Hong_Kong ("HKT-8")
|
||||
#define TZ_Asia_Hovd ("<+07>-7")
|
||||
#define TZ_Asia_Irkutsk ("<+08>-8")
|
||||
#define TZ_Asia_Jakarta ("WIB-7")
|
||||
#define TZ_Asia_Jayapura ("WIT-9")
|
||||
#define TZ_Asia_Jerusalem ("IST-2IDT,M3.4.4/26,M10.5.0")
|
||||
#define TZ_Asia_Kabul ("<+0430>-4:30")
|
||||
#define TZ_Asia_Kamchatka ("<+12>-12")
|
||||
#define TZ_Asia_Karachi ("PKT-5")
|
||||
#define TZ_Asia_Kathmandu ("<+0545>-5:45")
|
||||
#define TZ_Asia_Khandyga ("<+09>-9")
|
||||
#define TZ_Asia_Kolkata ("IST-5:30")
|
||||
#define TZ_Asia_Krasnoyarsk ("<+07>-7")
|
||||
#define TZ_Asia_Kuala_Lumpur ("<+08>-8")
|
||||
#define TZ_Asia_Kuching ("<+08>-8")
|
||||
#define TZ_Asia_Kuwait ("<+03>-3")
|
||||
#define TZ_Asia_Macau ("CST-8")
|
||||
#define TZ_Asia_Magadan ("<+11>-11")
|
||||
#define TZ_Asia_Makassar ("WITA-8")
|
||||
#define TZ_Asia_Manila ("PST-8")
|
||||
#define TZ_Asia_Muscat ("<+04>-4")
|
||||
#define TZ_Asia_Nicosia ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Asia_Novokuznetsk ("<+07>-7")
|
||||
#define TZ_Asia_Novosibirsk ("<+07>-7")
|
||||
#define TZ_Asia_Omsk ("<+06>-6")
|
||||
#define TZ_Asia_Oral ("<+05>-5")
|
||||
#define TZ_Asia_Phnom_Penh ("<+07>-7")
|
||||
#define TZ_Asia_Pontianak ("WIB-7")
|
||||
#define TZ_Asia_Pyongyang ("KST-9")
|
||||
#define TZ_Asia_Qatar ("<+03>-3")
|
||||
#define TZ_Asia_Qyzylorda ("<+05>-5")
|
||||
#define TZ_Asia_Riyadh ("<+03>-3")
|
||||
#define TZ_Asia_Sakhalin ("<+11>-11")
|
||||
#define TZ_Asia_Samarkand ("<+05>-5")
|
||||
#define TZ_Asia_Seoul ("KST-9")
|
||||
#define TZ_Asia_Shanghai ("CST-8")
|
||||
#define TZ_Asia_Singapore ("<+08>-8")
|
||||
#define TZ_Asia_Srednekolymsk ("<+11>-11")
|
||||
#define TZ_Asia_Taipei ("CST-8")
|
||||
#define TZ_Asia_Tashkent ("<+05>-5")
|
||||
#define TZ_Asia_Tbilisi ("<+04>-4")
|
||||
#define TZ_Asia_Tehran ("<+0330>-3:30")
|
||||
#define TZ_Asia_Thimphu ("<+06>-6")
|
||||
#define TZ_Asia_Tokyo ("JST-9")
|
||||
#define TZ_Asia_Tomsk ("<+07>-7")
|
||||
#define TZ_Asia_Ulaanbaatar ("<+08>-8")
|
||||
#define TZ_Asia_Urumqi ("<+06>-6")
|
||||
#define TZ_Asia_UstmNera ("<+10>-10")
|
||||
#define TZ_Asia_Vientiane ("<+07>-7")
|
||||
#define TZ_Asia_Vladivostok ("<+10>-10")
|
||||
#define TZ_Asia_Yakutsk ("<+09>-9")
|
||||
#define TZ_Asia_Yangon ("<+0630>-6:30")
|
||||
#define TZ_Asia_Yekaterinburg ("<+05>-5")
|
||||
#define TZ_Asia_Yerevan ("<+04>-4")
|
||||
#define TZ_Atlantic_Azores ("<-01>1<+00>,M3.5.0/0,M10.5.0/1")
|
||||
#define TZ_Atlantic_Bermuda ("AST4ADT,M3.2.0,M11.1.0")
|
||||
#define TZ_Atlantic_Canary ("WET0WEST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Atlantic_Cape_Verde ("<-01>1")
|
||||
#define TZ_Atlantic_Faroe ("WET0WEST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Atlantic_Madeira ("WET0WEST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Atlantic_Reykjavik ("GMT0")
|
||||
#define TZ_Atlantic_South_Georgia ("<-02>2")
|
||||
#define TZ_Atlantic_Stanley ("<-03>3")
|
||||
#define TZ_Atlantic_St_Helena ("GMT0")
|
||||
#define TZ_Australia_Adelaide ("ACST-9:30ACDT,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Australia_Brisbane ("AEST-10")
|
||||
#define TZ_Australia_Broken_Hill ("ACST-9:30ACDT,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Australia_Currie ("AEST-10AEDT,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Australia_Darwin ("ACST-9:30")
|
||||
#define TZ_Australia_Eucla ("<+0845>-8:45")
|
||||
#define TZ_Australia_Hobart ("AEST-10AEDT,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Australia_Lindeman ("AEST-10")
|
||||
#define TZ_Australia_Lord_Howe ("<+1030>-10:30<+11>-11,M10.1.0,M4.1.0")
|
||||
#define TZ_Australia_Melbourne ("AEST-10AEDT,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Australia_Perth ("AWST-8")
|
||||
#define TZ_Australia_Sydney ("AEST-10AEDT,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Europe_Amsterdam ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Andorra ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Astrakhan ("<+04>-4")
|
||||
#define TZ_Europe_Athens ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Belgrade ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Berlin ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Bratislava ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Brussels ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Bucharest ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Budapest ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Busingen ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Chisinau ("EET-2EEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Copenhagen ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Dublin ("IST-1GMT0,M10.5.0,M3.5.0/1")
|
||||
#define TZ_Europe_Gibraltar ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Guernsey ("GMT0BST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Europe_Helsinki ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Isle_of_Man ("GMT0BST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Europe_Istanbul ("<+03>-3")
|
||||
#define TZ_Europe_Jersey ("GMT0BST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Europe_Kaliningrad ("EET-2")
|
||||
#define TZ_Europe_Kiev ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Kirov ("MSK-3")
|
||||
#define TZ_Europe_Lisbon ("WET0WEST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Europe_Ljubljana ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_London ("GMT0BST,M3.5.0/1,M10.5.0")
|
||||
#define TZ_Europe_Luxembourg ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Madrid ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Malta ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Mariehamn ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Minsk ("<+03>-3")
|
||||
#define TZ_Europe_Monaco ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Moscow ("MSK-3")
|
||||
#define TZ_Europe_Oslo ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Paris ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Podgorica ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Prague ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Riga ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Rome ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Samara ("<+04>-4")
|
||||
#define TZ_Europe_San_Marino ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Sarajevo ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Saratov ("<+04>-4")
|
||||
#define TZ_Europe_Simferopol ("MSK-3")
|
||||
#define TZ_Europe_Skopje ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Sofia ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Stockholm ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Tallinn ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Tirane ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Ulyanovsk ("<+04>-4")
|
||||
#define TZ_Europe_Uzhgorod ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Vaduz ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Vatican ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Vienna ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Vilnius ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Volgograd ("MSK-3")
|
||||
#define TZ_Europe_Warsaw ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Zagreb ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Europe_Zaporozhye ("EET-2EEST,M3.5.0/3,M10.5.0/4")
|
||||
#define TZ_Europe_Zurich ("CET-1CEST,M3.5.0,M10.5.0/3")
|
||||
#define TZ_Indian_Antananarivo ("EAT-3")
|
||||
#define TZ_Indian_Chagos ("<+06>-6")
|
||||
#define TZ_Indian_Christmas ("<+07>-7")
|
||||
#define TZ_Indian_Cocos ("<+0630>-6:30")
|
||||
#define TZ_Indian_Comoro ("EAT-3")
|
||||
#define TZ_Indian_Kerguelen ("<+05>-5")
|
||||
#define TZ_Indian_Mahe ("<+04>-4")
|
||||
#define TZ_Indian_Maldives ("<+05>-5")
|
||||
#define TZ_Indian_Mauritius ("<+04>-4")
|
||||
#define TZ_Indian_Mayotte ("EAT-3")
|
||||
#define TZ_Indian_Reunion ("<+04>-4")
|
||||
#define TZ_Pacific_Apia ("<+13>-13")
|
||||
#define TZ_Pacific_Auckland ("NZST-12NZDT,M9.5.0,M4.1.0/3")
|
||||
#define TZ_Pacific_Bougainville ("<+11>-11")
|
||||
#define TZ_Pacific_Chatham ("<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45")
|
||||
#define TZ_Pacific_Chuuk ("<+10>-10")
|
||||
#define TZ_Pacific_Easter ("<-06>6<-05>,M9.1.6/22,M4.1.6/22")
|
||||
#define TZ_Pacific_Efate ("<+11>-11")
|
||||
#define TZ_Pacific_Enderbury ("<+13>-13")
|
||||
#define TZ_Pacific_Fakaofo ("<+13>-13")
|
||||
#define TZ_Pacific_Fiji ("<+12>-12")
|
||||
#define TZ_Pacific_Funafuti ("<+12>-12")
|
||||
#define TZ_Pacific_Galapagos ("<-06>6")
|
||||
#define TZ_Pacific_Gambier ("<-09>9")
|
||||
#define TZ_Pacific_Guadalcanal ("<+11>-11")
|
||||
#define TZ_Pacific_Guam ("ChST-10")
|
||||
#define TZ_Pacific_Honolulu ("HST10")
|
||||
#define TZ_Pacific_Kiritimati ("<+14>-14")
|
||||
#define TZ_Pacific_Kosrae ("<+11>-11")
|
||||
#define TZ_Pacific_Kwajalein ("<+12>-12")
|
||||
#define TZ_Pacific_Majuro ("<+12>-12")
|
||||
#define TZ_Pacific_Marquesas ("<-0930>9:30")
|
||||
#define TZ_Pacific_Midway ("SST11")
|
||||
#define TZ_Pacific_Nauru ("<+12>-12")
|
||||
#define TZ_Pacific_Niue ("<-11>11")
|
||||
#define TZ_Pacific_Norfolk ("<+11>-11<+12>,M10.1.0,M4.1.0/3")
|
||||
#define TZ_Pacific_Noumea ("<+11>-11")
|
||||
#define TZ_Pacific_Pago_Pago ("SST11")
|
||||
#define TZ_Pacific_Palau ("<+09>-9")
|
||||
#define TZ_Pacific_Pitcairn ("<-08>8")
|
||||
#define TZ_Pacific_Pohnpei ("<+11>-11")
|
||||
#define TZ_Pacific_Port_Moresby ("<+10>-10")
|
||||
#define TZ_Pacific_Rarotonga ("<-10>10")
|
||||
#define TZ_Pacific_Saipan ("ChST-10")
|
||||
#define TZ_Pacific_Tahiti ("<-10>10")
|
||||
#define TZ_Pacific_Tarawa ("<+12>-12")
|
||||
#define TZ_Pacific_Tongatapu ("<+13>-13")
|
||||
#define TZ_Pacific_Wake ("<+12>-12")
|
||||
#define TZ_Pacific_Wallis ("<+12>-12")
|
||||
#define TZ_Etc_GMT ("GMT0")
|
||||
#define TZ_Etc_GMTm0 ("GMT0")
|
||||
#define TZ_Etc_GMTm1 ("<+01>-1")
|
||||
#define TZ_Etc_GMTm2 ("<+02>-2")
|
||||
#define TZ_Etc_GMTm3 ("<+03>-3")
|
||||
#define TZ_Etc_GMTm4 ("<+04>-4")
|
||||
#define TZ_Etc_GMTm5 ("<+05>-5")
|
||||
#define TZ_Etc_GMTm6 ("<+06>-6")
|
||||
#define TZ_Etc_GMTm7 ("<+07>-7")
|
||||
#define TZ_Etc_GMTm8 ("<+08>-8")
|
||||
#define TZ_Etc_GMTm9 ("<+09>-9")
|
||||
#define TZ_Etc_GMTm10 ("<+10>-10")
|
||||
#define TZ_Etc_GMTm11 ("<+11>-11")
|
||||
#define TZ_Etc_GMTm12 ("<+12>-12")
|
||||
#define TZ_Etc_GMTm13 ("<+13>-13")
|
||||
#define TZ_Etc_GMTm14 ("<+14>-14")
|
||||
#define TZ_Etc_GMT0 ("GMT0")
|
||||
#define TZ_Etc_GMTp0 ("GMT0")
|
||||
#define TZ_Etc_GMTp1 ("<-01>1")
|
||||
#define TZ_Etc_GMTp2 ("<-02>2")
|
||||
#define TZ_Etc_GMTp3 ("<-03>3")
|
||||
#define TZ_Etc_GMTp4 ("<-04>4")
|
||||
#define TZ_Etc_GMTp5 ("<-05>5")
|
||||
#define TZ_Etc_GMTp6 ("<-06>6")
|
||||
#define TZ_Etc_GMTp7 ("<-07>7")
|
||||
#define TZ_Etc_GMTp8 ("<-08>8")
|
||||
#define TZ_Etc_GMTp9 ("<-09>9")
|
||||
#define TZ_Etc_GMTp10 ("<-10>10")
|
||||
#define TZ_Etc_GMTp11 ("<-11>11")
|
||||
#define TZ_Etc_GMTp12 ("<-12>12")
|
||||
#define TZ_Etc_UCT ("UTC0")
|
||||
#define TZ_Etc_UTC ("UTC0")
|
||||
#define TZ_Etc_Greenwich ("GMT0")
|
||||
#define TZ_Etc_Universal ("UTC0")
|
||||
#define TZ_Etc_Zulu ("UTC0")
|
||||
@@ -60,45 +60,3 @@ SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive) {
|
||||
}
|
||||
return nullptr; // Need to make space for more mutex maps!
|
||||
}
|
||||
|
||||
|
||||
// The HW Random code needs a precise sleep_until() in order to assure it
|
||||
// grabs the ROSC bit when it wants. Unfortunately, under FreeRTOS the
|
||||
// sleep_until() becomes imprecise and the "did I get the bit when I wanted"
|
||||
// check in the pico_rand code always fails and you get an infinite loop.
|
||||
|
||||
// This block wraps the 2 get_rand calls to set a flag to convert
|
||||
// sleep_until() (which can do a task swap and cause bad timing) into a
|
||||
// busy wait.
|
||||
|
||||
extern "C" {
|
||||
static bool __inRand = false;
|
||||
|
||||
extern uint64_t __real_get_rand_64();
|
||||
uint64_t __wrap_get_rand_64() {
|
||||
if (__isFreeRTOS) {
|
||||
rp2040.idleOtherCore();
|
||||
__inRand = true;
|
||||
auto r = __real_get_rand_64();
|
||||
__inRand = false;
|
||||
rp2040.resumeOtherCore();
|
||||
return r;
|
||||
} else {
|
||||
return __real_get_rand_64();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t __wrap_get_rand_32() {
|
||||
return (uint32_t) __wrap_get_rand_64();
|
||||
}
|
||||
|
||||
extern void __real_sleep_until(absolute_time_t t);
|
||||
void __wrap_sleep_until(absolute_time_t t) {
|
||||
if (__inRand) {
|
||||
busy_wait_until(t);
|
||||
} else {
|
||||
__real_sleep_until(t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,12 +31,10 @@ extern bool __isFreeRTOS;
|
||||
extern volatile bool __freeRTOSinitted;
|
||||
|
||||
extern "C" {
|
||||
#ifndef INC_FREERTOS_H
|
||||
struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */
|
||||
typedef struct QueueDefinition * QueueHandle_t;
|
||||
typedef QueueHandle_t SemaphoreHandle_t;
|
||||
typedef int32_t BaseType_t;
|
||||
#endif
|
||||
|
||||
extern bool __freertos_check_if_in_isr() __attribute__((weak));
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@
|
||||
|
||||
#define ccount_wrap_target 0
|
||||
#define ccount_wrap 1
|
||||
#define ccount_pio_version 0
|
||||
|
||||
static const uint16_t ccount_program_instructions[] = {
|
||||
// .wrap_target
|
||||
@@ -27,6 +28,10 @@ static const struct pio_program ccount_program = {
|
||||
.instructions = ccount_program_instructions,
|
||||
.length = 2,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config ccount_program_get_default_config(uint offset) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Use to create a callback thunk from C to C++
|
||||
// #define CCALLBACKNAME to a unique per-file name and #include this file
|
||||
// To make a CB use a define of the form:
|
||||
/*
|
||||
#define PACKETHANDLERCB(class, cbFcn) \
|
||||
(CCALLBACKNAME<void(uint8_t, uint16_t, uint8_t*, uint16_t), __COUNTER__>::func = std::bind(&class::cbFcn, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), \
|
||||
static_cast<btstack_packet_handler_t>(<CCALLBACKNAMEvoid(uint8_t, uint16_t, uint8_t*, uint16_t), __COUNTER__ - 1>::callback))
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
|
||||
// Thank you to https://stackoverflow.com/questions/66474621/multiple-non-static-callbacks-of-c-member-functions for the following beautiful hack
|
||||
|
||||
#ifndef CCALLBACKNAME
|
||||
#define CCALLBACKNAME _CCallback
|
||||
#endif
|
||||
|
||||
template <typename T, int tag>
|
||||
struct CCALLBACKNAME;
|
||||
|
||||
template <typename Ret, typename... Params, int tag>
|
||||
struct CCALLBACKNAME<Ret(Params...), tag> {
|
||||
template <typename... Args>
|
||||
static Ret callback(Args... args) {
|
||||
return func(args...);
|
||||
}
|
||||
int _tag = tag;
|
||||
static std::function<Ret(Params...)> func;
|
||||
};
|
||||
|
||||
template <typename Ret, typename... Params, int tag>
|
||||
std::function<Ret(Params...)> CCALLBACKNAME<Ret(Params...), tag>::func;
|
||||
+41
-11
@@ -26,18 +26,26 @@
|
||||
#include <lwip/dns.h>
|
||||
#include <lwip/raw.h>
|
||||
#include <lwip/timeouts.h>
|
||||
#ifdef PICO_RP2040
|
||||
#include <pico/cyw43_arch.h>
|
||||
#endif
|
||||
#include <pico/mutex.h>
|
||||
#include <sys/lock.h>
|
||||
#include "_xoshiro.h"
|
||||
|
||||
extern void ethernet_arch_lwip_begin() __attribute__((weak));
|
||||
extern void ethernet_arch_lwip_end() __attribute__((weak));
|
||||
extern void ethernet_arch_lwip_gpio_mask() __attribute__((weak));
|
||||
extern void ethernet_arch_lwip_gpio_unmask() __attribute__((weak));
|
||||
|
||||
auto_init_recursive_mutex(__lwipMutex); // Only for case with no Ethernet or PicoW, but still doing LWIP (PPP?)
|
||||
|
||||
class LWIPMutex {
|
||||
public:
|
||||
LWIPMutex() {
|
||||
if (ethernet_arch_lwip_gpio_mask) {
|
||||
ethernet_arch_lwip_gpio_mask();
|
||||
}
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
||||
if (rp2040.isPicoW()) {
|
||||
cyw43_arch_lwip_begin();
|
||||
@@ -55,26 +63,36 @@ public:
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
||||
if (rp2040.isPicoW()) {
|
||||
cyw43_arch_lwip_end();
|
||||
return;
|
||||
} else {
|
||||
#endif
|
||||
if (ethernet_arch_lwip_end) {
|
||||
ethernet_arch_lwip_end();
|
||||
} else {
|
||||
recursive_mutex_exit(&__lwipMutex);
|
||||
}
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
||||
}
|
||||
#endif
|
||||
if (ethernet_arch_lwip_end) {
|
||||
ethernet_arch_lwip_end();
|
||||
} else {
|
||||
recursive_mutex_exit(&__lwipMutex);
|
||||
if (ethernet_arch_lwip_gpio_unmask) {
|
||||
ethernet_arch_lwip_gpio_unmask();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
static XoshiroCpp::Xoshiro256PlusPlus *_lwip_rng = nullptr;
|
||||
// Random number generator for LWIP
|
||||
unsigned long __lwip_rand() {
|
||||
return (unsigned long)(*_lwip_rng)();
|
||||
}
|
||||
|
||||
// Avoid calling lwip_init multiple times
|
||||
extern void __real_lwip_init();
|
||||
void __wrap_lwip_init() {
|
||||
static bool initted = false;
|
||||
if (!initted) {
|
||||
if (!_lwip_rng) {
|
||||
_lwip_rng = new XoshiroCpp::Xoshiro256PlusPlus(micros() * rp2040.getCycleCount());
|
||||
__real_lwip_init();
|
||||
initted = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,19 +249,19 @@ extern "C" {
|
||||
extern void __real_tcp_setprio(struct tcp_pcb *pcb, u8_t prio);
|
||||
void __wrap_tcp_setprio(struct tcp_pcb *pcb, u8_t prio) {
|
||||
LWIPMutex m;
|
||||
return __real_tcp_setprio(pcb, prio);
|
||||
__real_tcp_setprio(pcb, prio);
|
||||
}
|
||||
|
||||
extern void __real_tcp_backlog_delayed(struct tcp_pcb* pcb);
|
||||
void __wrap_tcp_backlog_delayed(struct tcp_pcb* pcb) {
|
||||
LWIPMutex m;
|
||||
return __real_tcp_backlog_delayed(pcb);
|
||||
__real_tcp_backlog_delayed(pcb);
|
||||
}
|
||||
|
||||
extern void __real_tcp_backlog_accepted(struct tcp_pcb* pcb);
|
||||
void __wrap_tcp_backlog_accepted(struct tcp_pcb* pcb) {
|
||||
LWIPMutex m;
|
||||
return __real_tcp_backlog_accepted(pcb);
|
||||
__real_tcp_backlog_accepted(pcb);
|
||||
}
|
||||
extern struct udp_pcb *__real_udp_new(void);
|
||||
struct udp_pcb *__wrap_udp_new(void) {
|
||||
@@ -342,4 +360,16 @@ extern "C" {
|
||||
__real_raw_remove(pcb);
|
||||
}
|
||||
|
||||
extern struct netif *__real_netif_add(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input);
|
||||
struct netif *__wrap_netif_add(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) {
|
||||
LWIPMutex m;
|
||||
return __real_netif_add(netif, ipaddr, netmask, gw, state, init, input);
|
||||
}
|
||||
|
||||
extern void __real_netif_remove(struct netif *netif);
|
||||
void __wrap_netif_remove(struct netif *netif) {
|
||||
LWIPMutex m;
|
||||
__real_netif_remove(netif);
|
||||
}
|
||||
|
||||
}; // extern "C"
|
||||
|
||||
+12
-1
@@ -27,6 +27,7 @@
|
||||
RP2040 rp2040;
|
||||
extern "C" {
|
||||
volatile bool __otherCoreIdled = false;
|
||||
uint32_t* core1_separate_stack_address = nullptr;
|
||||
};
|
||||
|
||||
extern void setup();
|
||||
@@ -38,12 +39,14 @@ extern void startFreeRTOS() __attribute__((weak));
|
||||
bool __isFreeRTOS;
|
||||
volatile bool __freeRTOSinitted;
|
||||
|
||||
extern void __EnableBluetoothDebug(Print &);
|
||||
|
||||
// Weak empty variant initialization. May be redefined by variant files.
|
||||
void initVariant() __attribute__((weak));
|
||||
void initVariant() { }
|
||||
|
||||
// Optional 2nd core setup and loop
|
||||
bool core1_separate_stack __attribute__((weak)) = false;
|
||||
extern void setup1() __attribute__((weak));
|
||||
extern void loop1() __attribute__((weak));
|
||||
extern "C" void main1() {
|
||||
@@ -117,6 +120,9 @@ extern "C" int main() {
|
||||
#if defined DEBUG_RP2040_PORT
|
||||
if (!__isFreeRTOS) {
|
||||
DEBUG_RP2040_PORT.begin(115200);
|
||||
#if (defined(ENABLE_BLUETOOTH) || defined(ENABLE_BLE)) && defined(DEBUG_RP2040_BLUETOOTH)
|
||||
__EnableBluetoothDebug(DEBUG_RP2040_PORT);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -132,7 +138,12 @@ extern "C" int main() {
|
||||
if (!__isFreeRTOS) {
|
||||
if (setup1 || loop1) {
|
||||
delay(1); // Needed to make Picoprobe upload start 2nd core
|
||||
multicore_launch_core1(main1);
|
||||
if (core1_separate_stack) {
|
||||
core1_separate_stack_address = (uint32_t*)malloc(0x2000);
|
||||
multicore_launch_core1_with_stack(main1, core1_separate_stack_address, 0x2000);
|
||||
} else {
|
||||
multicore_launch_core1(main1);
|
||||
}
|
||||
}
|
||||
setup();
|
||||
while (true) {
|
||||
|
||||
@@ -19,11 +19,25 @@
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <malloc.h>
|
||||
#include <reent.h>
|
||||
#include "psram.h"
|
||||
|
||||
extern "C" void *__real_malloc(size_t size);
|
||||
extern "C" void *__real_calloc(size_t count, size_t size);
|
||||
extern "C" void *__real_realloc(void *mem, size_t size);
|
||||
extern "C" void __real_free(void *mem);
|
||||
extern "C" struct mallinfo __real_mallinfo();
|
||||
|
||||
#ifdef RP2350_PSRAM_CS
|
||||
extern "C" {
|
||||
extern uint8_t __psram_start__;
|
||||
extern uint8_t __psram_heap_start__;
|
||||
void __malloc_lock(struct _reent *ptr);
|
||||
void __malloc_unlock(struct _reent *ptr);
|
||||
static void *__ram_start = (void *)0x20000000; // TODO - Is there a SDK exposed variable/macro?
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" void *__wrap_malloc(size_t size) {
|
||||
noInterrupts();
|
||||
@@ -39,15 +53,63 @@ extern "C" void *__wrap_calloc(size_t count, size_t size) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
extern "C" void *__wrap_realloc(void *mem, size_t size) {
|
||||
#ifdef RP2350_PSRAM_CS
|
||||
// Utilize the existing malloc lock infrastructure and interrupt blocking
|
||||
// to work with multicore and FreeRTOS
|
||||
extern "C" void *pmalloc(size_t size) {
|
||||
noInterrupts();
|
||||
void *rc = __real_realloc(mem, size);
|
||||
__malloc_lock(__getreent());
|
||||
auto rc = __psram_malloc(size);
|
||||
__malloc_unlock(__getreent());
|
||||
interrupts();
|
||||
return rc;
|
||||
}
|
||||
|
||||
extern "C" void *pcalloc(size_t count, size_t size) {
|
||||
noInterrupts();
|
||||
__malloc_lock(__getreent());
|
||||
auto rc = __psram_calloc(count, size);
|
||||
__malloc_unlock(__getreent());
|
||||
interrupts();
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" void *__wrap_realloc(void *mem, size_t size) {
|
||||
void *rc;
|
||||
noInterrupts();
|
||||
#ifdef RP2350_PSRAM_CS
|
||||
if (mem < __ram_start) {
|
||||
rc = __psram_realloc(mem, size);
|
||||
} else {
|
||||
rc = __real_realloc(mem, size);
|
||||
}
|
||||
#else
|
||||
rc = __real_realloc(mem, size);
|
||||
#endif
|
||||
interrupts();
|
||||
return rc;
|
||||
}
|
||||
|
||||
extern "C" void __wrap_free(void *mem) {
|
||||
noInterrupts();
|
||||
#ifdef RP2350_PSRAM_CS
|
||||
if (mem < __ram_start) {
|
||||
__psram_free(mem);
|
||||
} else {
|
||||
__real_free(mem);
|
||||
}
|
||||
#else
|
||||
__real_free(mem);
|
||||
#endif
|
||||
interrupts();
|
||||
}
|
||||
|
||||
extern "C" struct mallinfo __wrap_mallinfo() {
|
||||
noInterrupts();
|
||||
__malloc_lock(__getreent());
|
||||
auto ret = __real_mallinfo();
|
||||
__malloc_unlock(__getreent());
|
||||
interrupts();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#define pio_tx_wrap_target 0
|
||||
#define pio_tx_wrap 5
|
||||
#define pio_tx_pio_version 0
|
||||
|
||||
static const uint16_t pio_tx_program_instructions[] = {
|
||||
// .wrap_target
|
||||
@@ -31,6 +32,10 @@ static const struct pio_program pio_tx_program = {
|
||||
.instructions = pio_tx_program_instructions,
|
||||
.length = 6,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_tx_program_get_default_config(uint offset) {
|
||||
@@ -47,6 +52,7 @@ static inline pio_sm_config pio_tx_program_get_default_config(uint offset) {
|
||||
|
||||
#define pio_tx_inv_wrap_target 0
|
||||
#define pio_tx_inv_wrap 5
|
||||
#define pio_tx_inv_pio_version 0
|
||||
|
||||
static const uint16_t pio_tx_inv_program_instructions[] = {
|
||||
// .wrap_target
|
||||
@@ -64,6 +70,10 @@ static const struct pio_program pio_tx_inv_program = {
|
||||
.instructions = pio_tx_inv_program_instructions,
|
||||
.length = 6,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_tx_inv_program_get_default_config(uint offset) {
|
||||
@@ -100,6 +110,7 @@ static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_t
|
||||
|
||||
#define pio_rx_wrap_target 0
|
||||
#define pio_rx_wrap 6
|
||||
#define pio_rx_pio_version 0
|
||||
|
||||
static const uint16_t pio_rx_program_instructions[] = {
|
||||
// .wrap_target
|
||||
@@ -118,6 +129,10 @@ static const struct pio_program pio_rx_program = {
|
||||
.instructions = pio_rx_program_instructions,
|
||||
.length = 7,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_rx_program_get_default_config(uint offset) {
|
||||
@@ -133,6 +148,7 @@ static inline pio_sm_config pio_rx_program_get_default_config(uint offset) {
|
||||
|
||||
#define pio_rx_inv_wrap_target 0
|
||||
#define pio_rx_inv_wrap 6
|
||||
#define pio_rx_inv_pio_version 0
|
||||
|
||||
static const uint16_t pio_rx_inv_program_instructions[] = {
|
||||
// .wrap_target
|
||||
@@ -151,6 +167,10 @@ static const struct pio_program pio_rx_inv_program = {
|
||||
.instructions = pio_rx_inv_program_instructions,
|
||||
.length = 7,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config pio_rx_inv_program_get_default_config(uint offset) {
|
||||
|
||||
+39
-13
@@ -33,7 +33,9 @@
|
||||
|
||||
extern "C" int errno;
|
||||
|
||||
extern "C" ssize_t _write(int fd, const void *buf, size_t count) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
ssize_t _write(int fd, const void *buf, size_t count) {
|
||||
#if defined DEBUG_RP2040_PORT
|
||||
(void) fd;
|
||||
return DEBUG_RP2040_PORT.write((const char *)buf, count);
|
||||
@@ -45,7 +47,9 @@ extern "C" ssize_t _write(int fd, const void *buf, size_t count) {
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" int _chown(const char *path, uid_t owner, gid_t group) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _chown(const char *path, uid_t owner, gid_t group) {
|
||||
(void) path;
|
||||
(void) owner;
|
||||
(void) group;
|
||||
@@ -53,7 +57,9 @@ extern "C" int _chown(const char *path, uid_t owner, gid_t group) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _close(int fd) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _close(int fd) {
|
||||
(void) fd;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@@ -72,7 +78,9 @@ extern "C" int _fork(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _fstat(int fd, struct stat *st) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _fstat(int fd, struct stat *st) {
|
||||
(void) fd;
|
||||
(void) st;
|
||||
errno = ENOSYS;
|
||||
@@ -115,7 +123,9 @@ extern "C" void __setSystemTime(unsigned long long sec, unsigned long usec) {
|
||||
__timedelta_us = newnow_us - now_us;
|
||||
}
|
||||
|
||||
extern "C" int _isatty(int file) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _isatty(int file) {
|
||||
(void) file;
|
||||
errno = ENOSYS;
|
||||
return 0;
|
||||
@@ -128,14 +138,18 @@ extern "C" int _kill(int pid, int sig) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _link(char *existing, char *newlink) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _link(char *existing, char *newlink) {
|
||||
(void) existing;
|
||||
(void) newlink;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _lseek(int file, int ptr, int dir) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _lseek(int file, int ptr, int dir) {
|
||||
(void) file;
|
||||
(void) ptr;
|
||||
(void) dir;
|
||||
@@ -143,7 +157,9 @@ extern "C" int _lseek(int file, int ptr, int dir) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _open(char *file, int flags, int mode) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _open(char *file, int flags, int mode) {
|
||||
(void) file;
|
||||
(void) flags;
|
||||
(void) mode;
|
||||
@@ -151,7 +167,9 @@ extern "C" int _open(char *file, int flags, int mode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _read(int file, char *ptr, int len) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _read(int file, char *ptr, int len) {
|
||||
(void) file;
|
||||
(void) ptr;
|
||||
(void) len;
|
||||
@@ -159,7 +177,9 @@ extern "C" int _read(int file, char *ptr, int len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _readlink(const char *path, char *buf, size_t bufsize) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _readlink(const char *path, char *buf, size_t bufsize) {
|
||||
(void) path;
|
||||
(void) buf;
|
||||
(void) bufsize;
|
||||
@@ -167,14 +187,18 @@ extern "C" int _readlink(const char *path, char *buf, size_t bufsize) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _stat(const char *file, struct stat *st) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _stat(const char *file, struct stat *st) {
|
||||
(void) file;
|
||||
(void) st;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _symlink(const char *path1, const char *path2) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _symlink(const char *path1, const char *path2) {
|
||||
(void) path1;
|
||||
(void) path2;
|
||||
errno = ENOSYS;
|
||||
@@ -187,7 +211,9 @@ extern "C" clock_t _times(struct tms *buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int _unlink(char *name) {
|
||||
extern "C"
|
||||
__attribute((weak))
|
||||
int _unlink(char *name) {
|
||||
(void) name;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
// Originally from https://github.com/sparkfun/sparkfun-pico
|
||||
/**
|
||||
@file sfe_psram.c
|
||||
|
||||
@brief This file contains a function that is used to detect and initialize PSRAM on
|
||||
SparkFun rp2350 boards.
|
||||
*/
|
||||
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 SparkFun Electronics
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
// Hacked by Earle Philhower to work with the Arduino-Pico core
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef RP2350_PSRAM_CS
|
||||
|
||||
#include <hardware/address_mapped.h>
|
||||
#include <hardware/clocks.h>
|
||||
#include <hardware/gpio.h>
|
||||
#include <hardware/regs/addressmap.h>
|
||||
#include <hardware/spi.h>
|
||||
#include <hardware/structs/qmi.h>
|
||||
#include <hardware/structs/xip_ctrl.h>
|
||||
#include <pico/runtime_init.h>
|
||||
|
||||
// Include TLSF in this compilation unit
|
||||
#include "../../lib/tlsf/tlsf.c"
|
||||
static tlsf_t _mem_heap = nullptr;
|
||||
static pool_t _mem_psram_pool = nullptr;
|
||||
|
||||
// PSRAM heap minus PSRAM global/static variables from the linker
|
||||
extern "C" {
|
||||
extern uint8_t __psram_start__;
|
||||
extern uint8_t __psram_heap_start__;
|
||||
}
|
||||
|
||||
static bool _bInitalized = false;
|
||||
size_t __psram_size = 0;
|
||||
size_t __psram_heap_size = 0;
|
||||
|
||||
#define PICO_RUNTIME_INIT_PSRAM "11001" // Towards the end, after alarms
|
||||
|
||||
#ifndef RP2350_PSRAM_MAX_SELECT_FS64
|
||||
#define RP2350_PSRAM_MAX_SELECT_FS64 (125'000'000)
|
||||
#endif
|
||||
|
||||
#ifndef RP2350_PSRAM_MIN_DESELECT_FS
|
||||
#define RP2350_PSRAM_MIN_DESELECT_FS (50'000'000)
|
||||
#endif
|
||||
|
||||
#ifndef RP2350_PSRAM_MAX_SCK_HZ
|
||||
#define RP2350_PSRAM_MAX_SCK_HZ (109'000'000)
|
||||
#endif
|
||||
|
||||
#ifndef RP2350_PSRAM_ID
|
||||
#define RP2350_PSRAM_ID (0x5D)
|
||||
#endif
|
||||
|
||||
// DETAILS/
|
||||
//
|
||||
// SparkFun RP2350 boards use the following PSRAM IC:
|
||||
//
|
||||
// apmemory APS6404L-3SQR-ZR
|
||||
// https://www.mouser.com/ProductDetail/AP-Memory/APS6404L-3SQR-ZR?qs=IS%252B4QmGtzzpDOdsCIglviw%3D%3D
|
||||
//
|
||||
// The origin of this logic is from the Circuit Python code that was downloaded from:
|
||||
// https://github.com/raspberrypi/pico-sdk-rp2350/issues/12#issuecomment-2055274428
|
||||
//
|
||||
|
||||
// Details on the PSRAM IC that are used during setup/configuration of PSRAM on SparkFun RP2350 boards.
|
||||
|
||||
// For PSRAM timing calculations - to use int math, we work in femto seconds (fs) (1e-15),
|
||||
// NOTE: This idea is from micro python work on psram..
|
||||
|
||||
#define SFE_SEC_TO_FS 1000000000000000ll
|
||||
|
||||
// max select pulse width = 8us => 8e6 ns => 8000 ns => 8000 * 1e6 fs => 8000e6 fs
|
||||
// Additionally, the MAX select is in units of 64 clock cycles - will use a constant that
|
||||
// takes this into account - so 8000e6 fs / 64 = 125e6 fs
|
||||
|
||||
const uint32_t SFE_PSRAM_MAX_SELECT_FS64 = RP2350_PSRAM_MAX_SELECT_FS64;
|
||||
|
||||
// min deselect pulse width = 50ns => 50 * 1e6 fs => 50e7 fs
|
||||
const uint32_t SFE_PSRAM_MIN_DESELECT_FS = RP2350_PSRAM_MIN_DESELECT_FS;
|
||||
|
||||
// from psram datasheet - max Freq with VDDat 3.3v - SparkFun RP2350 boards run at 3.3v.
|
||||
// If VDD = 3.0 Max Freq is 133 Mhz
|
||||
const uint32_t SFE_PSRAM_MAX_SCK_HZ = RP2350_PSRAM_MAX_SCK_HZ;
|
||||
|
||||
// PSRAM SPI command codes
|
||||
const uint8_t PSRAM_CMD_QUAD_END = 0xF5;
|
||||
const uint8_t PSRAM_CMD_QUAD_ENABLE = 0x35;
|
||||
const uint8_t PSRAM_CMD_READ_ID = 0x9F;
|
||||
const uint8_t PSRAM_CMD_RSTEN = 0x66;
|
||||
const uint8_t PSRAM_CMD_RST = 0x99;
|
||||
const uint8_t PSRAM_CMD_QUAD_READ = 0xEB;
|
||||
const uint8_t PSRAM_CMD_QUAD_WRITE = 0x38;
|
||||
const uint8_t PSRAM_CMD_NOOP = 0xFF;
|
||||
|
||||
const uint8_t PSRAM_ID = RP2350_PSRAM_ID;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// @brief Communicate directly with the PSRAM IC - validate it is present and return the size
|
||||
///
|
||||
/// @return size_t The size of the PSRAM
|
||||
///
|
||||
/// @note This function expects the CS pin set
|
||||
static size_t __no_inline_not_in_flash_func(get_psram_size)(void) {
|
||||
size_t psram_size = 0;
|
||||
uint32_t intr_stash = save_and_disable_interrupts();
|
||||
|
||||
// Try and read the PSRAM ID via direct_csr.
|
||||
qmi_hw->direct_csr = 30 << QMI_DIRECT_CSR_CLKDIV_LSB | QMI_DIRECT_CSR_EN_BITS;
|
||||
|
||||
// Need to poll for the cooldown on the last XIP transfer to expire
|
||||
// (via direct-mode BUSY flag) before it is safe to perform the first
|
||||
// direct-mode operation
|
||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
||||
}
|
||||
|
||||
// Exit out of QMI in case we've inited already
|
||||
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
|
||||
|
||||
// Transmit the command to exit QPI quad mode - read ID as standard SPI
|
||||
qmi_hw->direct_tx =
|
||||
QMI_DIRECT_TX_OE_BITS | QMI_DIRECT_TX_IWIDTH_VALUE_Q << QMI_DIRECT_TX_IWIDTH_LSB | PSRAM_CMD_QUAD_END;
|
||||
|
||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
||||
}
|
||||
|
||||
(void)qmi_hw->direct_rx;
|
||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS);
|
||||
|
||||
// Read the id
|
||||
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
|
||||
uint8_t kgd = 0;
|
||||
uint8_t eid = 0;
|
||||
for (size_t i = 0; i < 7; i++) {
|
||||
qmi_hw->direct_tx = (i == 0 ? PSRAM_CMD_READ_ID : PSRAM_CMD_NOOP);
|
||||
|
||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_TXEMPTY_BITS) == 0) {
|
||||
}
|
||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
||||
}
|
||||
if (i == 5) {
|
||||
kgd = qmi_hw->direct_rx;
|
||||
} else if (i == 6) {
|
||||
eid = qmi_hw->direct_rx;
|
||||
} else {
|
||||
(void)qmi_hw->direct_rx; // just read and discard
|
||||
}
|
||||
}
|
||||
|
||||
// Disable direct csr.
|
||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS | QMI_DIRECT_CSR_EN_BITS);
|
||||
|
||||
// is this the PSRAM we're looking for obi-wan?
|
||||
if (kgd == PSRAM_ID) {
|
||||
// PSRAM size
|
||||
psram_size = 1024 * 1024; // 1 MiB
|
||||
uint8_t size_id = eid >> 5;
|
||||
if (eid == 0x26 || size_id == 2) {
|
||||
psram_size *= 8;
|
||||
} else if (size_id == 0) {
|
||||
psram_size *= 2;
|
||||
} else if (size_id == 1) {
|
||||
psram_size *= 4;
|
||||
}
|
||||
}
|
||||
restore_interrupts(intr_stash);
|
||||
return psram_size;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
/// @brief Update the PSRAM timing configuration based on system clock
|
||||
///
|
||||
/// @note This function expects interrupts to be enabled on entry
|
||||
|
||||
static void __no_inline_not_in_flash_func(set_psram_timing)(void) {
|
||||
// Get secs / cycle for the system clock - get before disabling interrupts.
|
||||
uint32_t sysHz = (uint32_t)clock_get_hz(clk_sys);
|
||||
|
||||
// Calculate the clock divider - goal to get clock used for PSRAM <= what
|
||||
// the PSRAM IC can handle - which is defined in SFE_PSRAM_MAX_SCK_HZ
|
||||
volatile uint8_t clockDivider = (sysHz + SFE_PSRAM_MAX_SCK_HZ - 1) / SFE_PSRAM_MAX_SCK_HZ;
|
||||
|
||||
uint32_t intr_stash = save_and_disable_interrupts();
|
||||
|
||||
// Get the clock femto seconds per cycle.
|
||||
|
||||
uint32_t fsPerCycle = SFE_SEC_TO_FS / sysHz;
|
||||
|
||||
// the maxSelect value is defined in units of 64 clock cycles
|
||||
// So maxFS / (64 * fsPerCycle) = maxSelect = SFE_PSRAM_MAX_SELECT_FS64/fsPerCycle
|
||||
volatile uint8_t maxSelect = SFE_PSRAM_MAX_SELECT_FS64 / fsPerCycle;
|
||||
|
||||
// minDeselect time - in system clock cycle
|
||||
// Must be higher than 50ns (min deselect time for PSRAM) so add a fsPerCycle - 1 to round up
|
||||
// So minFS/fsPerCycle = minDeselect = SFE_PSRAM_MIN_DESELECT_FS/fsPerCycle
|
||||
|
||||
volatile uint8_t minDeselect = (SFE_PSRAM_MIN_DESELECT_FS + fsPerCycle - 1) / fsPerCycle;
|
||||
|
||||
// printf("Max Select: %d, Min Deselect: %d, clock divider: %d\n", maxSelect, minDeselect, clockDivider);
|
||||
|
||||
qmi_hw->m[1].timing = QMI_M1_TIMING_PAGEBREAK_VALUE_1024 << QMI_M1_TIMING_PAGEBREAK_LSB | // Break between pages.
|
||||
3 << QMI_M1_TIMING_SELECT_HOLD_LSB | // Delay releasing CS for 3 extra system cycles.
|
||||
1 << QMI_M1_TIMING_COOLDOWN_LSB | 1 << QMI_M1_TIMING_RXDELAY_LSB |
|
||||
maxSelect << QMI_M1_TIMING_MAX_SELECT_LSB | minDeselect << QMI_M1_TIMING_MIN_DESELECT_LSB |
|
||||
clockDivider << QMI_M1_TIMING_CLKDIV_LSB;
|
||||
|
||||
restore_interrupts(intr_stash);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// @brief The setup_psram function - note that this is not in flash
|
||||
///
|
||||
///
|
||||
static void __no_inline_not_in_flash_func(runtime_init_setup_psram)(/*uint32_t psram_cs_pin*/) {
|
||||
// Set the PSRAM CS pin in the SDK
|
||||
gpio_set_function(RP2350_PSRAM_CS, GPIO_FUNC_XIP_CS1);
|
||||
|
||||
// start with zero size
|
||||
size_t psram_size = get_psram_size();
|
||||
|
||||
// No PSRAM - no dice
|
||||
if (psram_size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t intr_stash = save_and_disable_interrupts();
|
||||
// Enable quad mode.
|
||||
qmi_hw->direct_csr = 30 << QMI_DIRECT_CSR_CLKDIV_LSB | QMI_DIRECT_CSR_EN_BITS;
|
||||
|
||||
// Need to poll for the cooldown on the last XIP transfer to expire
|
||||
// (via direct-mode BUSY flag) before it is safe to perform the first
|
||||
// direct-mode operation
|
||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
||||
}
|
||||
|
||||
// RESETEN, RESET and quad enable
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
|
||||
if (i == 0) {
|
||||
qmi_hw->direct_tx = PSRAM_CMD_RSTEN;
|
||||
} else if (i == 1) {
|
||||
qmi_hw->direct_tx = PSRAM_CMD_RST;
|
||||
} else {
|
||||
qmi_hw->direct_tx = PSRAM_CMD_QUAD_ENABLE;
|
||||
}
|
||||
|
||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
||||
}
|
||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS);
|
||||
for (size_t j = 0; j < 20; j++) {
|
||||
asm("nop");
|
||||
}
|
||||
|
||||
(void)qmi_hw->direct_rx;
|
||||
}
|
||||
|
||||
// Disable direct csr.
|
||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS | QMI_DIRECT_CSR_EN_BITS);
|
||||
|
||||
// check our interrupts and setup the timing
|
||||
restore_interrupts(intr_stash);
|
||||
set_psram_timing();
|
||||
|
||||
// and now stash interrupts again
|
||||
intr_stash = save_and_disable_interrupts();
|
||||
|
||||
qmi_hw->m[1].rfmt = (QMI_M1_RFMT_PREFIX_WIDTH_VALUE_Q << QMI_M1_RFMT_PREFIX_WIDTH_LSB |
|
||||
QMI_M1_RFMT_ADDR_WIDTH_VALUE_Q << QMI_M1_RFMT_ADDR_WIDTH_LSB |
|
||||
QMI_M1_RFMT_SUFFIX_WIDTH_VALUE_Q << QMI_M1_RFMT_SUFFIX_WIDTH_LSB |
|
||||
QMI_M1_RFMT_DUMMY_WIDTH_VALUE_Q << QMI_M1_RFMT_DUMMY_WIDTH_LSB |
|
||||
QMI_M1_RFMT_DUMMY_LEN_VALUE_24 << QMI_M1_RFMT_DUMMY_LEN_LSB |
|
||||
QMI_M1_RFMT_DATA_WIDTH_VALUE_Q << QMI_M1_RFMT_DATA_WIDTH_LSB |
|
||||
QMI_M1_RFMT_PREFIX_LEN_VALUE_8 << QMI_M1_RFMT_PREFIX_LEN_LSB |
|
||||
QMI_M1_RFMT_SUFFIX_LEN_VALUE_NONE << QMI_M1_RFMT_SUFFIX_LEN_LSB);
|
||||
|
||||
qmi_hw->m[1].rcmd = PSRAM_CMD_QUAD_READ << QMI_M1_RCMD_PREFIX_LSB | 0 << QMI_M1_RCMD_SUFFIX_LSB;
|
||||
|
||||
qmi_hw->m[1].wfmt = (QMI_M1_WFMT_PREFIX_WIDTH_VALUE_Q << QMI_M1_WFMT_PREFIX_WIDTH_LSB |
|
||||
QMI_M1_WFMT_ADDR_WIDTH_VALUE_Q << QMI_M1_WFMT_ADDR_WIDTH_LSB |
|
||||
QMI_M1_WFMT_SUFFIX_WIDTH_VALUE_Q << QMI_M1_WFMT_SUFFIX_WIDTH_LSB |
|
||||
QMI_M1_WFMT_DUMMY_WIDTH_VALUE_Q << QMI_M1_WFMT_DUMMY_WIDTH_LSB |
|
||||
QMI_M1_WFMT_DUMMY_LEN_VALUE_NONE << QMI_M1_WFMT_DUMMY_LEN_LSB |
|
||||
QMI_M1_WFMT_DATA_WIDTH_VALUE_Q << QMI_M1_WFMT_DATA_WIDTH_LSB |
|
||||
QMI_M1_WFMT_PREFIX_LEN_VALUE_8 << QMI_M1_WFMT_PREFIX_LEN_LSB |
|
||||
QMI_M1_WFMT_SUFFIX_LEN_VALUE_NONE << QMI_M1_WFMT_SUFFIX_LEN_LSB);
|
||||
|
||||
qmi_hw->m[1].wcmd = PSRAM_CMD_QUAD_WRITE << QMI_M1_WCMD_PREFIX_LSB | 0 << QMI_M1_WCMD_SUFFIX_LSB;
|
||||
|
||||
// Mark that we can write to PSRAM.
|
||||
xip_ctrl_hw->ctrl |= XIP_CTRL_WRITABLE_M1_BITS;
|
||||
|
||||
restore_interrupts(intr_stash);
|
||||
|
||||
__psram_size = psram_size;
|
||||
|
||||
uint32_t used_psram_size = &__psram_heap_start__ - &__psram_start__;
|
||||
__psram_heap_size = __psram_size - used_psram_size;
|
||||
}
|
||||
PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_setup_psram, PICO_RUNTIME_INIT_PSRAM);
|
||||
|
||||
// update timing -- used if the system clock/timing was changed.
|
||||
void psram_reinit_timing() {
|
||||
set_psram_timing();
|
||||
}
|
||||
|
||||
static bool __psram_heap_init() {
|
||||
if (_bInitalized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_mem_heap = NULL;
|
||||
_mem_psram_pool = NULL;
|
||||
_mem_heap = tlsf_create_with_pool((void *)&__psram_heap_start__, __psram_heap_size, 16 * 1024 * 1024);
|
||||
if (!_mem_heap) {
|
||||
return false;
|
||||
}
|
||||
_mem_psram_pool = tlsf_get_pool(_mem_heap);
|
||||
if (!_mem_psram_pool) {
|
||||
return false;
|
||||
}
|
||||
_bInitalized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void *__psram_malloc(size_t size) {
|
||||
if (!__psram_heap_init() || !_mem_heap) {
|
||||
return NULL;
|
||||
}
|
||||
return tlsf_malloc(_mem_heap, size);
|
||||
}
|
||||
|
||||
void __psram_free(void *ptr) {
|
||||
if (!__psram_heap_init() || !_mem_heap) {
|
||||
return;
|
||||
}
|
||||
tlsf_free(_mem_heap, ptr);
|
||||
}
|
||||
|
||||
void *__psram_realloc(void *ptr, size_t size) {
|
||||
if (!__psram_heap_init() || !_mem_heap) {
|
||||
return NULL;
|
||||
}
|
||||
return tlsf_realloc(_mem_heap, ptr, size);
|
||||
}
|
||||
|
||||
void *__psram_calloc(size_t num, size_t size) {
|
||||
if (!__psram_heap_init() || !_mem_heap) {
|
||||
return NULL;
|
||||
}
|
||||
void *ptr = tlsf_malloc(_mem_heap, num * size);
|
||||
if (ptr) {
|
||||
bzero(ptr, num * size);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static bool max_free_walker(void *ptr, size_t size, int used, void *user) {
|
||||
size_t *max_size = (size_t *)user;
|
||||
if (!used && *max_size < size) {
|
||||
*max_size = size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t __psram_largest_free_block() {
|
||||
if (!__psram_heap_init() || !_mem_heap) {
|
||||
return 0;
|
||||
}
|
||||
size_t max_free = 0;
|
||||
if (_mem_psram_pool) {
|
||||
tlsf_walk_pool(_mem_psram_pool, max_free_walker, &max_free);
|
||||
}
|
||||
return max_free;
|
||||
}
|
||||
|
||||
static bool memory_size_walker(void *ptr, size_t size, int used, void *user) {
|
||||
*((size_t *)user) += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t __psram_total_space() {
|
||||
if (!__psram_heap_init() || !_mem_heap) {
|
||||
return 0;
|
||||
}
|
||||
size_t total_size = 0;
|
||||
if (_mem_psram_pool) {
|
||||
tlsf_walk_pool(_mem_psram_pool, memory_size_walker, &total_size);
|
||||
}
|
||||
return total_size;
|
||||
}
|
||||
|
||||
static bool memory_used_walker(void *ptr, size_t size, int used, void *user) {
|
||||
if (used) {
|
||||
*((size_t *)user) += size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t __psram_total_used() {
|
||||
if (!__psram_heap_init() || !_mem_heap) {
|
||||
return 0;
|
||||
}
|
||||
size_t total_size = 0;
|
||||
if (_mem_psram_pool) {
|
||||
tlsf_walk_pool(_mem_psram_pool, memory_used_walker, &total_size);
|
||||
}
|
||||
return total_size;
|
||||
}
|
||||
|
||||
#endif // RP2350_PSRAM_CS
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
@file sfe_psram.c
|
||||
|
||||
@brief This file contains a function that is used to detect and initialize PSRAM on
|
||||
SparkFun rp2350 boards.
|
||||
*/
|
||||
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 SparkFun Electronics
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
void psram_reinit_timing();
|
||||
void *__psram_malloc(size_t size);
|
||||
void __psram_free(void *ptr);
|
||||
void *__psram_realloc(void *ptr, size_t size);
|
||||
void *__psram_calloc(size_t num, size_t size);
|
||||
size_t __psram_largest_free_block();
|
||||
size_t __psram_total_space();
|
||||
size_t __psram_total_used();
|
||||
@@ -1212,7 +1212,7 @@ static uint16_t handle_prepare_write_request(att_connection_t * att_connection,
|
||||
}
|
||||
|
||||
/*
|
||||
@brief transcation queue of prepared writes, e.g., after disconnect
|
||||
@brief transaction queue of prepared writes, e.g., after disconnect
|
||||
*/
|
||||
void att_clear_transaction_queue(att_connection_t * att_connection) {
|
||||
(*att_write_callback)(att_connection->con_handle, 0, ATT_TRANSACTION_MODE_CANCEL, 0, NULL, 0);
|
||||
|
||||
@@ -257,7 +257,7 @@ extern "C" {
|
||||
uint8_t * response_buffer);
|
||||
|
||||
/**
|
||||
@brief transcation queue of prepared writes, e.g., after disconnect
|
||||
@brief transaction queue of prepared writes, e.g., after disconnect
|
||||
@return att_connection
|
||||
*/
|
||||
void att_clear_transaction_queue(att_connection_t * att_connection);
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
// Taken from LWIP's inet_chksum.c just to set the -O2 flag
|
||||
|
||||
/*
|
||||
Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
This file is part of the lwIP TCP/IP stack.
|
||||
|
||||
Author: Adam Dunkels <adam@sics.se>
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
|
||||
#pragma GCC optimize ("O2")
|
||||
/**
|
||||
An optimized checksum routine. Basically, it uses loop-unrolling on
|
||||
the checksum loop, treating the head and tail bytes specially, whereas
|
||||
the inner loop acts on 8 bytes at a time.
|
||||
|
||||
@arg start of buffer to be checksummed. May be an odd byte address.
|
||||
@len number of bytes in the buffer to be checksummed.
|
||||
@return host order (!) lwip checksum (non-inverted Internet sum)
|
||||
|
||||
by Curt McDowell, Broadcom Corp. December 8th, 2005
|
||||
*/
|
||||
extern "C" u16_t lwip_standard_chksum(const void *dataptr, int len) {
|
||||
const u8_t *pb = (const u8_t *)dataptr;
|
||||
const u16_t *ps;
|
||||
u16_t t = 0;
|
||||
const u32_t *pl;
|
||||
u32_t sum = 0, tmp;
|
||||
/* starts at odd byte address? */
|
||||
int odd = ((mem_ptr_t)pb & 1);
|
||||
|
||||
if (odd && len > 0) {
|
||||
((u8_t *)&t)[1] = *pb++;
|
||||
len--;
|
||||
}
|
||||
|
||||
ps = (const u16_t *)(const void *)pb;
|
||||
|
||||
if (((mem_ptr_t)ps & 3) && len > 1) {
|
||||
sum += *ps++;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
pl = (const u32_t *)(const void *)ps;
|
||||
|
||||
while (len > 7) {
|
||||
tmp = sum + *pl++; /* ping */
|
||||
if (tmp < sum) {
|
||||
tmp++; /* add back carry */
|
||||
}
|
||||
|
||||
sum = tmp + *pl++; /* pong */
|
||||
if (sum < tmp) {
|
||||
sum++; /* add back carry */
|
||||
}
|
||||
|
||||
len -= 8;
|
||||
}
|
||||
|
||||
/* make room in upper bits */
|
||||
sum = FOLD_U32T(sum);
|
||||
|
||||
ps = (const u16_t *)pl;
|
||||
|
||||
/* 16-bit aligned word remaining? */
|
||||
while (len > 1) {
|
||||
sum += *ps++;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
/* dangling tail byte remaining? */
|
||||
if (len > 0) { /* include odd byte */
|
||||
((u8_t *)&t)[0] = *(const u8_t *)ps;
|
||||
}
|
||||
|
||||
sum += t; /* add end bytes */
|
||||
|
||||
/* Fold 32-bit sum to 16 bits
|
||||
calling this twice is probably faster than if statements... */
|
||||
sum = FOLD_U32T(sum);
|
||||
sum = FOLD_U32T(sum);
|
||||
|
||||
if (odd) {
|
||||
sum = SWAP_BYTES_IN_WORD(sum);
|
||||
}
|
||||
|
||||
return (u16_t)sum;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#if PICO_ENTER_USB_BOOT_ON_EXIT
|
||||
#include "pico/bootrom.h"
|
||||
#endif
|
||||
#include "pico/time.h"
|
||||
#include "pico/runtime_init.h"
|
||||
|
||||
#if LIB_PICO_PRINTF_PICO
|
||||
#include "pico/printf.h"
|
||||
#else
|
||||
#define weak_raw_printf printf
|
||||
#define weak_raw_vprintf vprintf
|
||||
#endif
|
||||
#if LIB_PICO_STDIO
|
||||
#include "pico/stdio.h"
|
||||
#endif
|
||||
|
||||
#if PICO_ENTER_USB_BOOT_ON_EXIT
|
||||
#include "pico/bootrom.h"
|
||||
#endif
|
||||
|
||||
extern char __StackLimit; /* Set by linker. */
|
||||
|
||||
#define STDIO_HANDLE_STDIN 0
|
||||
#define STDIO_HANDLE_STDOUT 1
|
||||
#define STDIO_HANDLE_STDERR 2
|
||||
|
||||
void __attribute__((noreturn)) __weak _exit(__unused int status) {
|
||||
#if PICO_ENTER_USB_BOOT_ON_EXIT
|
||||
reset_usb_boot(0, 0);
|
||||
#else
|
||||
while (1) {
|
||||
__breakpoint();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__weak void *_sbrk(int incr) {
|
||||
extern char end; /* Set by linker. */
|
||||
static char *heap_end;
|
||||
char *prev_heap_end;
|
||||
|
||||
if (heap_end == 0) {
|
||||
heap_end = &end;
|
||||
}
|
||||
|
||||
prev_heap_end = heap_end;
|
||||
char *next_heap_end = heap_end + incr;
|
||||
|
||||
if (__builtin_expect(next_heap_end > (&__StackLimit), false)) {
|
||||
#if PICO_USE_OPTIMISTIC_SBRK
|
||||
if (heap_end == &__StackLimit) {
|
||||
// errno = ENOMEM;
|
||||
return (char *) -1;
|
||||
}
|
||||
next_heap_end = &__StackLimit;
|
||||
#else
|
||||
return (char *) -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
heap_end = next_heap_end;
|
||||
return (void *) prev_heap_end;
|
||||
}
|
||||
#if 0
|
||||
static int64_t epoch_time_us_since_boot;
|
||||
|
||||
__weak int _gettimeofday(struct timeval *__restrict tv, __unused void *__restrict tz) {
|
||||
if (tv) {
|
||||
int64_t us_since_epoch = ((int64_t)to_us_since_boot(get_absolute_time())) - epoch_time_us_since_boot;
|
||||
tv->tv_sec = (time_t)(us_since_epoch / 1000000);
|
||||
tv->tv_usec = (suseconds_t)(us_since_epoch % 1000000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak int settimeofday(__unused const struct timeval *tv, __unused const struct timezone *tz) {
|
||||
if (tv) {
|
||||
int64_t us_since_epoch = tv->tv_sec * 1000000 + tv->tv_usec;
|
||||
epoch_time_us_since_boot = (int64_t)to_us_since_boot(get_absolute_time()) - us_since_epoch;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak int _times(struct tms *tms) {
|
||||
#if CLOCKS_PER_SEC >= 1000000
|
||||
tms->tms_utime = (clock_t)(to_us_since_boot(get_absolute_time()) * (CLOCKS_PER_SEC / 1000000));
|
||||
#else
|
||||
tms->tms_utime = (clock_t)(to_us_since_boot(get_absolute_time()) / (1000000 / CLOCKS_PER_SEC));
|
||||
#endif
|
||||
tms->tms_stime = 0;
|
||||
tms->tms_cutime = 0;
|
||||
tms->tms_cstime = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak pid_t _getpid(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak int _kill(__unused pid_t pid, __unused int sig) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) _read(int handle, char *buffer, int length) {
|
||||
#if LIB_PICO_STDIO
|
||||
if (handle == STDIO_HANDLE_STDIN) {
|
||||
return stdio_get_until(buffer, length, at_the_end_of_time);
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) _write(int handle, char *buffer, int length) {
|
||||
#if LIB_PICO_STDIO
|
||||
if (handle == STDIO_HANDLE_STDOUT || handle == STDIO_HANDLE_STDERR) {
|
||||
stdio_put_string(buffer, length, false, true);
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) _open(__unused const char *fn, __unused int oflag, ...) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) _close(__unused int fd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
off_t __attribute__((weak)) _lseek(__unused int fd, __unused off_t pos, __unused int whence) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) _fstat(__unused int fd, __unused struct stat *buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) _isatty(int fd) {
|
||||
return fd == STDIO_HANDLE_STDIN || fd == STDIO_HANDLE_STDOUT || fd == STDIO_HANDLE_STDERR;
|
||||
}
|
||||
|
||||
// exit is not useful... no desire to pull in __call_exitprocs
|
||||
void exit(int status) {
|
||||
_exit(status);
|
||||
}
|
||||
|
||||
// incorrect warning from GCC 6
|
||||
GCC_Pragma("GCC diagnostic push")
|
||||
GCC_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
|
||||
void __weak __assert_func(const char *file, int line, const char *func, const char *failedexpr) {
|
||||
weak_raw_printf("assertion \"%s\" failed: file \"%s\", line %d%s%s\n",
|
||||
failedexpr, file, line, func ? ", function: " : "",
|
||||
func ? func : "");
|
||||
|
||||
_exit(1);
|
||||
}
|
||||
GCC_Pragma("GCC diagnostic pop")
|
||||
#endif
|
||||
void runtime_init(void) {
|
||||
#ifndef NDEBUG
|
||||
if (__get_current_exception()) {
|
||||
// crap; started in exception handler
|
||||
__breakpoint();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !PICO_RUNTIME_SKIP_INIT_PER_CORE_INSTALL_STACK_GUARD
|
||||
// install core0 stack guard
|
||||
extern char __StackBottom;
|
||||
runtime_init_per_core_install_stack_guard(&__StackBottom);
|
||||
#endif
|
||||
|
||||
// todo maybe we want to do this in the future, but it does stuff like register_tm_clones
|
||||
// which we didn't do in previous SDKs
|
||||
//extern void __libc_init_array(void);
|
||||
//__libc_init_array();
|
||||
|
||||
// ... so instead just do the __preinit_array
|
||||
runtime_run_initializers();
|
||||
// ... and the __init_array
|
||||
extern void (*__init_array_start)(void);
|
||||
extern void (*__init_array_end)(void);
|
||||
for (void (**p)(void) = &__init_array_start; p < &__init_array_end; ++p) {
|
||||
(*p)();
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
Expost absolute mouse HID descriptor and report
|
||||
Taken from @tobozo PR https://github.com/hathach/tinyusb/pull/1363
|
||||
TODO - remove once that PR merged with TinyUSB
|
||||
|
||||
Copyright (c) 2023 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 "tusb.h"
|
||||
#include "class/hid/hid_device.h"
|
||||
|
||||
// Absolute Mouse: same as the Standard (relative) Mouse Report but
|
||||
// with int16_t instead of int8_t for X and Y coordinates.
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */
|
||||
int16_t x; /**< Current x position of the mouse. */
|
||||
int16_t y; /**< Current y position of the mouse. */
|
||||
int8_t wheel; /**< Current delta wheel movement on the mouse. */
|
||||
int8_t pan; // using AC Pan
|
||||
} hid_abs_mouse_report_t;
|
||||
|
||||
|
||||
// Absolute Mouse Report Descriptor Template
|
||||
#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||
HID_USAGE_MIN ( 1 ) ,\
|
||||
HID_USAGE_MAX ( 5 ) ,\
|
||||
HID_LOGICAL_MIN ( 0 ) ,\
|
||||
HID_LOGICAL_MAX ( 1 ) ,\
|
||||
/* Left, Right, Middle, Backward, Forward buttons */ \
|
||||
HID_REPORT_COUNT( 5 ) ,\
|
||||
HID_REPORT_SIZE ( 1 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
/* 3 bit padding */ \
|
||||
HID_REPORT_COUNT( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 3 ) ,\
|
||||
HID_INPUT ( HID_CONSTANT ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
/* X, Y absolute position [0, 32767] */ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
||||
HID_LOGICAL_MIN ( 0x00 ) ,\
|
||||
HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\
|
||||
HID_REPORT_SIZE ( 16 ) ,\
|
||||
HID_REPORT_COUNT ( 2 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
/* Vertical wheel scroll [-127, 127] */ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
|
||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||
HID_REPORT_COUNT( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 8 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
|
||||
/* Horizontal wheel scroll [-127, 127] */ \
|
||||
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
|
||||
HID_LOGICAL_MIN ( 0x81 ), \
|
||||
HID_LOGICAL_MAX ( 0x7f ), \
|
||||
HID_REPORT_COUNT( 1 ), \
|
||||
HID_REPORT_SIZE ( 8 ), \
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
|
||||
HID_COLLECTION_END , \
|
||||
HID_COLLECTION_END \
|
||||
|
||||
|
||||
static inline bool tud_hid_abs_mouse_report(uint8_t report_id,
|
||||
uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) {
|
||||
hid_abs_mouse_report_t report = {
|
||||
.buttons = buttons,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.wheel = vertical,
|
||||
.pan = horizontal
|
||||
};
|
||||
|
||||
return tud_hid_n_report(0, report_id, &report, sizeof(report));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
16-bit axis gamepad definition
|
||||
Copyright (c) 2024 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 "tusb.h"
|
||||
#include "class/hid/hid_device.h"
|
||||
|
||||
#define TUD_HID_REPORT_DESC_GAMEPAD16(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
/* 16 bit X, Y, Z, Rz, Rx, Ry (min -32767, max 32767 ) */ \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\
|
||||
HID_LOGICAL_MIN_N ( -32767, 2 ) ,\
|
||||
HID_LOGICAL_MAX_N ( 32767, 2 ) ,\
|
||||
HID_REPORT_COUNT ( 6 ) ,\
|
||||
HID_REPORT_SIZE ( 16 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
/* 8 bit DPad/Hat Button Map */ \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\
|
||||
HID_LOGICAL_MIN ( 1 ) ,\
|
||||
HID_LOGICAL_MAX ( 8 ) ,\
|
||||
HID_PHYSICAL_MIN ( 0 ) ,\
|
||||
HID_PHYSICAL_MAX_N ( 315, 2 ) ,\
|
||||
HID_REPORT_COUNT ( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 8 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
/* 32 bit Button Map */ \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||
HID_USAGE_MIN ( 1 ) ,\
|
||||
HID_USAGE_MAX ( 32 ) ,\
|
||||
HID_LOGICAL_MIN ( 0 ) ,\
|
||||
HID_LOGICAL_MAX ( 1 ) ,\
|
||||
HID_REPORT_COUNT ( 32 ) ,\
|
||||
HID_REPORT_SIZE ( 1 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
HID_COLLECTION_END \
|
||||
|
||||
// HID Gamepad Protocol Report.
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
int16_t x; ///< Delta x movement of left analog-stick
|
||||
int16_t y; ///< Delta y movement of left analog-stick
|
||||
int16_t z; ///< Delta z movement of right analog-joystick
|
||||
int16_t rz; ///< Delta Rz movement of right analog-joystick
|
||||
int16_t rx; ///< Delta Rx movement of analog left trigger
|
||||
int16_t ry; ///< Delta Ry movement of analog right trigger
|
||||
uint8_t hat; ///< Buttons mask for currently pressed buttons in the DPad/hat
|
||||
uint32_t buttons; ///< Buttons mask for currently pressed buttons
|
||||
} hid_gamepad16_report_t;
|
||||
@@ -2,6 +2,8 @@
|
||||
// This file is autogenerated by pioasm; do not edit! //
|
||||
// -------------------------------------------------- //
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
#include "hardware/pio.h"
|
||||
#endif
|
||||
@@ -12,6 +14,7 @@
|
||||
|
||||
#define tone2_wrap_target 0
|
||||
#define tone2_wrap 8
|
||||
#define tone2_pio_version 0
|
||||
|
||||
static const uint16_t tone2_program_instructions[] = {
|
||||
// .wrap_target
|
||||
@@ -32,6 +35,10 @@ static const struct pio_program tone2_program = {
|
||||
.instructions = tone2_program_instructions,
|
||||
.length = 9,
|
||||
.origin = -1,
|
||||
.pio_version = 0,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config tone2_program_get_default_config(uint offset) {
|
||||
|
||||
@@ -66,10 +66,14 @@ typedef enum {
|
||||
} wl_status_t;
|
||||
|
||||
/* Encryption modes */
|
||||
enum wl_enc_type { /* Values map to 802.11 encryption suites... */
|
||||
enum wl_enc_type { /* Values map to 802.11 Cipher Algorithm Identifier */
|
||||
ENC_TYPE_WEP = 5,
|
||||
ENC_TYPE_TKIP = 2,
|
||||
ENC_TYPE_WPA = ENC_TYPE_TKIP,
|
||||
ENC_TYPE_CCMP = 4,
|
||||
ENC_TYPE_WPA2 = ENC_TYPE_CCMP,
|
||||
ENC_TYPE_GCMP = 6,
|
||||
ENC_TYPE_WPA3 = ENC_TYPE_GCMP,
|
||||
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
|
||||
ENC_TYPE_NONE = 7,
|
||||
ENC_TYPE_AUTO = 8,
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
Bluetooth Audio (A2DP Source and Sink)
|
||||
======================================
|
||||
|
||||
The PicoW can be used as a Bluetooth Audio sink or source with the ``BluetoothAudio`` class.
|
||||
Operation is generally handled "automatically" in the background so while the audio is
|
||||
playing or streaming the main application can perform other operations (like displaying
|
||||
playback info, polling buttons for controls, etc.)
|
||||
|
||||
.. code :: cpp
|
||||
|
||||
#include <BluetoothAudio.h>
|
||||
...
|
||||
|
||||
**Note about CPU usage:** Bluetooth SBC audio is a compressed format. That means
|
||||
that it takes non-trivial amounts of CPU to compress on send, or decompress on receive.
|
||||
Transmitting precompressed audio from, say, MP3 or AAC, requires first decompressing
|
||||
the source file into raw PCM and then re-compressing them in the SBC format. You may
|
||||
want to consider overclocking in this case to avoid underflow.
|
||||
|
||||
A2DPSink
|
||||
--------
|
||||
|
||||
This class implements slave sink-mode operation with player control (play, pause, etc.) and
|
||||
can play the received and decoded SBC audio to ``PWMAudio``, ``I2S``, or a user-created
|
||||
`BluetoothAudioConsumer`` class.
|
||||
|
||||
The ``A2DPSink.ino`` example demonstrates turning a PicoW into a Bluetooth headset with
|
||||
``PWMAudio``.
|
||||
|
||||
A2DPSource
|
||||
-----------
|
||||
|
||||
This class implements a master source-mode SBC Bluetooth A2DP audio connection which
|
||||
transmits audio using the standard ``Stream`` interface (like ``I2S`` or ``PWMAudio``.
|
||||
The main application connects to a Bluetooth speaker and then writes samples into a buffer
|
||||
that's automatically transmitted behind the scenes.
|
||||
|
||||
The ``A2DPSource.ino`` example shows how to connect to a Bluetooth speaker, transmit
|
||||
data, and respond to commands from the speaker.
|
||||
+4
-2
@@ -30,7 +30,7 @@ Analog Outputs
|
||||
--------------
|
||||
The RP2040 does not have any onboard DACs, so analog outputs are
|
||||
simulated using the standard method of using pulse width modulation
|
||||
(PWM) using the RP20400's hardware PWM units.
|
||||
(PWM) using the RP2040's hardware PWM units.
|
||||
|
||||
While up to 16 PWM channels can be generated, they are not independent
|
||||
and there are significant restrictions as to allowed pins in parallel.
|
||||
@@ -40,7 +40,9 @@ Analog Output Restrictions
|
||||
--------------------------
|
||||
|
||||
The PWM generator source clock restricts the legal combinations of
|
||||
frequency and ranges. For example, at 1MHz only about 6 bits of range
|
||||
frequency and ranges.
|
||||
At a CPU frequency of 133MHz, the 16 bit maximum range decreases by 1 bit for every doubling of the default PWM frequency of 1 kHz.
|
||||
For example, at 1MHz only about 6 bits of range
|
||||
are possible. When you define an ``analogWriteFreq`` and ``analogWriteRange``
|
||||
that can't be fulfilled by the hardware, the frequency will be preserved
|
||||
but the accuracy (range) will be reduced automatically. Your code will
|
||||
|
||||
@@ -120,7 +120,7 @@ Valid values for min and max are `BR_TLS10`, `BR_TLS11`, `BR_TLS12`. Min and ma
|
||||
|
||||
|
||||
ESP32 Compatibility
|
||||
===================
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Simple ESP32 ``WiFiClientSecure`` compatibility is built-in, allow for some sketches to run without any modification.
|
||||
The following methods are implemented:
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Similar to the `BearSSL::WiFiClientSecure` method, sets the receive and transmit
|
||||
Setting Server Certificates
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
TLS servers require a certificate identifying itself and containing its public key, and a private key they will use to encrypt information with. The application author is responsible for generating this certificate and key, either using a self-signed generator or using a commercial certification authority. **Do not re-use the certificates included in the examples provided.**
|
||||
TLS servers require a certificate identifying itself and containing its public key, and a private key they will use to encrypt information with. The application author is responsible for generating this certificate and key, either using a self-signed generator or using a commercial certification authority. **Do not reuse the certificates included in the examples provided.**
|
||||
|
||||
This example command will generate a RSA 2048-bit key and certificate:
|
||||
|
||||
|
||||
+7
-5
@@ -2,9 +2,6 @@ Bluetooth on PicoW Support
|
||||
==========================
|
||||
|
||||
As of the Pico-SDK version 1.5.0, the PicoW has **BETA** Bluetooth support.
|
||||
So, since this core builds off the SDK the best that can be suggested it
|
||||
that we have **ALPHA** Bluetooth support. As such, bug reports are welcome,
|
||||
but Pull Requests fixing problems you find are seriously appreciated.
|
||||
|
||||
Enabling Bluetooth
|
||||
------------------
|
||||
@@ -24,6 +21,11 @@ Bluetooth Low Energy (BLE) HID device using the same API as their USB versions.
|
||||
The ``SerialBT`` library implements a very simple SPP (Serial Port Profile)
|
||||
Serial-compatible port.
|
||||
|
||||
Connect and use Bluetooth peripherals with the PicoW using the
|
||||
``BluetoothHIDMaster`` library.
|
||||
|
||||
``BluetoothAudio`` (A2DP) is also supported, both sink and source.
|
||||
|
||||
Writing Custom Bluetooth Applications
|
||||
-------------------------------------
|
||||
You may also write full applications using the ``BTStack`` standard callback
|
||||
@@ -40,8 +42,8 @@ For many BTStack examples, you simply need call the included
|
||||
called afterwards to start processing (in the background).
|
||||
|
||||
You will also need to acquire the BT ``async_context`` system lock before
|
||||
calling any BTStack APIs. See the ``libraries/PicoBluetoothHID`` helper
|
||||
class for an example of how to do this.
|
||||
calling any BTStack APIs. ``__lockBluetooth`` and ``unlockBluetooth`` are
|
||||
provided in the PicoW variant code.
|
||||
|
||||
Note that if you need to modify the system ``btstack_config.h`` file, do so
|
||||
in the ``tools/libpico`` directory and rebuild the Pico SDK static library.
|
||||
|
||||
+20
-20
@@ -1,21 +1,21 @@
|
||||
BOOTSEL Button
|
||||
==============
|
||||
|
||||
The BOOTSEL button on the Pico is not connected to a standard GPIO, so
|
||||
it cannot be read using the usual ``digitalRead`` function. It **can**,
|
||||
however, be read using a special (relatively slow) method.
|
||||
|
||||
The ``BOOTSEL`` object implements a simple way of reading the BOOTSEL
|
||||
button. Simply use the object ``BOOTSEL`` as a boolean (as a conditional
|
||||
in an ``if`` or ``while``, or assigning to a ``bool``):
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
// Print "BEEP" if the BOOTSEL button is pressed
|
||||
if (BOOTSEL) {
|
||||
Serial.println("BEEP!");
|
||||
// Wait until BOOTSEL is released
|
||||
while (BOOTSEL) {
|
||||
delay(1);
|
||||
}
|
||||
BOOTSEL Button
|
||||
==============
|
||||
|
||||
The BOOTSEL button on the Pico is not connected to a standard GPIO, so
|
||||
it cannot be read using the usual ``digitalRead`` function. It **can**,
|
||||
however, be read using a special (relatively slow) method.
|
||||
|
||||
The ``BOOTSEL`` object implements a simple way of reading the BOOTSEL
|
||||
button. Simply use the object ``BOOTSEL`` as a boolean (as a conditional
|
||||
in an ``if`` or ``while``, or assigning to a ``bool``):
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
// Print "BEEP" if the BOOTSEL button is pressed
|
||||
if (BOOTSEL) {
|
||||
Serial.println("BEEP!");
|
||||
// Wait until BOOTSEL is released
|
||||
while (BOOTSEL) {
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -54,9 +54,9 @@ author = u'Earle F. Philhower, III'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'3.6.0'
|
||||
version = u'4.0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'3.6.0'
|
||||
release = u'4.0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
+15
-2
@@ -86,6 +86,19 @@ Pico may not have enough time to service the Ethernet port before the timer fire
|
||||
leading to a lock up and hang.
|
||||
|
||||
|
||||
Using Interrupt-Driven Handling
|
||||
-------------------------------
|
||||
|
||||
The WizNet and ENC28J60 devices support generating an interrupt when a packet is received,
|
||||
removing the need for polling and decreasing latency. Simply specify the SPI object to use and the
|
||||
interrupt pin when instantiating the Ethernet object:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#include <W5100lwIP.h>
|
||||
Wiznet5100lwIP eth(SS /* Chip Select*/, SPI /* SPI interface */, 17 /* Interrupt GPIO */ );
|
||||
|
||||
|
||||
Adjusting SPI Speed
|
||||
-------------------
|
||||
|
||||
@@ -114,12 +127,12 @@ For example, to set the W5500 to use a 30MHZ clock:
|
||||
Using the WIZnet W5100S-EVB-Pico
|
||||
--------------------------------
|
||||
|
||||
You can use the onboard Ethernet chip with these drivers by utilizing the following options:
|
||||
You can use the onboard Ethernet chip with these drivers, in interrupt mode, by utilizing the following options:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#include <W5100lwIP.h>
|
||||
Wiznet5100lwIP eth(17); // Note chip select is **17**
|
||||
Wiznet5100lwIP eth(17, SPI, 21); // Note chip select is **17**
|
||||
|
||||
void setup() {
|
||||
// Set SPI to the onboard Wiznet chip
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
FatFSUSB
|
||||
========
|
||||
|
||||
When the onboard flash memory is used as a ``FatFS`` filesystem, the
|
||||
``FatFSUSB`` can be used to allow exporting it to a PC as a standard
|
||||
memory stick. The PC can then access, add, and remove files as if the
|
||||
Pico was a USB memory stick, and upon ejection the Pico can access
|
||||
any new files just as if it made them itself.
|
||||
|
||||
(Note, if you are using LittleFS then you need to use ``SingleFileDrive``
|
||||
to export a single file, not this class, because the PC does not
|
||||
understand the LittleFS disk format.)
|
||||
|
||||
Callbacks, Interrupt Safety, and File Operations
|
||||
------------------------------------------------
|
||||
|
||||
The ``FatFSUSB`` library allows your application to get a callback
|
||||
when a PC attempts to mount or unmount the Pico as a FAT drive.
|
||||
|
||||
When the drive is being used by the Pico (i.e. any ``File`` is open for
|
||||
read or write, the ``FatFS`` is not ``end()`` -ed and still mounted,
|
||||
etc.) the host may not access it. Conversely, while the host PC is
|
||||
connected to the drive no ``FatFS`` access by the Pico is allowed.
|
||||
|
||||
Your ``driveReady`` callback will be called when the PC attempts to mount
|
||||
the drive. If you have any files open, then this callback can report back
|
||||
that the drive is not yet ready. When you complete file processing, the PC
|
||||
can re-attempt to mount the drive and your callback can return ``true`` .
|
||||
|
||||
The ``onPlug`` callback will generally ``FatFS.end()`` and set a
|
||||
global flag letting your application know not to touch the filesystem until
|
||||
the flag is cleared by the ``onUnplug`` callback (which will also do a
|
||||
``FatFS.begin()`` call).
|
||||
|
||||
Failing to close all files **and** ``FatFS.end()`` before granting the
|
||||
PC access to flash memory will result in corruption. FAT does not allow multiple
|
||||
writers to access the same drive. Even mounting and only reading files from
|
||||
the PC may cause hidden writes (things like access time, etc.) which would
|
||||
also cause corruption.
|
||||
|
||||
See the included ``Listfiles-USB`` sketch for an example of working with
|
||||
these limitations.
|
||||
@@ -1,6 +1,8 @@
|
||||
FreeRTOS SMP
|
||||
============
|
||||
|
||||
**NOTE:** FreeRTOS is not yet supported on the RP2350. PRs gladly accepted!
|
||||
|
||||
The SMP (multicore) port of FreeRTOS is included with the core. This allows complex
|
||||
task operations and real preemptive multithreading in your sketches. While the
|
||||
``setup1`` and ``loop1`` way of multitasking is simplest for most folks, FreeRTOS
|
||||
|
||||
+122
-33
@@ -18,12 +18,12 @@ The following diagram shows the flash layout used in Arduino-Pico:
|
||||
|
||||
::
|
||||
|
||||
|---------------------|-------------|----|
|
||||
^ ^ ^
|
||||
Sketch File system EEPROM
|
||||
|----|---------------------|-------------|----|
|
||||
^ ^ ^ ^
|
||||
OTA Sketch File system EEPROM
|
||||
|
||||
The file system size is configurable via the IDE menus, rom 64k up to 15MB
|
||||
(assuming you have an RP2040 boad with that much flash)
|
||||
The file system size is configurable via the IDE menus, from 64k up to 15MB
|
||||
(assuming you have an RP2040 board with that much flash)
|
||||
|
||||
**Note:** to use any of file system functions in the sketch, add the
|
||||
following include to the sketch:
|
||||
@@ -33,25 +33,61 @@ following include to the sketch:
|
||||
#include "LittleFS.h" // LittleFS is declared
|
||||
// #include <SDFS.h>
|
||||
// #include <SD.h>
|
||||
// #include <FatFS.h>
|
||||
|
||||
|
||||
Compatible Filesystem APIs
|
||||
--------------------------
|
||||
|
||||
LittleFS is an onboard filesystem that sets asidesome program flash for
|
||||
LittleFS is an onboard filesystem that sets aside some program flash for
|
||||
use as a filesystem without requiring any external hardware.
|
||||
|
||||
SDFS is a filesystem for SD cards, based on [SdFat 2.0](https://github.com/earlephilhower/ESP8266SdFat).
|
||||
It supports FAT16 and FAT32 formatted cards, and requires an external
|
||||
SD card reader.
|
||||
|
||||
SD is the Arduino supported, somewhat old and limited SD card filesystem.
|
||||
SD is the Arduino-supported, somewhat old and limited SD card filesystem.
|
||||
It is recommended to use SDFS for new applications instead of SD.
|
||||
|
||||
All three of these filesystems can open and manipulate ``File`` and ``Dir``
|
||||
FatFS implements a wear-leveled, FTL-backed FAT filesystem in the onboard
|
||||
flash which can be easily accessed over USB as a standard memory stick
|
||||
via FatFSUSB.
|
||||
|
||||
All of these filesystems can open and manipulate ``File`` and ``Dir``
|
||||
objects with the same code because the implement a common end-user
|
||||
filesystem API.
|
||||
|
||||
FatFS File System Caveats and Warnings
|
||||
--------------------------------------
|
||||
|
||||
The FAT filesystem is ubiquitous, but it is also around 50 years old and ill
|
||||
suited to SPI flash memory due to having "hot spots" like the FAT copies that
|
||||
are rewritten many times over. SPI flash allows a high, but limited, number
|
||||
of writes before losing the ability to write safely. Applications like
|
||||
data loggers where many writes occur could end up wearing out the SPI flash
|
||||
sector that holds the FAT **years** before coming close to the write limits of
|
||||
the data sectors.
|
||||
|
||||
To circumvent this issue, the FatFS implementation here uses a flash translation
|
||||
layer (FTL) developed for SPI flash on embedded systems. This allows for the
|
||||
same LBA to be written over and over by the FAT filesystem, but use different
|
||||
flash locations. For more information see
|
||||
[SPIFTL](https://github.com/earlephilhower/SPIFTL). In this mode the Pico
|
||||
flash appears as a normal, 512-byte sector drive to the FAT.
|
||||
|
||||
What this means, practically, is that about 5KB of RAM per megabyte of flash
|
||||
is required for housekeeping. Writes can also become very slow if most of the
|
||||
flash LBA range is used (i.e. if the FAT drive is 99% full) due to the need
|
||||
for garbage collection processes to move data around and preserve the flash
|
||||
lifetime.
|
||||
|
||||
Alternatively, if an FTL is not desired or memory is tight, FatFS can use the
|
||||
raw flash directly. In this mode sectors are 4K in size and flash is mapped
|
||||
1:1 to sectors, so things like the FAT table updates will all use the same
|
||||
physical flash bits. For low-utilization operations this may be fine, but if
|
||||
significant writes are done (from the Pico or the PC host) this may wear out
|
||||
portions of flash very quickly , rendering it unusable.
|
||||
|
||||
LittleFS File System Limitations
|
||||
--------------------------------
|
||||
|
||||
@@ -75,22 +111,28 @@ Uploading Files to the LittleFS File System
|
||||
menu item to **Tools** menu for uploading the contents of sketch data
|
||||
directory into a new LittleFS flash file system.
|
||||
|
||||
**IDE 1.x**
|
||||
|
||||
- Download the tool: https://github.com/earlephilhower/arduino-pico-littlefs-plugin/releases
|
||||
- In your Arduino sketchbook directory, create ``tools`` directory if
|
||||
it doesn't exist yet.
|
||||
- Unpack the tool into ``tools`` directory (the path will look like
|
||||
``<home_dir>/Arduino/tools/PicoLittleFS/tool/picolittlefs.jar``)
|
||||
- In your Arduino sketchbook directory, create ``tools`` directory if it doesn't exist yet.
|
||||
- Unpack the tool into ``tools`` directory (the path will look like ``<home_dir>/Arduino/tools/PicoLittleFS/tool/picolittlefs.jar``)
|
||||
If upgrading, overwrite the existing JAR file with the newer version.
|
||||
- Restart Arduino IDE.
|
||||
- Open a sketch (or create a new one and save it).
|
||||
- Go to sketch directory (choose Sketch > Show Sketch Folder).
|
||||
- Create a directory named ``data`` and any files you want in the file
|
||||
system there.
|
||||
- Create a directory named ``data`` and any files you want in the file system there.
|
||||
- Make sure you have selected a board, port, and closed Serial Monitor.
|
||||
- Double check theSerial Monitor is closed. Uploads will fail if the Serial
|
||||
Monitor has control of the serial port.
|
||||
- Select ``Tools > Pico LittleFS Data Upload``. This should start
|
||||
uploading the files into the flash file system.
|
||||
- Double check the Serial Monitor is closed. Uploads will fail if the Serial Monitor has control of the serial port.
|
||||
- Select ``Tools > Pico LittleFS Data Upload``. This should start uploading the files into the flash file system.
|
||||
|
||||
**IDE 2.x**
|
||||
|
||||
- Download the new tool: https://github.com/earlephilhower/arduino-littlefs-upload/releases
|
||||
- Exit the IDE, if running
|
||||
- Copy the VSIX file manually to (Linux/Mac) ``~/.arduinoIDE/plugins/`` (you may need to make this directory yourself beforehand) or to (Windows) ``C:\Users\<username>\.arduinoIDE\``
|
||||
- Restart the IDE
|
||||
- Double check the Serial Monitor is closed. Uploads will fail if the Serial Monitor has control of the serial port.
|
||||
- Enter ``[Ctrl]`` + ``[Shift]`` + ``[P]`` to bring up the command palette, then select/type ``Upload LittleFS to Pico/ESP8266``
|
||||
|
||||
SD Library Information
|
||||
----------------------
|
||||
@@ -109,8 +151,50 @@ second SPI port, ``SPI1``. Just use the following call in place of
|
||||
SD.begin(cspin, SPI1);
|
||||
|
||||
|
||||
File system object (LittleFS/SD/SDFS)
|
||||
-------------------------------------
|
||||
Using VFS (Virtual File System) for POSIX support
|
||||
-------------------------------------------------
|
||||
The ``VFS`` library enables sketches to use standard POSIX file I/O operations using
|
||||
standard ``FILE *`` operations. Include the ``VFS`` library in your application and
|
||||
add a call to map the ``VFS.root()`` to your filesystem. I.e.:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#include <VFS.h>
|
||||
#include <LittleFS.h>
|
||||
|
||||
void setup() {
|
||||
LittleFS.begin();
|
||||
VFS.root(LittleFS);
|
||||
FILE *fp = fopen("/thisfilelivesonflash.txt", "w");
|
||||
fprintf(fp, "Hello!\n");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
Multiple filesystems can be ``VFS.map()`` into the VFS namespace under different directory
|
||||
names. For example, the following will make files on ``/sd`` reside on an external\
|
||||
SD card and files on ``/lfs`` live in internal flash.
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#include <VFS.h>
|
||||
#include <LittleFS.h>
|
||||
#include <SDFS.h>
|
||||
|
||||
void setup() {
|
||||
LittleFS.begin();
|
||||
SDFS.begin();
|
||||
VFS.map("/lfs", LittleFS);
|
||||
VFS.map("/sd", SDFS);
|
||||
FILE *onSD = fopen("/sd/thislivesonsd.txt", "wb");
|
||||
....
|
||||
}
|
||||
|
||||
See the examples in the ``VFS`` library for more information.
|
||||
|
||||
|
||||
|
||||
File system object (LittleFS/SD/SDFS/FatFS)
|
||||
-------------------------------------------
|
||||
|
||||
setConfig
|
||||
~~~~~~~~~
|
||||
@@ -125,14 +209,22 @@ setConfig
|
||||
c2.setCSPin(12);
|
||||
SDFS.setConfig(c2);
|
||||
|
||||
FatFSConfig c3;
|
||||
c3.setUseFTL(false); // Directly access flash memory
|
||||
c3.setDirEntries(256); // We need 256 root directory entries on a format()
|
||||
c3.setFATCopies(1); // Only 1 FAT to save 4K of space and extra writes
|
||||
FatFS.setConfig(c3);
|
||||
FatFS.format(); // Format using these settings, erasing everything
|
||||
|
||||
This method allows you to configure the parameters of a filesystem
|
||||
before mounting. All filesystems have their own ``*Config`` (i.e.
|
||||
``SDFSConfig`` or ``LittleFSConfig`` with their custom set of options.
|
||||
All filesystems allow explicitly enabling/disabling formatting when
|
||||
mounts fail. If you do not call this ``setConfig`` method before
|
||||
perforing ``begin()``, you will get the filesystem's default
|
||||
behavior and configuration. By default, SPIFFS will autoformat the
|
||||
filesystem if it cannot mount it, while SDFS will not.
|
||||
behavior and configuration. By default, LittleFS and FatFS will autoformat the
|
||||
filesystem if it cannot mount it, while SDFS will not. FatFS will also use
|
||||
the built-in FTL to support 512 byte sectors and higher write lifetime.
|
||||
|
||||
begin
|
||||
~~~~~
|
||||
@@ -144,11 +236,10 @@ begin
|
||||
|
||||
This method mounts file system. It must be called before any
|
||||
other FS APIs are used. Returns *true* if file system was mounted
|
||||
successfully, false otherwise. With no options it will format SPIFFS
|
||||
if it is unable to mount it on the first try.
|
||||
successfully, false otherwise.
|
||||
|
||||
Note that LittleFS will automatically format the filesystem
|
||||
if one is not detected. This is configurable via ``setConfig``
|
||||
if one is not detected. This is configurable via ``setConfig``.
|
||||
|
||||
end
|
||||
~~~
|
||||
@@ -181,8 +272,8 @@ open
|
||||
|
||||
Opens a file. ``path`` should be an absolute path starting with a slash
|
||||
(e.g. ``/dir/filename.txt``). ``mode`` is a string specifying access
|
||||
mode. It can be one of "r", "w", "a", "r+", "w+", "a+". Meaning of these
|
||||
modes is the same as for ``fopen`` C function.
|
||||
mode. It can be one of "r", "w", "a", "r+", "w+", "a+". The meaning of these
|
||||
modes is the same as for the ``fopen`` C function.
|
||||
|
||||
::
|
||||
|
||||
@@ -258,8 +349,6 @@ openDir
|
||||
or LittleFS.openDir(path)
|
||||
|
||||
Opens a directory given its absolute path. Returns a *Dir* object.
|
||||
Please note the previous discussion on the difference in behavior between
|
||||
LittleFS and SPIFFS for this call.
|
||||
|
||||
remove
|
||||
~~~~~~
|
||||
@@ -550,8 +639,8 @@ close
|
||||
Close the file. No other operations should be performed on *File* object
|
||||
after ``close`` function was called.
|
||||
|
||||
openNextFile (compatibiity method, not recommended for new code)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
openNextFile (compatibility method, not recommended for new code)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
@@ -562,8 +651,8 @@ openNextFile (compatibiity method, not recommended for new code)
|
||||
Opens the next file in the directory pointed to by the File. Only valid
|
||||
when ``File.isDirectory() == true``.
|
||||
|
||||
rewindDirectory (compatibiity method, not recommended for new code)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
rewindDirectory (compatibility method, not recommended for new code)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
Bluetooth HID Master
|
||||
====================
|
||||
|
||||
The PicoW can connect to a Bluetooth Classic or Bluetooth BLE keyboard,
|
||||
mouse, or joystick and receive input events from it. As opposed to
|
||||
the ``Keyboard``, ``Mouse``, and ``Joystick`` libraries, which make
|
||||
the PicoW into a peripheral others can use, this lets the PicoW use the
|
||||
same kinds of peripherals in a master rols.
|
||||
|
||||
BTDeviceInfo Class
|
||||
------------------
|
||||
|
||||
The ``BluetoothHCI`` class implements a scanning function for classic
|
||||
and BLE devices and can return a ``std::vector`` of discovered devices to an application.
|
||||
Iterate over the list using any of the STL iteration methods (i.e. ``for (auto e : list)``).
|
||||
The elements of this list are ``BTDeviceInfo`` objects which have the following
|
||||
member functions:
|
||||
|
||||
``BTDeviceInfo::deviceClass()`` returns the Bluetooth BLE UUID or the Blustooth device
|
||||
class for the device. This specifies the general class of the device (keyboard, mouse,
|
||||
etc.).
|
||||
|
||||
``BTDeviceInfo::address()`` and ``BTDeviceInfo::addressString()`` return the
|
||||
Bluetooth address as a binary array or a string that can be used to ``print``.
|
||||
|
||||
``BTDeviceInfo::addressType()`` returns whether the BLE address is random or not, and
|
||||
is not generally needed by a user application.
|
||||
|
||||
``BTDeviceInfo::rssi()`` returns an approximate dB level for the device. Less
|
||||
negative is stronger signal.
|
||||
|
||||
``BTDeviceInfo::name()`` returns the advertised name of the device, if present. Some
|
||||
devices or scans do not return names for valid devices.
|
||||
|
||||
|
||||
BluetoothHCI Class
|
||||
------------------
|
||||
|
||||
The ``BluetoothHCI`` class is responsible for scanning for devices and the lower-level
|
||||
housekeeping for a master-mode Bluetooth application. Most applications will not need
|
||||
to access it directly, but it can be used to discover nearby BT devices. As
|
||||
part of the application Bluetooth setup, call ``BluetoothHCI::install()`` and then
|
||||
``BluetoothHCI::begin()`` to start BT processing. Your application is still responsible
|
||||
for all the non-default HCI initialization and customization. See the ``BluetoothScanner.ino``
|
||||
example for more info.
|
||||
|
||||
|
||||
BluetoothHIDMaster Operation
|
||||
----------------------------
|
||||
|
||||
Most applications will use the ``BluetoothHIDMaster`` class and, after connecting, receive
|
||||
callbacks from the Bluetooth stack when input events (key presses, mouse moves, button
|
||||
mashes) occur.
|
||||
|
||||
Application flow will generally be:
|
||||
1. Install the appropriate callbacks using the ``BluetoothHIDMaster::onXXX`` methods
|
||||
2. Start the Bluetooth processing with ``BluetoothHIDMaster::begin()`` or ``BluetoothHIDMaster::beginBLE()``
|
||||
3. Connect to the first device found with ``BluetoothHIDMaster::connectXXX()`` and start receiving callbacks.
|
||||
4. Callbacks will come at interrupt time and set global state variables, which the main ``loop()`` will process
|
||||
|
||||
Callback Event Handlers
|
||||
-----------------------
|
||||
The main application is informed of new inputs via a standard callback mechanism. These callbacks run at
|
||||
interrupt time and should not do significant work, ``delay()``, or allocate or free memory. The most common
|
||||
way of handling this is setting global ``volatile`` flags and variables that the main ``loop()`` will poll
|
||||
and process.
|
||||
|
||||
Mouse Callbacks
|
||||
~~~~~~~~~~~~~~~
|
||||
The ``BluetoothHIDMaster::onMouseMove`` callback gets the delta X, Y, and wheel reported by the device.
|
||||
The ``BluetoothHIDMaster::onMouseButton`` gets a button number and state (up or down) and will be called
|
||||
each time an individual button is reported changed by the mouse.
|
||||
|
||||
.. code :: cpp
|
||||
|
||||
void mouseMoveCB(void *cbdata, int dx, int dy, int dw) {
|
||||
// Process the deltas, adjust global mouse state
|
||||
}
|
||||
|
||||
void mouseButtonCB(void *cbdata, int butt, bool down) {
|
||||
// Set the global button array with this new info
|
||||
}
|
||||
|
||||
|
||||
Meyboard Callbacks
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
The `BluetoothHIDMaster::onKeyDown`` callback receives the raw HID key (**NOT ASCII**) sent by the device on a key press
|
||||
while `BluetoothHIDMaster::onKeyUp`` gets the same when a key is released. Note that up to 6 keys can be pressed at any
|
||||
one time. For media keys ("consumer keys" in the USB HID documentation) the ``BluetoothHIDMaster::onConsumerKeyDown`` and
|
||||
``BluetoothHIDMaster::onConsumerKeyUp`` perform the same function (and receive the consumer key IDs defined by the
|
||||
USB HID spec and not ASCII).
|
||||
|
||||
To convert the key press and release (including SHIFT handling), use a ``HIDKeyStream`` object. Simply write the raw
|
||||
HID key and the up/down state to the stream and read back the ASCII for use in an application.
|
||||
|
||||
.. code :: cpp
|
||||
|
||||
HIDKeyStream keystream;
|
||||
|
||||
void keyDownCB(void *cbdata, int key) {
|
||||
keystream.write((uint8_t )key);
|
||||
keystream.write((uint8_t) true); // Keystream now has 1 ASCII character to read out and use
|
||||
char ascii = keystream.read();
|
||||
// ....
|
||||
}
|
||||
|
||||
void keyUpCB(void *cbdata, int key) {
|
||||
// Normally don't do anything on this, the character was read in the keyDownCB
|
||||
}
|
||||
|
||||
void consumerKeyDownCB(void *cbdata, int key) {
|
||||
// switch(key) and use cases from the USB Consumer Key page
|
||||
}
|
||||
|
||||
void consumerKeyUpCB(void *cbdata, int key) {
|
||||
// switch(key) and use cases from the USB Consumer Key page
|
||||
}
|
||||
|
||||
|
||||
Joystick Callbacks
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
A single ``BluetoothHIDMaster::onJoystick`` callback gets activated every time a report from a joystick is processed.
|
||||
It receives (potentially, if supported by the device) 4 analog axes, one 8-way digital hat switch position, and up
|
||||
to 32 button states at a time.
|
||||
|
||||
.. code :: cpp
|
||||
|
||||
void joystickCB(void *cbdata, int x, int y, int z, int rz, uint8_t hat, uint32_t buttons) {
|
||||
// HAT 0 = UP and continues clockwise. If no hat direction it is set to 0x0f.
|
||||
// Use "buttons & (1 << buttonNumber)" to look at the individual button states
|
||||
// ...
|
||||
}
|
||||
|
||||
PianoKeyboard Example
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
See the ``PianoKeyboard.ino`` and ``PianoKeyboardBLE.ino`` examples for more information on callback operation.
|
||||
|
||||
|
||||
BluetoothHIDMaster::onXXX Callback Installers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code :: cpp
|
||||
|
||||
void BluetoothHIDMaster::onMouseMove(void (*)(void *, int, int, int), void *cbData = nullptr);
|
||||
void BluetoothHIDMaster::onMouseButton(void (*)(void *, int, bool), void *cbData = nullptr);
|
||||
void BluetoothHIDMaster::onKeyDown(void (*)(void *, int), void *cbData = nullptr);
|
||||
void BluetoothHIDMaster::onKeyUp(void (*)(void *, int), void *cbData = nullptr);
|
||||
void BluetoothHIDMaster::onConsumerKeyDown(void (*)(void *, int), void *cbData = nullptr);
|
||||
void BluetoothHIDMaster::onConsumerKeyUp(void (*)(void *, int), void *cbData = nullptr);
|
||||
void BluetoothHIDMaster::onJoystick(void (*)(void *, int, int, int, int, uint8_t, uint32_t), void *cbData = nullptr);
|
||||
|
||||
BluetoothHIDMaster Class
|
||||
------------------------
|
||||
|
||||
bool BluetoothHIDMaster::begin()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Installs and configures the Bluetooth Classic stack and starts processing events. No connections are made at this point.
|
||||
When running in Classic mode, no BLE devices can be detected or used.
|
||||
|
||||
|
||||
bool BluetoothHIDMaster::begin(const char *BLEName)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Installs and configures the Bluetooth BLE stack and starts processing events. No connections are made at this point.
|
||||
When running in BLE mode, no Classic devices can be detected or used.
|
||||
|
||||
bool BluetoothHIDMaster::connected()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Returns if the Bluetooth stack is up and running and a connection to a device is currently active.
|
||||
|
||||
void BluetoothHIDMaster::end()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Disables the Bluetooth stack. Note that with the current Bluetooth implementation restarting the stack (i.e. calling ``begin()`` after ``end()``) is not stable and will not work. Consider storing state and rebooting completely if this is necessary.
|
||||
|
||||
bool BluetoothHIDMaster::running()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Returns if the Bluetooth stack is running at all. Does not indicate if there is an active connection or not.
|
||||
|
||||
bool BluetoothHIDMaster::hciRunning()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Returns if the Bluetooth stack has passed the initial HCI start up phase. Until this returns ``true`` no Bluetooth operations can be performed.
|
||||
|
||||
std::vector<BTDeviceInfo> BluetoothHIDMaster::scan(uint32_t mask, int scanTimeSec, bool async)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Passes through the ``BluetoothHCI::scan()`` function to manually scan for a list of nearby devices. If you want to connect to the first found device, this is not needed.
|
||||
|
||||
bool BluetoothHIDMaster::connect(const uint8_t *addr)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Start the connection process to the Bluetooth Classic device with the given MAC. Note that this returns immediately, but it may take several seconds until ``connected()`` reports that the connection has been established.
|
||||
|
||||
bool BluetoothHIDMaster::connectKeyboard(), connectMouse(), connectJoystick(), connectAny()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Connect to the first found specified Bluetooth Classic device type (or any HID device) in pairing mode. No need to call ``scan()`` or have an address.
|
||||
|
||||
bool BluetoothHIDMaster::connectBLE(const uint8_t *addr, int addrType)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Start the connection process to the Bluetooth BLE device with the given MAC. Note that this returns immediately, but it may take several seconds until ``connected()`` reports that the connection has been established.
|
||||
|
||||
bool BluetoothHIDMaster::connectBLE()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Connect to the first found BLE device that has a HID service UUID (keyboard, mouse, or joystick)
|
||||
|
||||
bool BluetoothHIDMaster::disconnect()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Shuts down the connection to the currently connected device.
|
||||
|
||||
void BluetoothHIDMaster::clearPairing()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Erases all Bluetooth keys from memory. This effectively "forgets" all pairing between devices and can help avoid issues with the beta Bluetooth stack in the SDK.
|
||||
+3
-7
@@ -1,15 +1,11 @@
|
||||
IDE Menus
|
||||
=========
|
||||
|
||||
Model
|
||||
Board
|
||||
-----
|
||||
Use the boards menu to select your model of RP2040 board. There will be two
|
||||
options: `Boardname` and `Boardname (Picoprobe)`. If you want to use a
|
||||
Picoprobe to upload your sketches and not the default automatic UF2 upload,
|
||||
use the `(Picoprobe)` option, otherwise use the normal name. No functional
|
||||
or code changes are done because of this.
|
||||
Use the boards menu to select your model of RP2040 board.
|
||||
|
||||
There is also a `Generic` board which allows you to individually select
|
||||
There is also a `Generic RP2040` board which allows you to individually select
|
||||
things such as flash size or boot2 flash type. Use this if your board isn't
|
||||
yet fully supported and isn't working with the normal `Raspberry Pi Pico`
|
||||
option.
|
||||
|
||||
+12
-7
@@ -2,12 +2,12 @@ Arduino-Pico
|
||||
============
|
||||
|
||||
This is the documentation for the Raspberry Pi Pico Arduino core,
|
||||
Arduino-Pico. Arduino-Pico is a community port of the RP2040
|
||||
(Raspberry Pi Pico processor) to the Arduino ecosystem, intended
|
||||
to make it easier and more fun to use and program the Raspberry Pi
|
||||
Pico / RP2040 based boards.
|
||||
Arduino-Pico. Arduino-Pico is a community port of Arduino to the
|
||||
RP2040 (Raspberry Pi Pico processor) and RP2350 (Raspberry Pi Pico 2
|
||||
processor), intended to make it easier and more fun to use and
|
||||
program the Raspberry Pi Pico / RP2040 / RP2350 based boards.
|
||||
|
||||
This Arduino core uses a custom toolset with GCC 10.3 and Newlib 4.0.0
|
||||
This Arduino core uses a custom toolset with GCC 12.3 and Newlib 4.0.0
|
||||
and doesn't require any system-installed prerequisites.
|
||||
|
||||
For the latest version, always check https://github.com/earlephilhower/arduino-pico
|
||||
@@ -26,7 +26,7 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
|
||||
|
||||
Pin (Re)Assignment <pins>
|
||||
|
||||
RP2040 Helper <rp2040>
|
||||
RP2040/RP2350 Helper <rp2040>
|
||||
|
||||
Analog I/O <analog>
|
||||
Digital I/O <digital>
|
||||
@@ -44,9 +44,14 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
|
||||
USB (Arduino and Adafruit_TinyUSB) <usb>
|
||||
Multicore Processing <multicore>
|
||||
|
||||
Bluetooth (Alpha/Beta) <bluetooth>
|
||||
RP2350 PSRAM <psram>
|
||||
|
||||
Bluetooth <bluetooth>
|
||||
Bluetooth HID Master <hidmaster>
|
||||
Bluetooth Audio (A2DP) <a2dp>
|
||||
|
||||
Single File USB Drive <singlefile>
|
||||
FatFSUSB - full FS access over USB <fatfsusb>
|
||||
|
||||
FreeRTOS SMP (multicore) <freertos>
|
||||
|
||||
|
||||
+5
-11
@@ -26,9 +26,7 @@ Arduino IDE Installation Warning
|
||||
the actual Arduino application because it has issues detecting attached Pico
|
||||
boards. Use the "Windows ZIP" or plain "Windows" executable (EXE) download
|
||||
direct from https://arduino.cc. and allow it to install any device drivers
|
||||
it suggests. Otherwise the Pico board may not be detected. Also, if trying
|
||||
out the 2.0 beta Arduino please install the release 1.8 version beforehand
|
||||
to ensure needed device drivers are present.
|
||||
it suggests. Otherwise the Pico board may not be detected.
|
||||
|
||||
**Note for Linux Users**: If you installed the Arduino IDE using Flatpak, which
|
||||
is common in Pop!_OS, Fedora, and Mint, among others, you may need to configure
|
||||
@@ -141,11 +139,13 @@ Uploading Filesystem Images
|
||||
---------------------------
|
||||
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
|
||||
* `IDE 1.x`: https://github.com/earlephilhower/arduino-pico-littlefs-plugin/releases
|
||||
* `IDE 2.x`: https://github.com/earlephilhower/arduino-littlefs-upload/releases
|
||||
|
||||
To install, follow the directions in
|
||||
|
||||
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
|
||||
* `IDE 1.x`: https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
|
||||
* `IDE 2.x`: https://github.com/earlephilhower/arduino-littlefs-upload/blob/main/README.md
|
||||
|
||||
For detailed usage information, please check the repo documentation available at
|
||||
|
||||
@@ -159,12 +159,6 @@ So for the first sketch you will need to rebuild (with the ``Upload Method->Pico
|
||||
|
||||
After the initial upload, as long as the running binary was built using the ``Picotool`` upload method, then the normal upload process should work.
|
||||
|
||||
Under MacOS, it may be necessary to install the USB support libraries from a command terminal before the ``Picotool`` upload method can be used:
|
||||
|
||||
.. code::
|
||||
|
||||
brew install libusb
|
||||
|
||||
For Ubuntu and other Linux operating systems you may need to add the following lines to a new `udev` config file(``99-picotool.rules``) to allow normal users to access the special USB device the Pico exports:
|
||||
|
||||
.. code::
|
||||
|
||||
+28
-2
@@ -16,11 +16,32 @@ not necessarily simultaneously!).
|
||||
See the ``Multicore.ino`` example in the ``rp2040`` example directory for a
|
||||
quick introduction.
|
||||
|
||||
Stack Sizes
|
||||
-----------
|
||||
|
||||
When the Pico is running in single core mode, core 0 has the full 8KB of stack
|
||||
space available to it. When using multicore ``setup1``/``loop1`` the 8KB is split
|
||||
into two 4K stacks, one per core. It is possible for core 0's stack to overwrite
|
||||
core 1's stack in this case, if you go beyond the 4K limitation.
|
||||
|
||||
To allocate a separate 8K stack for core 1, resulting in 8K stacks being available
|
||||
for both cores, simply define the following variable in your sketch and set it
|
||||
to ``true``:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
bool core1_separate_stack = true;
|
||||
|
||||
Pausing Cores
|
||||
-------------
|
||||
|
||||
Sometimes an application needs to pause the other core on chip (i.e. it is
|
||||
writing to flash or needs to stop processing while some other event occurs).
|
||||
In most cases, however, these calls are **SHOULD NOT BE USED**. To synchronize
|
||||
cross-core operations use normal multiprocessor methods such as circular buffers,
|
||||
global ``volatile`` flags, mutexes, and the like. Stopping a core has massive
|
||||
implications and can kill networking and USB communications if done too long or
|
||||
too frequently.
|
||||
|
||||
void rp2040.idleOtherCore()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -53,7 +74,12 @@ Communicating Between Cores
|
||||
The RP2040 provides a hardware FIFO for communicating between cores, but it
|
||||
is used exclusively for the idle/resume calls described above. Instead, please
|
||||
use the following functions to access a software-managed, multicore safe
|
||||
FIFO.
|
||||
FIFO. There are two FIFOs, one written to by core 0 and read by core 1, and
|
||||
the other written to by core 1 and read by core 0.
|
||||
|
||||
You can (and probably should) use shared memory (such as ``volatile`` globals)
|
||||
or other normal multiprocessor communication algorithms to transfer data or
|
||||
work between cores, but for simple tasks these FIFO routines can suffice.
|
||||
|
||||
void rp2040.fifo.push(uint32_t)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -80,4 +106,4 @@ Reads a value from this core's FIFO and places it in dest. Will return
|
||||
int rp2040.fifo.available()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Returns the number of values available in this core's FIFO.
|
||||
Returns the number of values available to read in this core's FIFO.
|
||||
|
||||
+5
-4
@@ -1,6 +1,7 @@
|
||||
OTA Updates
|
||||
===========
|
||||
|
||||
**NOTE:** OTA is not yet supported on the RP2350. PRs gladly accepted!
|
||||
|
||||
Introduction
|
||||
------------
|
||||
@@ -12,7 +13,7 @@ OTA may be done using:
|
||||
- `Arduino IDE <#arduino-ide>`__
|
||||
- `Web Browser <#web-browser>`__
|
||||
- `HTTP Server <#http-server>`__
|
||||
- Any other method (ZModen receive over a UART port, etc.) by using the ``Updater`` object in your sketch
|
||||
- Any other method (ZModem receive over a UART port, etc.) by using the ``Updater`` object in your sketch
|
||||
|
||||
The Arduino IDE option is intended primarily for the software development phase. The other two options would be more useful after deployment, to provide the module with application updates either manually with a web browser, or automatically using an HTTP server.
|
||||
|
||||
@@ -189,7 +190,7 @@ Uploading modules wirelessly from Arduino IDE is intended for the following typi
|
||||
|
||||
To upload wirelessly from the IDE:
|
||||
|
||||
1. Build a sketch starts ``WiFi`` and includes the appropriate calls to ``ArduinoOTA`` (see the examples for reference). These include the ``ArduinoOTA.begin()`` call in ``setup()`` and periodically calling ``ArduinoOTA.handle();`` from the ``loop()``
|
||||
1. Build a sketch that starts ``WiFi`` and includes the appropriate calls to ``ArduinoOTA`` (see the examples for reference). These include the ``ArduinoOTA.begin()`` call in ``setup()`` and periodically calling ``ArduinoOTA.handle();`` from the ``loop()``
|
||||
|
||||
2. Upload using standard USB connection the first time.
|
||||
|
||||
@@ -212,9 +213,9 @@ Before implementing it in your sketch, it is a good idea to check how it works u
|
||||
|
||||
Enter the password and upload should be initiated as usual with the only difference being ``Authenticating...OK`` message visible in the upload log.
|
||||
|
||||
You will not be prompted for a reentering the same password next time. Arduino IDE will remember it for you. You will see a prompt for password only after reopening IDE, or if you change it in your sketch, upload the sketch and then try to upload it again.
|
||||
You will not be prompted for a reentering the same password next time. Arduino IDE will remember it for you. You will see a prompt for password only after reopening the IDE, or if you change it in your sketch, upload the sketch and then try to upload it again.
|
||||
|
||||
Please note, it is possible to reveal password entered previously in Arduino IDE, if IDE has not been closed since last upload. This can be done by enabling *Show verbose output during: upload* in *File > Preferences* and attempting to upload the module.
|
||||
Please note, it is possible to reveal password entered previously in Arduino IDE, if the IDE has not been closed since last upload. This can be done by enabling *Show verbose output during: upload* in *File > Preferences* and attempting to upload the module.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ 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 );
|
||||
|
||||
+400
-401
@@ -1,401 +1,400 @@
|
||||
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 the `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.
|
||||
|
||||
Important steps for Windows users, before installing
|
||||
----------------------------------------------------
|
||||
|
||||
By default, Windows has a limited path length that is not long enough to fully clone the ``Pico-SDK``'s ``tinyusb`` repository, resulting in error messages like the one below while attempting to fetch the repository.
|
||||
|
||||
.. code::
|
||||
|
||||
error: unable to create file '.....' : Filename too long
|
||||
|
||||
To work around this requires performing two steps and rebooting Windows once. These steps will enable longer file paths at the Windows OS and the ``git`` level.
|
||||
|
||||
Step 1: Enabling long paths in git
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Open up a Windows ``cmd`` or ``terminal`` window and execute the following command
|
||||
|
||||
.. code::
|
||||
|
||||
git config --system core.longpaths true
|
||||
|
||||
Step 2: Enabling long paths in the Windows OS
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
(taken from https://www.microfocus.com/documentation/filr/filr-4/filr-desktop/t47bx2ogpfz7.html)
|
||||
|
||||
1. Click Window key and type gpedit.msc, then press the Enter key. This launches the Local Group Policy Editor.
|
||||
|
||||
2. Navigate to Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem.
|
||||
|
||||
3. Double click Enable NTFS/Win32 long paths and close the dialog.
|
||||
|
||||
.. image:: images/longpath.png
|
||||
|
||||
|
||||
Step 3: Reboot the computer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once the two prior stages are complete, please do a full reboot or power cycle so that the new settings will take effect.
|
||||
|
||||
|
||||
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 once `this pull request <https://github.com/platformio/platform-raspberrypi/pull/36>`_ is merged.
|
||||
|
||||
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 and switch to the new core.
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[env:pico]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
board = pico
|
||||
framework = arduino
|
||||
board_build.core = earlephilhower
|
||||
|
||||
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.
|
||||
|
||||
Deprecation warnings
|
||||
---------------------
|
||||
|
||||
Previous versions of this documentation told users to inject the framework and toolchain package into the project by using
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; 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
|
||||
|
||||
This is now **deprecated** and should not be done anymore. Users should delete these ``platform_packages`` lines and update the platform integration by issuing the command
|
||||
|
||||
.. code:: bash
|
||||
|
||||
pio pkg update -g -p https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
|
||||
in the `PlatformIO CLI <https://docs.platformio.org/en/latest/integration/ide/vscode.html#platformio-core-cli>`_. The same can be achieved by using the VSCode PIO Home -> Platforms -> Updates GUI.
|
||||
|
||||
The toolchain, which was also renamed to ``toolchain-rp2040-earlephilhower`` is downloaded automatically from the registry. The same goes for the ``framework-arduinopico`` toolchain package, which points directly to the Arduino-Pico Github repository.
|
||||
However, users can still select a custom fork or branch of the core if desired so, as detailed in a chapter below.
|
||||
|
||||
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 (which are only
|
||||
``board = pico`` and ``board = nanorp2040connect``), 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>`__.
|
||||
|
||||
When using Arduino-Pico-only boards like ``board = rpipico`` or ``board = adafruit_feather``, this is not needed.
|
||||
|
||||
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
|
||||
|
||||
C++ Exceptions
|
||||
--------------
|
||||
|
||||
Exceptions are disabled by default. To enable them, use
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Enable Exceptions
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_EXCEPTIONS
|
||||
|
||||
Stack Protector
|
||||
---------------
|
||||
|
||||
To enable GCC's stack protection feature, use
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Enable Stack Protector
|
||||
build_flags = -fstack-protector
|
||||
|
||||
|
||||
RTTI
|
||||
----
|
||||
|
||||
RTTI (run-time type information) is disabled by default. To enable it, use
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Enable RTTI
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_RTTI
|
||||
|
||||
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``.
|
||||
|
||||
IP Stack
|
||||
---------
|
||||
|
||||
The lwIP stack can be configured to support only IPv4 (default) or additionally IPv6. To activate IPv6 support, add
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; IPv6
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6
|
||||
|
||||
to the ``platformio.ini``.
|
||||
|
||||
Bluetooth Stack
|
||||
---------------
|
||||
|
||||
The Bluetooth Classic (BTC) and Bluetooth Low Energy (BLE) stack can be activated by adding
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; BTC and BLE
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
|
||||
|
||||
to the ``platformio.ini``.
|
||||
|
||||
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://`` and ``symlink://`` pseudo-protocols can also be used instead of ``https://`` to point to a
|
||||
local copy of the core (with e.g. some modifications) on disk (`see documentation <https://docs.platformio.org/en/latest/core/userguide/pkg/cmd_install.html?#local-folder>`_).
|
||||
|
||||
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 can use both Arduino cores -- we select Arduino-Pico here
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
With recent updates to the toolchain and OpenOCD, debugging firmwares is also possible.
|
||||
|
||||
To specify the debugging adapter, use ``debug_tool`` (`documentation <https://docs.platformio.org/en/latest/projectconf/section_env_debug.html#debug-tool>`_). Supported values are:
|
||||
|
||||
* ``picoprobe``
|
||||
* ``cmsis-dap``
|
||||
* ``jlink``
|
||||
* ``raspberrypi-swd``
|
||||
* ``blackmagic``
|
||||
* ``pico-debug``
|
||||
|
||||
These values can also be used in ``upload_protocol`` if you want PlatformIO to upload the regular firmware through this method, which you likely want.
|
||||
|
||||
Especially the PicoProbe method is convenient when you have two Raspberry Pi Pico boards. One of them can be flashed with the PicoProbe firmware (`documentation <https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#debugging-using-another-raspberry-pi-pico>`__) and is then connected to the target Raspberry Pi Pico board (see `documentation <https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf>`__ chapter "Picoprobe Wiring"). Remember that on Windows, you have to use `Zadig <https://zadig.akeo.ie/>`_ to also load "WinUSB" drivers for the "Picoprobe (Interface 2)" device so that OpenOCD can speak to it.
|
||||
|
||||
.. note::
|
||||
Newer PicoProbe firmware versions have dropped the proprietary "PicoProbe" USB communication protocol and emulate a **CMSIS-DAP** instead. Meaning, you have to use ``debug_tool = cmsis-dap`` for these newer firmwares, such as those obtained from `raspberrypi/picoprobe <https://github.com/raspberrypi/picoprobe/releases>`__
|
||||
|
||||
With that set up, debugging can be started via the left debugging sidebar and works nicely: Setup breakpoints, inspect the value of variables in the code, step through the code line by line. When a breakpoint is hit or execution is halted, you can even see the execution state both Cortex-M0+ cores of the RP2040.
|
||||
|
||||
.. image:: images/pio_debugging.png
|
||||
|
||||
For further information on customizing debug options, like the initial breakpoint or debugging / SWD speed, consult `the documentation <https://docs.platformio.org/en/latest/projectconf/section_env_debug.html>`_.
|
||||
|
||||
.. note::
|
||||
For the BlackMagicProbe debugging probe (as can be e.g., created by simply flashing a STM32F103C8 "Bluepill" board), you currently have to use the branch ``fix/rp2040-flash-reliability`` (or at least commit ``1d001bc``) **and** use the `official ARM provided toolchain <https://github.com/blackmagic-debug/blackmagic/issues/1364#issuecomment-1503393266>`_.
|
||||
|
||||
You can obtain precompiled binaries from `here <https://github.com/blackmagic-debug/blackmagic/issues/1364#issuecomment-1503372723>`__. A flashing guide is available `here <https://primalcortex.wordpress.com/2017/06/13/building-a-black-magic-debug-probe/>`__. You then have to configure the target serial port ("GDB port") in your project per `documentation <https://docs.platformio.org/en/latest/plus/debug-tools/blackmagic.html#debugging-tool-blackmagic>`__.
|
||||
|
||||
.. note::
|
||||
For the pico-debug (`download <https://github.com/majbthrd/pico-debug/releases>`__) debugging way, *which needs to no additional debug probe*, add this snippet to your ``platformio.ini`` and follow the given procedure:
|
||||
|
||||
.. code:: ini
|
||||
|
||||
upload_protocol = pico-debug
|
||||
debug_tool = pico-debug
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB
|
||||
|
||||
1. Build your firmware normally
|
||||
2. Plug in the Pico in BOOTSEL mode
|
||||
3. Drag and drop your ``.pio/build/<env>/firmware.uf2`` onto the boot drive
|
||||
4. Unplug and replug your Pico back into BOOTSEL mode for the second time
|
||||
5. Drag and drop the downloaded ``pico-debug-gimmecache.uf2`` file onto the boot drive
|
||||
6. A CMSIS-DAP device should now appear on your computer
|
||||
7. Start debugging via the debug sidebar as normal
|
||||
|
||||
Note the restrictions: The second core cannot be used, the USB port cannot be used (no USB serial, only UART serial), 16KB less RAM is available.
|
||||
|
||||
Filesystem Uploading
|
||||
--------------------
|
||||
|
||||
For the Arduino IDE, `a plugin <https://github.com/earlephilhower/arduino-pico#uploading-filesystem-images>`_ is available that enables a data folder to be packed as a LittleFS filesystem binary and uploaded to the Pico.
|
||||
|
||||
This functionality is also built-in in the PlatformIO integration. Open the `project tasks <https://docs.platformio.org/en/latest/integration/ide/vscode.html#project-tasks>`_ and expand the "Platform" tasks:
|
||||
|
||||
.. image:: images/pio_fs_upload.png
|
||||
|
||||
The files you want to upload should be placed in a folder called ``data`` inside the project. This can be customized `if needed <https://docs.platformio.org/en/latest/projectconf/section_platformio.html#data-dir>`_.
|
||||
|
||||
The task "Build Filesystem Image" will take all files in the data directory and create a ``littlefs.bin`` file from it using the ``mklittlefs`` tool.
|
||||
|
||||
The task "Upload Filesystem Image" will upload the filesystem image to the Pico via the specified ``upload_protocol``.
|
||||
|
||||
.. note::
|
||||
Set the space available for the filesystem in the ``platformio.ini`` using e.g., ``board_build.filesystem_size = 0.5m``, or filesystem
|
||||
creation will fail!
|
||||
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 the `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.
|
||||
|
||||
Important steps for Windows users, before installing
|
||||
----------------------------------------------------
|
||||
|
||||
By default, Windows has a limited path length that is not long enough to fully clone the ``Pico-SDK``'s ``tinyusb`` repository, resulting in error messages like the one below while attempting to fetch the repository.
|
||||
|
||||
.. code::
|
||||
|
||||
error: unable to create file '.....' : Filename too long
|
||||
|
||||
To work around this requires performing two steps and rebooting Windows once. These steps will enable longer file paths at the Windows OS and the ``git`` level.
|
||||
|
||||
Step 1: Enabling long paths in git
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Open up a Windows ``cmd`` or ``terminal`` window and execute the following command
|
||||
|
||||
.. code::
|
||||
|
||||
git config --system core.longpaths true
|
||||
|
||||
Step 2: Enabling long paths in the Windows OS
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
(taken from https://www.microfocus.com/documentation/filr/filr-4/filr-desktop/t47bx2ogpfz7.html)
|
||||
|
||||
1. Click Window key and type gpedit.msc, then press the Enter key. This launches the Local Group Policy Editor.
|
||||
|
||||
2. Navigate to Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem.
|
||||
|
||||
3. Double click Enable NTFS/Win32 long paths and close the dialog.
|
||||
|
||||
.. image:: images/longpath.png
|
||||
|
||||
|
||||
Step 3: Reboot the computer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once the two prior stages are complete, please do a full reboot or power cycle so that the new settings will take effect.
|
||||
|
||||
|
||||
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 once `this pull request <https://github.com/platformio/platform-raspberrypi/pull/36>`_ is merged.
|
||||
|
||||
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 and switch to the new core.
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[env:pico]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
board = pico
|
||||
framework = arduino
|
||||
board_build.core = earlephilhower
|
||||
|
||||
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.
|
||||
|
||||
Deprecation warnings
|
||||
---------------------
|
||||
|
||||
Previous versions of this documentation told users to inject the framework and toolchain package into the project by using
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; 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
|
||||
|
||||
This is now **deprecated** and should not be done anymore. Users should delete these ``platform_packages`` lines and update the platform integration by issuing the command
|
||||
|
||||
.. code:: bash
|
||||
|
||||
pio pkg update -g -p https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
|
||||
in the `PlatformIO CLI <https://docs.platformio.org/en/latest/integration/ide/vscode.html#platformio-core-cli>`_. The same can be achieved by using the VSCode PIO Home -> Platforms -> Updates GUI.
|
||||
|
||||
The toolchain, which was also renamed to ``toolchain-rp2040-earlephilhower`` is downloaded automatically from the registry. The same goes for the ``framework-arduinopico`` toolchain package, which points directly to the Arduino-Pico Github repository.
|
||||
However, users can still select a custom fork or branch of the core if desired so, as detailed in a chapter below.
|
||||
|
||||
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 (which are only
|
||||
``board = pico`` and ``board = nanorp2040connect``), 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>`__.
|
||||
|
||||
When using Arduino-Pico-only boards like ``board = rpipico`` or ``board = adafruit_feather``, this is not needed.
|
||||
|
||||
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 single 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
|
||||
|
||||
C++ Exceptions
|
||||
--------------
|
||||
|
||||
Exceptions are disabled by default. To enable them, use
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Enable Exceptions
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_EXCEPTIONS
|
||||
|
||||
Stack Protector
|
||||
---------------
|
||||
|
||||
To enable GCC's stack protection feature, use
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Enable Stack Protector
|
||||
build_flags = -fstack-protector
|
||||
|
||||
|
||||
RTTI
|
||||
----
|
||||
|
||||
RTTI (run-time type information) is disabled by default. To enable it, use
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; Enable RTTI
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_RTTI
|
||||
|
||||
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``.
|
||||
|
||||
IP Stack
|
||||
--------
|
||||
|
||||
The lwIP stack can be configured to support only IPv4 (default) or additionally IPv6. To activate IPv6 support, add
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; IPv6
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6
|
||||
|
||||
to the ``platformio.ini``.
|
||||
|
||||
Bluetooth Stack
|
||||
---------------
|
||||
|
||||
The Bluetooth Classic (BTC) and Bluetooth Low Energy (BLE) stack can be activated by adding
|
||||
|
||||
.. code:: ini
|
||||
|
||||
; BTC and BLE
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
|
||||
|
||||
to the ``platformio.ini``.
|
||||
|
||||
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://`` and ``symlink://`` pseudo-protocols can also be used instead of ``https://`` to point to a
|
||||
local copy of the core (with e.g. some modifications) on disk (`see documentation <https://docs.platformio.org/en/latest/core/userguide/pkg/cmd_install.html?#local-folder>`_).
|
||||
|
||||
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 can use both Arduino cores -- we select Arduino-Pico here
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
With recent updates to the toolchain and OpenOCD, debugging firmwares is also possible.
|
||||
|
||||
To specify the debugging adapter, use ``debug_tool`` (`documentation <https://docs.platformio.org/en/latest/projectconf/section_env_debug.html#debug-tool>`_). Supported values are:
|
||||
|
||||
* ``picoprobe``
|
||||
* ``cmsis-dap``
|
||||
* ``jlink``
|
||||
* ``raspberrypi-swd``
|
||||
* ``blackmagic``
|
||||
* ``pico-debug``
|
||||
|
||||
These values can also be used in ``upload_protocol`` if you want PlatformIO to upload the regular firmware through this method, which you likely want.
|
||||
|
||||
Especially the PicoProbe method is convenient when you have two Raspberry Pi Pico boards. One of them can be flashed with the PicoProbe firmware (`documentation <https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#debugging-using-another-raspberry-pi-pico>`__) and is then connected to the target Raspberry Pi Pico board (see `documentation <https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf>`__ chapter "Picoprobe Wiring"). Remember that on Windows, you have to use `Zadig <https://zadig.akeo.ie/>`_ to also load "WinUSB" drivers for the "Picoprobe (Interface 2)" device so that OpenOCD can speak to it.
|
||||
|
||||
.. note::
|
||||
Newer PicoProbe firmware versions have dropped the proprietary "PicoProbe" USB communication protocol and emulate a **CMSIS-DAP** instead. Meaning, you have to use ``debug_tool = cmsis-dap`` for these newer firmwares, such as those obtained from `raspberrypi/picoprobe <https://github.com/raspberrypi/picoprobe/releases>`__
|
||||
|
||||
With that set up, debugging can be started via the left debugging sidebar and works nicely: Setup breakpoints, inspect the value of variables in the code, step through the code line by line. When a breakpoint is hit or execution is halted, you can even see the execution state both Cortex-M0+ cores of the RP2040.
|
||||
|
||||
.. image:: images/pio_debugging.png
|
||||
|
||||
For further information on customizing debug options, like the initial breakpoint or debugging / SWD speed, consult `the documentation <https://docs.platformio.org/en/latest/projectconf/section_env_debug.html>`_.
|
||||
|
||||
.. note::
|
||||
For the BlackMagicProbe debugging probe (as can be e.g., created by simply flashing a STM32F103C8 "Bluepill" board), you currently have to use the branch ``fix/rp2040-flash-reliability`` (or at least commit ``1d001bc``) **and** use the `official ARM provided toolchain <https://github.com/blackmagic-debug/blackmagic/issues/1364#issuecomment-1503393266>`_.
|
||||
|
||||
You can obtain precompiled binaries from `here <https://github.com/blackmagic-debug/blackmagic/issues/1364#issuecomment-1503372723>`__. A flashing guide is available `here <https://primalcortex.wordpress.com/2017/06/13/building-a-black-magic-debug-probe/>`__. You then have to configure the target serial port ("GDB port") in your project per `documentation <https://docs.platformio.org/en/latest/plus/debug-tools/blackmagic.html#debugging-tool-blackmagic>`__.
|
||||
|
||||
.. note::
|
||||
For the pico-debug (`download <https://github.com/majbthrd/pico-debug/releases>`__) debugging way, *which needs no additional debug probe*, add this snippet to your ``platformio.ini`` and follow the given procedure:
|
||||
|
||||
.. code:: ini
|
||||
|
||||
upload_protocol = pico-debug
|
||||
debug_tool = pico-debug
|
||||
build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB
|
||||
|
||||
1. Build your firmware normally
|
||||
2. Plug in the Pico in BOOTSEL mode
|
||||
3. Drag and drop your ``.pio/build/<env>/firmware.uf2`` onto the boot drive
|
||||
4. Unplug and replug your Pico back into BOOTSEL mode for the second time
|
||||
5. Drag and drop the downloaded ``pico-debug-gimmecache.uf2`` file onto the boot drive
|
||||
6. A CMSIS-DAP device should now appear on your computer
|
||||
7. Start debugging via the debug sidebar as normal
|
||||
|
||||
Note the restrictions: The second core cannot be used, the USB port cannot be used (no USB serial, only UART serial), 16KB less RAM is available.
|
||||
|
||||
Filesystem Uploading
|
||||
--------------------
|
||||
|
||||
For the Arduino IDE, `a plugin <https://github.com/earlephilhower/arduino-pico#uploading-filesystem-images>`_ is available that enables a data folder to be packed as a LittleFS filesystem binary and uploaded to the Pico.
|
||||
|
||||
This functionality is also built-in in the PlatformIO integration. Open the `project tasks <https://docs.platformio.org/en/latest/integration/ide/vscode.html#project-tasks>`_ and expand the "Platform" tasks:
|
||||
|
||||
.. image:: images/pio_fs_upload.png
|
||||
|
||||
The files you want to upload should be placed in a folder called ``data`` inside the project. This can be customized `if needed <https://docs.platformio.org/en/latest/projectconf/section_platformio.html#data-dir>`_.
|
||||
|
||||
The task "Build Filesystem Image" will take all files in the data directory and create a ``littlefs.bin`` file from it using the ``mklittlefs`` tool.
|
||||
|
||||
The task "Upload Filesystem Image" will upload the filesystem image to the Pico via the specified ``upload_protocol``.
|
||||
|
||||
.. note::
|
||||
Set the space available for the filesystem in the ``platformio.ini`` using e.g., ``board_build.filesystem_size = 0.5m``, or filesystem creation will fail!
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
RP2350 PSRAM Support
|
||||
====================
|
||||
|
||||
The RP2350 chip in the Raspberry Pi Pico 2, and other RP2350 boards,
|
||||
supports an external interface to PSRAM. When a PSRAM chip is attached
|
||||
to the processor (please note that there is none on the Pico 2 board, but
|
||||
iLabs and SparkFun boards, among others, do have it), up to 16 megabytes
|
||||
of additional memory can be used by the chip.
|
||||
|
||||
While this external RAM is slower than the built-in SRAM, it is still
|
||||
able to be used in any place where normal RAM would be used (other than
|
||||
for memory-mapped functions and statically initialized variables).
|
||||
|
||||
When present, PSRAM can be used in two ways: for specific instantiated
|
||||
variables, or through a ``malloc``-like access method. Both can be used
|
||||
in any single application.
|
||||
|
||||
Using PSRAM for regular variables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Similar to ``PROGMEM`` in the original Arduino AVR devices, the variable
|
||||
decorator ``PSRAM`` can be added to map a variable into PSRAM. Simply add
|
||||
``PSRAM`` to an array and it will be mapped into PSRAM:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
...
|
||||
float weights[4000] PSRAM; // Place an array of 4000 floats in PSRAM
|
||||
char samplefile[1'000'000] PSRAM; // Allocate 1M for WAV samples in PSRAM
|
||||
...
|
||||
|
||||
These variables can be used just like normal ones, no special handling is
|
||||
required. For example:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
char buff[4 *1024 * 1024]; // 4MB array
|
||||
|
||||
void initBuff() {
|
||||
bzero(buff, sizeof(buff));
|
||||
for (int i = 0; i < 4 *1024 * 1024; i += 4096) {
|
||||
buff[i] = rand();
|
||||
}
|
||||
}
|
||||
|
||||
The only restriction is that these variables may not be initialized statically.
|
||||
The following example will **NOT** work:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
char buff[] = "This is illegal and will not function";
|
||||
|
||||
Using PSRAM for dynamic allocations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
PSRAM can also be used as a heap for dynamica allocations using ``pmalloc`` and
|
||||
``pcalloc``. These calls function exactly like normal ``malloc`` and ``calloc``
|
||||
except they allocate space from PSRAM.
|
||||
|
||||
Simply replace a ``malloc`` or ``calloc`` with ``pmalloc`` or ``pcalloc`` to use
|
||||
the PSRAM heap. Other calls, such as ``free`` and ``realloc`` "just work" and do
|
||||
not need to be modified (they check where the passed-in pointer resides and
|
||||
do the right thing automatically).
|
||||
|
||||
For example, to create and modify large buffer in PSRAM:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
void ex() {
|
||||
int *buff;
|
||||
// Ignoring OOM error conditions in example for brevity
|
||||
buff = (int *)pmalloc(10000 * sizeof(*buff));
|
||||
// Something happened and we need more space, so...
|
||||
buff = (int *)realloc(buff, 20000 * sizeof(*buff)); // buff now has 20K elements
|
||||
for (int i = 0; i < 20000; i++) {
|
||||
buff[i] = i;
|
||||
}
|
||||
// Do some work, now we're done
|
||||
free(buff);
|
||||
}
|
||||
|
||||
C++ objects can be allocated in PSRAM using "placement new" constructors. Note that
|
||||
this will only place immediate object data in PSRAM: if the object creates any other
|
||||
objects via ``new`` *those* objects will be placed in normal RAM unless the object
|
||||
also uses placement new constructors.
|
||||
|
||||
|
||||
|
||||
Checking on PSRAM space
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``rp2040`` helper object has the following calls to return the state of the
|
||||
PSRAM heap with the following calls, similar to the normal RAM heap:
|
||||
|
||||
int rp2040.getPSRAMSize()
|
||||
-------------------------
|
||||
|
||||
Return the total size of the attached PSRAM chip. This is the **RAW** space and
|
||||
does not take into account any allocations for static variables or dynamic
|
||||
allocations. (i.e. it will return 1, 2, 4, 8, or 16MV depending on the chip).
|
||||
|
||||
int rp2040.getTotalPSRAMHeap()
|
||||
------------------------------
|
||||
|
||||
Returns the total PSRAM heap (free and used) available or used for ``pmalloc``
|
||||
allocations.
|
||||
|
||||
int rp2040.getUsedPSRAMHeap()
|
||||
-----------------------------
|
||||
|
||||
Returns the total used bytes (including any overhead) of the PSRAM heap.
|
||||
|
||||
int getFreePSRAMHeap()
|
||||
----------------------
|
||||
|
||||
Returns the total free bytes in the PSRAM heap. (Note that this may include
|
||||
multiple non-contiguous chunks, so this is not always the maximum block size
|
||||
that can be allocated.)
|
||||
@@ -99,3 +99,13 @@ bootloader.
|
||||
void rp2040.rebootToBootloader()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Will reboot the RP2040 into USB UF2 upload mode.
|
||||
|
||||
DMA-based MEMCPY
|
||||
----------------
|
||||
The onboard DMA engines can copy 4-byte aligned quantities faster than the CPU.
|
||||
|
||||
void \*rp2040.memcpyDMA(void \*dest, const void \*src, size_t count);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Uses a DMA engine to transfer data from src to dest in 4-byte chunks without CPU
|
||||
intervention. If any arguments are not 4-byte aligned, or if the count is not a
|
||||
multiple of 4, then it will fall back to CPU-managed memcpy.
|
||||
|
||||
@@ -55,3 +55,13 @@ void Serial.ignoreFlowControl(bool ignore)
|
||||
In some cases, the target application will not assert the DTR virtual line, thus preventing writing operations to succeed.
|
||||
|
||||
For this reason, the SerialUSB::ignoreFlowControl() method disables the connection's state verification, enabling the program to write on the port, even though the data might be lost.
|
||||
|
||||
bool Serial.dtr()
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Returns the current state of the DTR virtual line. A USB CDC host (such as the Arduino serial monitor) typically raises the DTR pin when opening the device, and may lower it when closing the device.
|
||||
|
||||
bool Serial.rts()
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Returns the current state of the RTS virtual line.
|
||||
|
||||
+35
-3
@@ -8,10 +8,10 @@ SPI pinouts can be set **before SPI.begin()** using the following calls:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
bool setRX(pin_size_t pin);
|
||||
bool setRX(pin_size_t pin); // or setMISO()
|
||||
bool setCS(pin_size_t pin);
|
||||
bool setSCK(pin_size_t pin);
|
||||
bool setTX(pin_size_t pin);
|
||||
bool setTX(pin_size_t pin); // or setMOSI()
|
||||
|
||||
Note that the ``CS`` pin can be hardware or software controlled by the sketch.
|
||||
When software controlled, the ``setCS()`` call is ignored.
|
||||
@@ -39,7 +39,39 @@ in order to consunme the received data and provide data to transmit.
|
||||
* The callbacks operate at IRQ time and may be called very frequently at high SPI frequencies. So, make then small, fast, and with no memory allocations or locking.
|
||||
|
||||
|
||||
Asynchronous Operation
|
||||
======================
|
||||
|
||||
Applications can use asynchronous SPI calls to allow for processing while long-running SPI transfers are
|
||||
being performed. For example, a game could send a full screen update out over SPI and immediately start
|
||||
processing the next frame without waiting for the first one to be sent. DMA is used to handle
|
||||
the transfer to/from the hardware freeing the CPU from bit-banging or busy waiting.
|
||||
|
||||
Note that asynchronous operations can not be intersped with normal, synchronous ones. ``transferAsync``
|
||||
should still occur after a ``beginTransaction()`` and when ``finishedAsync()`` returns ``true`` then
|
||||
``endTransaction()`` should also be called.
|
||||
|
||||
All buffers need to be valid throughout the entire operation. Read data cannot be accessed until
|
||||
the transaction is completed and can't be "peeked" at while the operation is ongoing.
|
||||
|
||||
bool transferAsync(const void \*send, void \*recv, size_t bytes)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Begins an SPI asynchronous transaction. Either ``send`` or ``recv`` can be ``nullptr`` if data only needs
|
||||
to be transferred in one direction.
|
||||
Check ``finishedAsync()`` to determine when the operation completes and conclude the transaction.
|
||||
This operation needs to allocate a buffer from heap equal to ``bytes`` in size if ``LSBMODE`` is used.
|
||||
|
||||
bool finishedAsync()
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Call to check if the asynchronous operations is completed and the buffer passed in can be either read or
|
||||
reused. Frees the allocated memory and completes the asynchronous transaction.
|
||||
|
||||
void abortAsync()
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Cancels the outstanding asynchronous transaction and frees any allocated memory.
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
See the SPItoMyself example for a complete Master and Slave application.
|
||||
See the SPItoMyself and SPItoMyselfAsync examples for a complete Master and Slave application.
|
||||
|
||||
+16
-1
@@ -14,13 +14,28 @@ from the IDE.
|
||||
The Arduino-Pico core includes ported versions of the basic Arduino
|
||||
``Keyboard``, ``Mouse`` and ``Joystick`` libraries. These libraries
|
||||
allow you to emulate a keyboard, a gamepad or mouse (or all together)
|
||||
with the Pico in your sketches.
|
||||
with the Pico in your sketches. These libraries only are available
|
||||
when using the built-in USB, not the Adafruit library.
|
||||
|
||||
See the examples and Arduino Reference at
|
||||
https://www.arduino.cc/reference/en/language/functions/usb/keyboard/
|
||||
and
|
||||
https://www.arduino.cc/reference/en/language/functions/usb/mouse
|
||||
|
||||
HID Polling Interval
|
||||
--------------------
|
||||
By default, HID devices will request to be polled every 10ms (i.e. 100x
|
||||
per second). If you have a higher performance need, you can override
|
||||
this value by creating a global variable in your main application, set
|
||||
to the polling period:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
int usb_hid_poll_interval = 1; // Set HID poll interval to 1ms (1kHz)
|
||||
void setup() {
|
||||
....
|
||||
}
|
||||
|
||||
Adafruit TinyUSB Arduino Support
|
||||
--------------------------------
|
||||
Examples are provided in the Adafruit_TinyUSB_Arduino for the more
|
||||
|
||||
+3
-1
@@ -42,7 +42,9 @@ Please note that WiFi on the Pico W is a work-in-progress and there are some imp
|
||||
|
||||
* Multicore is supported, but only core 0 may run ``WiFi`` related code.
|
||||
|
||||
* FreeRTOS is supported only on core 0 and from within ``setup`` and ``loop`, not tasks, due to the requirement for a very different LWIP implementation. PRs always appreciated!
|
||||
* FreeRTOS is supported only on core 0 and from within ``setup`` and ``loop``, not tasks, due to the requirement for a very different LWIP implementation. PRs always appreciated!
|
||||
|
||||
* LEAmDNS (``MDNS``) is not supported in FreeRTOS due to internal IRQ-time memory allocations.
|
||||
|
||||
The WiFi library borrows much work from the `ESP8266 Arduino Core <https://github.com/esp8266/Arduino>`__ , especially the ``WiFiClient`` and ``WiFiServer`` classes.
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ NTP allows the Pico to set its internal clock using the internet, and is
|
||||
required for secure connections because the certificates used have valid
|
||||
date stamps.
|
||||
|
||||
After ``WiFi.begin()`` use ``NTP.begin(s1)`` or ``NTP,begin(s1, s2)`` to
|
||||
After ``WiFi.begin()`` use ``NTP.begin(s1)`` or ``NTP.begin(s1, s2)`` to
|
||||
use one or two NTP servers (common ones are ``pool.ntp.org`` and
|
||||
``time.nist.gov``) .
|
||||
|
||||
|
||||
+39
-1
@@ -20,7 +20,45 @@ diagram for your board, or it won't work.
|
||||
Other than that, the API is compatible with the Arduino standard.
|
||||
Both master and slave operation are supported.
|
||||
|
||||
Master transmissions are buffered (up to 128 bytes) and only performed
|
||||
Master transmissions are buffered (up to 256 bytes) and only performed
|
||||
on ``endTransmission``, as is standard with modern Arduino Wire implementations.
|
||||
|
||||
For more detailed information, check the `Arduino Wire documentation <https://www.arduino.cc/en/reference/wire>`_ .
|
||||
|
||||
Asynchronous Operation
|
||||
----------------------
|
||||
|
||||
Applications can use asynchronous I2C calls to allow for processing while long-running I2C operations are
|
||||
being performed. For example, a game could send a full screen update out over I2C and immediately start
|
||||
processing the next frame without waiting for the first one to be sent over I2C. DMA is used to handle
|
||||
the transfer to/from the I2C hardware freeing the CPU from bit-banging or busy waiting.
|
||||
|
||||
Note that asynchronous operations can not be intersped with normal, synchronous ones. Fully complete an
|
||||
asynchronous operation before attempting to do a normal ``Wire.beginTransaction()`` or ``Wire.requestFrom``.
|
||||
Also, all buffers need to be valid throughout the entire operation. Read data cannot be accessed until
|
||||
the transaction is completed and can't be "peeked" at while the operation is ongoing.
|
||||
|
||||
|
||||
bool writeAsync(uint8_t address, const void \*buffer, size_t bytes, bool sendStop)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Begins an I2C asynchronous write transaction. Writes to ``address`` of ``bytes`` from ``buffer`` and
|
||||
at the end will send an I2C stop if ``sendStop`` is ``true``.
|
||||
Check ``finishedAsync()`` to determine when the operation completes and conclude the transaction.
|
||||
This operation needs to allocate a buffer from heap equal to 2x ``bytes`` in size.
|
||||
|
||||
bool readAsync(uint8_t address, void \*buffer, size_t bytes, bool sendStop)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Begins an I2C asynchronous read transaction. Reads from ``address`` for ``bytes`` into ``buffer`` and
|
||||
at the end will send an I2C stop if ``sendStop`` is ``true``.
|
||||
Check ``finishedAsync()`` to determine when the operation completes and conclude the transaction.
|
||||
This operation needs to allocate a buffer from heap equal to 4x ``bytes`` in size.
|
||||
|
||||
bool finishedAsync()
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Call to check if the asynchronous operations is completed and the buffer passed in can be either read or
|
||||
reused. Frees the allocated memory and completes the asynchronous transaction.
|
||||
|
||||
void abortAsync()
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Cancels the outstanding asynchronous transaction and frees any allocated memory.
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// Do not edit -- Automatically generated by tools/sdk/ssl/bearssl/Makefile
|
||||
#define BEARSSL_GIT f294aa0
|
||||
#define BEARSSL_GIT c2c9d9d
|
||||
|
||||
+17
-21
@@ -1,11 +1,9 @@
|
||||
#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
|
||||
#define _LWIPOPTS_EXAMPLE_COMMONH_H
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
// Critical section protection
|
||||
extern void noInterrupts();
|
||||
extern void interrupts();
|
||||
@@ -13,8 +11,12 @@ extern void interrupts();
|
||||
#define SYS_ARCH_PROTECT(lev) noInterrupts
|
||||
#define SYS_ARCH_UNPROTECT(lev) interrupts
|
||||
|
||||
extern unsigned long get_rand_32(void);
|
||||
#define LWIP_RAND() get_rand_32()
|
||||
extern unsigned long __lwip_rand(void);
|
||||
#define LWIP_RAND() __lwip_rand()
|
||||
|
||||
#ifndef __LWIP_MEMMULT
|
||||
#define __LWIP_MEMMULT 1
|
||||
#endif
|
||||
|
||||
// Common settings used in most of the pico_w examples
|
||||
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)
|
||||
@@ -24,10 +26,10 @@ extern unsigned long get_rand_32(void);
|
||||
#define MEM_LIBC_MALLOC 0
|
||||
|
||||
#define MEM_ALIGNMENT 4
|
||||
#define MEM_SIZE 16384
|
||||
#define MEMP_NUM_TCP_SEG 32
|
||||
#define MEMP_NUM_ARP_QUEUE 10
|
||||
#define PBUF_POOL_SIZE 24
|
||||
#define MEM_SIZE (__LWIP_MEMMULT * 16384)
|
||||
#define MEMP_NUM_TCP_SEG (32)
|
||||
#define MEMP_NUM_ARP_QUEUE (10)
|
||||
#define PBUF_POOL_SIZE (__LWIP_MEMMULT > 1 ? 32 : 24)
|
||||
#define LWIP_ARP 2
|
||||
#define LWIP_ETHERNET 1
|
||||
#define LWIP_ICMP 1
|
||||
@@ -40,12 +42,13 @@ extern unsigned long get_rand_32(void);
|
||||
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||
#define LWIP_NETIF_HOSTNAME 1
|
||||
#define LWIP_NETCONN 0
|
||||
#define LWIP_STATS 0
|
||||
#define LWIP_STATS_DISPLAY 0
|
||||
#define MEM_STATS 0
|
||||
#define SYS_STATS 0
|
||||
#define MEMP_STATS 0
|
||||
#define LINK_STATS 0
|
||||
// #define ETH_PAD_SIZE 2
|
||||
#define LWIP_CHKSUM_ALGORITHM 3
|
||||
#define LWIP_CHKSUM_ALGORITHM 0
|
||||
#define LWIP_DHCP 1
|
||||
#define LWIP_IPV4 1
|
||||
#define LWIP_TCP 1
|
||||
@@ -57,7 +60,8 @@ extern unsigned long get_rand_32(void);
|
||||
#define LWIP_DHCP_DOES_ACD_CHECK 0
|
||||
|
||||
// See #1285
|
||||
#define MEMP_NUM_UDP_PCB 6
|
||||
#define MEMP_NUM_UDP_PCB (__LWIP_MEMMULT * 6)
|
||||
#define MEMP_NUM_TCP_PCB (__LWIP_MEMMULT * 5)
|
||||
|
||||
#if LWIP_IPV6
|
||||
#define LWIP_IPV6_DHCP6 1
|
||||
@@ -70,12 +74,7 @@ extern void __setSystemTime(unsigned long long sec, unsigned long us);
|
||||
//#define SNTP_SERVER_ADDRESS "pool.ntp.org"
|
||||
#define SNTP_SERVER_DNS 1
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define LWIP_DEBUG 1
|
||||
#define LWIP_STATS 1
|
||||
#define LWIP_STATS_DISPLAY 1
|
||||
#endif
|
||||
|
||||
#define LWIP_DEBUG 0
|
||||
#define ETHARP_DEBUG LWIP_DBG_OFF
|
||||
#define NETIF_DEBUG LWIP_DBG_OFF
|
||||
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||
@@ -108,6 +107,3 @@ extern void __setSystemTime(unsigned long long sec, unsigned long us);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#endif /* __LWIPOPTS_H__ */
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
// BTstack features that can be enabled
|
||||
#define ENABLE_LOG_INFO
|
||||
#define ENABLE_LOG_DEBUG
|
||||
#define ENABLE_LOG_ERROR
|
||||
#define ENABLE_PRINTF_HEXDUMP
|
||||
#define ENABLE_SCO_OVER_HCI
|
||||
+2
-1
@@ -4,6 +4,7 @@
|
||||
|
||||
// based on PICO_CONFIG_HEADER_FILES:
|
||||
|
||||
#include "../../pico-sdk/src/boards/include/boards/pico.h"
|
||||
#include "../../pico-sdk/src/boards/include/boards/pico_w.h"
|
||||
#include "../../pico-sdk/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h"
|
||||
|
||||
// based on PICO_RP2040_CONFIG_HEADER_FILES:
|
||||
@@ -11,9 +11,9 @@
|
||||
#ifndef _PICO_VERSION_H
|
||||
#define _PICO_VERSION_H
|
||||
|
||||
#define PICO_SDK_VERSION_MAJOR 1
|
||||
#define PICO_SDK_VERSION_MINOR 5
|
||||
#define PICO_SDK_VERSION_REVISION 1
|
||||
#define PICO_SDK_VERSION_STRING "1.5.1"
|
||||
#define PICO_SDK_VERSION_MAJOR 2
|
||||
#define PICO_SDK_VERSION_MINOR 0
|
||||
#define PICO_SDK_VERSION_REVISION 0
|
||||
#define PICO_SDK_VERSION_STRING "2.0.0"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
// BTstack features that can be enabled
|
||||
#define ENABLE_LOG_INFO
|
||||
#define ENABLE_LOG_DEBUG
|
||||
#define ENABLE_LOG_ERROR
|
||||
#define ENABLE_PRINTF_HEXDUMP
|
||||
#define ENABLE_SCO_OVER_HCI
|
||||
|
||||
#ifdef ENABLE_CLASSIC
|
||||
#define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BLE
|
||||
#define ENABLE_L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE
|
||||
#define ENABLE_LE_PERIPHERAL
|
||||
#define ENABLE_LE_CENTRAL
|
||||
#endif
|
||||
|
||||
// BTstack configuration. buffers, sizes, ...
|
||||
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4
|
||||
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
|
||||
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4
|
||||
#define MAX_NR_AVDTP_CONNECTIONS 1
|
||||
#define MAX_NR_AVDTP_STREAM_ENDPOINTS 1
|
||||
#define MAX_NR_AVRCP_CONNECTIONS 2
|
||||
#define MAX_NR_BNEP_CHANNELS 1
|
||||
#define MAX_NR_BNEP_SERVICES 1
|
||||
#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 2
|
||||
#define MAX_NR_GATT_CLIENTS 1
|
||||
#define MAX_NR_HCI_CONNECTIONS 2
|
||||
#define MAX_NR_HID_HOST_CONNECTIONS 1
|
||||
#define MAX_NR_HIDS_CLIENTS 1
|
||||
#define MAX_NR_HFP_CONNECTIONS 1
|
||||
#define MAX_NR_L2CAP_CHANNELS 4
|
||||
#define MAX_NR_L2CAP_SERVICES 3
|
||||
#define MAX_NR_RFCOMM_CHANNELS 1
|
||||
#define MAX_NR_RFCOMM_MULTIPLEXERS 1
|
||||
#define MAX_NR_RFCOMM_SERVICES 1
|
||||
#define MAX_NR_SERVICE_RECORD_ITEMS 4
|
||||
#define MAX_NR_SM_LOOKUP_ENTRIES 3
|
||||
#define MAX_NR_WHITELIST_ENTRIES 16
|
||||
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16
|
||||
|
||||
// Limit number of ACL/SCO Buffer to use by stack to avoid cyw43 shared bus overrun
|
||||
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3
|
||||
#define MAX_NR_CONTROLLER_SCO_PACKETS 3
|
||||
|
||||
// Enable and configure HCI Controller to Host Flow Control to avoid cyw43 shared bus overrun
|
||||
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL
|
||||
#define HCI_HOST_ACL_PACKET_LEN 1024
|
||||
#define HCI_HOST_ACL_PACKET_NUM 3
|
||||
#define HCI_HOST_SCO_PACKET_LEN 120
|
||||
#define HCI_HOST_SCO_PACKET_NUM 3
|
||||
|
||||
// Link Key DB and LE Device DB using TLV on top of Flash Sector interface
|
||||
#define NVM_NUM_DEVICE_DB_ENTRIES 16
|
||||
#define NVM_NUM_LINK_KEYS 16
|
||||
|
||||
// We don't give btstack a malloc, so use a fixed-size ATT DB.
|
||||
#define MAX_ATT_DB_SIZE 512
|
||||
|
||||
// BTstack HAL configuration
|
||||
#define HAVE_EMBEDDED_TIME_MS
|
||||
|
||||
// map btstack_assert onto Pico SDK assert()
|
||||
#define HAVE_ASSERT
|
||||
|
||||
// Some USB dongles take longer to respond to HCI reset (e.g. BCM20702A).
|
||||
#define HCI_RESET_RESEND_TIMEOUT_MS 1000
|
||||
|
||||
#define ENABLE_SOFTWARE_AES128
|
||||
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS
|
||||
|
||||
#undef HAVE_BTSTACK_STDIN
|
||||
@@ -0,0 +1,10 @@
|
||||
// AUTOGENERATED FROM PICO_CONFIG_HEADER_FILES and then PICO_<PLATFORM>_CONFIG_HEADER_FILES
|
||||
// DO NOT EDIT!
|
||||
|
||||
|
||||
// based on PICO_CONFIG_HEADER_FILES:
|
||||
|
||||
#include "../../pico-sdk/src/boards/include/boards/pico2.h"
|
||||
#include "../../pico-sdk/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h"
|
||||
|
||||
// based on PICO_RP2350_ARM_S_CONFIG_HEADER_FILES:
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
ota_command.h - OTA stub that copies from LittleFS to flash
|
||||
Copyright (c) 2022 Earle F. Philhower, III. All rights 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define _OTA_WRITE 1
|
||||
#define _OTA_VERIFY 1
|
||||
|
||||
typedef struct {
|
||||
uint32_t command;
|
||||
union {
|
||||
struct {
|
||||
char filename[64];
|
||||
uint32_t fileOffset;
|
||||
uint32_t fileLength;
|
||||
uint32_t flashAddress; // Normally XIP_BASE
|
||||
} write;
|
||||
};
|
||||
} commandEntry;
|
||||
|
||||
// Must fit within 4K page
|
||||
typedef struct {
|
||||
uint8_t sign[8]; // "Pico OTA"
|
||||
|
||||
// List of operations
|
||||
uint32_t count;
|
||||
commandEntry cmd[8];
|
||||
|
||||
uint32_t crc32; // CRC32 over just the contents of this struct, up until just before this value
|
||||
} OTACmdPage;
|
||||
|
||||
#define _OTA_COMMAND_FILE "otacommand.bin"
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// ---------------------------------------
|
||||
// THIS FILE IS AUTOGENERATED; DO NOT EDIT
|
||||
// ---------------------------------------
|
||||
|
||||
#ifndef _PICO_VERSION_H
|
||||
#define _PICO_VERSION_H
|
||||
|
||||
#define PICO_SDK_VERSION_MAJOR 2
|
||||
#define PICO_SDK_VERSION_MINOR 0
|
||||
#define PICO_SDK_VERSION_REVISION 0
|
||||
#define PICO_SDK_VERSION_STRING "2.0.0"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* 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
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#define CFG_TUSB_MCU OPT_MCU_RP2040
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define CFG_TUSB_OS OPT_OS_PICO
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
* e.g
|
||||
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||
*/
|
||||
#ifndef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_HID (2)
|
||||
#define CFG_TUD_CDC (1)
|
||||
#define CFG_TUD_MSC (1)
|
||||
#define CFG_TUD_MIDI (0)
|
||||
#define CFG_TUD_VENDOR (0)
|
||||
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE (256)
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE (256)
|
||||
|
||||
#define CFG_TUD_MSC_EP_BUFSIZE (64)
|
||||
|
||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
#define CFG_TUD_HID_EP_BUFSIZE (64)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
@@ -3,15 +3,25 @@
|
||||
#######################################
|
||||
|
||||
Arduino KEYWORD3 RESERVED_WORD
|
||||
defined KEYWORD3 RESERVED_WORD
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
Dir KEYWORD1
|
||||
File KEYWORD1
|
||||
timeval KEYWORD1
|
||||
time_t KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
openDir KEYWORD2
|
||||
setConfig KEYWORD2
|
||||
fileCreationTime KEYWORD2
|
||||
|
||||
setup1 KEYWORD2
|
||||
loop1 KEYWORD2
|
||||
|
||||
@@ -46,6 +56,14 @@ restart KEYWORD2
|
||||
|
||||
isPicoW KEYWORD2
|
||||
|
||||
pmalloc KEYWORD2
|
||||
pcalloc KEYWORD2
|
||||
getPSRAMSize KEYWORD2
|
||||
getFreePSRAMHeap KEYWORD2
|
||||
getUsedPSRAMHeap KEYWORD2
|
||||
getTotalPSRAMHeap KEYWORD2
|
||||
getTotalPSRAM KEYWORD2
|
||||
|
||||
getChipID KEYWORD2
|
||||
|
||||
hwrand32 KEYWORD2
|
||||
@@ -61,7 +79,26 @@ digitalReadFast KEYWORD2
|
||||
|
||||
enableDoubleResetBootloader KEYWORD2
|
||||
|
||||
openDir KEYWORD2
|
||||
next KEYWORD2
|
||||
getLastWrite KEYWORD2
|
||||
getCreationTime KEYWORD2
|
||||
fileTime KEYWORD2
|
||||
fileCreationTime KEYWORD2
|
||||
check KEYWORD2
|
||||
setTimeCallback KEYWORD2
|
||||
settimeofday KEYWORD2
|
||||
|
||||
sprintf_P KEYWORD2
|
||||
strcpy_P KEYWORD2
|
||||
snprintf_P KEYWORD2
|
||||
strncpy_P KEYWORD2
|
||||
|
||||
OUTPUT_2MA LITERAL1
|
||||
OUTPUT_4MA LITERAL1
|
||||
OUTPUT_8MA LITERAL1
|
||||
OUTPUT_12MA LITERAL1
|
||||
|
||||
ARDUINO_ARCH_RP2040 LITERAL1
|
||||
|
||||
PRAM LITERAL1
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
-iwithprefixbefore/cores/rp2040/api/deprecated-avr-comp/
|
||||
-iwithprefixbefore/include/pico_base/
|
||||
-iwithprefixbefore/pico-sdk/lib/tinyusb/src/
|
||||
-iwithprefixbefore/cores/rp2040/api/deprecated-avr-comp
|
||||
|
||||
-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_headers/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
|
||||
@@ -11,13 +12,13 @@
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_time/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_usb_reset_interface/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_util/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_regs/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2040/hardware_structs/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_stdlib_headers/include
|
||||
-iwithprefixbefore/pico-sdk/src/common/pico_usb_reset_interface_headers/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_boot_lock/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
|
||||
@@ -35,6 +36,7 @@
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_resets/include
|
||||
-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_sync_spin_lock/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
|
||||
@@ -42,22 +44,21 @@
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/hardware_xosc/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_async_context/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_bootrom/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_btstack/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_cyw43_arch/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_cyw43_driver/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_double/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include
|
||||
-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_lwip/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_compiler/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_platform_sections/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_platform_panic/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_runtime_init/include
|
||||
-iwithprefixbefore/pico-sdk/src/rp2_common/pico_rand/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_unique_id/include
|
||||
-iwithprefixbefore/pico-sdk/lib/cyw43-driver/src
|
||||
-iwithprefixbefore/pico-sdk/lib/lwip/src/include
|
||||
-iwithprefixbefore/pico-sdk/lib/btstack/src
|
||||
-iwithprefixbefore/pico-sdk/lib/btstack/platform/embedded
|
||||
@@ -0,0 +1,69 @@
|
||||
-Wl,--wrap=__getreent
|
||||
|
||||
-Wl,--wrap=malloc
|
||||
-Wl,--wrap=calloc
|
||||
-Wl,--wrap=realloc
|
||||
-Wl,--wrap=free
|
||||
-Wl,--wrap=mallinfo
|
||||
|
||||
-Wl,--wrap=lwip_init
|
||||
|
||||
-Wl,--wrap=pbuf_header
|
||||
-Wl,--wrap=pbuf_free
|
||||
-Wl,--wrap=pbuf_alloc
|
||||
-Wl,--wrap=pbuf_take
|
||||
-Wl,--wrap=pbuf_copy_partial
|
||||
-Wl,--wrap=pbuf_ref
|
||||
-Wl,--wrap=pbuf_get_at
|
||||
-Wl,--wrap=pbuf_get_contiguous
|
||||
-Wl,--wrap=pbuf_cat
|
||||
|
||||
-Wl,--wrap=tcp_arg
|
||||
-Wl,--wrap=tcp_new
|
||||
-Wl,--wrap=tcp_bind
|
||||
-Wl,--wrap=tcp_listen
|
||||
-Wl,--wrap=tcp_listen_with_backlog
|
||||
-Wl,--wrap=tcp_accept
|
||||
-Wl,--wrap=tcp_connect
|
||||
-Wl,--wrap=tcp_write
|
||||
-Wl,--wrap=tcp_sent
|
||||
-Wl,--wrap=tcp_recv
|
||||
-Wl,--wrap=tcp_recved
|
||||
-Wl,--wrap=tcp_poll
|
||||
-Wl,--wrap=tcp_close
|
||||
-Wl,--wrap=tcp_abort
|
||||
-Wl,--wrap=tcp_err
|
||||
-Wl,--wrap=tcp_output
|
||||
-Wl,--wrap=tcp_setprio
|
||||
-Wl,--wrap=tcp_backlog_delayed
|
||||
-Wl,--wrap=tcp_backlog_accepted
|
||||
|
||||
-Wl,--wrap=udp_new
|
||||
-Wl,--wrap=udp_remove
|
||||
-Wl,--wrap=udp_bind
|
||||
-Wl,--wrap=udp_connect
|
||||
-Wl,--wrap=udp_disconnect
|
||||
-Wl,--wrap=udp_send
|
||||
-Wl,--wrap=udp_recv
|
||||
-Wl,--wrap=udp_sendto_if
|
||||
|
||||
-Wl,--wrap=sys_check_timeouts
|
||||
|
||||
-Wl,--wrap=dns_gethostbyname
|
||||
-Wl,--wrap=dns_gethostbyname_addrtype
|
||||
|
||||
-Wl,--wrap=raw_new
|
||||
-Wl,--wrap=raw_recv
|
||||
-Wl,--wrap=raw_bind
|
||||
-Wl,--wrap=raw_sendto
|
||||
-Wl,--wrap=raw_remove
|
||||
|
||||
-Wl,--wrap=netif_add
|
||||
-Wl,--wrap=netif_remove
|
||||
|
||||
-Wl,--wrap=cyw43_cb_process_ethernet
|
||||
-Wl,--wrap=cyw43_cb_tcpip_set_link_up
|
||||
-Wl,--wrap=cyw43_cb_tcpip_set_link_down
|
||||
-Wl,--wrap=cyw43_tcpip_link_status
|
||||
-Wl,--wrap=cyw43_cb_tcpip_init
|
||||
-Wl,--wrap=cyw43_cb_tcpip_deinit
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user