Compare commits

...
30 Commits
Author SHA1 Message Date
Earle F. Philhower, III e0d33e2536 Try to mount Pico drive if not already present (#175)
Fixes #27

As @vslinuxdotnet discovered, sometimes the Pico firmware update emulated USB
stick does not get automounted under Linux.  Add logic to attempt to use
standard tools to mount it to the uploader, only tried if no drives are
detected normally.
2021-05-27 13:07:55 -07:00
Earle F. Philhower, III 657464f134 Display offending lines in Style CI failure (#174) 2021-05-26 18:40:28 -07:00
Brian Slesinsky 799e3a03f5 Docs: larify pin assignments for i2c (#173) 2021-05-26 18:25:48 -07:00
Earle F. Philhower, III 6d11ec6e70 Update README.md 2021-05-26 18:12:50 -07:00
Limor "Ladyada" Fried 860b43b342 Two board variant definitions and a high speed SPI transfer function (#172) 2021-05-26 18:09:49 -07:00
Earle F. Philhower, III 35260c1f0f Add baud rate to main Serial.begin() (#170) 2021-05-26 02:45:18 -07:00
Brian Slesinsky a1c9dfe84d Add TinyUSB usage note. (#168) 2021-05-26 02:17:42 -07:00
Earle F. Philhower, III 8016a932f3 Add astyle format, boards.txt, and package check (#166)
Miscellaneous CI checks for code style, boards.txt update, and that all
referenced packages are available.
2021-05-24 15:01:03 -07:00
Earle F. Philhower, III fd4f7bbf0b Add TinyUSB examples to CI (#163) 2021-05-23 09:29:44 -07:00
Earle F. Philhower, III 77eae66cb1 Add Win and Mac build to CI (#159) 2021-05-22 03:42:22 -07:00
Earle F. Philhower, III eb6750d7d4 Add Arduino examples to CI (#158)
* Add Arduino examples to CI
* Remove bad example sketches
2021-05-22 03:24:56 -07:00
Earle F. Philhower, III 83a32f1ba3 Add compilation to CI (#155)
Stolen from ESP8266, modified to run basic sanity compiles on the core.

Fix warnings identified by the new checks.
2021-05-22 02:58:57 -07:00
Earle F. Philhower, III 10a44c83f1 Add quasi-sane abs() implementation to Arduino.h (#157)
As mentioned in https://github.com/earlephilhower/arduino-pico/discussions/156#discussion-3376456
2021-05-21 15:32:31 -07:00
Earle F. Philhower, III a55fac8c82 Typo fix in docs 2021-05-21 13:40:02 -07:00
Earle F. Philhower, III 052331168e Fix repo spelling issues (#152) 2021-05-19 18:03:12 -07:00
Scott Smith 4509e6cf38 Fix debug level "Wire" compile error (#151)
* add missing character for debug level "Wire"

if Debug Level "Wire" is chosen, the compiler posts error
> arm-none-eabi-g++: error: DDEBUG_RP2040_WIRE: No such file or directory

Add the missing '-' to correct the issue.

* change must be made via makeboards.py

The generator script needs to be fixed and rerun. If we just update the boards.txt, changes will be lost on a rebuild.

* Update boards.txt

boards.txt as generated by revised makeboards.py

* correct spelling issue for CI tool
2021-05-19 17:46:21 -07:00
Earle F. Philhower, III 69876c7d03 Place CI script in the right spot 2021-05-19 17:21:56 -07:00
Earle F. Philhower, III a6bd1c55ac Add initial CI check (spelling) (#150) 2021-05-19 17:21:10 -07:00
Earle F. Philhower, III 0d593252e6 Ignore non-UTF8 chars in UF2 upload (#148)
Fixes #95
2021-05-19 15:38:56 -07:00
Earle F. Philhower, III a1dc348ec7 Fix over/underclock support (#147)
Removed needed header from main.cpp during prior cleanup.  Re-add.

Fixes #146
2021-05-19 12:28:47 -07:00
Earle F. Philhower, III a0dac52e0e Rationalize Adafruit Feather infra, update docs (#145)
Use same board.txt format as other Adafruit boards.
Add in quick note about the new USB stack to the docs.
2021-05-19 10:07:03 -07:00
Ha Thach 010039578f Add Adafruit ItsyBitsy and QTPy RP2040 (#144)
* add adafruit qtpy and itsybitsy rp2040
* change qtpy boot2 to generic_03h_4
2021-05-19 09:39:19 -07:00
Ha Thach f8a2f38fe7 Port Adafruit_TinyUSB_Arduino lib (#127)
* initial tinyusb lib port

* add Adafruit_TinyUSB_Arduino as submodules

* add yield() to main loop

* sync with tinyusb lib latest

* add USB manufacturer and product

* fix typo in tinyusb lib

* sync with master

updating implementation

* Rationalize link stage command line

Make the build process less insane.

* clean up delay

* clean up platform and board

* update makeboards.py for generating usbstack menu

* update tinyusb lib to 1.0.0
2021-05-18 18:10:47 -07:00
Earle F. Philhower, III 39d1a286a8 Rationalize link stage command line (#143) 2021-05-18 02:47:57 -07:00
Khoi Hoang 7dc0aa16ec Add defs for compatibility (#142)
Add definitions for compatibility to many platforms and libraries
- clockCyclesPerMicrosecond()
- clockCyclesToMicroseconds(a)
- microsecondsToClockCycles(a)
2021-05-16 20:48:44 -07:00
Khoi Hoang b504feaa50 Add -DBOARD_NAME="{build.board}" (#136)
Add -DBOARD_NAME="{build.board}" to Compile patterns to facilitate using BOARD_NAME in sketches
2021-05-16 08:10:10 -07:00
Earle F. Philhower, III fa982c8dd0 Update index.md 2021-05-16 04:14:37 -07:00
Earle F. Philhower, III f1f62264fe Split newlib syscall support to its own file (#141) 2021-05-16 03:59:32 -07:00
Earle F. Philhower, III 1de1d04fb4 Remove hack sync__synchronize from main.cpp (#139)
Was required before due to C++ internals, but is not needed anymore thanks
to #137
2021-05-16 03:49:22 -07:00
Earle F. Philhower, III af8b548e29 Add time support (time, gettimeofday, etc.) (#138) 2021-05-16 03:23:25 -07:00
89 changed files with 4690 additions and 1798 deletions
+182
View File
@@ -0,0 +1,182 @@
# Run whenever a PR is generated or updated.
name: Arduino-Pico CI
on:
pull_request:
jobs:
# Me no spell so good
code-spell:
name: Check spelling
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Run codespell
uses: codespell-project/actions-codespell@master
with:
skip: ./pico-extras,./ArduinoCore-API,./libraries/SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst
ignore_words_list: ser,DOUT
# Consistent style
astyle:
name: Style, Boards, Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: false
- name: Check package references
run: |
./tests/ci/pkgrefs_test.sh
- name: Check boards.txt was not edited after makeboards.py
run: |
./tools/makeboards.py > boards.txt
- name: Run astyle on all code/examples
run: |
sudo apt update
sudo apt install astyle
./tests/restyle.sh
# If anything changed, GIT should return an error and fail the test
git diff --exit-code
# Build all examples on linux (core and Arduino IDE)
build-linux:
name: Build ${{ matrix.chunk }}
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3]
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
BUILD_PARITY: custom
mod: 4
rem: ${{ matrix.chunk }}
run: |
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build.sh
# Build TinyUSB examples, requires custom build command line
build-tinyusb:
name: Build TinyUSB Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
BUILD_PARITY: custom
run: |
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build-tinyusb.sh
# Single build under Windows to ensure the Win toolchain is good.
build-windows:
name: Windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Windows toolchain
id: cache-windows
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketch
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
WINDOWS: 1
BUILD_PARITY: custom
mod: 500
rem: 1
run: |
# Windows has python3 already installed, but it's called "python".
# Copy python.exe to the proper name so scripts "just work".
try { Get-Command python3 } catch { copy (get-command python).source (get-command python).source.Replace("python.exe", "python3.exe") }
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build.sh
# Single build under macOS to ensure the Mac toolchain is good.
build-mac:
name: Mac
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Mac toolchain
id: cache-mac
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketch
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
MACOSX: 1
BUILD_PARITY: custom
mod: 500
rem: 1
run: |
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build.sh
+3
View File
@@ -22,3 +22,6 @@
[submodule "libraries/Mouse"]
path = libraries/Mouse
url = https://github.com/earlephilhower/Mouse
[submodule "libraries/Adafruit_TinyUSB_Arduino"]
path = libraries/Adafruit_TinyUSB_Arduino
url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
+16 -18
View File
@@ -7,6 +7,15 @@ This is a port of the RP2040 (Raspberry Pi Pico processor) to the Arduino ecosys
# Documentation
See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for more detailed usage information.
# Supported Boards
* Raspberry Pi Pico
* Adafruit Feather RP2040
* Adafruit ItsyBitsy RP2040
* Adafruit QTPy RP2040
* Adafruit STEMMA Friend RP2040
* Adafruit Trinkey RP2040 QT
* Generic (configurable flash, I/O pins)
# Installing via Arduino Boards Manager
**Windows Users**: Please do not use the Windows Store version of the actual Arduino application
because it has issues detecting attached Pico boards. Use the "Windows ZIP" or plain "Windows"
@@ -15,7 +24,6 @@ drivers it suggests. Otherwise the Pico board may not be detected. Also, if tr
2.0 beta Arduino please install the release 1.8 version beforehand to ensure needed device drivers
are present. (See #20 for more details.)
Open up the Arduino IDE and go to File->Preferences.
In the dialog that pops up, enter the following URL in the "Additional Boards Manager URLs" field:
@@ -92,24 +100,14 @@ Once Picoprobe permissions are set up properly, then select the board "Raspberry
# Debugging with Picoprobe, OpenOCD, and GDB
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation.
# Status of Port
Relatively stable and very functional, but bug reports and PRs always accepted.
* USB Keyboard and Mouse emulation
* Multicore support (setup1() and loop1())
* digitalWrite/Read
* shiftIn/Out
* SPI master
* analogWrite/PWM
* tone/noTone
* Wire/I2C Master and Slave
* EEPROM
* USB Serial(ACM) w/automatic reboot-to-UF2 upload)
* Hardware UART
* Servo, glitchless
* Overclocking and underclocking from the menus
* analogRead and Pico chip temperature
# Features
* Adafruit TinyUSB Arduino (USB mouse, keyboard, flash drive, generic HID, CDC Serial, MIDI, WebUSB, others)
* Generic Arduino USB Serial, Keyboard, and Mouse emulation
* Filesystems (LittleFS and SD/SDFS)
* I2S audio output
* Multicore support (setup1() and loop1())
* Overclocking and underclocking from the menus
* digitalWrite/Read, shiftIn/Out, tone, analogWrite(PWM)/Read, temperature
* Peripherals: SPI master, Wire(I2C) master/slave, dual UART, emulated EEPROM, I2S audio output, Servo
* printf (i.e. debug) output over USB serial
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
+1513 -272
View File
File diff suppressed because it is too large Load Diff
+47 -23
View File
@@ -1,22 +1,22 @@
/*
* Arduino header for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Arduino header for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Arduino_h
#define Arduino_h
@@ -24,7 +24,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
// Wacky deprecated AVR compatibilty functions
// Wacky deprecated AVR compatibility functions
#include "stdlib_noniso.h"
#include "api/ArduinoAPI.h"
@@ -36,11 +36,28 @@
#include "debug_internal.h"
// Try and make the best of the old Arduino abs() macro. When in C++, use
// the sane std::abs() call, but for C code use their macro since stdlib abs()
// is int but their macro "works" for everything (with potential side effects)
#ifdef abs
#undef abs
#endif // abs
#ifdef __cplusplus
extern "C"{
using std::abs;
#else
#define abs(x) ((x)>0?(x):-(x))
#endif
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Disable/reenable all interrupts. Safely handles nested disables
// For compatibility to many platforms and libraries
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
// Disable/re-enable all interrupts. Safely handles nested disables
void interrupts();
void noInterrupts();
@@ -48,7 +65,7 @@ void noInterrupts();
void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus mode);
void detachInterrupt(pin_size_t pin);
// AVR compatibilty macros...naughty and accesses the HW directly
// AVR compatibility macros...naughty and accesses the HW directly
#define digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToTimer(pin) (0)
@@ -90,7 +107,14 @@ unsigned long millis();
#define HAVE_HWSERIAL2
#ifdef __cplusplus
#ifdef USE_TINYUSB
// Needed for declaring Serial
#include "Adafruit_USBD_CDC.h"
#else
#include "SerialUSB.h"
#endif
#include "SerialUART.h"
#include "RP2040.h"
#include "Bootsel.h"
@@ -99,7 +123,7 @@ unsigned long millis();
// with the specified bits set.
template <size_t N>
constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) {
return i < N ? (1L << a[i]) | __bitset(a, i+1) : 0;
return i < N ? (1L << a[i]) | __bitset(a, i + 1) : 0;
}
#endif
+4 -4
View File
@@ -1,8 +1,8 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
SPDX-License-Identifier: BSD-3-Clause
*/
#include <Arduino.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
+18 -18
View File
@@ -1,22 +1,22 @@
/*
* Simple BOOTSEL reader object
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Simple BOOTSEL reader object
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
+21 -21
View File
@@ -1,25 +1,25 @@
/*
* CoreMutex for the Raspberry Pi Pico RP2040
*
* Implements a deadlock-safe multicore mutex for sharing things like the
* USB or UARTs.
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
CoreMutex for the Raspberry Pi Pico RP2040
Implements a deadlock-safe multicore mutex for sharing things like the
USB or UARTs.
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
+99 -75
View File
@@ -1,22 +1,22 @@
/*
FS.cpp - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
FS.cpp - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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 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.
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
*/
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "FS.h"
#include "FSImpl.h"
@@ -26,37 +26,42 @@ using namespace fs;
static bool sflags(const char* mode, OpenMode& om, AccessMode& am);
size_t File::write(uint8_t c) {
if (!_p)
if (!_p) {
return 0;
}
return _p->write(&c, 1);
}
size_t File::write(const uint8_t *buf, size_t size) {
if (!_p)
if (!_p) {
return 0;
}
return _p->write(buf, size);
}
int File::available() {
if (!_p)
if (!_p) {
return false;
}
return _p->size() - _p->position();
}
int File::availableForWrite() {
if (!_p)
if (!_p) {
return false;
}
return _p->availableForWrite();
}
int File::read() {
if (!_p)
if (!_p) {
return -1;
}
uint8_t result;
if (_p->read(&result, 1) != 1) {
@@ -67,15 +72,17 @@ int File::read() {
}
int File::read(uint8_t* buf, size_t size) {
if (!_p)
if (!_p) {
return 0;
}
return _p->read(buf, size);
}
int File::peek() {
if (!_p)
if (!_p) {
return -1;
}
size_t curPos = _p->position();
int result = read();
@@ -84,29 +91,33 @@ int File::peek() {
}
void File::flush() {
if (!_p)
if (!_p) {
return;
}
_p->flush();
}
bool File::seek(uint32_t pos, SeekMode mode) {
if (!_p)
if (!_p) {
return false;
}
return _p->seek(pos, mode);
}
size_t File::position() const {
if (!_p)
if (!_p) {
return 0;
}
return _p->position();
}
size_t File::size() const {
if (!_p)
if (!_p) {
return 0;
}
return _p->size();
}
@@ -123,36 +134,41 @@ File::operator bool() const {
}
bool File::truncate(uint32_t size) {
if (!_p)
if (!_p) {
return false;
}
return _p->truncate(size);
}
const char* File::name() const {
if (!_p)
if (!_p) {
return nullptr;
}
return _p->name();
}
const char* File::fullName() const {
if (!_p)
if (!_p) {
return nullptr;
}
return _p->fullName();
}
bool File::isFile() const {
if (!_p)
if (!_p) {
return false;
}
return _p->isFile();
}
bool File::isDirectory() const {
if (!_p)
if (!_p) {
return false;
}
return _p->isDirectory();
}
@@ -162,7 +178,7 @@ void File::rewindDirectory() {
_fakeDir = std::make_shared<Dir>(_baseFS->openDir(fullName()));
} else {
_fakeDir->rewind();
}
}
}
File File::openNextFile() {
@@ -173,38 +189,39 @@ File File::openNextFile() {
return _fakeDir->openFile("r");
}
String File::readString()
{
String File::readString() {
String ret;
ret.reserve(size() - position());
char temp[256+1];
int countRead = readBytes(temp, sizeof(temp)-1);
while (countRead > 0)
{
char temp[256 + 1];
int countRead = readBytes(temp, sizeof(temp) - 1);
while (countRead > 0) {
temp[countRead] = 0;
ret += temp;
countRead = readBytes(temp, sizeof(temp)-1);
countRead = readBytes(temp, sizeof(temp) - 1);
}
return ret;
}
time_t File::getLastWrite() {
if (!_p)
if (!_p) {
return 0;
}
return _p->getLastWrite();
}
time_t File::getCreationTime() {
if (!_p)
if (!_p) {
return 0;
}
return _p->getCreationTime();
}
void File::setTimeCallback(time_t (*cb)(void)) {
if (!_p)
if (!_p) {
return;
}
_p->setTimeCallback(cb);
_timeCallback = cb;
}
@@ -235,14 +252,16 @@ String Dir::fileName() {
}
time_t Dir::fileTime() {
if (!_impl)
if (!_impl) {
return 0;
}
return _impl->fileTime();
}
time_t Dir::fileCreationTime() {
if (!_impl)
if (!_impl) {
return 0;
}
return _impl->fileCreationTime();
}
@@ -255,15 +274,17 @@ size_t Dir::fileSize() {
}
bool Dir::isFile() const {
if (!_impl)
if (!_impl) {
return false;
}
return _impl->isFile();
}
bool Dir::isDirectory() const {
if (!_impl)
if (!_impl) {
return false;
}
return _impl->isDirectory();
}
@@ -285,8 +306,9 @@ bool Dir::rewind() {
}
void Dir::setTimeCallback(time_t (*cb)(void)) {
if (!_impl)
if (!_impl) {
return;
}
_impl->setTimeCallback(cb);
_timeCallback = cb;
}
@@ -307,7 +329,7 @@ bool FS::begin() {
}
_impl->setTimeCallback(_timeCallback);
bool ret = _impl->begin();
DEBUGV("%s\n", ret? "": "#error: FS could not start");
DEBUGV("%s\n", ret ? "" : "#error: FS could not start");
return ret;
}
@@ -338,14 +360,14 @@ bool FS::format() {
return _impl->format();
}
bool FS::info(FSInfo& info){
bool FS::info(FSInfo& info) {
if (!_impl) {
return false;
}
return _impl->info(info);
}
bool FS::info64(FSInfo64& info){
bool FS::info64(FSInfo64& info) {
if (!_impl) {
return false;
}
@@ -449,8 +471,9 @@ time_t FS::getCreationTime() {
}
void FS::setTimeCallback(time_t (*cb)(void)) {
if (!_impl)
if (!_impl) {
return;
}
_impl->setTimeCallback(cb);
_timeCallback = cb;
}
@@ -458,29 +481,29 @@ void FS::setTimeCallback(time_t (*cb)(void)) {
static bool sflags(const char* mode, OpenMode& om, AccessMode& am) {
switch (mode[0]) {
case 'r':
am = AM_READ;
om = OM_DEFAULT;
break;
case 'w':
am = AM_WRITE;
om = (OpenMode) (OM_CREATE | OM_TRUNCATE);
break;
case 'a':
am = AM_WRITE;
om = (OpenMode) (OM_CREATE | OM_APPEND);
break;
default:
return false;
case 'r':
am = AM_READ;
om = OM_DEFAULT;
break;
case 'w':
am = AM_WRITE;
om = (OpenMode)(OM_CREATE | OM_TRUNCATE);
break;
case 'a':
am = AM_WRITE;
om = (OpenMode)(OM_CREATE | OM_APPEND);
break;
default:
return false;
}
switch(mode[1]) {
case '+':
am = (AccessMode) (AM_WRITE | AM_READ);
break;
case 0:
break;
default:
return false;
switch (mode[1]) {
case '+':
am = (AccessMode)(AM_WRITE | AM_READ);
break;
case 0:
break;
default:
return false;
}
return true;
}
@@ -489,7 +512,7 @@ static bool sflags(const char* mode, OpenMode& om, AccessMode& am) {
#if defined(FS_FREESTANDING_FUNCTIONS)
/*
TODO: move these functions to public API:
TODO: move these functions to public API:
*/
File open(const char* path, const char* mode);
File open(String& path, const char* mode);
@@ -545,8 +568,9 @@ File open(const char* path, const char* mode) {
size_t offset = entry->path.length();
if (strstr(path, entry->path.c_str())) {
File result = entry->fs->open(path + offset);
if (result)
if (result) {
return result;
}
}
}
+51 -47
View File
@@ -1,22 +1,22 @@
/*
FS.h - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
FS.h - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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 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.
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
*/
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FS_H
#define FS_H
@@ -49,8 +49,7 @@ enum SeekMode {
SeekEnd = 2
};
class File : public Stream
{
class File : public Stream {
public:
File(FileImplPtr p = FileImplPtr(), FS *baseFS = nullptr) : _p(p), _fakeDir(nullptr), _baseFS(baseFS) { }
@@ -74,7 +73,9 @@ public:
}
size_t position() const;
size_t size() const;
virtual ssize_t streamRemaining() { return (ssize_t)size() - (ssize_t)position(); }
virtual ssize_t streamRemaining() {
return (ssize_t)size() - (ssize_t)position();
}
void close();
operator bool() const;
const char* name() const;
@@ -86,26 +87,26 @@ public:
// Arduino "class SD" methods for compatibility
//TODO use stream::send / check read(buf,size) result
template<typename T> size_t write(T &src){
uint8_t obuf[256];
size_t doneLen = 0;
size_t sentLen;
int i;
template<typename T> size_t write(T &src) {
uint8_t obuf[256];
size_t doneLen = 0;
size_t sentLen;
int i;
while (src.available() > sizeof(obuf)){
src.read(obuf, sizeof(obuf));
sentLen = write(obuf, sizeof(obuf));
doneLen = doneLen + sentLen;
if(sentLen != sizeof(obuf)){
return doneLen;
while (src.available() > sizeof(obuf)) {
src.read(obuf, sizeof(obuf));
sentLen = write(obuf, sizeof(obuf));
doneLen = doneLen + sentLen;
if (sentLen != sizeof(obuf)) {
return doneLen;
}
}
}
size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
}
using Print::write;
@@ -172,8 +173,7 @@ struct FSInfo64 {
};
class FSConfig
{
class FSConfig {
public:
static constexpr uint32_t FSId = 0x00000000;
@@ -188,8 +188,7 @@ public:
bool _autoFormat;
};
class SPIFFSConfig : public FSConfig
{
class SPIFFSConfig : public FSConfig {
public:
static constexpr uint32_t FSId = 0x53504946;
SPIFFSConfig(bool autoFormat = true) : FSConfig(FSId, autoFormat) { }
@@ -198,10 +197,11 @@ public:
// nothing yet, enableTime TBD when SPIFFS has metadate
};
class FS
{
class FS {
public:
FS(FSImplPtr impl) : _impl(impl) { _timeCallback = _defaultTimeCB; }
FS(FSImplPtr impl) : _impl(impl) {
_timeCallback = _defaultTimeCB;
}
bool setConfig(const FSConfig &cfg);
@@ -244,18 +244,22 @@ public:
friend class ::SDClass; // More of a frenemy, but SD needs internal implementation to get private FAT bits
protected:
FSImplPtr _impl;
FSImplPtr getImpl() { return _impl; }
FSImplPtr getImpl() {
return _impl;
}
time_t (*_timeCallback)(void) = nullptr;
static time_t _defaultTimeCB(void) { return time(NULL); }
static time_t _defaultTimeCB(void) {
return time(NULL);
}
};
} // namespace fs
extern "C"
{
void close_all_fs(void);
void littlefs_request_end(void);
void spiffs_request_end(void);
void close_all_fs(void);
void littlefs_request_end(void);
void spiffs_request_end(void);
}
#ifndef FS_NO_GLOBALS
+49 -27
View File
@@ -1,22 +1,22 @@
/*
FSImpl.h - base file system interface
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
FSImpl.h - base file system interface
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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 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.
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
*/
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FSIMPL_H
#define FSIMPL_H
@@ -35,7 +35,9 @@ public:
virtual bool seek(uint32_t pos, SeekMode mode) = 0;
virtual size_t position() const = 0;
virtual size_t size() const = 0;
virtual int availableForWrite() { return 0; }
virtual int availableForWrite() {
return 0;
}
virtual bool truncate(uint32_t size) = 0;
virtual void close() = 0;
virtual const char* name() const = 0;
@@ -46,14 +48,20 @@ public:
// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for *this specific* file (as opposed to the FSImpl call of the
// same name. The default implementation simply returns time(null)
virtual void setTimeCallback(time_t (*cb)(void)) { _timeCallback = cb; }
virtual void setTimeCallback(time_t (*cb)(void)) {
_timeCallback = cb;
}
// Return the last written time for a file. Undefined when called on a writable file
// as the FS is allowed to return either the time of the last write() operation or the
// time present in the filesystem metadata (often the last time the file was closed)
virtual time_t getLastWrite() { return 0; } // Default is to not support timestamps
virtual time_t getLastWrite() {
return 0; // Default is to not support timestamps
}
// Same for creation time.
virtual time_t getCreationTime() { return 0; } // Default is to not support timestamps
virtual time_t getCreationTime() {
return 0; // Default is to not support timestamps
}
protected:
time_t (*_timeCallback)(void) = nullptr;
@@ -81,8 +89,12 @@ public:
// Return the last written time for a file. Undefined when called on a writable file
// as the FS is allowed to return either the time of the last write() operation or the
// time present in the filesystem metadata (often the last time the file was closed)
virtual time_t fileTime() { return 0; } // By default, FS doesn't report file times
virtual time_t fileCreationTime() { return 0; } // By default, FS doesn't report file times
virtual time_t fileTime() {
return 0; // By default, FS doesn't report file times
}
virtual time_t fileCreationTime() {
return 0; // By default, FS doesn't report file times
}
virtual bool isFile() const = 0;
virtual bool isDirectory() const = 0;
virtual bool next() = 0;
@@ -91,7 +103,9 @@ public:
// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for *this specific* file (as opposed to the FSImpl call of the
// same name. The default implementation simply returns time(null)
virtual void setTimeCallback(time_t (*cb)(void)) { _timeCallback = cb; }
virtual void setTimeCallback(time_t (*cb)(void)) {
_timeCallback = cb;
}
protected:
time_t (*_timeCallback)(void) = nullptr;
@@ -99,7 +113,7 @@ protected:
class FSImpl {
public:
virtual ~FSImpl () { }
virtual ~FSImpl() { }
virtual bool setConfig(const FSConfig &cfg) = 0;
virtual bool begin() = 0;
virtual void end() = 0;
@@ -113,14 +127,22 @@ public:
virtual bool remove(const char* path) = 0;
virtual bool mkdir(const char* path) = 0;
virtual bool rmdir(const char* path) = 0;
virtual bool gc() { return true; } // May not be implemented in all file systems.
virtual bool check() { return true; } // May not be implemented in all file systems.
virtual time_t getCreationTime() { return 0; } // May not be implemented in all file systems.
virtual bool gc() {
return true; // May not be implemented in all file systems.
}
virtual bool check() {
return true; // May not be implemented in all file systems.
}
virtual time_t getCreationTime() {
return 0; // May not be implemented in all file systems.
}
// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for all files on this FS. The default implementation simply
// returns the present time as reported by time(null)
virtual void setTimeCallback(time_t (*cb)(void)) { _timeCallback = cb; }
virtual void setTimeCallback(time_t (*cb)(void)) {
_timeCallback = cb;
}
protected:
time_t (*_timeCallback)(void) = nullptr;
+42 -28
View File
@@ -1,22 +1,22 @@
/*
* RP2040 utility class
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
RP2040 utility class
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <hardware/clocks.h>
#include <hardware/irq.h>
@@ -54,7 +54,7 @@ public:
bool push_nb(uint32_t val) {
// Push to the other FIFO
return queue_try_add(&_queue[get_core_num()^1], &val);
return queue_try_add(&_queue[get_core_num() ^ 1], &val);
}
uint32_t pop() {
@@ -73,7 +73,9 @@ public:
}
void idleOtherCore() {
if (!_multicore) return;
if (!_multicore) {
return;
}
mutex_enter_blocking(&_idleMutex);
_otherIdled = false;
multicore_fifo_push_blocking(_GOTOSLEEP);
@@ -81,7 +83,9 @@ public:
}
void resumeOtherCore() {
if (!_multicore) return;
if (!_multicore) {
return;
}
mutex_exit(&_idleMutex);
_otherIdled = false;
// Other core will exit busy-loop and return to operation
@@ -115,7 +119,7 @@ public:
// Convert from microseconds to PIO clock cycles
static int usToPIOCycles(int us) {
// Parenthesis needed to guarantee order of operations to avoid 32bit overflow
return (us * ( clock_get_hz(clk_sys) / 1000000 ));
return (us * (clock_get_hz(clk_sys) / 1000000));
}
// Get current clock frequency
@@ -123,8 +127,12 @@ public:
return clock_get_hz(clk_sys);
}
void idleOtherCore() { fifo.idleOtherCore(); }
void resumeOtherCore() { fifo.resumeOtherCore(); }
void idleOtherCore() {
fifo.idleOtherCore();
}
void resumeOtherCore() {
fifo.resumeOtherCore();
}
// Multicore comms FIFO
_MFIFO fifo;
@@ -136,18 +144,24 @@ extern RP2040 rp2040;
// TODO - Add unload/destructor
class PIOProgram {
public:
PIOProgram(const pio_program_t *pgm) { _pgm = pgm; }
PIOProgram(const pio_program_t *pgm) {
_pgm = pgm;
}
// Possibly load into a PIO and allocate a SM
bool prepare(PIO *pio, int *sm, int *offset) {
extern mutex_t _pioMutex;
CoreMutex m(&_pioMutex);
// Is there an open slot to run in, first?
if (!_findFreeSM(pio, sm)) return false;
// Is it loaded on that PIO?
if (!_findFreeSM(pio, sm)) {
return false;
}
// Is it loaded on that PIO?
if (_offset[pio_get_index(*pio)] < 0) {
// Nope, need to load it
if (!pio_can_add_program(*pio, _pgm)) return false;
if (!pio_can_add_program(*pio, _pgm)) {
return false;
}
_offset[pio_get_index(*pio)] = pio_add_program(*pio, _pgm);
}
// Here it's guaranteed loaded, return values
+47 -46
View File
@@ -1,23 +1,25 @@
/*
* Shared USB for the Raspberry Pi Pico RP2040
* Allows for multiple endpoints to share the USB controller
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Shared USB for the Raspberry Pi Pico RP2040
Allows for multiple endpoints to share the USB controller
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef USE_TINYUSB
#include <Arduino.h>
#include "CoreMutex.h"
@@ -44,9 +46,9 @@ mutex_t __usb_mutex;
#define USBD_VID (0x2E8A) // Raspberry Pi
#ifdef SERIALUSB_PID
#define USBD_PID (SERIALUSB_PID)
#define USBD_PID (SERIALUSB_PID)
#else
#define USBD_PID (0x000a) // Raspberry Pi Pico SDK CDC
#define USBD_PID (0x000a) // Raspberry Pi Pico SDK CDC
#endif
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
@@ -122,8 +124,8 @@ int __USBGetMouseReportID() {
static uint8_t *GetDescHIDReport(int *len) {
if (__USBInstallKeyboard && __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) ),
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2) )
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)),
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(2))
};
if (len) {
*len = sizeof(desc_hid_report);
@@ -131,7 +133,7 @@ static uint8_t *GetDescHIDReport(int *len) {
return desc_hid_report;
} else if (__USBInstallKeyboard && ! __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) )
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1))
};
if (len) {
*len = sizeof(desc_hid_report);
@@ -139,7 +141,7 @@ static uint8_t *GetDescHIDReport(int *len) {
return desc_hid_report;
} else { // if (!__USBInstallKeyboard && __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_MOUSE( HID_REPORT_ID(1) )
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1))
};
if (len) {
*len = sizeof(desc_hid_report);
@@ -151,17 +153,15 @@ static uint8_t *GetDescHIDReport(int *len) {
// Invoked when received GET HID REPORT DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(void)
{
uint8_t const * tud_hid_descriptor_report_cb(void) {
return GetDescHIDReport(nullptr);
}
}
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
(void)index;
int len = 0;
static uint8_t *usbd_desc_cfg;
if (!usbd_desc_cfg) {
bool hasHID = __USBInstallKeyboard || __USBInstallMouse;
@@ -215,7 +215,8 @@ const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
}
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
#define DESC_STR_MAX (20)
(void) langid;
#define DESC_STR_MAX (20)
static uint16_t desc_str[DESC_STR_MAX];
static char idString[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];
@@ -295,25 +296,25 @@ void __USBStart() {
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
{
// TODO not Implemented
(void) report_id;
(void) report_type;
(void) buffer;
(void) reqlen;
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
// TODO not Implemented
(void) report_id;
(void) report_type;
(void) buffer;
(void) reqlen;
return 0;
return 0;
}
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
// TODO set LED based on CAPLOCK, NUMLOCK etc...
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
// TODO set LED based on CAPLOCK, NUMLOCK etc...
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
}
#endif
+19 -19
View File
@@ -1,23 +1,23 @@
/*
* Shared USB for the Raspberry Pi Pico RP2040
* Allows for multiple endpoints to share the USB controller
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Shared USB for the Raspberry Pi Pico RP2040
Allows for multiple endpoints to share the USB controller
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pico/mutex.h"
+34 -32
View File
@@ -1,22 +1,22 @@
/*
* Serial-over-UART for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-over-UART for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "SerialUART.h"
#include "CoreMutex.h"
@@ -33,7 +33,8 @@ extern void serialEvent2() __attribute__((weak));
bool SerialUART::setRX(pin_size_t rx) {
constexpr uint32_t valid[2] = { __bitset({1, 13, 17, 29}) /* UART0 */,
__bitset({5, 9, 21, 25}) /* UART1 */};
__bitset({5, 9, 21, 25}) /* UART1 */
};
if (_running) {
DEBUGCORE("ERROR: SerialUART setRX while running\n");
return false;
@@ -48,7 +49,8 @@ bool SerialUART::setRX(pin_size_t rx) {
bool SerialUART::setTX(pin_size_t tx) {
constexpr uint32_t valid[2] = { __bitset({0, 12, 16, 28}) /* UART0 */,
__bitset({4, 8, 20, 24}) /* UART1 */};
__bitset({4, 8, 20, 24}) /* UART1 */
};
if (_running) {
DEBUGCORE("ERROR: SerialUART setTX while running\n");
return false;
@@ -74,19 +76,19 @@ void SerialUART::begin(unsigned long baud, uint16_t config) {
int bits, stop;
uart_parity_t parity;
switch (config & SERIAL_PARITY_MASK) {
case SERIAL_PARITY_EVEN: parity = UART_PARITY_EVEN; break;
case SERIAL_PARITY_ODD: parity = UART_PARITY_ODD; break;
default: parity = UART_PARITY_NONE; break;
case SERIAL_PARITY_EVEN: parity = UART_PARITY_EVEN; break;
case SERIAL_PARITY_ODD: parity = UART_PARITY_ODD; break;
default: parity = UART_PARITY_NONE; break;
}
switch ( config & SERIAL_STOP_BIT_MASK) {
case SERIAL_STOP_BIT_1: stop = 1; break;
default: stop = 2; break;
switch (config & SERIAL_STOP_BIT_MASK) {
case SERIAL_STOP_BIT_1: stop = 1; break;
default: stop = 2; break;
}
switch (config & SERIAL_DATA_MASK) {
case SERIAL_DATA_5: bits = 5; break;
case SERIAL_DATA_6: bits = 6; break;
case SERIAL_DATA_7: bits = 7; break;
default: bits = 8; break;
case SERIAL_DATA_5: bits = 5; break;
case SERIAL_DATA_6: bits = 6; break;
case SERIAL_DATA_7: bits = 7; break;
default: bits = 8; break;
}
uart_set_format(_uart, bits, stop, parity);
gpio_set_function(_tx, GPIO_FUNC_UART);
@@ -184,12 +186,12 @@ SerialUART Serial2(uart1, PIN_SERIAL2_TX, PIN_SERIAL2_RX);
void arduino::serialEvent1Run(void) {
if (serialEvent1 && Serial1.available()) {
serialEvent1();
serialEvent1();
}
}
void arduino::serialEvent2Run(void) {
if (serialEvent2 && Serial2.available()) {
serialEvent2();
serialEvent2();
}
}
+29 -23
View File
@@ -1,22 +1,22 @@
/*
* Serial-over-UART for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-over-UART for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
@@ -30,13 +30,19 @@ extern "C" typedef struct uart_inst uart_inst_t;
class SerialUART : public HardwareSerial {
public:
SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx);
// Select the pinout. Call before .begin()
bool setRX(pin_size_t pin);
bool setTX(pin_size_t pin);
bool setPinout(pin_size_t tx, pin_size_t rx) { bool ret = setRX(rx); ret &= setTX(tx); return ret; }
bool setPinout(pin_size_t tx, pin_size_t rx) {
bool ret = setRX(rx);
ret &= setTX(tx);
return ret;
}
void begin(unsigned long baud = 115200) override { begin(baud, SERIAL_8N1); };
void begin(unsigned long baud = 115200) override {
begin(baud, SERIAL_8N1);
};
void begin(unsigned long baud, uint16_t config) override;
void end() override;
@@ -63,6 +69,6 @@ extern SerialUART Serial1; // HW UART 0
extern SerialUART Serial2; // HW UART 1
namespace arduino {
extern void serialEvent1Run(void) __attribute__((weak));
extern void serialEvent2Run(void) __attribute__((weak));
extern void serialEvent1Run(void) __attribute__((weak));
extern void serialEvent2Run(void) __attribute__((weak));
};
+37 -30
View File
@@ -1,24 +1,26 @@
/*
* Serial-Over-USB for the Raspberry Pi Pico RP2040
* Implements an ACM which will reboot into UF2 mode on a 1200bps DTR toggle.
* Much of this was modified from the Raspberry Pi Pico SDK stdio_usb.c file.
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-Over-USB for the Raspberry Pi Pico RP2040
Implements an ACM which will reboot into UF2 mode on a 1200bps DTR toggle.
Much of this was modified from the Raspberry Pi Pico SDK stdio_usb.c file.
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef USE_TINYUSB
#include <Arduino.h>
#include "CoreMutex.h"
@@ -33,8 +35,8 @@
#include "pico/unique_id.h"
#ifndef DISABLE_USB_SERIAL
// Ensure we are installed in the USB chain
void __USBInstallSerial() { /* noop */ }
// Ensure we are installed in the USB chain
void __USBInstallSerial() { /* noop */ }
#endif
// SerialEvent functions are weak, so when the user doesn't define them,
@@ -123,10 +125,12 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
static uint64_t last_avail_time;
int i = 0;
if (tud_cdc_connected()) {
for (int i = 0; i < length;) {
for (size_t i = 0; i < length;) {
int n = length - i;
int avail = tud_cdc_write_available();
if (n > avail) n = avail;
if (n > avail) {
n = avail;
}
if (n) {
int n2 = tud_cdc_write(buf + i, n);
tud_task();
@@ -137,7 +141,7 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
tud_task();
tud_cdc_write_flush();
if (!tud_cdc_connected() ||
(!tud_cdc_write_available() && time_us_64() > last_avail_time + 1000000 /* 1 second */)) {
(!tud_cdc_write_available() && time_us_64() > last_avail_time + 1000000 /* 1 second */)) {
break;
}
}
@@ -165,27 +169,30 @@ static bool _rts = false;
static int _bps = 115200;
static void CheckSerialReset() {
if ((_bps == 1200) && (!_dtr)) {
reset_usb_boot(0,0);
while (1); // WDT will fire here
reset_usb_boot(0, 0);
while (1); // WDT will fire here
}
}
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
(void) itf;
_dtr = dtr ? true : false;
_rts = rts ? true : false;
CheckSerialReset();
}
extern "C" void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) {
(void) itf;
_bps = p_line_coding->bit_rate;
CheckSerialReset();
}
SerialUSB Serial;
void arduino::serialEventRun(void)
{
void arduino::serialEventRun(void) {
if (serialEvent && Serial.available()) {
serialEvent();
serialEvent();
}
}
#endif
+23 -20
View File
@@ -1,22 +1,22 @@
/*
* Serial-over-USB for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-over-USB for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __SERIALUSB_H__
#define __SERIALUSB_H__
@@ -29,7 +29,10 @@ class SerialUSB : public HardwareSerial {
public:
SerialUSB() { }
void begin(unsigned long baud = 115200) override;
void begin(unsigned long baud, uint16_t config) override { begin(baud); };
void begin(unsigned long baud, uint16_t config) override {
(void) config;
begin(baud);
};
void end() override;
virtual int peek() override;
@@ -49,7 +52,7 @@ private:
extern SerialUSB Serial;
namespace arduino {
extern void serialEventRun(void) __attribute__((weak));
extern void serialEventRun(void) __attribute__((weak));
};
#endif
+1 -1
View File
@@ -1 +1 @@
#include "api/String.h"
#include "api/Stream.h"
+90
View File
@@ -0,0 +1,90 @@
/*
The MIT License (MIT)
Copyright (c) 2018, hathach for Adafruit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
#ifdef USE_TINYUSB
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
#else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
#endif
//#ifndef CFG_TUSB_MCU
// #define CFG_TUSB_MCU OPT_MCU_RP2040
//#endif
#define CFG_TUSB_OS OPT_OS_PICO
#define CFG_TUSB_DEBUG 0
//#if CFG_TUSB_DEBUG
// #define tu_printf serial1_printf
// extern int serial1_printf(const char *__restrict __format, ...);
//#endif
#define CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUD_ENDOINT0_SIZE 64
//------------- CLASS -------------//
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1
#define CFG_TUD_HID 1
#define CFG_TUD_MIDI 1
#define CFG_TUD_VENDOR 1
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE 256
#define CFG_TUD_CDC_TX_BUFSIZE 256
// MSC Buffer size of Device Mass storage
#define CFG_TUD_MSC_BUFSIZE 512
// HID buffer size Should be sufficient to hold ID (if any) + Data
#define CFG_TUD_HID_BUFSIZE 64
// MIDI FIFO size of TX and RX
#define CFG_TUD_MIDI_RX_BUFSIZE 128
#define CFG_TUD_MIDI_TX_BUFSIZE 128
// Vendor FIFO size of TX and RX
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CONFIG_H_ */
+25 -23
View File
@@ -1,22 +1,22 @@
/*
* Tone for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Tone for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include "CoreMutex.h"
@@ -39,7 +39,7 @@ static PIOProgram _tonePgm(&tone_program);
static std::map<pin_size_t, Tone *> _toneMap;
void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
if ((pin < 0) || (pin > 29)) {
if (pin > 29) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
}
@@ -50,7 +50,9 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
// Ensure only 1 core can start or stop at a time
CoreMutex m(&_toneMutex);
if (!m) return; // Weird deadlock case
if (!m) {
return; // Weird deadlock case
}
int us = 1000000 / frequency / 2;
if (us < 5) {
@@ -70,7 +72,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
if (!_tonePgm.prepare(&newTone->pio, &newTone->sm, &off)) {
DEBUGCORE("ERROR: tone unable to start, out of PIO resources\n");
// ERROR, no free slots
delete newTone;
delete newTone;
return;
}
tone_program_init(newTone->pio, newTone->sm, off, pin);
@@ -87,14 +89,14 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
void noTone(uint8_t pin) {
CoreMutex m(&_toneMutex);
if ((pin < 0) || (pin > 29) || !m) {
if ((pin > 29) || !m) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
}
auto entry = _toneMap.find(pin);
if (entry != _toneMap.end()) {
pio_sm_set_enabled(entry->second->pio, entry->second->sm, false);
pio_sm_unclaim(entry->second->pio, entry->second->sm);
pio_sm_unclaim(entry->second->pio, entry->second->sm);
delete entry->second;
_toneMap.erase(entry);
pinMode(pin, OUTPUT);
+27 -27
View File
@@ -1,44 +1,44 @@
/*
Copyright (c) 2014 Arduino. All right reserved.
Copyright (c) 2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is 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.
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
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "stdlib.h"
#include "stdint.h"
void randomSeed( uint32_t dwSeed ) {
if ( dwSeed != 0 ) {
srand( dwSeed ) ;
}
void randomSeed(uint32_t dwSeed) {
if (dwSeed != 0) {
srand(dwSeed) ;
}
}
long random( long howbig ) {
if ( howbig == 0 ) {
return 0 ;
}
long random(long howbig) {
if (howbig == 0) {
return 0 ;
}
return rand() % howbig;
return rand() % howbig;
}
long random( long howsmall, long howbig ) {
if (howsmall >= howbig) {
return howsmall;
}
long random(long howsmall, long howbig) {
if (howsmall >= howbig) {
return howsmall;
}
long diff = howbig - howsmall;
long diff = howbig - howsmall;
return random(diff) + howsmall;
return random(diff) + howsmall;
}
+38 -38
View File
@@ -1,46 +1,46 @@
/*
* Core debug macros header for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Core debug macros header for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(DEBUG_RP2040_PORT)
#define DEBUGV(...) do { } while(0)
#define DEBUGCORE(...) do { } while(0)
#define DEBUGWIRE(...) do { } while(0)
#define DEBUGSPI(...) do { } while(0)
#define DEBUGV(...) do { } while(0)
#define DEBUGCORE(...) do { } while(0)
#define DEBUGWIRE(...) do { } while(0)
#define DEBUGSPI(...) do { } while(0)
#else
#define DEBUGV(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#define DEBUGV(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#if defined(DEBUG_RP2040_CORE)
#define DEBUGCORE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGCORE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_CORE)
#define DEBUGCORE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGCORE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_WIRE)
#define DEBUGWIRE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGWIRE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_WIRE)
#define DEBUGWIRE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGWIRE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_SPI)
#define DEBUGSPI(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGSPI(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_SPI)
#define DEBUGSPI(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGSPI(...) do { } while(0)
#endif
#endif
+50 -38
View File
@@ -1,50 +1,62 @@
/*
* delay() for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
delay() for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <pico.h>
#include <pico/time.h>
extern "C" void delay( unsigned long ms ) {
if (!ms) {
return;
#ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_API.h"
#endif
extern "C"
{
void delay(unsigned long ms) {
if (!ms) {
return;
}
sleep_ms(ms);
}
sleep_ms(ms);
}
extern "C" void delayMicroseconds( unsigned int usec ) {
if (!usec) {
return;
void delayMicroseconds(unsigned int usec) {
if (!usec) {
return;
}
sleep_us(usec);
}
sleep_us(usec);
}
extern "C" void yield() {
// NOOP
}
void yield() {
#ifdef USE_TINYUSB
TinyUSB_Device_Task();
TinyUSB_Device_FlushCDC();
#endif
}
extern "C" uint32_t millis() {
return to_ms_since_boot(get_absolute_time());
}
extern "C" uint32_t micros() {
return to_us_since_boot(get_absolute_time());
}
uint32_t millis() {
return to_ms_since_boot(get_absolute_time());
}
uint32_t micros() {
return to_us_since_boot(get_absolute_time());
}
} // extern C
+30 -144
View File
@@ -1,22 +1,22 @@
/*
* Main handler for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Main handler for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include "RP2040USB.h"
@@ -60,11 +60,17 @@ extern "C" int main() {
mutex_init(&_pioMutex);
initVariant();
#ifdef USE_TINYUSB
TinyUSB_Device_Init(0);
#else
__USBStart();
#ifndef DISABLE_USB_SERIAL
// Enable serial port for reset/upload always
Serial.begin();
Serial.begin(115200);
#endif
#endif
#if defined DEBUG_RP2040_PORT
@@ -82,6 +88,11 @@ extern "C" int main() {
setup();
while (true) {
loop();
#ifdef USE_TINYUSB
yield();
#endif
if (arduino::serialEventRun) {
arduino::serialEventRun();
}
@@ -94,128 +105,3 @@ extern "C" int main() {
}
return 0;
}
/* NEWLIB syscall overloads, so we can ::print() and ::getc() using our objects */
/* Placed here to ensure this compilation unit will be present when it's time */
/* to link newlib.a. */
#include <stdint.h>
#include <errno.h>
#include <_syslist.h>
#include <sys/times.h>
#undef errno
// TODO - check the fd, create a VFS, etc.
extern "C" int errno;
extern "C" ssize_t _write(int fd, const void *buf, size_t count) {
#if defined DEBUG_RP2040_PORT
return DEBUG_RP2040_PORT.write((const char *)buf, count);
#else
return 0;
#endif
}
extern "C" int _chown (const char *path, uid_t owner, gid_t group) {
errno = ENOSYS;
return -1;
}
extern "C" int _close (int fildes) {
errno = ENOSYS;
return -1;
}
extern "C" int _execve (char *name, char **argv, char **env) {
errno = ENOSYS;
return -1;
}
extern "C" int _fork (void) {
errno = ENOSYS;
return -1;
}
extern "C" int _fstat (int fildes, struct stat *st) {
errno = ENOSYS;
return -1;
}
extern "C" int _getpid (void) {
errno = ENOSYS;
return -1;
}
struct timeval;
extern "C" int _gettimeofday (struct timeval *ptimeval, void *ptimezone)
{
errno = ENOSYS;
return -1;
}
extern "C" int _isatty (int file) {
errno = ENOSYS;
return 0;
}
extern "C" int _kill (int pid, int sig) {
errno = ENOSYS;
return -1;
}
extern "C" int _link (char *existing, char *newlink) {
errno = ENOSYS;
return -1;
}
extern "C" int _lseek (int file, int ptr, int dir) {
errno = ENOSYS;
return -1;
}
extern "C" int _open (char *file, int flags, int mode) {
errno = ENOSYS;
return -1;
}
extern "C" int _read (int file, char *ptr, int len)
{
// return Serial.read(ptr, len);
return -1;
}
extern "C" int _readlink (const char *path, char *buf, size_t bufsize) {
errno = ENOSYS;
return -1;
}
extern "C" int _stat (const char *file, struct stat *st) {
errno = ENOSYS;
return -1;
}
extern "C" int _symlink (const char *path1, const char *path2) {
errno = ENOSYS;
return -1;
}
extern "C" clock_t _times (struct tms *buf) {
errno = ENOSYS;
return -1;
}
extern "C" int _unlink (char *name) {
errno = ENOSYS;
return -1;
}
extern "C" int _wait (int *status) {
errno = ENOSYS;
return -1;
}
extern "C" void __sync_synchronize() { /* noop */ }
+18 -18
View File
@@ -1,22 +1,22 @@
/*
* Millis() for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Millis() for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <pico/time.h>
+193
View File
@@ -0,0 +1,193 @@
/*
NEWLIB syscall implementations
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <stdint.h>
#include <errno.h>
#include <_syslist.h>
#include <sys/times.h>
#include <pico/stdlib.h>
#include <pico/multicore.h>
#undef errno
// TODO - check the fd, create a VFS, etc.
extern "C" int errno;
extern "C" 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);
#else
(void) fd;
(void) buf;
(void) count;
return 0;
#endif
}
extern "C" int _chown(const char *path, uid_t owner, gid_t group) {
(void) path;
(void) owner;
(void) group;
errno = ENOSYS;
return -1;
}
extern "C" int _close(int fd) {
(void) fd;
errno = ENOSYS;
return -1;
}
extern "C" int _execve(char *name, char **argv, char **env) {
(void) name;
(void) argv;
(void) env;
errno = ENOSYS;
return -1;
}
extern "C" int _fork(void) {
errno = ENOSYS;
return -1;
}
extern "C" int _fstat(int fd, struct stat *st) {
(void) fd;
(void) st;
errno = ENOSYS;
return -1;
}
extern "C" int _getpid(void) {
errno = ENOSYS;
return -1;
}
static int64_t __timedelta_us = 0.0;
extern "C" int _gettimeofday(struct timeval *tv, void *tz) {
(void) tz;
uint64_t now_us = to_us_since_boot(get_absolute_time()) + __timedelta_us;
if (tv) {
tv->tv_sec = now_us / 1000000L;
tv->tv_usec = now_us % 1000000L;
}
return 0;
}
extern "C" int settimeofday(const struct timeval *tv, const struct timezone *tz) {
(void) tz;
uint64_t now_us = to_us_since_boot(get_absolute_time());
if (tv) {
uint64_t newnow_us;
newnow_us = tv->tv_sec * 1000000L;
newnow_us += tv->tv_usec;
__timedelta_us = newnow_us - now_us;
}
return 0;
}
extern "C" int _isatty(int file) {
(void) file;
errno = ENOSYS;
return 0;
}
extern "C" int _kill(int pid, int sig) {
(void) pid;
(void) sig;
errno = ENOSYS;
return -1;
}
extern "C" int _link(char *existing, char *newlink) {
(void) existing;
(void) newlink;
errno = ENOSYS;
return -1;
}
extern "C" int _lseek(int file, int ptr, int dir) {
(void) file;
(void) ptr;
(void) dir;
errno = ENOSYS;
return -1;
}
extern "C" int _open(char *file, int flags, int mode) {
(void) file;
(void) flags;
(void) mode;
errno = ENOSYS;
return -1;
}
extern "C" int _read(int file, char *ptr, int len) {
(void) file;
(void) ptr;
(void) len;
// return Serial.read(ptr, len);
return -1;
}
extern "C" int _readlink(const char *path, char *buf, size_t bufsize) {
(void) path;
(void) buf;
(void) bufsize;
errno = ENOSYS;
return -1;
}
extern "C" 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) {
(void) path1;
(void) path2;
errno = ENOSYS;
return -1;
}
extern "C" clock_t _times(struct tms *buf) {
(void) buf;
errno = ENOSYS;
return -1;
}
extern "C" int _unlink(char *name) {
(void) name;
errno = ENOSYS;
return -1;
}
extern "C" int _wait(int *status) {
(void) status;
errno = ENOSYS;
return -1;
}
+37 -42
View File
@@ -1,23 +1,23 @@
/*
stdlib_noniso.h - nonstandard (but useful) conversion functions
stdlib_noniso.h - nonstandard (but useful) conversion functions
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
Copyright (c) 2021 David Gauchard. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
Copyright (c) 2021 David Gauchard. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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 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.
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
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
@@ -32,37 +32,31 @@
// but is smaller by ~800B/flash and ~250B/rodata
// ulltoa fills str backwards and can return a pointer different from str
extern "C" char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix)
{
extern "C" char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) {
str += --slen;
*str = 0;
do
{
do {
auto mod = val % radix;
val /= radix;
*--str = mod + ((mod > 9) ? ('a' - 10) : '0');
} while (--slen && val);
return val? nullptr: str;
return val ? nullptr : str;
}
// lltoa fills str backwards and can return a pointer different from str
extern "C" char* lltoa (long long val, char* str, int slen, unsigned int radix)
{
extern "C" char* lltoa(long long val, char* str, int slen, unsigned int radix) {
bool neg;
if (val < 0)
{
if (val < 0) {
val = -val;
neg = true;
}
else
{
} else {
neg = false;
}
char* ret = ulltoa(val, str, slen, radix);
if (neg)
{
if (ret == str || ret == nullptr)
if (neg) {
if (ret == str || ret == nullptr) {
return nullptr;
}
*--ret = '-';
}
return ret;
@@ -92,7 +86,7 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
int fillme = width; // how many cells to fill for the integer part
if (prec > 0) {
fillme -= (prec+1);
fillme -= (prec + 1);
}
// Handle negative numbers
@@ -105,8 +99,9 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
// Round correctly so that print(1.999, 2) prints as "2.00"
// I optimized out most of the divisions
double rounding = 2.0;
for (uint8_t i = 0; i < prec; ++i)
for (uint8_t i = 0; i < prec; ++i) {
rounding *= 10.0;
}
rounding = 1.0 / rounding;
number += rounding;
@@ -132,14 +127,18 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
}
// Handle negative sign
if (negative) *out++ = '-';
if (negative) {
*out++ = '-';
}
// Print the digits, and if necessary, the decimal point
digitcount += prec;
int8_t digit = 0;
while (digitcount-- > 0) {
digit = (int8_t)number;
if (digit > 9) digit = 9; // insurance
if (digit > 9) {
digit = 9; // insurance
}
*out++ = (char)('0' | digit);
if ((digitcount == prec) && (prec > 0)) {
*out++ = '.';
@@ -161,8 +160,7 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
*/
extern "C" const char* strrstr(const char*__restrict p_pcString,
const char*__restrict p_pcPattern)
{
const char*__restrict p_pcPattern) {
const char* pcResult = 0;
size_t stStringLength = (p_pcString ? strlen(p_pcString) : 0);
@@ -170,13 +168,10 @@ extern "C" const char* strrstr(const char*__restrict p_pcString,
if ((stStringLength) &&
(stPatternLength) &&
(stPatternLength <= stStringLength))
{
(stPatternLength <= stStringLength)) {
// Pattern is shorter or has the same length than the string
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s)
{
if (0 == strncmp(s, p_pcPattern, stPatternLength))
{
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s) {
if (0 == strncmp(s, p_pcPattern, stPatternLength)) {
pcResult = s;
break;
}
+22 -22
View File
@@ -1,29 +1,29 @@
/*
stdlib_noniso.h - nonstandard (but useful) conversion functions
stdlib_noniso.h - nonstandard (but useful) conversion functions
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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 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.
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
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef STDLIB_NONISO_H
#define STDLIB_NONISO_H
#ifdef __cplusplus
extern "C"{
extern "C" {
#endif
int atoi(const char *s);
@@ -32,19 +32,19 @@ long atol(const char* s);
double atof(const char* s);
char* itoa (int val, char *s, int radix);
char* itoa(int val, char *s, int radix);
char* ltoa (long val, char *s, int radix);
char* ltoa(long val, char *s, int radix);
char* lltoa (long long val, char* str, int slen, unsigned int radix);
char* lltoa(long long val, char* str, int slen, unsigned int radix);
char* utoa (unsigned int val, char *s, int radix);
char* utoa(unsigned int val, char *s, int radix);
char* ultoa (unsigned long val, char *s, int radix);
char* ultoa(unsigned long val, char *s, int radix);
char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix);
char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix);
char* dtostrf (double val, signed char width, unsigned char prec, char *s);
char* dtostrf(double val, signed char width, unsigned char prec, char *s);
void reverse(char* begin, char* end);
+15 -15
View File
@@ -14,16 +14,16 @@
#define tone_wrap 7
static const uint16_t tone_program_instructions[] = {
// .wrap_target
0x80a0, // 0: pull block
0xa027, // 1: mov x, osr
0xb846, // 2: mov y, isr side 1
0x0083, // 3: jmp y--, 3
0x0045, // 4: jmp x--, 5
0xb046, // 5: mov y, isr side 0
0x0086, // 6: jmp y--, 6
0x0042, // 7: jmp x--, 2
// .wrap
// .wrap_target
0x80a0, // 0: pull block
0xa027, // 1: mov x, osr
0xb846, // 2: mov y, isr side 1
0x0083, // 3: jmp y--, 3
0x0045, // 4: jmp x--, 5
0xb046, // 5: mov y, isr side 0
0x0086, // 6: jmp y--, 6
0x0042, // 7: jmp x--, 2
// .wrap
};
#if !PICO_NO_HARDWARE
@@ -41,11 +41,11 @@ static inline pio_sm_config tone_program_get_default_config(uint offset) {
}
static inline void tone_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = tone_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
pio_sm_init(pio, sm, offset, &c);
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = tone_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
pio_sm_init(pio, sm, offset, &c);
}
#endif
+25 -26
View File
@@ -1,22 +1,22 @@
/*
* PWM and analogRead for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
PWM and analogRead for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <CoreMutex.h>
@@ -26,8 +26,7 @@
#include <hardware/pll.h>
#include <hardware/adc.h>
static int32_t analogScale = 255;
static uint32_t analogMap = 0;
static uint32_t analogScale = 255;
static uint16_t analogFreq = 1000;
static bool pwmInitted = false;
static bool adcInitted = false;
@@ -73,23 +72,23 @@ extern "C" void analogWriteResolution(int res) {
extern "C" void analogWrite(pin_size_t pin, int val) {
CoreMutex m(&_dacMutex);
if ((pin < 0) || (pin > 29) || !m) {
if ((pin > 29) || !m) {
DEBUGCORE("ERROR: Illegal analogWrite pin (%d)\n", pin);
return;
}
if (!pwmInitted) {
pwm_config c = pwm_get_default_config();
pwm_config_set_clkdiv( &c, clock_get_hz(clk_sys) / (float) (analogScale * analogFreq) );
pwm_config_set_wrap( &c, analogScale );
for (int i=0; i<30; i++) {
pwm_config_set_clkdiv(&c, clock_get_hz(clk_sys) / (float)(analogScale * analogFreq));
pwm_config_set_wrap(&c, analogScale);
for (int i = 0; i < 30; i++) {
pwm_init(pwm_gpio_to_slice_num(i), &c, true);
}
pwmInitted = true;
}
if (val < 0) {
val = 0;
} else if (val > analogScale) {
} else if ((uint32_t)val > analogScale) {
val = analogScale;
}
+48 -49
View File
@@ -1,65 +1,65 @@
/*
* pinMode and digitalRead/Write for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
pinMode and digitalRead/Write for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Arduino.h"
#include <hardware/gpio.h>
static PinMode _pm[30];
extern "C" void pinMode( pin_size_t ulPin, PinMode ulMode ) {
extern "C" void pinMode(pin_size_t ulPin, PinMode ulMode) {
switch (ulMode) {
case INPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
break;
case INPUT_PULLUP:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_up(ulPin);
gpio_put(ulPin, 0);
break;
case INPUT_PULLDOWN:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_down(ulPin);
gpio_put(ulPin, 1);
break;
case OUTPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, true);
break;
default:
DEBUGCORE("ERROR: Illegal pinMode mode (%d)\n", ulMode);
// Error
return;
case INPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
break;
case INPUT_PULLUP:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_up(ulPin);
gpio_put(ulPin, 0);
break;
case INPUT_PULLDOWN:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_down(ulPin);
gpio_put(ulPin, 1);
break;
case OUTPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, true);
break;
default:
DEBUGCORE("ERROR: Illegal pinMode mode (%d)\n", ulMode);
// Error
return;
}
if ((ulPin < 0) || (ulPin > 29)) {
if (ulPin > 29) {
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
return;
}
_pm[ulPin] = ulMode;
}
extern "C" void digitalWrite( pin_size_t ulPin, PinStatus ulVal ) {
if ((ulPin < 0) || (ulPin > 29)) {
extern "C" void digitalWrite(pin_size_t ulPin, PinStatus ulVal) {
if (ulPin > 29) {
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
return;
}
@@ -80,11 +80,10 @@ extern "C" void digitalWrite( pin_size_t ulPin, PinStatus ulVal ) {
}
}
extern "C" PinStatus digitalRead( pin_size_t ulPin ) {
if ((ulPin < 0) || (ulPin > 29)) {
extern "C" PinStatus digitalRead(pin_size_t ulPin) {
if (ulPin > 29) {
DEBUGCORE("ERROR: Illegal pin in digitalRead (%d)\n", ulPin);
return LOW;
}
return gpio_get(ulPin) ? HIGH : LOW;
}
+26 -25
View File
@@ -1,22 +1,22 @@
/*
* wiring_private for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
wiring_private for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <CoreMutex.h>
@@ -48,10 +48,11 @@ auto_init_mutex(_irqMutex);
static std::map<pin_size_t, voidFuncPtr> _map;
void _gpioInterruptDispatcher(uint gpio, uint32_t events) {
(void) events;
// Only need to lock around the std::map check, not the whole IRQ callback
voidFuncPtr cb = nullptr;
{
CoreMutex m(&_irqMutex);
CoreMutex m(&_irqMutex);
if (m) {
auto irq = _map.find(gpio);
if (irq != _map.end()) {
@@ -74,12 +75,12 @@ extern "C" void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus
uint32_t events;
switch (mode) {
case LOW: events = 1; break;
case HIGH: events = 2; break;
case FALLING: events = 4; break;
case RISING: events = 8; break;
case CHANGE: events = 4 | 8; break;
default: return; // ERROR
case LOW: events = 1; break;
case HIGH: events = 2; break;
case FALLING: events = 4; break;
case RISING: events = 8; break;
case CHANGE: events = 4 | 8; break;
default: return; // ERROR
}
noInterrupts();
detachInterrupt(pin);
+33 -29
View File
@@ -1,55 +1,59 @@
/*
* pulseIn for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
pulseIn for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <hardware/timer.h>
#include <hardware/gpio.h>
extern "C" unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
extern "C" unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) {
uint64_t start = time_us_64();
uint64_t abort = start + timeout;
if ((pin < 0) || (pin > 29)) {
if (pin > 29) {
DEBUGCORE("ERROR: Illegal pin in pulseIn (%d)\n", pin);
return 0;
}
// Wait for deassert, if needed
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort) );
if (time_us_64() >= abort) return 0;
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort));
if (time_us_64() >= abort) {
return 0;
}
// Wait for assert
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort) );
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort));
uint64_t begin = time_us_64();
if (begin >= abort) return 0;
if (begin >= abort) {
return 0;
}
// Wait for deassert
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort) );
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort));
uint64_t end = time_us_64();
if (end >= abort) return 0;
if (end >= abort) {
return 0;
}
return end - begin;
}
extern "C" unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
extern "C" unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) {
return pulseIn(pin, state, timeout);
}
+34 -32
View File
@@ -1,22 +1,22 @@
/*
* wiring_shift.c - shiftOut() function
* Part of Arduino - http://www.arduino.cc/
*
* Copyright (c) 2005-2006 David A. Mellis
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA
wiring_shift.c - shiftOut() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
#include <Arduino.h>
@@ -24,42 +24,44 @@
extern "C" uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder) {
uint8_t value = 0;
uint8_t i;
if ((dataPin < 0) || (dataPin > 29)) {
if (dataPin > 29) {
DEBUGCORE("ERROR: Illegal dataPin in shiftIn (%d)\n", dataPin);
return 0;
}
if ((clockPin < 0) || (clockPin > 29)) {
if (clockPin > 29) {
DEBUGCORE("ERROR: Illegal clockPin in shiftIn (%d)\n", clockPin);
return 0;
}
for (i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST) {
value |= digitalRead(dataPin) << i;
} else {
value |= digitalRead(dataPin) << (7 - i);
}
digitalWrite(clockPin, LOW);
}
return value;
}
extern "C" void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val) {
uint8_t i;
if ((dataPin < 0) || (dataPin > 29)) {
if (dataPin > 29) {
DEBUGCORE("ERROR: Illegal dataPin in shiftOut (%d)\n", dataPin);
return;
}
if ((clockPin < 0) || (clockPin > 29)) {
if (clockPin > 29) {
DEBUGCORE("ERROR: Illegal clockPin in shiftOut (%d)\n", clockPin);
return;
}
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
if (bitOrder == LSBFIRST) {
digitalWrite(dataPin, !!(val & (1 << i)));
else
} else {
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
}
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, LOW);
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ EEPROM Library
While the Raspberry Pi Pico RP2040 does not come with an EEPROM onboard, we
simulate one by using a single 4K chunk of flash at the end of flash space.
**Note that this is a simulated EEPROM and will only support the numeber of
**Note that this is a simulated EEPROM and will only support the number of
writes as the onboard flash chip, not the 100,000 or so of a real EEPROM.**
Therefore, do not frequently update the EEPROM or you may prematurely wear
out the flash.
+1 -1
View File
@@ -3,7 +3,7 @@ File Systems
The Arduino-Pico core supports using some of the onboard flash as a file
system, useful for storing configuration data, output strings, logging,
and more. It also supports using SD cards as another (FAT32) filesytem,
and more. It also supports using SD cards as another (FAT32) filesystem,
with an API that's compatible with the onboard flash file system.
+1 -1
View File
@@ -47,7 +47,7 @@ the output will be changing.
size_t write(uint8_t)
~~~~~~~~~~~~~~~~~~~~~
Provided for compatibilty, but not very useful. Writes a sample from 0...255
Provided for compatibility, but not very useful. Writes a sample from 0...255
to the I2S buffer. See ``write(int16_t)`` for a better one
size_t write(const uint8_t \*buffer, size_t size)
+1 -1
View File
@@ -1,4 +1,4 @@
## Welcome to Arduino-Pico
Please go to https://arduino-pico.readthedocs.io/en/latest/ for the
Please go to [https://arduino-pico.readthedocs.io/en/latest/](https://arduino-pico.readthedocs.io/en/latest/) for the
latest documentation.
+1 -1
View File
@@ -31,7 +31,7 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
SPI <spi>
Wire(I2C) <wire>
File Systems (SD, SDFS, LittleFS) <fs>
USB Keyboard/Mouse <usb>
USB (Arduino and Adafruit_TinyUSB) <usb>
Multicore Processing <multicore>
Ported/Optimized Libraries <libraries>
+2 -2
View File
@@ -1,5 +1,5 @@
Intallation
===========
Installation
============
The Arduino-Pico core can be installed using the Arduino IDE Boards Manager
or using `git`. If you want to simply write programs for your RP2040 board,
+40 -3
View File
@@ -1,7 +1,17 @@
USB Keyboard and Mouse
======================
USB (Arduino and Adafruit_TinyUSB)
==================================
The Arduino-Pico core includes ported versions of the standard Arduino
Two USB stacks are present in the core. Users can choose the simpler
Pico-SDK version or the more powerful Adafruit TinyUSB library.
Use the ``Tools->USB Stack`` menu to select between the two.
Pico SDK USB Support
--------------------
This is the default mode and automatically includes a USB-based
serial port, ``Serial`` as well as supporting automatic reset-to-upload
from the IDE.
The Arduino-Pico core includes ported versions of the basic Arduino
``Keyboard`` and ``Mouse`` libraries. These libraries allow you to
emulate a keyboard or mouse with the Pico in your sketches.
@@ -9,3 +19,30 @@ 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
Adafruit TinyUSB Arduino Support
--------------------------------
Examples are provided in the Adafruit_TinyUSB_Arduino for the more
advanced USB stack.
To use Serial with TinyUSB, you must include the TinyUSB header in your
sketch to avoid a compile error.
.. code:: cpp
#include <Adafruit_TinyUSB.h>
If you need to be compatible with the
other USB stack, you can use an ifdef:
.. code:: cpp
#ifdef USE_TINYUSB
#include <Adafruit_TinyUSB.h>
#endif
Also, this stack requires sketches to manually call
``Serial.begin(115200)`` to enable the USB serial port and automatic
sketch upload from the IDE. If a sketch is run without this command
in ``setup()``, the user will need to use the standard "hold BOOTSEL
and plug in USB" method to enter program upload mode.
+11 -5
View File
@@ -1,18 +1,24 @@
Wire (I2C Master and Slave)
===========================
The RP2040 has two I2C devices, ``i2c0 (Wire)`` and ``i2c1 (Wire1)``
The RP2040 has two I2C devices, ``i2c0 (Wire)`` and ``i2c1 (Wire1)``.
The current implementation is compatible with the Arduino standard
with the addition of two calls to allof the `SDA` and `SCL` pins
to be set **before calling Wire.begin()**
The default pins for `Wire` and `Wire1` vary depending on which board you're using.
(Here are the pinout diagrams for `Pico <https://datasheets.raspberrypi.org/pico/Pico-R3-A4-Pinout.pdf>`_
and `Adafruit Feather <https://learn.adafruit.com/assets/100740>`_.)
You may change these pins **before calling Wire.begin() or Wire1.begin()** using:
.. code:: cpp
bool setSDA(pin_size_t sda);
bool setSCL(pin_size_t scl);
Both master and slave operation is supported.
Be sure to use pins labeled ``I2C0`` for Wire and ``I2C1`` for Wire1 on the pinout
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
on ``endTransmission``, as is standard with modern Arduino Wire implementations.
+28 -26
View File
@@ -1,23 +1,23 @@
/*
* EEPROM.cpp - RP2040 EEPROM emulation
* Copyright (c) 2021 Earle F. Philhower III. All rights reserved.
*
* Based on ESP8266 EEPROM library, which is
* Copyright (c) 2014 Ivan Grokhotkov. 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
EEPROM.cpp - RP2040 EEPROM emulation
Copyright (c) 2021 Earle F. Philhower III. All rights reserved.
Based on ESP8266 EEPROM library, which is
Copyright (c) 2014 Ivan Grokhotkov. 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
*/
#include <Arduino.h>
@@ -28,8 +28,7 @@
extern "C" uint8_t _EEPROM_start;
EEPROMClass::EEPROMClass(void)
: _sector(&_EEPROM_start)
{
: _sector(&_EEPROM_start) {
}
void EEPROMClass::begin(size_t size) {
@@ -43,7 +42,7 @@ void EEPROMClass::begin(size_t size) {
if (_data && size != _size) {
delete[] _data;
_data = new uint8_t[size];
} else if(!_data) {
} else if (!_data) {
_data = new uint8_t[size];
}
@@ -60,7 +59,7 @@ bool EEPROMClass::end() {
}
retval = commit();
if (_data) {
if (_data) {
delete[] _data;
}
_data = 0;
@@ -98,12 +97,15 @@ void EEPROMClass::write(int const address, uint8_t const value) {
}
bool EEPROMClass::commit() {
if (!_size)
if (!_size) {
return false;
if (!_dirty)
}
if (!_dirty) {
return true;
if (!_data)
}
if (!_data) {
return false;
}
noInterrupts();
rp2040.idleOtherCore();
+56 -48
View File
@@ -1,22 +1,22 @@
/*
EEPROM.cpp - RPI2040 EEPROM emulation
/*
EEPROM.cpp - RPI2040 EEPROM emulation
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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.
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
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.
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.
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
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EEPROM_h
@@ -28,48 +28,56 @@
class EEPROMClass {
public:
EEPROMClass(void);
EEPROMClass(void);
void begin(size_t size);
uint8_t read(int const address);
void write(int const address, uint8_t const val);
bool commit();
bool end();
void begin(size_t size);
uint8_t read(int const address);
void write(int const address, uint8_t const val);
bool commit();
bool end();
uint8_t * getDataPtr();
uint8_t const * getConstDataPtr() const;
uint8_t * getDataPtr();
uint8_t const * getConstDataPtr() const;
template<typename T>
T &get(int const address, T &t) {
if (address < 0 || address + sizeof(T) > _size)
return t;
template<typename T>
T &get(int const address, T &t) {
if (address < 0 || address + sizeof(T) > _size) {
return t;
}
memcpy((uint8_t*) &t, _data + address, sizeof(T));
return t;
}
template<typename T>
const T &put(int const address, const T &t) {
if (address < 0 || address + sizeof(T) > _size)
return t;
if (memcmp(_data + address, (const uint8_t*)&t, sizeof(T)) != 0) {
_dirty = true;
memcpy(_data + address, (const uint8_t*)&t, sizeof(T));
memcpy((uint8_t*) &t, _data + address, sizeof(T));
return t;
}
return t;
}
template<typename T>
const T &put(int const address, const T &t) {
if (address < 0 || address + sizeof(T) > _size) {
return t;
}
if (memcmp(_data + address, (const uint8_t*)&t, sizeof(T)) != 0) {
_dirty = true;
memcpy(_data + address, (const uint8_t*)&t, sizeof(T));
}
size_t length() {return _size;}
return t;
}
uint8_t& operator[](int const address) {return getDataPtr()[address];}
uint8_t const & operator[](int const address) const {return getConstDataPtr()[address];}
size_t length() {
return _size;
}
uint8_t& operator[](int const address) {
return getDataPtr()[address];
}
uint8_t const & operator[](int const address) const {
return getConstDataPtr()[address];
}
protected:
uint8_t* _sector;
uint8_t* _data = nullptr;
size_t _size = 0;
bool _dirty = false;
uint8_t* _sector;
uint8_t* _data = nullptr;
size_t _size = 0;
bool _dirty = false;
};
extern EEPROMClass EEPROM;
+23 -21
View File
@@ -1,22 +1,22 @@
/*
* I2S Master library for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
I2S Master library for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include "I2S.h"
@@ -32,17 +32,19 @@ I2SClass::I2SClass() {
}
bool I2SClass::setBCLK(pin_size_t pin) {
if (_running || (pin < 0) || (pin > 28)) {
if (_running || (pin > 28)) {
return false;
}
_pinBCLK = pin;
return true;
}
bool I2SClass::setDOUT(pin_size_t pin) {
if (_running || (pin < 0) || (pin > 29)) {
if (_running || (pin > 29)) {
return false;
}
_pinDOUT = pin;
return true;
}
bool I2SClass::begin(long sampleRate) {
@@ -204,7 +206,7 @@ size_t I2SClass::write(const void *buffer, size_t size) {
_curBuff->sample_count += writeSize;
inSamples += writeSize;
written += writeSize;
wantToWrite -= writeSize;
wantToWrite -= writeSize;
if (_curBuff->sample_count == _curBuff->max_sample_count) {
_audio_format.sample_freq = _freq;
give_audio_buffer(_pool, _curBuff);
+53 -48
View File
@@ -1,65 +1,70 @@
/*
* I2S Master library for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
I2S Master library for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <Arduino.h>
#include "pico/audio_i2s.h"
class I2SClass : public Stream
{
class I2SClass : public Stream {
public:
I2SClass();
I2SClass();
// Only 16 bitsPerSample are allowed by the PIO code. Only write, no read.
bool setBCLK(pin_size_t pin);
bool setDOUT(pin_size_t pin);
bool begin(long sampleRate);
void end();
// Only 16 bitsPerSample are allowed by the PIO code. Only write, no read.
bool setBCLK(pin_size_t pin);
bool setDOUT(pin_size_t pin);
bool begin(long sampleRate);
void end();
// from Stream
virtual int available() override { return -1; }
virtual int read() override { return -1; }
virtual int peek() override { return -1; }
virtual void flush() override;
// from Stream
virtual int available() override {
return -1;
}
virtual int read() override {
return -1;
}
virtual int peek() override {
return -1;
}
virtual void flush() override;
// from Print (see notes on write() methods below)
virtual size_t write(uint8_t) override;
virtual size_t write(const uint8_t *buffer, size_t size) override;
virtual int availableForWrite() override;
// from Print (see notes on write() methods below)
virtual size_t write(uint8_t) override;
virtual size_t write(const uint8_t *buffer, size_t size) override;
virtual int availableForWrite() override;
bool setFrequency(int newFreq);
bool setFrequency(int newFreq);
// Write a single L:R sample to the I2S device. Blocking until write succeeds
size_t write(int16_t);
// Write up to size samples to the I2S device. Non-blocking, will write
// from 0...size samples and return that count. Be sure your app handles
// partial writes (i.e. by yield()ing and then retrying to write the
// remaining data.
size_t write(const void *buffer, size_t lrsamples);
// Write a single L:R sample to the I2S device. Blocking until write succeeds
size_t write(int16_t);
// Write up to size samples to the I2S device. Non-blocking, will write
// from 0...size samples and return that count. Be sure your app handles
// partial writes (i.e. by yield()ing and then retrying to write the
// remaining data.
size_t write(const void *buffer, size_t lrsamples);
// Note that these callback are called from **INTERRUPT CONTEXT** and hence
// must be both stored in IRAM and not perform anything that's not legal in
// an interrupt
//void onTransmit(void(*)(void)); -- Not yet implemented, need to edit pico-extra to get callback
//void onReceive(void(*)(void)); -- no I2S input yet
// Note that these callback are called from **INTERRUPT CONTEXT** and hence
// must be both stored in IRAM and not perform anything that's not legal in
// an interrupt
//void onTransmit(void(*)(void)); -- Not yet implemented, need to edit pico-extra to get callback
//void onReceive(void(*)(void)); -- no I2S input yet
private:
pin_size_t _pinBCLK;
+31 -31
View File
@@ -1,24 +1,24 @@
/*
LittleFS.cpp - Wrapper for LittleFS for RP2040
Copyright (c) 2021 Earle F. Philhower, III. All rights reserved.
LittleFS.cpp - Wrapper for LittleFS for RP2040
Copyright (c) 2021 Earle F. Philhower, III. All rights reserved.
Based extensively off of the ESP8266 SPIFFS code, which is
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
Based extensively off of the ESP8266 SPIFFS code, which is
Copyright (c) 2015 Ivan Grokhotkov. 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 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.
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
*/
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <stdlib.h>
@@ -60,7 +60,7 @@ FileImplPtr LittleFSImpl::open(const char* path, OpenMode openMode, AccessMode a
*ptr = 0;
lfs_mkdir(&_lfs, pathStr);
*ptr = '/';
ptr = strchr(ptr+1, '/');
ptr = strchr(ptr + 1, '/');
}
}
free(pathStr);
@@ -71,7 +71,7 @@ FileImplPtr LittleFSImpl::open(const char* path, OpenMode openMode, AccessMode a
// O_CREATE means we *may* make the file, but not if it already exists.
// See if it exists, and only if not update the creation time
int rc = lfs_file_open(&_lfs, fd.get(), path, LFS_O_RDONLY);
if (rc == 0) {
if (rc == 0) {
lfs_file_close(&_lfs, fd.get()); // It exists, don't update create time
} else {
creation = _timeCallback(); // File didn't exist or otherwise, so we're going to create this time
@@ -99,8 +99,8 @@ DirImplPtr LittleFSImpl::openDir(const char *path) {
}
char *pathStr = strdup(path); // Allow edits on our scratch copy
// Get rid of any trailing slashes
while (strlen(pathStr) && (pathStr[strlen(pathStr)-1]=='/')) {
pathStr[strlen(pathStr)-1] = 0;
while (strlen(pathStr) && (pathStr[strlen(pathStr) - 1] == '/')) {
pathStr[strlen(pathStr) - 1] = 0;
}
// At this point we have a name of "blah/blah/blah" or "blah" or ""
// If that references a directory, just open it and we're done.
@@ -116,34 +116,34 @@ DirImplPtr LittleFSImpl::openDir(const char *path) {
if (info.type == LFS_TYPE_DIR) {
// Easy peasy, path specifies an existing dir!
rc = lfs_dir_open(&_lfs, dir.get(), pathStr);
filter = "";
filter = "";
} else {
// This is a file, so open the containing dir
char *ptr = strrchr(pathStr, '/');
if (!ptr) {
// No slashes, open the root dir
rc = lfs_dir_open(&_lfs, dir.get(), "/");
filter = pathStr;
filter = pathStr;
} else {
// We've got slashes, open the dir one up
*ptr = 0; // Remove slash, truncate string
rc = lfs_dir_open(&_lfs, dir.get(), pathStr);
filter = ptr + 1;
filter = ptr + 1;
}
}
} else {
} else {
// Name doesn't exist, so use the parent dir of whatever was sent in
// This is a file, so open the containing dir
char *ptr = strrchr(pathStr, '/');
if (!ptr) {
// No slashes, open the root dir
rc = lfs_dir_open(&_lfs, dir.get(), "/");
filter = pathStr;
filter = pathStr;
} else {
// We've got slashes, open the dir one up
*ptr = 0; // Remove slash, truncate string
rc = lfs_dir_open(&_lfs, dir.get(), pathStr);
filter = ptr + 1;
filter = ptr + 1;
}
}
if (rc < 0) {
@@ -162,20 +162,20 @@ DirImplPtr LittleFSImpl::openDir(const char *path) {
}
int LittleFSImpl::lfs_flash_read(const struct lfs_config *c,
lfs_block_t block, lfs_off_t off, void *dst, lfs_size_t size) {
lfs_block_t block, lfs_off_t off, void *dst, lfs_size_t size) {
LittleFSImpl *me = reinterpret_cast<LittleFSImpl*>(c->context);
// Serial.printf(" READ: %p, %d\n", me->_start + (block * me->_blockSize) + off, size);
// Serial.printf(" READ: %p, %d\n", me->_start + (block * me->_blockSize) + off, size);
memcpy(dst, me->_start + (block * me->_blockSize) + off, size);
return 0;
}
int LittleFSImpl::lfs_flash_prog(const struct lfs_config *c,
lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
LittleFSImpl *me = reinterpret_cast<LittleFSImpl*>(c->context);
uint8_t *addr = me->_start + (block * me->_blockSize) + off;
noInterrupts();
rp2040.idleOtherCore();
// Serial.printf("WRITE: %p, $d\n", (intptr_t)addr - (intptr_t)XIP_BASE, size);
// Serial.printf("WRITE: %p, $d\n", (intptr_t)addr - (intptr_t)XIP_BASE, size);
flash_range_program((intptr_t)addr - (intptr_t)XIP_BASE, (const uint8_t *)buffer, size);
rp2040.resumeOtherCore();
interrupts();
@@ -185,7 +185,7 @@ int LittleFSImpl::lfs_flash_prog(const struct lfs_config *c,
int LittleFSImpl::lfs_flash_erase(const struct lfs_config *c, lfs_block_t block) {
LittleFSImpl *me = reinterpret_cast<LittleFSImpl*>(c->context);
uint8_t *addr = me->_start + (block * me->_blockSize);
// Serial.printf("ERASE: %p, %d\n", (intptr_t)addr - (intptr_t)XIP_BASE, me->_blockSize);
// Serial.printf("ERASE: %p, %d\n", (intptr_t)addr - (intptr_t)XIP_BASE, me->_blockSize);
noInterrupts();
rp2040.idleOtherCore();
flash_range_erase((intptr_t)addr - (intptr_t)XIP_BASE, me->_blockSize);
+40 -43
View File
@@ -1,27 +1,27 @@
/*
LittleFS.h - Filesystem wrapper for LittleFS on the RP2040
Copyright (c) 2019 Earle F. Philhower, III. All rights reserved.
LittleFS.h - Filesystem wrapper for LittleFS on the RP2040
Copyright (c) 2019 Earle F. Philhower, III. All rights reserved.
Based heavily off of the SPIFFS equivalent code in the ESP8266 core
"Copyright (c) 2015 Ivan Grokhotkov. All rights reserved."
Based heavily off of the SPIFFS equivalent code in the ESP8266 core
"Copyright (c) 2015 Ivan Grokhotkov. All rights reserved."
This code was influenced by NodeMCU and Sming libraries, and first version of
Arduino wrapper written by Hristo Gochkov.
This code was influenced by NodeMCU and Sming libraries, and first version of
Arduino wrapper written by Hristo Gochkov.
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 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.
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
*/
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __LITTLEFS_H
@@ -41,18 +41,16 @@ namespace littlefs_impl {
class LittleFSFileImpl;
class LittleFSDirImpl;
class LittleFSConfig : public FSConfig
{
class LittleFSConfig : public FSConfig {
public:
static constexpr uint32_t FSId = 0x4c495454;
LittleFSConfig(bool autoFormat = true) : FSConfig(FSId, autoFormat) { }
};
class LittleFSImpl : public FSImpl
{
class LittleFSImpl : public FSImpl {
public:
LittleFSImpl(uint8_t *start, uint32_t size, uint32_t pageSize, uint32_t blockSize, uint32_t maxOpenFds)
: _start(start) , _size(size) , _pageSize(pageSize) , _blockSize(blockSize) , _maxOpenFds(maxOpenFds),
: _start(start), _size(size), _pageSize(pageSize), _blockSize(blockSize), _maxOpenFds(maxOpenFds),
_mounted(false) {
memset(&_lfs, 0, sizeof(_lfs));
memset(&_lfs_cfg, 0, sizeof(_lfs_cfg));
@@ -64,7 +62,7 @@ public:
_lfs_cfg.read_size = 256;
_lfs_cfg.prog_size = 256;
_lfs_cfg.block_size = _blockSize;
_lfs_cfg.block_count =_blockSize? _size / _blockSize: 0;
_lfs_cfg.block_count = _blockSize ? _size / _blockSize : 0;
_lfs_cfg.block_cycles = 16; // TODO - need better explanation
_lfs_cfg.cache_size = 256;
_lfs_cfg.lookahead_size = 256;
@@ -162,7 +160,7 @@ public:
return false;
}
int rc = lfs_mkdir(&_lfs, path);
return (rc==0);
return (rc == 0);
}
bool rmdir(const char* path) override {
@@ -174,7 +172,7 @@ public:
return false;
}
_cfg = *static_cast<const LittleFSConfig *>(&cfg);
return true;
return true;
}
bool begin() override {
@@ -218,7 +216,7 @@ public:
return false;
}
if(_timeCallback && _tryMount()) {
if (_timeCallback && _tryMount()) {
// Mounting is required to set attributes
time_t t = _timeCallback();
@@ -233,7 +231,7 @@ public:
DEBUGV("lfs_format, lfs_setattr 't': rc=%d\n", rc);
return false;
}
lfs_unmount(&_lfs);
_mounted = false;
}
@@ -274,7 +272,7 @@ protected:
}
memset(&_lfs, 0, sizeof(_lfs));
int rc = lfs_mount(&_lfs, &_lfs_cfg);
if (rc==0) {
if (rc == 0) {
_mounted = true;
}
return _mounted;
@@ -302,7 +300,7 @@ protected:
mode |= LFS_O_RDONLY;
}
if (accessMode & AM_WRITE) {
mode |= LFS_O_WRONLY;
mode |= LFS_O_WRONLY;
}
return mode;
}
@@ -350,8 +348,7 @@ protected:
};
class LittleFSFileImpl : public FileImpl
{
class LittleFSFileImpl : public FileImpl {
public:
LittleFSFileImpl(LittleFSImpl* fs, const char *name, std::shared_ptr<lfs_file_t> fd, int flags, time_t creation) : _fs(fs), _fd(fd), _opened(true), _flags(flags), _creation(creation) {
_name = std::shared_ptr<char>(new char[strlen(name) + 1], std::default_delete<char[]>());
@@ -434,7 +431,7 @@ public:
}
size_t size() const override {
return (_opened && _fd)? lfs_file_size(_fs->getFS(), _getFD()) : 0;
return (_opened && _fd) ? lfs_file_size(_fs->getFS(), _getFD()) : 0;
}
bool truncate(uint32_t size) override {
@@ -476,8 +473,9 @@ public:
time_t ftime = 0;
if (_opened && _fd) {
int rc = lfs_getattr(_fs->getFS(), _name.get(), 't', (void *)&ftime, sizeof(ftime));
if (rc != sizeof(ftime))
ftime = 0; // Error, so clear read value
if (rc != sizeof(ftime)) {
ftime = 0; // Error, so clear read value
}
}
return ftime;
}
@@ -486,8 +484,9 @@ public:
time_t ftime = 0;
if (_opened && _fd) {
int rc = lfs_getattr(_fs->getFS(), _name.get(), 'c', (void *)&ftime, sizeof(ftime));
if (rc != sizeof(ftime))
ftime = 0; // Error, so clear read value
if (rc != sizeof(ftime)) {
ftime = 0; // Error, so clear read value
}
}
return ftime;
}
@@ -539,12 +538,10 @@ protected:
time_t _creation;
};
class LittleFSDirImpl : public DirImpl
{
class LittleFSDirImpl : public DirImpl {
public:
LittleFSDirImpl(const String& pattern, LittleFSImpl* fs, std::shared_ptr<lfs_dir_t> dir, const char *dirPath = nullptr)
: _pattern(pattern) , _fs(fs) , _dir(dir) , _dirPath(nullptr), _valid(false), _opened(true)
{
: _pattern(pattern), _fs(fs), _dir(dir), _dirPath(nullptr), _valid(false), _opened(true) {
memset(&_dirent, 0, sizeof(_dirent));
if (dirPath) {
_dirPath = std::shared_ptr<char>(new char[strlen(dirPath) + 1], std::default_delete<char[]>());
@@ -566,7 +563,7 @@ public:
nameLen += _dirPath.get() ? strlen(_dirPath.get()) : 0;
nameLen += strlen(_dirent.name);
char tmpName[nameLen];
snprintf(tmpName, nameLen, "%s%s%s", _dirPath.get() ? _dirPath.get() : "", _dirPath.get()&&_dirPath.get()[0]?"/":"", _dirent.name);
snprintf(tmpName, nameLen, "%s%s%s", _dirPath.get() ? _dirPath.get() : "", _dirPath.get() && _dirPath.get()[0] ? "/" : "", _dirent.name);
auto ret = _fs->open((const char *)tmpName, openMode, accessMode);
return ret;
}
@@ -661,7 +658,7 @@ protected:
nameLen += _dirPath.get() ? strlen(_dirPath.get()) : 0;
nameLen += strlen(_dirent.name);
char tmpName[nameLen];
snprintf(tmpName, nameLen, "%s%s%s", _dirPath.get() ? _dirPath.get() : "", _dirPath.get()&&_dirPath.get()[0]?"/":"", _dirent.name);
snprintf(tmpName, nameLen, "%s%s%s", _dirPath.get() ? _dirPath.get() : "", _dirPath.get() && _dirPath.get()[0] ? "/" : "", _dirent.name);
int rc = lfs_getattr(_fs->getFS(), tmpName, attr, dest, len);
return (rc == len);
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Can't place library in ths src/ directory, Arduino will attempt to build the tests/etc.
// Can't place library in the src/ directory, Arduino will attempt to build the tests/etc.
// Just have a stub here that redirects to the actual source file
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+40 -33
View File
@@ -1,20 +1,20 @@
/*
SD.h - A thin shim for Arduino ESP8266 Filesystems
Copyright (c) 2019 Earle F. Philhower, III. All rights reserved.
SD.h - A thin shim for Arduino ESP8266 Filesystems
Copyright (c) 2019 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 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.
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
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __SD_H__
@@ -33,7 +33,7 @@
class SDClass {
public:
boolean begin(uint8_t csPin, uint32_t cfg = SPI_HALF_SPEED) {
SDFS.setConfig(SDFSConfig(csPin, cfg));
SDFS.setConfig(SDFSConfig(csPin, cfg));
return (boolean)SDFS.begin();
}
@@ -83,7 +83,7 @@ public:
boolean mkdir(const String &filepath) {
return (boolean)SDFS.mkdir(filepath.c_str());
}
boolean remove(const char *filepath) {
return (boolean)SDFS.remove(filepath);
}
@@ -91,7 +91,7 @@ public:
boolean remove(const String &filepath) {
return remove(filepath.c_str());
}
boolean rmdir(const char *filepath) {
return (boolean)SDFS.rmdir(filepath);
}
@@ -135,7 +135,7 @@ public:
size_t size() {
uint64_t sz = size64();
#ifdef DEBUG_ESP_PORT
if (sz > (uint64_t)SIZE_MAX) {
if (sz > (uint64_t)SIZE_MAX) {
DEBUG_ESP_PORT.printf_P(PSTR("WARNING: SD card size overflow (%lld>= 4GB). Please update source to use size64().\n"), sz);
}
#endif
@@ -154,7 +154,7 @@ public:
void dateTimeCallback(void (*cb)(uint16_t*, uint16_t*)) {
extern void (*__SD__userDateTimeCB)(uint16_t*, uint16_t*);
__SD__userDateTimeCB = cb;
SDFS.setTimeCallback(wrapperTimeCB);
SDFS.setTimeCallback(wrapperTimeCB);
}
private:
@@ -162,12 +162,19 @@ private:
bool read = (mode & O_READ) ? true : false;
bool write = (mode & O_WRITE) ? true : false;
bool append = (mode & O_APPEND) ? true : false;
if ( read & !write ) { return "r"; }
else if ( !read & write & !append ) { return "w+"; }
else if ( !read & write & append ) { return "a"; }
else if ( read & write & !append ) { return "w+"; } // may be a bug in FS::mode interpretation, "r+" seems proper
else if ( read & write & append ) { return "a+"; }
else { return "r"; }
if (read & !write) {
return "r";
} else if (!read & write & !append) {
return "w+";
} else if (!read & write & append) {
return "a";
} else if (read & write & !append) {
return "w+"; // may be a bug in FS::mode interpretation, "r+" seems proper
} else if (read & write & append) {
return "a+";
} else {
return "r";
}
}
static time_t wrapperTimeCB(void) {
@@ -183,30 +190,30 @@ private:
};
// Expose FatStructs.h helpers for MSDOS date/time for use with dateTimeCallback
// Expose FatStructs.h helpers for MS-DOS date/time for use with dateTimeCallback
static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
return (year - 1980) << 9 | month << 5 | day;
return (year - 1980) << 9 | month << 5 | day;
}
static inline uint16_t FAT_YEAR(uint16_t fatDate) {
return 1980 + (fatDate >> 9);
return 1980 + (fatDate >> 9);
}
static inline uint8_t FAT_MONTH(uint16_t fatDate) {
return (fatDate >> 5) & 0XF;
return (fatDate >> 5) & 0XF;
}
static inline uint8_t FAT_DAY(uint16_t fatDate) {
return fatDate & 0X1F;
return fatDate & 0X1F;
}
static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
return hour << 11 | minute << 5 | second >> 1;
return hour << 11 | minute << 5 | second >> 1;
}
static inline uint8_t FAT_HOUR(uint16_t fatTime) {
return fatTime >> 11;
return fatTime >> 11;
}
static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
return (fatTime >> 5) & 0X3F;
return (fatTime >> 5) & 0X3F;
}
static inline uint8_t FAT_SECOND(uint16_t fatTime) {
return 2*(fatTime & 0X1F);
return 2 * (fatTime & 0X1F);
}
+95 -45
View File
@@ -1,22 +1,22 @@
/*
* SPI Master library for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
SPI Master library for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "SPI.h"
#include <hardware/spi.h>
@@ -34,26 +34,34 @@ SPIClassRP2040::SPIClassRP2040(spi_inst_t *spi, pin_size_t rx, pin_size_t cs, pi
}
inline spi_cpol_t SPIClassRP2040::cpol() {
switch(_spis.getDataMode()) {
case SPI_MODE0: return SPI_CPOL_0;
case SPI_MODE1: return SPI_CPOL_0;
case SPI_MODE2: return SPI_CPOL_1;
case SPI_MODE3: return SPI_CPOL_1;
switch (_spis.getDataMode()) {
case SPI_MODE0:
return SPI_CPOL_0;
case SPI_MODE1:
return SPI_CPOL_0;
case SPI_MODE2:
return SPI_CPOL_1;
case SPI_MODE3:
return SPI_CPOL_1;
}
// Error
return SPI_CPOL_0;
}
inline spi_cpha_t SPIClassRP2040::cpha() {
switch(_spis.getDataMode()) {
case SPI_MODE0: return SPI_CPHA_0;
case SPI_MODE1: return SPI_CPHA_1;
case SPI_MODE2: return SPI_CPHA_0;
case SPI_MODE3: return SPI_CPHA_1;
switch (_spis.getDataMode()) {
case SPI_MODE0:
return SPI_CPHA_0;
case SPI_MODE1:
return SPI_CPHA_1;
case SPI_MODE2:
return SPI_CPHA_0;
case SPI_MODE3:
return SPI_CPHA_1;
}
// Error
return SPI_CPHA_0;
}
}
inline uint8_t SPIClassRP2040::reverseByte(uint8_t b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
@@ -63,31 +71,33 @@ inline uint8_t SPIClassRP2040::reverseByte(uint8_t b) {
}
inline uint16_t SPIClassRP2040::reverse16Bit(uint16_t w) {
return ( reverseByte(w & 0xff) << 8 ) | ( reverseByte(w >> 8) );
return (reverseByte(w & 0xff) << 8) | (reverseByte(w >> 8));
}
// The HW can't do LSB first, only MSB first, so need to bitreverse
void SPIClassRP2040::adjustBuffer(const void *s, void *d, size_t cnt, bool by16) {
if (_spis.getBitOrder() == MSBFIRST) {
memcpy(d, s, cnt * (by16? 2 : 1));
memcpy(d, s, cnt * (by16 ? 2 : 1));
} else if (!by16) {
const uint8_t *src = (const uint8_t *)s;
uint8_t *dst = (uint8_t *)d;
for (auto i = 0; i < cnt; i++) {
*(dst++) = reverseByte( *(src++) );
for (size_t i = 0; i < cnt; i++) {
*(dst++) = reverseByte(*(src++));
}
} else { /* by16 */
const uint16_t *src = (const uint16_t *)s;
uint16_t *dst = (uint16_t *)d;
for (auto i = 0; i < cnt; i++) {
*(dst++) = reverse16Bit( *(src++) );
for (size_t i = 0; i < cnt; i++) {
*(dst++) = reverse16Bit(*(src++));
}
}
}
byte SPIClassRP2040::transfer(uint8_t data) {
uint8_t ret;
if (!_initted) return 0;
if (!_initted) {
return 0;
}
data = (_spis.getBitOrder() == MSBFIRST) ? data : reverseByte(data);
spi_set_format(_spi, 8, cpol(), cpha(), SPI_MSB_FIRST);
DEBUGSPI("SPI::transfer(%02x), cpol=%d, cpha=%d\n", data, cpol(), cpha());
@@ -114,7 +124,7 @@ uint16_t SPIClassRP2040::transfer16(uint16_t data) {
void SPIClassRP2040::transfer(void *buf, size_t count) {
DEBUGSPI("SPI::transfer(%p, %d)\n", buf, count);
uint8_t *buff = reinterpret_cast<uint8_t *>(buf);
for (auto i = 0; i < count; i++) {
for (size_t i = 0; i < count; i++) {
*buff = transfer(*buff);
*buff = (_spis.getBitOrder() == MSBFIRST) ? *buff : reverseByte(*buff);
buff++;
@@ -122,8 +132,44 @@ void SPIClassRP2040::transfer(void *buf, size_t count) {
DEBUGSPI("SPI::transfer completed\n");
}
void SPIClassRP2040::transfer(void *txbuf, void *rxbuf, size_t count) {
if (!_initted) {
return;
}
DEBUGSPI("SPI::transfer(%p, %p, %d)\n", txbuf, rxbuf, count);
uint8_t *txbuff = reinterpret_cast<uint8_t *>(txbuf);
uint8_t *rxbuff = reinterpret_cast<uint8_t *>(rxbuf);
// MSB version is easy!
if (_spis.getBitOrder() == MSBFIRST) {
spi_set_format(_spi, 8, cpol(), cpha(), SPI_MSB_FIRST);
if (rxbuf == NULL) { // transmit only!
spi_write_blocking(_spi, txbuff, count);
return;
}
if (txbuf == NULL) { // receive only!
spi_read_blocking(_spi, 0xFF, rxbuff, count);
return;
}
// transmit and receive!
spi_write_read_blocking(_spi, txbuff, rxbuff, count);
return;
}
// If its LSB this isn't nearly as fun, we'll just let transfer(x) do it :(
for (size_t i = 0; i < count; i++) {
*rxbuff = transfer(*txbuff);
*rxbuff = (_spis.getBitOrder() == MSBFIRST) ? *rxbuff : reverseByte(*rxbuff);
txbuff++;
rxbuff++;
}
DEBUGSPI("SPI::transfer completed\n");
}
void SPIClassRP2040::beginTransaction(SPISettings settings) {
DEBUGSPI("SPI::beginTransaction(clk=%d, bo=%s\n", _spis.getClockFreq(), (_spis.getBitOrder() == MSBFIRST) ? "MSB":"LSB");
DEBUGSPI("SPI::beginTransaction(clk=%d, bo=%s\n", _spis.getClockFreq(), (_spis.getBitOrder() == MSBFIRST) ? "MSB" : "LSB");
_spis = settings;
if (_initted) {
DEBUGSPI("SPI: deinitting currently active SPI\n");
@@ -145,7 +191,8 @@ void SPIClassRP2040::endTransaction(void) {
bool SPIClassRP2040::setRX(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({0, 4, 16, 20}) /* SPI0 */,
__bitset({8, 12, 24, 28}) /* SPI1 */};
__bitset({8, 12, 24, 28}) /* SPI1 */
};
if (_running) {
return false;
} else if ((1 << pin) & valid[spi_get_index(_spi)]) {
@@ -158,7 +205,8 @@ bool SPIClassRP2040::setRX(pin_size_t pin) {
bool SPIClassRP2040::setCS(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({1, 5, 17, 21}) /* SPI0 */,
__bitset({9, 13, 25, 29}) /* SPI1 */};
__bitset({9, 13, 25, 29}) /* SPI1 */
};
if (_running) {
return false;
} else if ((1 << pin) & valid[spi_get_index(_spi)]) {
@@ -171,7 +219,8 @@ bool SPIClassRP2040::setCS(pin_size_t pin) {
bool SPIClassRP2040::setSCK(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({2, 6, 18, 22}) /* SPI0 */,
__bitset({10, 14, 26}) /* SPI1 */};
__bitset({10, 14, 26}) /* SPI1 */
};
if (_running) {
return false;
} else if ((1 << pin) & valid[spi_get_index(_spi)]) {
@@ -184,7 +233,8 @@ bool SPIClassRP2040::setSCK(pin_size_t pin) {
bool SPIClassRP2040::setTX(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({3, 7, 19, 23}) /* SPI0 */,
__bitset({11, 15, 27}) /* SPI1 */};
__bitset({11, 15, 27}) /* SPI1 */
};
if (_running) {
return false;
} else if ((1 << pin) & valid[spi_get_index(_spi)]) {
@@ -219,17 +269,17 @@ void SPIClassRP2040::end() {
}
void SPIClassRP2040::setBitOrder(BitOrder order) {
_spis = SPISettings( _spis.getClockFreq(), order, _spis.getDataMode() );
_spis = SPISettings(_spis.getClockFreq(), order, _spis.getDataMode());
beginTransaction(_spis);
}
void SPIClassRP2040::setDataMode(uint8_t uc_mode) {
_spis = SPISettings( _spis.getClockFreq(), _spis.getBitOrder(), uc_mode );
_spis = SPISettings(_spis.getClockFreq(), _spis.getBitOrder(), uc_mode);
beginTransaction(_spis);
}
void SPIClassRP2040::setClockDivider(uint8_t uc_div) {
(void) uc_div; // no-op
(void) uc_div; // no-op
}
SPIClassRP2040 SPI(spi0, PIN_SPI0_MISO, PIN_SPI0_SS, PIN_SPI0_SCK, PIN_SPI0_MOSI);
+30 -21
View File
@@ -1,22 +1,22 @@
/*
* SPI Master library for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
SPI Master library for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
@@ -35,6 +35,9 @@ public:
// Sends buffer in 8 bit chunks. Overwrites buffer with read data
void transfer(void *buf, size_t count) override;
// Sends one buffer and receives into another, much faster! can set rx or txbuf to NULL
void transfer(void *txbuf, void *rxbuf, size_t count);
// Call before/after every complete transaction
void beginTransaction(SPISettings settings) override;
void endTransaction(void) override;
@@ -46,7 +49,9 @@ public:
bool setTX(pin_size_t pin);
// Call once to init/deinit SPI class, select pins, etc.
virtual void begin() override { begin(false); }
virtual void begin() override {
begin(false);
}
void begin(bool hwCS);
void end() override;
@@ -56,8 +61,12 @@ public:
void setClockDivider(uint8_t uc_div) __attribute__((deprecated));
// Unimplemented
virtual void usingInterrupt(int interruptNumber) override { (void) interruptNumber; }
virtual void notUsingInterrupt(int interruptNumber) override { (void) interruptNumber; }
virtual void usingInterrupt(int interruptNumber) override {
(void) interruptNumber;
}
virtual void notUsingInterrupt(int interruptNumber) override {
(void) interruptNumber;
}
virtual void attachInterrupt() override { /* noop */ }
virtual void detachInterrupt() override { /* noop */ }
+33 -44
View File
@@ -1,23 +1,23 @@
/*
* PIO-based Servo class for Rasperry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
* Original Copyright (c) 2015 Michael C. Miller. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
PIO-based Servo class for Rasperry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
Original Copyright (c) 2015 Michael C. Miller. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <Servo.h>
@@ -27,14 +27,13 @@
#include "servo.pio.h"
static PIOProgram _servoPgm(&servo_program);
// similiar to map but will have increased accuracy that provides a more
// Similar to map but will have increased accuracy that provides a more
// symmetrical api (call it and use result to reverse will provide the original value)
int improved_map(int value, int minIn, int maxIn, int minOut, int maxOut)
{
int improved_map(int value, int minIn, int maxIn, int minOut, int maxOut) {
const int rangeIn = maxIn - minIn;
const int rangeOut = maxOut - minOut;
const int deltaIn = value - minIn;
// fixed point math constants to improve accurancy of divide and rounding
// fixed point math constants to improve accuracy of divide and rounding
constexpr int fixedHalfDecimal = 1;
constexpr int fixedDecimal = fixedHalfDecimal * 2;
@@ -44,8 +43,7 @@ int improved_map(int value, int minIn, int maxIn, int minOut, int maxOut)
//-------------------------------------------------------------------
// Servo class methods
Servo::Servo()
{
Servo::Servo() {
_attached = false;
_valueUs = DEFAULT_NEUTRAL_PULSE_WIDTH;
_minUs = DEFAULT_MIN_PULSE_WIDTH;
@@ -59,18 +57,15 @@ Servo::~Servo() {
detach();
}
int Servo::attach(pin_size_t pin)
{
int Servo::attach(pin_size_t pin) {
return attach(pin, DEFAULT_MIN_PULSE_WIDTH, DEFAULT_MAX_PULSE_WIDTH);
}
int Servo::attach(pin_size_t pin, int minUs, int maxUs)
{
int Servo::attach(pin_size_t pin, int minUs, int maxUs) {
return attach(pin, minUs, maxUs, _valueUs);
}
int Servo::attach(pin_size_t pin, int minUs, int maxUs, int value)
{
int Servo::attach(pin_size_t pin, int minUs, int maxUs, int value) {
// keep the min and max within 200-3000 us, these are extreme
// ranges and should support extreme servos while maintaining
// reasonable ranges
@@ -85,7 +80,7 @@ int Servo::attach(pin_size_t pin, int minUs, int maxUs, int value)
// ERROR, no free slots
return -1;
}
_attached = true;
_attached = true;
servo_program_init(_pio, _smIdx, _pgmOffset, pin);
pio_sm_set_enabled(_pio, _smIdx, false);
pio_sm_put_blocking(_pio, _smIdx, RP2040::usToPIOCycles(REFRESH_INTERVAL) / 3);
@@ -102,8 +97,7 @@ int Servo::attach(pin_size_t pin, int minUs, int maxUs, int value)
return pin;
}
void Servo::detach()
{
void Servo::detach() {
if (_attached) {
// Set a 0 for the width and then wait for the halt loop
pio_sm_put_blocking(_pio, _smIdx, 0);
@@ -118,8 +112,7 @@ void Servo::detach()
}
}
void Servo::write(int value)
{
void Servo::write(int value) {
// treat any value less than 200 as angle in degrees (values equal or larger are handled as microseconds)
if (value < 200) {
// assumed to be 0-180 degrees servo
@@ -129,8 +122,7 @@ void Servo::write(int value)
writeMicroseconds(value);
}
void Servo::writeMicroseconds(int value)
{
void Servo::writeMicroseconds(int value) {
value = constrain(value, _minUs, _maxUs);
_valueUs = value;
if (_attached) {
@@ -138,18 +130,15 @@ void Servo::writeMicroseconds(int value)
}
}
int Servo::read() // return the value as degrees
{
int Servo::read() { // return the value as degrees
// read returns the angle for an assumed 0-180
return improved_map(readMicroseconds(), _minUs, _maxUs, 0, 180);
}
int Servo::readMicroseconds()
{
int Servo::readMicroseconds() {
return _valueUs;
}
bool Servo::attached()
{
bool Servo::attached() {
return _attached;
}
+40 -40
View File
@@ -1,41 +1,41 @@
/*
* PIO-based Servo class for Rasperry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
PIO-based Servo class for Rasperry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* A servo is activated by creating an instance of the Servo class passing
* the desired pin to the attach() method.
* The servos are pulsed in the background using the value most recently
* written using the write() method.
*
* The methods are:
* Servo - Class for manipulating servo motors connected to Arduino pins.
* attach(pin) - Attaches a servo motor to an i/o pin.
* attach(pin, min, max) - Attaches to a pin setting min and max values in microseconds
* default min is 1000, max is 2000
* write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds)
* writeMicroseconds() - Sets the servo pulse width in microseconds
* read() - Gets the last written servo pulse width as an angle between 0 and 180.
* readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
* attached() - Returns true if there is a servo attached.
* detach() - Stops an attached servos from pulsing its i/o pin.
*/
A servo is activated by creating an instance of the Servo class passing
the desired pin to the attach() method.
The servos are pulsed in the background using the value most recently
written using the write() method.
The methods are:
Servo - Class for manipulating servo motors connected to Arduino pins.
attach(pin) - Attaches a servo motor to an i/o pin.
attach(pin, min, max) - Attaches to a pin setting min and max values in microseconds
default min is 1000, max is 2000
write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds)
writeMicroseconds() - Sets the servo pulse width in microseconds
read() - Gets the last written servo pulse width as an angle between 0 and 180.
readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
attached() - Returns true if there is a servo attached.
detach() - Stops an attached servos from pulsing its i/o pin.
*/
#ifndef Servo_h
#define Servo_h
@@ -46,7 +46,7 @@
// The following values are in us (microseconds).
// Since the defaults can be overwritten in the new attach() member function,
// they were modified from the Arduino AVR defaults to be in the safe range
// of publically available specifications. While this implies that many 180°
// of publicly available specifications. While this implies that many 180°
// servos do not operate the full 0° to 180° sweep using these, it also prevents
// unsuspecting damage. For Arduino AVR, the same change is being discussed.
#define DEFAULT_MIN_PULSE_WIDTH 1000 // uncalibrated default, the shortest duty cycle sent to a servo
@@ -71,11 +71,11 @@ public:
// returns channel number or 0 if failure.
int attach(pin_size_t pin, int min, int max, int value);
void detach();
void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
void writeMicroseconds(int value); // Write pulse width in microseconds
void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
void writeMicroseconds(int value); // Write pulse width in microseconds
int read(); // returns current pulse width as an angle between 0 and 180 degrees
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
bool attached(); // return true if this servo is attached, otherwise false
bool attached(); // return true if this servo is attached, otherwise false
private:
bool _attached;
@@ -87,7 +87,7 @@ private:
int _maxUs;
int _valueUs;
};
#endif
+15 -15
View File
@@ -16,16 +16,16 @@
#define servo_offset_halt 2u
static const uint16_t servo_program_instructions[] = {
// .wrap_target
0x9080, // 0: pull noblock side 0
0xa027, // 1: mov x, osr
0x0022, // 2: jmp !x, 2
0xa046, // 3: mov y, isr
0x00a6, // 4: jmp x != y, 6
0x1807, // 5: jmp 7 side 1
0xa042, // 6: nop
0x0084, // 7: jmp y--, 4
// .wrap
// .wrap_target
0x9080, // 0: pull noblock side 0
0xa027, // 1: mov x, osr
0x0022, // 2: jmp !x, 2
0xa046, // 3: mov y, isr
0x00a6, // 4: jmp x != y, 6
0x1807, // 5: jmp 7 side 1
0xa042, // 6: nop
0x0084, // 7: jmp y--, 4
// .wrap
};
#if !PICO_NO_HARDWARE
@@ -43,11 +43,11 @@ static inline pio_sm_config servo_program_get_default_config(uint offset) {
}
static inline void servo_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = servo_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
pio_sm_init(pio, sm, offset, &c);
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = servo_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
pio_sm_init(pio, sm, offset, &c);
}
#endif
+48 -43
View File
@@ -1,25 +1,25 @@
/*
* I2C Master/Slave library for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* Based off of TWI/I2C library for Arduino Zero
* Copyright (c) 2015 Arduino LLC. 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
*/
I2C Master/Slave library for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
Based off of TWI/I2C library for Arduino Zero
Copyright (c) 2015 Arduino LLC. 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
*/
#include <Arduino.h>
#include <hardware/gpio.h>
@@ -40,7 +40,8 @@ TwoWire::TwoWire(i2c_inst_t *i2c, pin_size_t sda, pin_size_t scl) {
bool TwoWire::setSDA(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({0, 4, 8, 12, 16, 20, 24, 28}) /* I2C0 */,
__bitset({2, 6, 10, 14, 18, 22, 26}) /* I2C1 */};
__bitset({2, 6, 10, 14, 18, 22, 26}) /* I2C1 */
};
if (_running) {
return false;
} else if ((1 << pin) & valid[i2c_hw_index(_i2c)]) {
@@ -53,7 +54,8 @@ bool TwoWire::setSDA(pin_size_t pin) {
bool TwoWire::setSCL(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({1, 5, 9, 13, 17, 21, 25, 29}) /* I2C0 */,
__bitset({3, 7, 11, 15, 19, 23, 27}) /* I2C1 */};
__bitset({3, 7, 11, 15, 19, 23, 27}) /* I2C1 */
};
if (_running) {
return false;
} else if ((1 << pin) & valid[i2c_hw_index(_i2c)]) {
@@ -106,7 +108,7 @@ void TwoWire::begin(uint8_t addr) {
i2c_set_slave_mode(_i2c, true, addr);
// Our callback IRQ
_i2c->hw->intr_mask = (1<<10) | (1<<9) | (1<<5)| (1<<2);
_i2c->hw->intr_mask = (1 << 10) | (1 << 9) | (1 << 5) | (1 << 2);
int irqNo = I2C0_IRQ + i2c_hw_index(_i2c);
irq_set_exclusive_handler(irqNo, i2c_hw_index(_i2c) == 0 ? _handler0 : _handler1);
@@ -122,31 +124,31 @@ void TwoWire::begin(uint8_t addr) {
}
void TwoWire::onIRQ() {
if (_i2c->hw->intr_stat & (1<<10)) {
if (_i2c->hw->intr_stat & (1 << 10)) {
_buffLen = 0;
_buffOff = 0;
_slaveStartDet = true;
_i2c->hw->clr_start_det;
}
if (_i2c->hw->intr_stat & (1<<9)) {
if (_i2c->hw->intr_stat & (1 << 9)) {
if (_onReceiveCallback) {
_onReceiveCallback(_buffLen);
}
_buffLen = 0;
_buffOff = 0;
_buffOff = 0;
_slaveStartDet = false;
_i2c->hw->clr_stop_det;
}
if (_i2c->hw->intr_stat & (1<<5)) {
if (_i2c->hw->intr_stat & (1 << 5)) {
// RD_REQ
if (_onRequestCallback) {
_onRequestCallback();
}
_i2c->hw->clr_rd_req;
}
if (_i2c->hw->intr_stat & (1<<2)) {
if (_i2c->hw->intr_stat & (1 << 2)) {
// RX_FULL
if (_slaveStartDet && (_buffLen < sizeof(_buff))) {
if (_slaveStartDet && (_buffLen < (int)sizeof(_buff))) {
_buff[_buffLen++] = _i2c->hw->data_cmd & 0xff;
} else {
_i2c->hw->data_cmd;
@@ -179,7 +181,6 @@ size_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) {
return 0;
}
size_t byteRead = 0;
_buffLen = i2c_read_blocking_until(_i2c, address, _buff, quantity, !stopBit, make_timeout_time_ms(50));
_buffOff = 0;
return _buffLen;
@@ -207,18 +208,22 @@ bool _probe(int addr, pin_size_t sda, pin_size_t scl, int freq) {
digitalWrite(sda, HIGH);
sleep_us(delay);
digitalWrite(scl, HIGH);
if (!_clockStretch(scl)) goto stop;
if (!_clockStretch(scl)) {
goto stop;
}
digitalWrite(sda, LOW);
sleep_us(delay);
digitalWrite(scl, LOW);
sleep_us(delay);
for (int i=0; i<8; i++) {
for (int i = 0; i < 8; i++) {
addr <<= 1;
digitalWrite(sda, (addr & (1<<7)) ? HIGH : LOW);
digitalWrite(sda, (addr & (1 << 7)) ? HIGH : LOW);
sleep_us(delay);
digitalWrite(scl, HIGH);
sleep_us(delay);
if (!_clockStretch(scl)) goto stop;
if (!_clockStretch(scl)) {
goto stop;
}
digitalWrite(scl, LOW);
sleep_us(5); // Ensure we don't change too close to clock edge
}
@@ -226,7 +231,9 @@ bool _probe(int addr, pin_size_t sda, pin_size_t scl, int freq) {
digitalWrite(sda, HIGH);
sleep_us(delay);
digitalWrite(scl, HIGH);
if (!_clockStretch(scl)) goto stop;
if (!_clockStretch(scl)) {
goto stop;
}
ack = digitalRead(sda) == LOW;
sleep_us(delay);
@@ -254,7 +261,7 @@ stop:
// 4 : Other error
uint8_t TwoWire::endTransmission(bool stopBit) {
if (!_running || !_txBegun) {
return 4;
return 4;
}
_txBegun = false;
if (!_buffLen) {
@@ -269,7 +276,7 @@ uint8_t TwoWire::endTransmission(bool stopBit) {
}
uint8_t TwoWire::endTransmission() {
return endTransmission(true);
return endTransmission(true);
}
size_t TwoWire::write(uint8_t ucData) {
@@ -279,7 +286,7 @@ size_t TwoWire::write(uint8_t ucData) {
if (_slave) {
// Wait for a spot in the TX FIFO
while (0 == _i2c->hw->status & (1<<1)) { /* noop wait */ }
while (0 == (_i2c->hw->status & (1 << 1))) { /* noop wait */ }
_i2c->hw->data_cmd = ucData;
return 1;
} else {
@@ -325,13 +332,11 @@ void TwoWire::flush(void) {
}
void TwoWire::onReceive(void(*function)(int))
{
void TwoWire::onReceive(void(*function)(int)) {
_onReceiveCallback = function;
}
void TwoWire::onRequest(void(*function)(void))
{
void TwoWire::onRequest(void(*function)(void)) {
_onRequestCallback = function;
}
+35 -27
View File
@@ -1,25 +1,25 @@
/*
* I2C Master/Slave library for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* Based off of TWI/I2C library for Arduino Zero
* Copyright (c) 2015 Arduino LLC. 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
*/
I2C Master/Slave library for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
Based off of TWI/I2C library for Arduino Zero
Copyright (c) 2015 Arduino LLC. 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
@@ -27,11 +27,11 @@
#include "api/HardwareI2C.h"
#include <hardware/i2c.h>
// WIRE_HAS_END means Wire has end()
// WIRE_HAS_END means Wire has end()
#define WIRE_HAS_END 1
#ifndef WIRE_BUFFER_SIZE
#define WIRE_BUFFER_SIZE 128
#define WIRE_BUFFER_SIZE 128
#endif
class TwoWire : public HardwareI2C {
@@ -68,10 +68,18 @@ public:
void onReceive(void(*)(int));
void onRequest(void(*)(void));
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
inline size_t write(unsigned long n) {
return write((uint8_t)n);
}
inline size_t write(long n) {
return write((uint8_t)n);
}
inline size_t write(unsigned int n) {
return write((uint8_t)n);
}
inline size_t write(int n) {
return write((uint8_t)n);
}
using Print::write;
// IRQ callback
@@ -1,6 +1,6 @@
// Simple I2C master and slave demo - Earle F. Philhower, III
// Released into the public domain
//
//
// Using both onboard I2C interfaces, have one master and one slave
// and send data both ways between them
//
@@ -9,42 +9,42 @@
#include <Wire.h>
void setup() {
Serial.begin(115200);
delay(5000);
Wire.setSDA(0);
Wire.setSCL(1);
Wire.begin();
Wire1.setSDA(2);
Wire1.setSCL(3);
Wire1.begin(0x30);
Wire1.onReceive(recv);
Wire1.onRequest(req);
Serial.begin(115200);
delay(5000);
Wire.setSDA(0);
Wire.setSCL(1);
Wire.begin();
Wire1.setSDA(2);
Wire1.setSCL(3);
Wire1.begin(0x30);
Wire1.onReceive(recv);
Wire1.onRequest(req);
}
static char buff[100];
void loop() {
static int p;
char b[90];
static int p;
char b[90];
// Write a value over I2C to the slave
Serial.println("Sending...");
Wire.beginTransmission(0x30);
sprintf(b, "pass %d", p++);
Wire.write(b, strlen(b));
Wire.endTransmission();
// Write a value over I2C to the slave
Serial.println("Sending...");
Wire.beginTransmission(0x30);
sprintf(b, "pass %d", p++);
Wire.write(b, strlen(b));
Wire.endTransmission();
// Ensure the slave processing is done and print it out
delay(1000);
Serial.printf("buff: '%s'\r\n", buff);
// Ensure the slave processing is done and print it out
delay(1000);
Serial.printf("buff: '%s'\r\n", buff);
// Read from the slave and print out
Wire.requestFrom(0x30, 6);
Serial.print("\nrecv: '");
while(Wire.available()) {
Serial.print((char)Wire.read());
}
Serial.println("'");
delay(1000);
// Read from the slave and print out
Wire.requestFrom(0x30, 6);
Serial.print("\nrecv: '");
while (Wire.available()) {
Serial.print((char)Wire.read());
}
Serial.println("'");
delay(1000);
}
// These are called in an **INTERRUPT CONTEXT** which means NO serial port
@@ -52,17 +52,19 @@ void loop() {
// Called when the I2C slave gets written to
void recv(int len) {
int i;
// Just stuff the sent bytes into a global the main routine can pick up and use
for (i=0; i<len; i++) buff[i] = Wire1.read();
buff[i] = 0;
int i;
// Just stuff the sent bytes into a global the main routine can pick up and use
for (i = 0; i < len; i++) {
buff[i] = Wire1.read();
}
buff[i] = 0;
}
// Called when the I2C slave is read from
void req() {
static int ctr = 765;
char buff[7];
// Return a simple incrementing hex value
sprintf(buff, "%06X", (ctr++) % 65535);
Wire1.write(buff, 6);
static int ctr = 765;
char buff[7];
// Return a simple incrementing hex value
sprintf(buff, "%06X", (ctr++) % 65535);
Wire1.write(buff, 6);
}
@@ -12,6 +12,8 @@ void loop() {
if (BOOTSEL) {
Serial.printf("\a\aYou pressed BOOTSEL %d times!\n", ++c);
// Wait for BOOTSEL to be released
while (BOOTSEL) { delay(1); }
while (BOOTSEL) {
delay(1);
}
}
}
@@ -19,7 +19,7 @@
// The normal, core0 setup
void setup() {
Serial.begin();
Serial.begin(115200);
delay(5000);
}
@@ -1,11 +1,11 @@
/* Released into the public domain */
void setup() {
Serial.begin(115200);
delay(5000);
Serial.begin(115200);
delay(5000);
}
void loop() {
Serial.printf("Core temperature: %2.1fC\n", analogReadTemp());
delay(1000);
Serial.printf("Core temperature: %2.1fC\n", analogReadTemp());
delay(1000);
}
+27
View File
@@ -0,0 +1,27 @@
/* Simple demonstration of setting and printing the current time */
/* The initial time will need to come from an RTC, NTP, or user */
/* Released to the public domain by Earle F. Philhower, III <earlephilhower@yahoo.com> */
#include <time.h>
#include <sys/time.h>
void setup() {
Serial.begin(115200);
delay(5000);
struct timeval tv;
tv.tv_sec = 1611198855; // Jan 21, 2021 3:14:15AM ...RPi Pico Release;
tv.tv_usec = 0;
settimeofday(&tv, nullptr);
}
void loop() {
time_t now;
char buff[80];
time(&now);
strftime(buff, sizeof(buff), "%c", localtime(&now));
Serial.println(buff);
delay(1000);
}
+15 -8
View File
@@ -38,15 +38,16 @@ compiler.warning_flags.default=
compiler.warning_flags.more=-Wall
compiler.warning_flags.all=-Wall -Wextra
compiler.defines={build.led}
compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/platform_inc.txt"
compiler.flags=-Os -march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -fno-exceptions
compiler.wrap="@{runtime.platform.path}/lib/platform_wrap.txt"
compiler.libpico="{runtime.platform.path}/lib/libpico.a"
compiler.c.cmd=arm-none-eabi-gcc
compiler.c.flags=-c {compiler.defines} {compiler.flags} {compiler.includes} -std=gnu17 -g
compiler.c.elf.cmd=arm-none-eabi-g++
compiler.c.elf.flags={compiler.defines} {compiler.flags} -Wl,--gc-sections -u _printf_float -u _scanf_float
compiler.c.elf.flags={compiler.defines} {compiler.flags} -u _printf_float -u _scanf_float
compiler.S.cmd=arm-none-eabi-gcc
compiler.S.flags=-c -g -x assembler-with-cpp -MMD {compiler.includes} -g
compiler.cpp.cmd=arm-none-eabi-g++
@@ -64,7 +65,7 @@ compiler.size.cmd=arm-none-eabi-size
compiler.define=-DARDUINO=
compiler.readelf.cmd=arm-none-eabi-readelf
# this can be overriden in boards.txt
# this can be overridden in boards.txt
build.extra_flags=
# These can be overridden in platform.local.txt
@@ -80,6 +81,7 @@ build.flash_length=
build.eeprom_start=
build.fs_start=
build.fs_end=
build.usbstack_flags=
build.boot2=boot2_generic_03h_4_padded_checksum
@@ -91,22 +93,27 @@ discovery.rp2040.pattern="{runtime.tools.pqt-python3.path}/python3" "{runtime.pl
# ----------------
## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} {build.usbpid} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {includes} "{source_file}" -o "{object_file}"
## Create archives
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
archive_file_path={build.path}/{archive_file}
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
## Combine gc-sections, archives, and objects
## Generate the linker map with specific flash sizes/locations
recipe.hooks.linking.prelink.1.pattern="{runtime.tools.pqt-python3.path}/python3" "{runtime.platform.path}/tools/simplesub.py" --input "{runtime.platform.path}/lib/memmap_default.ld" --out "{build.path}/memmap_default.ld" --sub __FLASH_LENGTH__ {build.flash_length} --sub __EEPROM_START__ {build.eeprom_start} --sub __FS_START__ {build.fs_start} --sub __FS_END__ {build.fs_end}
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nosys.specs -Wl,--as-needed -Wl,--start-group {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" -Wl,--whole-archive "{runtime.platform.path}/lib/libpico.a" -Wl,--no-whole-archive -lm "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" "{runtime.platform.path}/assembly/{build.boot2}.S" -lc -lstdc++ -Wl,--end-group
## Compile the boot stage 2 blob
recipe.hooks.linking.prelink.2.pattern="{compiler.path}{compiler.S.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -c "{runtime.platform.path}/assembly/{build.boot2}.S" "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" -o "{build.path}/boot2.o"
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {compiler.ldflags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" "{build.path}/boot2.o" {compiler.libpico} -lm -lc -lstdc++ -lc -Wl,--end-group
## Create output (UF2 file)
recipe.objcopy.uf2.pattern="{runtime.tools.pqt-elf2uf2.path}/elf2uf2" "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.uf2"
+32
View File
@@ -0,0 +1,32 @@
# Code formatting rules for Arduino examples, taken from:
#
# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf
#
mode=c
lineend=linux
style=java
# 4 spaces indentation
indent=spaces=4
# also indent macros
#indent-preprocessor
# indent classes, switches (and cases), comments starting at column 1
indent-col1-comments
# put a space around operators
pad-oper
# put a space after if/for/while
pad-header
# if you like one-liners, keep them
keep-one-line-statements
attach-closing-while
unpad-paren
pad-oper
remove-comment-prefix
add-braces
+44
View File
@@ -0,0 +1,44 @@
# Code formatting rules for Arduino examples, taken from:
#
# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf
#
mode=c
lineend=linux
# 2 spaces indentation
indent=spaces=2
# also indent macros
#indent-preprocessor
# indent classes, switches (and cases), comments starting at column 1
indent-classes
indent-switches
indent-cases
indent-col1-comments
# put a space around operators
pad-oper
# put a space after if/for/while
pad-header
# if you like one-liners, keep them
keep-one-line-statements
add-braces
style=java
attach-namespaces
attach-classes
attach-inlines
attach-extern-c
indent-modifiers
indent-namespaces
indent-labels
#indent-preproc-block
#indent-preproc-define
#indent-preproc-cond
unpad-paren
add-braces
remove-comment-prefix
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
cache_dir=$(mktemp -d)
source "$TRAVIS_BUILD_DIR"/tests/common.sh
install_arduino nodebug
# Replace the skip function to only build TinyUSB tests
function skip_ino()
{
local ino=$1
local skiplist=""
echo $ino | grep -q Adafruit_TinyUSB_Arduino
if [ $? -eq 0 ]; then
# Add items to the following list with "\n" netween them to skip running. No spaces, tabs, etc. allowed
read -d '' skiplist << EOL || true
/mouse_external_flash/
/hid_keyboard/
/msc_external_flash/
/msc_external_flash_sdcard/
/msc_sdfat/
/msc_sd/
/midi_pizza_box_dj/
/hid_composite_joy_featherwing/
EOL
echo $ino | grep -q -F "$skiplist"
echo $(( 1 - $? ))
else
echo 1
fi
}
build_sketches_with_arduino 1 0 "--usbstack tinyusb"
rm -rf "$cache_dir"
Executable
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
cache_dir=$(mktemp -d)
source "$TRAVIS_BUILD_DIR"/tests/common.sh
if [ -z "$BUILD_PARITY" ]; then
mod=1
rem=0
elif [ "$BUILD_PARITY" = "even" ]; then
mod=2
rem=0
elif [ "$BUILD_PARITY" = "odd" ]; then
mod=2
rem=1
fi
install_arduino nodebug
build_sketches_with_arduino "$mod" "$rem" ""
rm -rf "$cache_dir"
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash
#
# CI job which checks that boards.txt and package_esp8266com_index.template.json are up to date
set -ev
cd $TRAVIS_BUILD_DIR
tools/boards.txt.py --boardsgen --ldgen --packagegen --docgen
git diff --exit-code -- boards.txt \
doc/boards.rst \
tools/sdk/ld/
git diff --exit-code -w -- package/package_esp8266com_index.template.json
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
#
# CI job to run the documentation build
set -ev
cd $TRAVIS_BUILD_DIR/doc
SPHINXOPTS="-W" make html
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
#
# CI job which builds the boards manager package
set -ev
export PKG_URL=https://github.com/esp8266/Arduino/releases/download/$TRAVIS_TAG/esp8266-$TRAVIS_TAG.zip
export DOC_URL=https://arduino-esp8266.readthedocs.io/en/$TRAVIS_TAG/
if [ -z "$CI_GITHUB_API_KEY" ]; then
echo "Github API key not set. Skip building the package."
exit 0
fi
cd $TRAVIS_BUILD_DIR/package
./build_boards_manager_package.sh
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
#
# CI job for running tests on the host
set -ev
cd $TRAVIS_BUILD_DIR/tests/host
make -j2 FORCE32=0 ssl
for i in ../../libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient \
../../libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation \
../../libraries/ESP8266WebServer/examples/HelloServer/HelloServer \
../../libraries/SD/examples/Files/Files \
../../libraries/LittleFS/examples/LittleFS_Timestamp/LittleFS_Timestamp \
../../libraries/LittleFS/examples/SpeedTest/SpeedTest ; do
make -j2 D=1 FORCE32=0 $i
valgrind --leak-check=full --track-origins=yes --error-limit=no --show-leak-kinds=all --error-exitcode=999 bin/$(basename $i)/$(basename $i) -1
done
make -j2 CI
make clean-objects
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
set -e
fail=0
for i in $(cat ./package/package_pico_index.template.json | jq '.packages[0]."tools" | .[] | .systems[] | "\(.url) \(.checksum)"' | sort -u | sed 's/ /@/'); do
url=$(echo $i | sed 's/@/ /' | cut -f2 -d\" | cut -f1 -d' ')
sha=$(echo $i | sed 's/@/ /' | cut -f2 -d\" | cut -f2 -d' ' | cut -f2 -d:)
echo "INFO: Checking $url"
rm -f file.bin
wget --quiet -O file.bin $url
calc=$(sha256sum file.bin | cut -f1 -d" ")
if [ "$sha" != "$calc" ]; then
echo "ERROR: Download failed or SHA mismatch for $url"
echo "ERROR: Expected $sha"
echo "ERROR: Received $calc"
fail=1
fi
done
if [ $fail -ne 0 ]; then
echo ERROR: Package file integrity check failed
exit 1
fi
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
#
# CI job for checking examples style
set -ev
org=$(cd ${0%/*}; pwd)
${org}/../restyle.sh
# Revert changes which astyle might have done to the submodules,
# as we don't want to fail the build because of the 3rd party libraries
git --version || true
git submodule foreach --recursive 'git reset --hard'
git diff --exit-code -- $TRAVIS_BUILD_DIR
+269
View File
@@ -0,0 +1,269 @@
#!/usr/bin/env bash
# return 1 if this test should not be built in CI (for other archs, not needed, etc.)
function skip_ino()
{
local ino=$1
local skiplist=""
# Add items to the following list with "\n" netween them to skip running. No spaces, tabs, etc. allowed
read -d '' skiplist << EOL || true
/#attic/
/AvrAdcLogger/
/BackwardCompatibility/
/examplesV1/
/ExFatFormatter/
/ExFatLogger/
/ExFatUnicodeTest/
/RtcTimestampTest/
/SoftwareSpi/
/STM32Test/
/TeensyRtcTimestamp/
/TeensySdioDemo/
/UserChipSelectFunction/
/UserSPIDriver/
/Adafruit_TinyUSB_Arduino/
/ArduinoISP/
/p08_DigitalHourglass/
/p13_TouchSensorLamp/
/StringComparisonOperators/
EOL
echo $ino | grep -q -F "$skiplist"
echo $(( 1 - $? ))
}
function print_size_info()
{
elf_file=$1
if [ -z "$elf_file" ]; then
printf "sketch data rodata bss text dram flash\n"
return 0
fi
elf_name=$(basename $elf_file)
sketch_name="${elf_name%.*}"
# echo $sketch_name
arm-none-eabi-size --format=sysv $elf_file | sed s/irom0.text/irom0text/g > size.txt
declare -A segments
for seg in data rodata bss text irom0text; do
segments[$seg]=$(grep ^.$seg size.txt | awk '{sum += $2} END {print sum}')
done
total_ram=$((${segments[data]} + ${segments[rodata]} + ${segments[bss]}))
total_flash=$((${segments[data]} + ${segments[rodata]} + ${segments[text]}))
printf "%-28s %-8d %-8d %-8d %-8d %-8d %-8d %-8d\n" $sketch_name ${segments[data]} ${segments[rodata]} ${segments[bss]} ${segments[text]} $total_ram $total_flash
return 0
}
function build_sketches()
{
set +e
local arduino=$1
local srcpath=$2
local build_arg=$3
local build_dir=build.tmp
local build_mod=$4
local build_rem=$5
mkdir -p $build_dir
local build_cmd="python3 tools/build.py -b generic -v -w all -v -k --build_cache $cache_dir -p ./$build_dir $build_arg "
if [ "$WINDOWS" = "1" ]; then
# Paths to the arduino builder need to be / referenced, not our native ones
build_cmd=$(echo $build_cmd --ide_path $arduino | sed 's/ \/c\// \//g' ) # replace '/c/' with '/'
fi
local sketches=$(find $srcpath -name *.ino | sort)
print_size_info >size.log
export ARDUINO_IDE_PATH=$arduino
local testcnt=0
for sketch in $sketches; do
testcnt=$(( ($testcnt + 1) % $build_mod ))
if [ $testcnt -ne $build_rem ]; then
continue # Not ours to do
fi
if [ -e $cache_dir/core/*.a ]; then
# We need to preserve the build.options.json file and replace the last .ino
# with this sketch's ino file, or builder will throw everything away.
jq '."sketchLocation" = "'$sketch'"' $build_dir/build.options.json > $build_dir/build.options.json.tmp
mv $build_dir/build.options.json.tmp $build_dir/build.options.json
# Set the time of the cached core.a file to the future so the GIT header
# we regen won't cause the builder to throw it out and rebuild from scratch.
touch -d 'now + 1 day' $cache_dir/core/*.a
fi
# Clear out the last built sketch, map, elf, bin files, but leave the compiled
# objects in the core and libraries available for use so we don't need to rebuild
# them each sketch.
rm -rf $build_dir/sketch $build_dir/*.bin $build_dir/*.map $build_dir/*.elf
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
echo "Skipping $sketch, because it is not the main sketch file";
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
echo -e "\n ------------ Skipping $sketch ------------ \n";
continue
fi
if [[ $(skip_ino $sketch) = 1 ]]; then
echo -e "\n ------------ Skipping $sketch ------------ \n";
continue
fi
echo -e "\n ------------ Building $sketch ------------ \n";
# $arduino --verify $sketch;
if [ "$WINDOWS" == "1" ]; then
sketch=$(echo $sketch | sed 's/^\/c//')
# MINGW will try to be helpful and silently convert args that look like paths to point to a spot inside the MinGW dir. This breaks everything.
# http://www.mingw.org/wiki/Posix_path_conversion
# https://stackoverflow.com/questions/7250130/how-to-stop-mingw-and-msys-from-mangling-path-names-given-at-the-command-line#34386471
export MSYS2_ARG_CONV_EXC="*"
export MSYS_NO_PATHCONV=1
fi
echo "$build_cmd $sketch"
time ($build_cmd $sketch >build.log)
local result=$?
if [ $result -ne 0 ]; then
echo "Build failed ($1)"
echo "Build log:"
cat build.log
set -e
return $result
else
local warns=$( grep -c warning: build.log )
if [ $warns -ne 0 ]; then
echo "Warnings detected, log follows:"
cat build.log
fi
fi
rm build.log
print_size_info $build_dir/*.elf >>size.log
done
set -e
}
function install_libraries()
{
mkdir -p $HOME/Arduino/libraries
pushd $HOME/Arduino/libraries
# install ArduinoJson library
{ test -r ArduinoJson-v6.11.0.zip || curl -sS --output ArduinoJson-v6.11.0.zip -L https://github.com/bblanchon/ArduinoJson/releases/download/v6.11.0/ArduinoJson-v6.11.0.zip; } && unzip -qo ArduinoJson-v6.11.0.zip
{ test -r Adafruit_SPIFlash-3.4.1.zip || curl -sS --output Adafruit_SPIFlash-3.4.1.zip -L https://github.com/adafruit/Adafruit_SPIFlash/archive/refs/tags/3.4.1.zip; } && unzip -qo Adafruit_SPIFlash-3.4.1.zip
{ test -r Adafruit_Seesaw-1.4.3.zip || curl -sS --output Adafruit_Seesaw-1.4.3.zip -L https://github.com/adafruit/Adafruit_Seesaw/archive/refs/tags/1.4.3.zip; } && unzip -qo Adafruit_Seesaw-1.4.3.zip
{ test -r Adafruit_BusIO-1.7.3.zip || curl -sS --output Adafruit_BusIO-1.7.3.zip -L https://github.com/adafruit/Adafruit_BusIO/archive/refs/tags/1.7.3.zip; } && unzip -qo Adafruit_BusIO-1.7.3.zip
{ test -r Adafruit_CircuitPlayground-1.11.3.zip || curl -sS --output Adafruit_CircuitPlayground-1.11.3.zip -L https://github.com/adafruit/Adafruit_CircuitPlayground/archive/refs/tags/1.11.3.zip; } && unzip -qo Adafruit_CircuitPlayground-1.11.3.zip
{ test -r Adafruit_NeoPixel-1.8.1.zip || curl -sS --output Adafruit_NeoPixel-1.8.1.zip -L https://github.com/adafruit/Adafruit_NeoPixel/archive/refs/tags/1.8.1.zip; } && unzip -qo Adafruit_NeoPixel-1.8.1.zip
{ test -r Arduino_MIDI_Library-5.0.2.zip || curl -sS --output Arduino_MIDI_Library-5.0.2.zip -L https://github.com/FortySevenEffects/arduino_midi_library/archive/refs/tags/5.0.2.zip; } && unzip -qo Arduino_MIDI_Library-5.0.2.zip
popd
}
function install_ide()
{
local idever='nightly'
local ideurl='https://www.arduino.cc/download.php?f=/arduino-nightly'
#local idever='1.8.10'
#local ideurl="https://downloads.arduino.cc/arduino-$idever"
echo "using Arduino IDE distribution ${idever}"
local ide_path=$1
local core_path=$2
local debug=$3
mkdir -p ${core_path}/tools/dist
if [ "$WINDOWS" = "1" ]; then
test -r ${core_path}/tools/dist/arduino-windows.zip || curl --output ${core_path}/tools/dist/arduino-windows.zip -L "${ideurl}-windows.zip"
unzip -q ${core_path}/tools/dist/arduino-windows.zip
mv arduino-${idever} arduino-distrib
elif [ "$MACOSX" = "1" ]; then
# MACOS only has next-to-obsolete Python2 installed. Install Python 3 from python.org
wget -q https://www.python.org/ftp/python/3.7.4/python-3.7.4-macosx10.9.pkg
sudo installer -pkg python-3.7.4-macosx10.9.pkg -target /
# Install the Python3 certificates, because SSL connections fail w/o them and of course they aren't installed by default.
( cd "/Applications/Python 3.7/" && sudo "./Install Certificates.command" )
# Hack to place arduino-builder in the same spot as sane OSes
test -r ${core_path}/tools/dist/arduino-macos.zip || wget -q -O ${core_path}/tools/dist/arduino-macos.zip "${ideurl}-macosx.zip"
unzip -q ${core_path}/tools/dist/arduino-macos.zip
mv Arduino.app arduino-distrib
mv arduino-distrib/Contents/Java/* arduino-distrib/.
else
test -r ${core_path}/tools/dist/arduino-linux.tar.xz || wget -q -O ${core_path}/tools/dist/arduino-linux.tar.xz "${ideurl}-linux64.tar.xz"
tar xf ${core_path}/tools/dist/arduino-linux.tar.xz
mv arduino-${idever} arduino-distrib
fi
mv arduino-distrib $ide_path
cd $ide_path/hardware
mkdir pico
cd pico
if [ "$WINDOWS" = "1" ]; then
rm $core_path/cores/rp2040/api
cp -a $core_path rp2040
cp -a $core_path/ArduinoCore-API/api rp2040/cores/rp2040/api
else
ln -s $core_path rp2040
fi
local debug_flags=""
if [ "$debug" = "debug" ]; then
debug_flags="-DDEBUG_RP2040_WIRE -DDEBUG_RP2040_SPI -DDEBUG_RP2040_CORE -DDEBUG_RP2040_PORT=Serial"
fi
# Set custom warnings for all builds (i.e. could add -Wextra at some point)
echo "compiler.c.extra_flags=-Wall -Wextra -Werror -Wno-ignored-qualifiers $debug_flags" > rp2040/platform.local.txt
echo "compiler.cpp.extra_flags=-Wall -Wextra -Werror -Wno-ignored-qualifiers $debug_flags" >> rp2040/platform.local.txt
echo -e "\n----platform.local.txt----"
cat rp2040/platform.local.txt
echo -e "\n----\n"
cd rp2040/tools
python3 get.py -q
if [ "$WINDOWS" = "1" ]; then
# Because the symlinks don't work well under Win32, we need to add the path to this copy, not the original...
relbin=$(realpath $PWD/../system/arm-none-eabi/bin)
export PATH="$ide_path:$relbin:$PATH"
else
export PATH="$ide_path:$core_path/system/arm-none-eabi/bin:$PATH"
fi
}
function install_arduino()
{
local debug=$1
# Install Arduino IDE and required libraries
echo -e "travis_fold:start:sketch_test_env_prepare"
cd $TRAVIS_BUILD_DIR
install_ide $HOME/arduino_ide $TRAVIS_BUILD_DIR $debug
cd $TRAVIS_BUILD_DIR
install_libraries
echo -e "travis_fold:end:sketch_test_env_prepare"
}
function build_sketches_with_arduino()
{
local build_mod=$1
local build_rem=$2
local build_extra=$3
# Compile sketches
echo -e "travis_fold:start:sketch_test"
build_sketches $HOME/arduino_ide $HOME/arduino_ide/examples "-l $HOME/Arduino/libraries ${build_extra}" $build_mod $build_rem
build_sketches $HOME/arduino_ide $TRAVIS_BUILD_DIR/libraries "-l $HOME/Arduino/libraries ${build_extra}" $build_mod $build_rem
echo -e "travis_fold:end:sketch_test"
# Generate size report
echo -e "travis_fold:start:size_report"
cat size.log
echo -e "travis_fold:end:size_report"
}
set -e
if [ -z "$TRAVIS_BUILD_DIR" ]; then
echo "TRAVIS_BUILD_DIR is not set, trying to guess:"
pushd $(dirname $0)/../ > /dev/null
TRAVIS_BUILD_DIR=$PWD
popd > /dev/null
echo "TRAVIS_BUILD_DIR=$TRAVIS_BUILD_DIR"
fi
Executable
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
cache_dir=$(mktemp -d)
source "$TRAVIS_BUILD_DIR"/tests/common.sh
if [ "$BUILD_PARITY" = "even" ]; then
mod=2
rem=0
elif [ "$BUILD_PARITY" = "odd" ]; then
mod=2
rem=1
fi
install_arduino debug
build_sketches_with_arduino "$mod" "$rem" lm2f
rm -rf "$cache_dir"
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S \
./libraries/LittleFS/src ./libraries/LittleFS/examples \
./libraries/rp2040 ./libraries/SD ./libraries/SdFat \
./libraries/Servo ./libraries/SPI ./libraries/Wire; do
find $dir \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
find $dir -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \;
done
+126
View File
@@ -0,0 +1,126 @@
#!/bin/sh
# temporary directory
[ -z "${TMPCI}" ] && TMPCI=/tmp/ci
##################
set -e
TMPDIR=${TMPCI%/*}
CIDIR=${TMPCI##*/}
mkdir -p ${TMPDIR}
# set root directory into $ESP
ESP="$(cd ${0%/*}/..; pwd)"
branch=$(git rev-parse --abbrev-ref HEAD)
echo ""
echo " -- CI directory: ${TMPCI} --"
echo ""
echo "Ensure your changes are committed in current branch ${branch}"
echo ""
echo "press return to run 'git diff'"
read junk
git diff
echo "press return to run CI, or ^C"
read junk
# clone or update this repository into ${TMPDIR}/${CIDIR}
if [ -d ${TMPCI} ]; then
echo ""
echo " -- updating CI directory in ${TMPCI} --"
echo ""
(cd ${TMPCI}; git checkout master; git branch -D ${branch} || true; git checkout -b ${branch}; git pull origin ${branch})
else
echo ""
echo " -- installing CI directory in ${TMPCI} --"
echo ""
(cd ${TMPDIR}; git clone ${ESP} ${CIDIR})
fi
cd ${TMPCI}
if [ "$branch" != "$branch" ]; then
echo "branch ${cibranch} in ${TMPCI} not matching branch ${branch} in ${ESP}"
exit 1
fi
rm -rf arduino_ide arduino-nightly Arduino/libraries/ArduinoJson
while true; do
cat << EOF
Which build?
1. main
2. tinyusb
4. debug even
5. debug odd
6. platformio
7. package
8. host
9. style
EOF
read answer
BUILD_TYPE=""
case "$answer" in
1) BUILD_TYPE=build;;
2) BUILD_TYPE=build_tinyusb;;
4) BUILD_TYPE=debug_even;;
5) BUILD_TYPE=debug_odd;;
6) BUILD_TYPE=platformio;;
7) BUILD_TYPE=package;;
8) BUILD_TYPE=host;;
9) BUILD_TYPE=style;;
esac
test -z "$BUILD_TYPE" || break
done
git submodule update --init
(cd pico-sdk && git submodule update --init)
(cd pico-extras && git submodule update --init)
export HOME="${TMPCI}"
export TRAVIS_BUILD_DIR="${TMPCI}"
export BUILD_TYPE="$BUILD_TYPE"
if [ "$BUILD_TYPE" = "build" ]; then
tests/build.sh
elif [ "$BUILD_TYPE" = "build_even" ]; then
BUILD_PARITY=even tests/build.sh
elif [ "$BUILD_TYPE" = "build_odd" ]; then
BUILD_PARITY=odd tests/build.sh
elif [ "$BUILD_TYPE" = "debug_even" ]; then
BUILD_PARITY=even tests/debug.sh
elif [ "$BUILD_TYPE" = "debug_odd" ]; then
BUILD_PARITY=odd tests/debug.sh
elif [ "$BUILD_TYPE" = "build_tinyusb" ]; then
tests/build-tinyusb.sh
elif [ "$BUILD_TYPE" = "build6_even" ]; then
BUILD_PARITY=even tests/build6.sh
elif [ "$BUILD_TYPE" = "build6_odd" ]; then
BUILD_PARITY=odd tests/build6.sh
elif [ "$BUILD_TYPE" = "platformio" ]; then
tests/platformio.sh
elif [ "$BUILD_TYPE" = "platformio_even" ]; then
BUILD_PARITY=even tests/platformio.sh
elif [ "$BUILD_TYPE" = "platformio_odd" ]; then
BUILD_PARITY=odd tests/platformio.sh
elif [ "$BUILD_TYPE" = host ]; then
tests/ci/host_test.sh
elif [ "$BUILD_TYPE" = style ]; then
tests/restyle.sh
else
echo "BUILD_TYPE not set or invalid"
exit 1
fi
+1 -1
View File
@@ -18,7 +18,7 @@ to get the board into update mode (1200bps connection).
Very dumb `sed`-like tool used by the platform scripts to generate the
linker `.ld` file (replacing the EEPROM location, FS sizes, etc.).
Because we run on Windows, Mac, and Linux, need to provide this and not
rely on existance of `sed` command.
rely on existence of `sed` command.
## pyserial
`git clone` of the PySerial Python3 library to be used by the IDE.
Executable
+160
View File
@@ -0,0 +1,160 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# build.py — build a sketch using arduino-builder
#
# Wrapper script around arduino-builder which accepts some ESP8266-specific
# options and translates them into FQBN
#
# Copyright © 2016 Ivan Grokhotkov
#
# 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.
#
#
from __future__ import print_function
import sys
import os
import argparse
import platform
import subprocess
import tempfile
import shutil
# Arduino-builder needs forward-slash paths for passed in params or it cannot
# launch the needed toolset.
def windowsize_paths(l):
"""Convert forward-slash paths to backslash paths referenced from C:"""
out = []
for i in l:
if i.startswith('/'):
i = 'C:' + i
out += [i.replace('/', '\\')]
return out
def compile(tmp_dir, sketch, cache, tools_dir, hardware_dir, ide_path, f, args):
cmd = []
cmd += [ide_path + '/arduino-builder']
cmd += ['-compile', '-logger=human']
cmd += ['-build-path', tmp_dir]
cmd += ['-tools', ide_path + '/tools-builder']
if cache != "":
cmd += ['-build-cache', cache ]
if args.library_path:
for lib_dir in args.library_path:
cmd += ['-libraries', lib_dir]
cmd += ['-hardware', ide_path + '/hardware']
if args.hardware_dir:
for hw_dir in args.hardware_dir:
cmd += ['-hardware', hw_dir]
else:
cmd += ['-hardware', hardware_dir]
# Debug=Serial,DebugLevel=Core____
fqbn = '-fqbn=pico:rp2040:rpipico:' \
'flash=2097152_65536,' \
'freq={freq},' \
'dbgport={dbgport},' \
'dbglvl={dbglvl},' \
'usbstack={usbstack}'.format(**vars(args))
cmd += [fqbn]
cmd += ['-built-in-libraries', ide_path + '/libraries']
cmd += ['-ide-version=10607']
cmd += ['-warnings={warnings}'.format(**vars(args))]
if args.verbose:
cmd += ['-verbose']
cmd += [sketch]
if platform.system() == "Windows":
cmd = windowsize_paths(cmd)
if args.verbose:
print('Building: ' + " ".join(cmd), file=f)
p = subprocess.Popen(cmd, stdout=f, stderr=subprocess.STDOUT)
p.wait()
return p.returncode
def parse_args():
parser = argparse.ArgumentParser(description='Sketch build helper')
parser.add_argument('-v', '--verbose', help='Enable verbose output',
action='store_true')
parser.add_argument('-i', '--ide_path', help='Arduino IDE path')
parser.add_argument('-p', '--build_path', help='Build directory')
parser.add_argument('-l', '--library_path', help='Additional library path',
action='append')
parser.add_argument('-d', '--hardware_dir', help='Additional hardware path',
action='append')
parser.add_argument('-b', '--board_name', help='Board name', default='generic')
parser.add_argument('-f', '--freq', help='CPU frequency', default=133,
choices=[50, 125, 133], type=int)
parser.add_argument('-w', '--warnings', help='Compilation warnings level',
default='none', choices=['none', 'all', 'more'])
parser.add_argument('-o', '--output_binary', help='File name for output binary')
parser.add_argument('-k', '--keep', action='store_true',
help='Don\'t delete temporary build directory')
parser.add_argument('--dbgport', help='Debug port', default='Disabled',
choices=['Disabled', 'Serial', 'Serial1'])
parser.add_argument('--dbglvl', help='Debug level', default='None',
choices=['None', 'All'])
parser.add_argument('--usbstack', help='USB stack', default='picosdk',
choices=['picosdk', 'tinyusb'])
parser.add_argument('--build_cache', help='Build directory to cache core.a', default='')
parser.add_argument('sketch_path', help='Sketch file path')
return parser.parse_args()
def main():
args = parse_args()
ide_path = args.ide_path
if not ide_path:
ide_path = os.environ.get('ARDUINO_IDE_PATH')
if not ide_path:
print("Please specify Arduino IDE path via --ide_path option"
"or ARDUINO_IDE_PATH environment variable.", file=sys.stderr)
return 2
sketch_path = args.sketch_path
tmp_dir = args.build_path
created_tmp_dir = False
if not tmp_dir:
tmp_dir = tempfile.mkdtemp()
created_tmp_dir = True
tools_dir = os.path.dirname(os.path.realpath(__file__)) + '/../tools'
# this is not the correct hardware folder to add.
hardware_dir = os.path.dirname(os.path.realpath(__file__)) + '/../cores'
output_name = tmp_dir + '/' + os.path.basename(sketch_path) + '.bin'
if args.verbose:
print("Sketch: ", sketch_path)
print("Build dir: ", tmp_dir)
print("Cache dir: ", args.build_cache)
print("Output: ", output_name)
if args.verbose:
f = sys.stdout
else:
f = open(tmp_dir + '/build.log', 'w')
res = compile(tmp_dir, sketch_path, args.build_cache, tools_dir, hardware_dir, ide_path, f, args)
if res != 0:
return res
if args.output_binary is not None:
shutil.copy(output_name, args.output_binary)
if created_tmp_dir and not args.keep:
shutil.rmtree(tmp_dir, ignore_errors=True)
if __name__ == '__main__':
sys.exit(main())
+30 -9
View File
@@ -24,7 +24,7 @@ def BuildDebugPort(name):
print("%s.menu.dbgport.%s.build.debug_port=-DDEBUG_RP2040_PORT=%s" % (name, p, p))
def BuildDebugLevel(name):
for l in [ ("None", ""), ("Core", "-DDEBUG_RP2040_CORE"), ("SPI", "-DDEBUG_RP2040_SPI"), ("Wire", "DDEBUG_RP2040_WIRE"),
for l in [ ("None", ""), ("Core", "-DDEBUG_RP2040_CORE"), ("SPI", "-DDEBUG_RP2040_SPI"), ("Wire", "-DDEBUG_RP2040_WIRE"),
("All", "-DDEBUG_RP2040_WIRE -DDEBUG_RP2040_SPI -DDEBUG_RP2040_CORE"), ("NDEBUG", "-DNDEBUG") ]:
print("%s.menu.dbglvl.%s=%s" % (name, l[0], l[0]))
print("%s.menu.dbglvl.%s.build.debug_level=%s" % (name, l[0], l[1]))
@@ -44,9 +44,20 @@ def BuildBoot(name):
print("%s.menu.boot2.%s=%s" % (name, l[1], l[0]))
print("%s.menu.boot2.%s.build.boot2=%s" % (name, l[1], l[1]))
def BuildHeader(name, prettyname, pidtouse, pid, boarddefine, variant, uploadtool, flashsize, boot2):
def BuildUSBStack(name):
print("%s.menu.usbstack.picosdk=Pico SDK" % (name))
print("%s.menu.usbstack.picosdk.build.usbstack_flags=" % (name))
print("%s.menu.usbstack.tinyusb=Adafruit TinyUSB" % (name))
print('%s.menu.usbstack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{build.core.path}/TinyUSB" "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"' % (name))
def BuildHeader(name, vendor_name, product_name, pidtouse, vid, pid, boarddefine, variant, uploadtool, flashsize, boot2):
prettyname = vendor_name + " " + product_name
print()
print("# -----------------------------------")
print("# %s" % (prettyname))
print("# -----------------------------------")
print("%s.name=%s" % (name, prettyname))
print("%s.vid.0=0x2e8a" % (name))
print("%s.vid.0=%s" % (name, vid))
print("%s.pid.0=%s" % (name, pidtouse))
print("%s.build.usbpid=-DSERIALUSB_PID=%s" % (name, pid))
print("%s.build.board=%s" % (name, boarddefine))
@@ -65,6 +76,10 @@ def BuildHeader(name, prettyname, pidtouse, pid, boarddefine, variant, uploadtoo
print("%s.build.mcu=rp2040" % (name))
print("%s.build.ldscript=memmap_default.ld" % (name))
print("%s.build.boot2=%s" % (name, boot2))
print("%s.build.vid=%s" % (name, vid))
print("%s.build.pid=%s" % (name, pid))
print('%s.build.usb_manufacturer="%s"' % (name, vendor_name))
print('%s.build.usb_product="%s"' % (name, product_name))
def BuildGlobalMenuList():
print("menu.BoardModel=Model")
@@ -73,12 +88,13 @@ def BuildGlobalMenuList():
print("menu.dbgport=Debug Port")
print("menu.dbglvl=Debug Level")
print("menu.boot2=Boot Stage 2")
print("menu.usbstack=USB Stack")
def MakeBoard(name, prettyname, pid, boarddefine, flashsizemb, boot2):
def MakeBoard(name, vendor_name, product_name, vid, pid, boarddefine, flashsizemb, boot2):
for a, b, c in [ ["", "", "uf2conv"], ["picoprobe", " (Picoprobe)", "picoprobe"]]:
n = name + a
p = prettyname + b
p = product_name + b
fssizelist = [ 0, 64 * 1024, 128 * 1024, 256 * 1024, 512 * 1024 ]
for i in range(1, flashsizemb):
fssizelist.append(i * 1024 * 1024)
@@ -86,7 +102,7 @@ def MakeBoard(name, prettyname, pid, boarddefine, flashsizemb, boot2):
pidtouse = '0x0004'
else:
pidtouse = pid
BuildHeader(n, p, pidtouse, pid, boarddefine, name, c, flashsizemb * 1024 * 1024, boot2)
BuildHeader(n, vendor_name, p, pidtouse, vid, pid, boarddefine, name, c, flashsizemb * 1024 * 1024, boot2)
if name == "generic":
BuildFlashMenu(n, 2*1024*1024, [0, 1*1024*1024])
BuildFlashMenu(n, 4*1024*1024, [0, 2*1024*1024])
@@ -97,12 +113,17 @@ def MakeBoard(name, prettyname, pid, boarddefine, flashsizemb, boot2):
BuildFreq(n)
BuildDebugPort(n)
BuildDebugLevel(n)
BuildUSBStack(n)
if name == "generic":
BuildBoot(n)
BuildGlobalMenuList()
MakeBoard("rpipico", "Raspberry Pi Pico", "0x000a", "RASPBERRY_PI_PICO", 2, "boot2_w25q080_2_padded_checksum")
MakeBoard("adafruitfeather", "Adafruit Feather RP2040", "0x000b", "ADAFRUIT_FEATHER_RP2040", 8, "boot2_w25x10cl_4_padded_checksum")
MakeBoard("generic", "Generic RP2040", "0xf00a", "GENERIC_RP2040", 16, "boot2_generic_03h_4_padded_checksum")
MakeBoard("rpipico", "Raspberry Pi", "Pico", "0x2e8a", "0x000a", "RASPBERRY_PI_PICO", 2, "boot2_w25q080_2_padded_checksum")
MakeBoard("adafruit_feather", "Adafruit", "Feather RP2040", "0x239a", "0x80f1", "ADAFRUIT_FEATHER_RP2040", 8, "boot2_w25x10cl_4_padded_checksum")
MakeBoard("adafruit_itsybitsy", "Adafruit", "ItsyBitsy RP2040", "0x239a", "0x80fd", "ADAFRUIT_ITSYBITSY_RP2040", 8, "boot2_w25q080_2_padded_checksum")
MakeBoard("adafruit_qtpy", "Adafruit", "QT Py RP2040", "0x239a", "0x80f7", "ADAFRUIT_QTPY_RP2040", 8, "boot2_generic_03h_4_padded_checksum")
MakeBoard("adafruit_stemmafriend", "Adafruit", "STEMMA Friend RP2040", "0x239a", "0x80e3", "ADAFRUIT_STEMMAFRIEND_RP2040", 8, "boot2_w25q080_2_padded_checksum")
MakeBoard("adafruit_trinkeyrp2040qt", "Adafruit", "Trinkey RP2040 QT", "0x239a", "0x8109", "ADAFRUIT_TRINKEYQT_RP2040", 8, "boot2_w25q080_2_padded_checksum")
MakeBoard("generic", "Generic", "RP2040", "0x2e8a", "0xf00a", "GENERIC_RP2040", 16, "boot2_generic_03h_4_padded_checksum")
+9 -1
View File
@@ -33,6 +33,7 @@ import os
import os.path
import argparse
import time
import glob
toolspath = os.path.dirname(os.path.realpath(__file__)).replace('\\', '/') # CWD in UNIX format
try:
@@ -222,7 +223,7 @@ def convert_from_hex_to_uf2(buf):
return resfile
def to_str(b):
return b.decode("utf-8")
return b.decode("utf-8", "replace")
def get_drives():
drives = []
@@ -357,6 +358,13 @@ def main():
args.output = "flash." + ext
else:
drives = get_drives()
if (len(drives) == 0) and (sys.platform == "linux"):
rpidisk = glob.glob("/dev/disk/by-id/usb-RPI_RP2*-part1")
try:
subprocess.run(["udisksctl", "mount", "--block-device", os.path.realpath(rpidisk[0])])
drives = get_drives()
except:
pass # If it fails, no problem since it was a heroic attempt
if args.output:
write_file(args.output, outbuf)
@@ -0,0 +1,41 @@
#pragma once
// Pin definitions taken from:
// https://learn.adafruit.com/assets/100337
// LEDs
#define PIN_LED (11u)
// Serial
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)
// Not pinned out
#define PIN_SERIAL2_TX (31u)
#define PIN_SERIAL2_RX (31u)
// SPI
#define PIN_SPI0_MISO (20u)
#define PIN_SPI0_MOSI (19u)
#define PIN_SPI0_SCK (18u)
#define PIN_SPI0_SS (31u) // not pinned out
// Not pinned out
#define PIN_SPI1_MISO (31u)
#define PIN_SPI1_MOSI (31u)
#define PIN_SPI1_SCK (31u)
#define PIN_SPI1_SS (31u)
// Wire
#define PIN_WIRE0_SDA (2u)
#define PIN_WIRE0_SCL (3u)
// Not pinned out
#define PIN_WIRE1_SDA (31u)
#define PIN_WIRE1_SCL (31u)
#define SERIAL_HOWMANY (2u)
#define SPI_HOWMANY (1u)
#define WIRE_HOWMANY (1u)
#include "../generic/common.h"
+41
View File
@@ -0,0 +1,41 @@
#pragma once
// Pin definitions taken from:
// https://learn.adafruit.com/assets/100337
// LEDs not pinned out
#define PIN_LED (31u)
// Serial
#define PIN_SERIAL1_TX (20u)
#define PIN_SERIAL1_RX (5u)
// Not pinned out
#define PIN_SERIAL2_TX (31u)
#define PIN_SERIAL2_RX (31u)
// SPI
#define PIN_SPI0_MISO (4u)
#define PIN_SPI0_MOSI (3u)
#define PIN_SPI0_SCK (6u)
#define PIN_SPI0_SS (31u) // not pinned out
// Not pinned out
#define PIN_SPI1_MISO (31u)
#define PIN_SPI1_MOSI (31u)
#define PIN_SPI1_SCK (31u)
#define PIN_SPI1_SS (31u)
// Wire
#define PIN_WIRE0_SDA (24u)
#define PIN_WIRE0_SCL (25u)
// Wire1 is connected to StemmaQT connector
#define PIN_WIRE1_SDA (22u)
#define PIN_WIRE1_SCL (23u)
#define SERIAL_HOWMANY (2u)
#define SPI_HOWMANY (1u)
#define WIRE_HOWMANY (2u)
#include "../generic/common.h"
@@ -0,0 +1,45 @@
#pragma once
// Pin definitions taken from:
// https://learn.adafruit.com/assets/100337
// LEDs not pinned out
#define PIN_LED (12u) // backlight, weird but why not?
#define PIN_NEOPIXEL (17u)
#define NUM_NEOPIXEL (1u)
#define PIN_SWITCH (11u)
// Serial
#define PIN_SERIAL1_TX (26u) // shared on grove/jst 2mm
#define PIN_SERIAL1_RX (27u) // shared on grove/jst 2mm
// Not pinned out
#define PIN_SERIAL2_TX (20u) // shared on JST SH
#define PIN_SERIAL2_RX (21u)
// SPI
#define PIN_SPI0_MISO (4u) // unconnected
#define PIN_SPI0_MOSI (7u) // TFT data
#define PIN_SPI0_SCK (2u) // TFT clock
#define PIN_SPI0_SS (1u) // TFT CS
// Not pinned out
#define PIN_SPI1_MISO (31u)
#define PIN_SPI1_MOSI (31u)
#define PIN_SPI1_SCK (31u)
#define PIN_SPI1_SS (31u)
// Wire connected to STEMMA QT
#define PIN_WIRE0_SDA (20u)
#define PIN_WIRE0_SCL (21u)
// Wire1 is connected to Stemma JST/grove connector
#define PIN_WIRE1_SDA (26u)
#define PIN_WIRE1_SCL (27u)
#define SERIAL_HOWMANY (2u)
#define SPI_HOWMANY (1u)
#define WIRE_HOWMANY (2u)
#include "../generic/common.h"
@@ -0,0 +1,42 @@
#pragma once
// LEDs not pinned out
#define PIN_LED (31u)
#define PIN_NEOPIXEL (27u)
#define NUM_NEOPIXEL (1u)
#define PIN_SWITCH (12u)
// Serial, shared on QT pin
#define PIN_SERIAL1_TX (16u)
#define PIN_SERIAL1_RX (17u)
// Not pinned out
#define PIN_SERIAL2_TX (31u)
#define PIN_SERIAL2_RX (31u)
// SPI Not pinned out
#define PIN_SPI0_MISO (31u)
#define PIN_SPI0_MOSI (31u)
#define PIN_SPI0_SCK (31u)
#define PIN_SPI0_SS (31u)
// Not pinned out
#define PIN_SPI1_MISO (31u)
#define PIN_SPI1_MOSI (31u)
#define PIN_SPI1_SCK (31u)
#define PIN_SPI1_SS (31u)
// Wire
#define PIN_WIRE0_SDA (16u)
#define PIN_WIRE0_SCL (17u)
// Wire1 Not pinned out
#define PIN_WIRE1_SDA (31u)
#define PIN_WIRE1_SCL (31u)
#define SERIAL_HOWMANY (1u)
#define SPI_HOWMANY (0u)
#define WIRE_HOWMANY (1u)
#include "../generic/common.h"