From 360962af4614f2ec3e08a97150af819c243d0538 Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Sat, 4 Jun 2022 12:04:23 +1000 Subject: [PATCH 1/4] Update changelog, readme and version number for HAL 0.5.0 release --- rp2040-hal/CHANGELOG.md | 29 +++++++++++++++++++++++++++-- rp2040-hal/Cargo.toml | 2 +- rp2040-hal/README.md | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/rp2040-hal/CHANGELOG.md b/rp2040-hal/CHANGELOG.md index 9bd6e4503..21ab57a0e 100644 --- a/rp2040-hal/CHANGELOG.md +++ b/rp2040-hal/CHANGELOG.md @@ -7,9 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.5.0] - 2022-06-22 + +### MSRV + +The Minimum-Supported Rust Version (MSRV) for this release is 1.61 + +### Added + +- RP2040 specific #[entry] macro that releases spinlocks - @jannic +- Start multiple state machines in sync with each other - @astraw +- Unsafe fn for freeing all spinlocks when you can't use the RP2040 entry macro (eg RTIC) - @9names +- Optional feature for enabling defmt formatting for i2c errors - @ithinuel + +### Changed + +- Use thread send safe UART* marker when splitting, improves UART ergonmics - @marius-meissner +- Improve performance for hardware division instrinsics. Internal intrinsics cleanup - @Sizurka +- Provide a better alarm abstraction - @ithinuel +- Update Multicore::spawn to be able to take a closure without requiring alloc. + Improve Multicore ergonomics and add example for how to use new API - @Liamolucko +- Allow PIO program to be 32 instructions long, was previously limited to 31 - @jannic +- Fix Typos - @mqy + ### Removed -- removed i2c embassy driver prototype +- I2c async driver. Use new one at https://github.com/ithinuel/rp2040-async-i2c/ - @ithinuel +- Unused fields from UartPeripheral and Reader - @jannic ## [0.4.0] - 2022-03-09 @@ -98,7 +122,8 @@ The Minimum-Supported Rust Version (MSRV) for this release is 1.54. - Initial release -[Unreleased]: https://github.com/rp-rs/rp-hal/compare/v0.4.0...HEAD +[Unreleased]: https://github.com/rp-rs/rp-hal/compare/v0.5.0...HEAD +[0.5.0]: https://github.com/rp-rs/rp-hal/compare/v0.4.0...v0.5.0 [0.4.0]: https://github.com/rp-rs/rp-hal/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/rp-rs/rp-hal/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/rp-rs/rp-hal/compare/v0.1.0...v0.2.0 diff --git a/rp2040-hal/Cargo.toml b/rp2040-hal/Cargo.toml index 0e112b243..7b5f62b5d 100644 --- a/rp2040-hal/Cargo.toml +++ b/rp2040-hal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rp2040-hal" -version = "0.4.0" +version = "0.5.0" authors = ["The rp-rs Developers"] edition = "2018" homepage = "https://github.com/rp-rs/rp-hal" diff --git a/rp2040-hal/README.md b/rp2040-hal/README.md index 9b46007de..acc79d065 100644 --- a/rp2040-hal/README.md +++ b/rp2040-hal/README.md @@ -68,7 +68,7 @@ https://github.com/rp-rs/rp-hal/ for more details. To include this crate in your project, amend your `Cargo.toml` file to include ```toml -rp2040-hal = "0.4.0" +rp2040-hal = "0.5.0" ``` To obtain a copy of the source code (e.g. if you want to propose a bug-fix or From 6c9e948a17659eac7fe0205f296ab2dfb01e472b Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Sat, 4 Jun 2022 13:54:13 +1000 Subject: [PATCH 2/4] Bump HAL version in BSP deps --- boards/adafruit-feather-rp2040/Cargo.toml | 2 +- boards/adafruit-itsy-bitsy-rp2040/Cargo.toml | 2 +- boards/adafruit-kb2040/Cargo.toml | 2 +- boards/adafruit-macropad/Cargo.toml | 2 +- boards/adafruit-qt-py-rp2040/Cargo.toml | 2 +- boards/adafruit-trinkey-qt2040/Cargo.toml | 2 +- boards/arduino_nano_connect/Cargo.toml | 2 +- boards/pimoroni-pico-explorer/Cargo.toml | 2 +- boards/pimoroni-pico-lipo-16mb/Cargo.toml | 2 +- boards/pimoroni-plasma-2040/Cargo.toml | 2 +- boards/pimoroni-tiny2040/Cargo.toml | 2 +- boards/rp-pico/Cargo.toml | 2 +- boards/solderparty-rp2040-stamp/Cargo.toml | 2 +- boards/sparkfun-pro-micro-rp2040/Cargo.toml | 2 +- boards/sparkfun-thing-plus-rp2040/Cargo.toml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/boards/adafruit-feather-rp2040/Cargo.toml b/boards/adafruit-feather-rp2040/Cargo.toml index b28a83b3c..205fd8bfe 100644 --- a/boards/adafruit-feather-rp2040/Cargo.toml +++ b/boards/adafruit-feather-rp2040/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } embedded-time = "0.12.0" diff --git a/boards/adafruit-itsy-bitsy-rp2040/Cargo.toml b/boards/adafruit-itsy-bitsy-rp2040/Cargo.toml index 41359d7c7..1059016ba 100644 --- a/boards/adafruit-itsy-bitsy-rp2040/Cargo.toml +++ b/boards/adafruit-itsy-bitsy-rp2040/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } embedded-time = "0.12.0" diff --git a/boards/adafruit-kb2040/Cargo.toml b/boards/adafruit-kb2040/Cargo.toml index b3223ffcd..076156dae 100644 --- a/boards/adafruit-kb2040/Cargo.toml +++ b/boards/adafruit-kb2040/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0" } +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7.0", optional = true } embedded-hal = { version = "0.2.4", features = ["unproven"] } rp2040-boot2 = { version = "0.2.0", optional = true } diff --git a/boards/adafruit-macropad/Cargo.toml b/boards/adafruit-macropad/Cargo.toml index 82601359c..8150b2f00 100644 --- a/boards/adafruit-macropad/Cargo.toml +++ b/boards/adafruit-macropad/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } [dev-dependencies] embedded-time = "0.12.0" diff --git a/boards/adafruit-qt-py-rp2040/Cargo.toml b/boards/adafruit-qt-py-rp2040/Cargo.toml index ac44e43a2..fd77378bc 100644 --- a/boards/adafruit-qt-py-rp2040/Cargo.toml +++ b/boards/adafruit-qt-py-rp2040/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } embedded-time = "0.12.0" rp2040-boot2 = { version = "0.2.0", optional = true } diff --git a/boards/adafruit-trinkey-qt2040/Cargo.toml b/boards/adafruit-trinkey-qt2040/Cargo.toml index 3cc30f1b7..002ae23e9 100644 --- a/boards/adafruit-trinkey-qt2040/Cargo.toml +++ b/boards/adafruit-trinkey-qt2040/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0" } +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7.0", optional = true } rp2040-boot2 = { version = "0.2.0", optional = true } diff --git a/boards/arduino_nano_connect/Cargo.toml b/boards/arduino_nano_connect/Cargo.toml index c1ee2b792..5fe37d9d3 100644 --- a/boards/arduino_nano_connect/Cargo.toml +++ b/boards/arduino_nano_connect/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.3" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0" } +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7.0", optional = true } embedded-hal = { version = "0.2.4", features = ["unproven"] } panic-probe = { version = "0.2.0", features = ["print-defmt"] } diff --git a/boards/pimoroni-pico-explorer/Cargo.toml b/boards/pimoroni-pico-explorer/Cargo.toml index a1f991648..1b917257c 100644 --- a/boards/pimoroni-pico-explorer/Cargo.toml +++ b/boards/pimoroni-pico-explorer/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } embedded-hal = { version = "0.2.4", features = ["unproven"] } st7789 = "0.6.1" diff --git a/boards/pimoroni-pico-lipo-16mb/Cargo.toml b/boards/pimoroni-pico-lipo-16mb/Cargo.toml index c5039852e..9f0697208 100644 --- a/boards/pimoroni-pico-lipo-16mb/Cargo.toml +++ b/boards/pimoroni-pico-lipo-16mb/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } rp2040-boot2 = { version = "0.2.0", optional = true } diff --git a/boards/pimoroni-plasma-2040/Cargo.toml b/boards/pimoroni-plasma-2040/Cargo.toml index a962e6e07..5fef00085 100644 --- a/boards/pimoroni-plasma-2040/Cargo.toml +++ b/boards/pimoroni-plasma-2040/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } embedded-time = "0.12.0" diff --git a/boards/pimoroni-tiny2040/Cargo.toml b/boards/pimoroni-tiny2040/Cargo.toml index 1f7b52cec..01150dc2e 100644 --- a/boards/pimoroni-tiny2040/Cargo.toml +++ b/boards/pimoroni-tiny2040/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } embedded-time = "0.12.0" diff --git a/boards/rp-pico/Cargo.toml b/boards/rp-pico/Cargo.toml index 609d8370b..dd81d7d5e 100644 --- a/boards/rp-pico/Cargo.toml +++ b/boards/rp-pico/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } embedded-time = "0.12.0" usb-device= "0.2.8" diff --git a/boards/solderparty-rp2040-stamp/Cargo.toml b/boards/solderparty-rp2040-stamp/Cargo.toml index 9ebe18cdb..76058114e 100644 --- a/boards/solderparty-rp2040-stamp/Cargo.toml +++ b/boards/solderparty-rp2040-stamp/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" rp2040-boot2 = { version = "0.2.0", optional = true } -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0"} +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7", optional = true } [features] diff --git a/boards/sparkfun-pro-micro-rp2040/Cargo.toml b/boards/sparkfun-pro-micro-rp2040/Cargo.toml index 3fe87bb82..630670d58 100644 --- a/boards/sparkfun-pro-micro-rp2040/Cargo.toml +++ b/boards/sparkfun-pro-micro-rp2040/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0" } +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7.0", optional = true } embedded-hal = { version = "0.2.4", features = ["unproven"] } rp2040-boot2 = { version = "0.2.0", optional = true } diff --git a/boards/sparkfun-thing-plus-rp2040/Cargo.toml b/boards/sparkfun-thing-plus-rp2040/Cargo.toml index 1f758e92e..c8e29b2c3 100644 --- a/boards/sparkfun-thing-plus-rp2040/Cargo.toml +++ b/boards/sparkfun-thing-plus-rp2040/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.2" -rp2040-hal = { path = "../../rp2040-hal", version = "0.4.0" } +rp2040-hal = { path = "../../rp2040-hal", version = "0.5.0" } cortex-m-rt = { version = "0.7.0", optional = true } embedded-hal = { version = "0.2.4", features = ["unproven"] } rp2040-boot2 = { version = "0.2.0", optional = true } From 4a3ef3728915174ab49171fc05bb8aa5cf6f4412 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Sat, 4 Jun 2022 09:11:41 +0000 Subject: [PATCH 3/4] Remove example pico_i2c_pio This example should be moved to the i2c-pio crate: https://github.com/ithinuel/i2c-pio-rs/pull/6 --- boards/arduino_nano_connect/Cargo.toml | 1 - boards/rp-pico/Cargo.toml | 1 - boards/rp-pico/examples/pico_i2c_pio.rs | 156 ------------------------ 3 files changed, 158 deletions(-) delete mode 100644 boards/rp-pico/examples/pico_i2c_pio.rs diff --git a/boards/arduino_nano_connect/Cargo.toml b/boards/arduino_nano_connect/Cargo.toml index 5fe37d9d3..bdcc881e1 100644 --- a/boards/arduino_nano_connect/Cargo.toml +++ b/boards/arduino_nano_connect/Cargo.toml @@ -41,7 +41,6 @@ panic-halt= "0.2.0" embedded-hal ="0.2.5" cortex-m-rtic = "0.6.0-alpha.5" nb = "1.0" -# i2c-pio = { git = "https://github.com/ithinuel/i2c-pio-rs", rev = "afc2dad0e955da2b712d7f7cd78c7af88ddc6a45" } [features] default = ["boot2", "rt"] diff --git a/boards/rp-pico/Cargo.toml b/boards/rp-pico/Cargo.toml index dd81d7d5e..a610c5b61 100644 --- a/boards/rp-pico/Cargo.toml +++ b/boards/rp-pico/Cargo.toml @@ -26,7 +26,6 @@ panic-halt= "0.2.0" embedded-hal ="0.2.5" cortex-m-rtic = "0.6.0-rc.4" nb = "1.0" -i2c-pio = { git = "https://github.com/ithinuel/i2c-pio-rs", rev = "fa155bbae4e8553b448a66cc47236db38b7524dd" } heapless = "0.7.9" embedded-sdmmc = { git = "https://github.com/rust-embedded-community/embedded-sdmmc-rs.git" } smart-leds = "0.3.0" diff --git a/boards/rp-pico/examples/pico_i2c_pio.rs b/boards/rp-pico/examples/pico_i2c_pio.rs deleted file mode 100644 index 9872d2b17..000000000 --- a/boards/rp-pico/examples/pico_i2c_pio.rs +++ /dev/null @@ -1,156 +0,0 @@ -//! # Pico I2C PIO Example -//! -//! Reads the temperature from an LM75B -//! -//! This read over I2C the temerature from an LM75B temperature sensor wired on pins 20 and 21 -//! using the PIO peripheral as an I2C bus controller. -//! The pins used for the I2C can be remapped to any other pin available to the PIO0 peripheral. -//! -//! See the `Cargo.toml` file for Copyright and license details. - -#![no_std] -#![no_main] - -// The trait used by formatting macros like write! and writeln! -use core::fmt::Write as FmtWrite; - -// The macro for our start-up function -use rp_pico::entry; - -// I2C HAL traits & Types. -use embedded_hal::blocking::i2c::{Operation, Read, Transactional, Write}; - -// Time handling traits -use embedded_time::rate::*; - -// Ensure we halt the program on panic (if we don't mention this crate it won't -// be linked) -use panic_halt as _; - -// Pull in any important traits -use rp_pico::hal::prelude::*; - -// A shorter alias for the Peripheral Access Crate, which provides low-level -// register access -use rp_pico::hal::pac; - -// A shorter alias for the Hardware Abstraction Layer, which provides -// higher-level drivers. -use rp_pico::hal; - -/// Prints the temperature received from the sensor -fn print_temperature(serial: &mut impl FmtWrite, temp: [u8; 2]) { - let temp_i16 = i16::from_be_bytes(temp) >> 5; - let temp_f32 = f32::from(temp_i16) * 0.125; - - // Write formatted output but ignore any error. - let _ = writeln!(serial, "Temperature: {:0.2}°C", temp_f32); -} - -/// Entry point to our bare-metal application. -/// -/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function -/// as soon as all global variables are initialised. -/// -/// The function configures the RP2040 peripherals, reads the temperature from -/// the attached LM75B using PIO0. -#[entry] -fn main() -> ! { - // Grab our singleton objects - let mut pac = pac::Peripherals::take().unwrap(); - - // Set up the watchdog driver - needed by the clock setup code - let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); - - // Configure the clocks - // - // The default is to generate a 125 MHz system clock - let clocks = hal::clocks::init_clocks_and_plls( - rp_pico::XOSC_CRYSTAL_FREQ, - pac.XOSC, - pac.CLOCKS, - pac.PLL_SYS, - pac.PLL_USB, - &mut pac.RESETS, - &mut watchdog, - ) - .ok() - .unwrap(); - - // The single-cycle I/O block controls our GPIO pins - let sio = hal::Sio::new(pac.SIO); - - // Set the pins up according to their function on this particular board - let pins = rp_pico::Pins::new( - pac.IO_BANK0, - pac.PADS_BANK0, - sio.gpio_bank0, - &mut pac.RESETS, - ); - - let uart_pins = ( - // UART TX (characters sent from RP2040) on pin 1 (GPIO0) - pins.gpio0.into_mode::(), - // UART RX (characters received by RP2040) on pin 2 (GPIO1) - pins.gpio1.into_mode::(), - ); - - let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) - .enable( - hal::uart::common_configs::_115200_8_N_1, - clocks.peripheral_clock.into(), - ) - .unwrap(); - - let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); - - let mut i2c_pio = i2c_pio::I2C::new( - &mut pio, - pins.gpio20, - pins.gpio21, - sm0, - 100_000.Hz(), - clocks.system_clock.freq(), - ); - - let mut temp = [0; 2]; - i2c_pio - .read(0x48u8, &mut temp) - .expect("Failed to read from the peripheral"); - print_temperature(&mut uart, temp); - - i2c_pio - .write(0x48u8, &[0]) - .expect("Failed to write to the peripheral"); - - let mut temp = [0; 2]; - i2c_pio - .read(0x48u8, &mut temp) - .expect("Failed to read from the peripheral"); - print_temperature(&mut uart, temp); - - let mut config = [0]; - let mut thyst = [0; 2]; - let mut tos = [0; 2]; - let mut temp = [0; 2]; - let mut operations = [ - Operation::Write(&[1]), - Operation::Read(&mut config), - Operation::Write(&[2]), - Operation::Read(&mut thyst), - Operation::Write(&[3]), - Operation::Read(&mut tos), - Operation::Write(&[0]), - Operation::Read(&mut temp), - ]; - i2c_pio - .exec(0x48u8, &mut operations) - .expect("Failed to run all operations"); - print_temperature(&mut uart, temp); - - loop { - cortex_m::asm::nop(); - } -} - -// End of file From 4c0f15af0fa5965105fa92870bb9f461065cc3a6 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Sat, 4 Jun 2022 09:46:42 +0000 Subject: [PATCH 4/4] Use vendored version of ws2812-pio in examples --- Cargo.toml | 3 + vendor/ws2812-pio/.cargo-checksum.json | 1 + vendor/ws2812-pio/Cargo.toml | 19 ++ vendor/ws2812-pio/LICENSE | 201 +++++++++++++++++++ vendor/ws2812-pio/README.md | 6 + vendor/ws2812-pio/src/lib.rs | 258 +++++++++++++++++++++++++ 6 files changed, 488 insertions(+) create mode 100644 vendor/ws2812-pio/.cargo-checksum.json create mode 100644 vendor/ws2812-pio/Cargo.toml create mode 100644 vendor/ws2812-pio/LICENSE create mode 100644 vendor/ws2812-pio/README.md create mode 100644 vendor/ws2812-pio/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 6b88f0b11..3b7889a7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,6 @@ rp2040-hal = { path ="./rp2040-hal" } [patch.crates-io] rp2040-hal = { path ="./rp2040-hal" } + +[patch.'https://github.com/ithinuel/ws2812-pio-rs.git'] +ws2812-pio = { path ="./vendor/ws2812-pio" } diff --git a/vendor/ws2812-pio/.cargo-checksum.json b/vendor/ws2812-pio/.cargo-checksum.json new file mode 100644 index 000000000..85f2a189a --- /dev/null +++ b/vendor/ws2812-pio/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"5b08ca6a9062cd01f73776893f3062a7ef3592abe93ad0b9d02661b57693c36c","LICENSE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","README.md":"bce8f6ef3d568df1391f63e6d76efbb37e35773e959224425663a8814272f093","src/lib.rs":"c5779e8114100f80668e9560a8742929f9c39e44764a1821062b0d64cca80d75"},"package":null} \ No newline at end of file diff --git a/vendor/ws2812-pio/Cargo.toml b/vendor/ws2812-pio/Cargo.toml new file mode 100644 index 000000000..5e78e6db1 --- /dev/null +++ b/vendor/ws2812-pio/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "ws2812-pio" +version = "0.2.0" +edition = "2018" +license = "Apache-2.0" +description = "Driver implementation for the WS2812 smart LED using the RP2040's PIO peripheral." +documentation = "https://docs.rs/ws2812-pio" +repository = "https://github.com/ithinuel/ws2812-pio-rs/" + +[dependencies] +embedded-hal = "0.2.5" +embedded-time = "0.12.0" +rp2040-hal = { path = "../../rp2040-hal" } +pio = "0.2.0" +smart-leds-trait = "0.2.1" +nb = "1.0.0" +cortex-m = "0.7.3" + +[workspace] diff --git a/vendor/ws2812-pio/LICENSE b/vendor/ws2812-pio/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/ws2812-pio/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/ws2812-pio/README.md b/vendor/ws2812-pio/README.md new file mode 100644 index 000000000..13ca72c0f --- /dev/null +++ b/vendor/ws2812-pio/README.md @@ -0,0 +1,6 @@ +# Ws2812b-pio + +Implements [`SmartLedsWrite`](https://docs.rs/smart-leds-trait/0.2.1/smart_leds_trait/trait.SmartLedsWrite.html) +for the Raspberry's [RP2040](https://www.raspberrypi.org/products/rp2040/) using the PIO peripheral. + +Refer to the [`rp-hal`](https://github.com/rp-rs/rp-hal) for examples. diff --git a/vendor/ws2812-pio/src/lib.rs b/vendor/ws2812-pio/src/lib.rs new file mode 100644 index 000000000..a72176b49 --- /dev/null +++ b/vendor/ws2812-pio/src/lib.rs @@ -0,0 +1,258 @@ +#![no_std] +//! WS2812 PIO Driver for the RP2040 +//! +//! This driver implements driving a WS2812 RGB LED strip from +//! a PIO device of the RP2040 chip. +//! +//! You should reach to [Ws2812] if you run the main loop +//! of your controller yourself and you want [Ws2812] to take +//! a hold of your timer. +//! +//! In case you use `cortex-m-rtic` and can't afford this crate +//! to wait blocking for you, you should try [Ws2812Direct]. +//! Bear in mind that you will have to take care of timing requirements +//! yourself then. + +use cortex_m; +use embedded_hal::timer::CountDown; +use embedded_time::{ + duration::{Extensions, Microseconds}, + fixed_point::FixedPoint, +}; +use rp2040_hal::{ + gpio::{Function, FunctionConfig, Pin, PinId, ValidPinMode}, + pio::{PIOExt, StateMachineIndex, Tx, UninitStateMachine, PIO}, +}; +use smart_leds_trait::SmartLedsWrite; + +/// This is the WS2812 PIO Driver. +/// +/// For blocking applications is recommended to use +/// the [Ws2812] struct instead of this raw driver. +/// +/// If you use this driver directly, you will need to +/// take care of the timing expectations of the [Ws2812Direct::write] +/// method. +/// +/// Typical usage example: +///```ignore +/// use rp2040_hal::clocks::init_clocks_and_plls; +/// let clocks = init_clocks_and_plls(...); +/// let pins = rp2040_hal::gpio::pin::bank0::Pins::new(...); +/// +/// let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); +/// let mut ws = Ws2812Direct::new( +/// pins.gpio4.into_mode(), +/// &mut pio, +/// sm0, +/// clocks.peripheral_clock.freq(), +/// ); +/// +/// // Then you will make sure yourself to not write too frequently: +/// loop { +/// use smart_leds::{SmartLedsWrite, RGB8}; +/// let color : RGB8 = (255, 0, 255).into(); +/// +/// ws.write([color].iter().copied()).unwrap(); +/// delay_for_at_least_60_microseconds(); +/// }; +///``` +pub struct Ws2812Direct +where + I: PinId, + P: PIOExt + FunctionConfig, + Function

: ValidPinMode, + SM: StateMachineIndex, +{ + tx: Tx<(P, SM)>, + _pin: Pin>, +} + +impl Ws2812Direct +where + I: PinId, + P: PIOExt + FunctionConfig, + Function

: ValidPinMode, + SM: StateMachineIndex, +{ + /// Creates a new instance of this driver. + pub fn new( + pin: Pin>, + pio: &mut PIO

, + sm: UninitStateMachine<(P, SM)>, + clock_freq: embedded_time::rate::Hertz, + ) -> Self { + // prepare the PIO program + let side_set = pio::SideSet::new(false, 1, false); + let mut a = pio::Assembler::new_with_side_set(side_set); + + const T1: u8 = 2; // start bit + const T2: u8 = 5; // data bit + const T3: u8 = 3; // stop bit + const CYCLES_PER_BIT: u32 = (T1 + T2 + T3) as u32; + const FREQ: u32 = 800_000; + + let mut wrap_target = a.label(); + let mut wrap_source = a.label(); + let mut do_zero = a.label(); + a.bind(&mut wrap_target); + // Do stop bit + a.out_with_delay_and_side_set(pio::OutDestination::X, 1, T3 - 1, 0); + // Do start bit + a.jmp_with_delay_and_side_set(pio::JmpCondition::XIsZero, &mut do_zero, T1 - 1, 1); + // Do data bit = 1 + a.jmp_with_delay_and_side_set(pio::JmpCondition::Always, &mut wrap_target, T2 - 1, 1); + a.bind(&mut do_zero); + // Do data bit = 0 + a.nop_with_delay_and_side_set(T2 - 1, 0); + a.bind(&mut wrap_source); + let program = a.assemble_with_wrap(wrap_source, wrap_target); + + // Install the program into PIO instruction memory. + let installed = pio.install(&program).unwrap(); + + // Configure the PIO state machine. + let div = clock_freq.integer() as f32 / (FREQ as f32 * CYCLES_PER_BIT as f32); + + let (mut sm, _, tx) = rp2040_hal::pio::PIOBuilder::from_program(installed) + // only use TX FIFO + .buffers(rp2040_hal::pio::Buffers::OnlyTx) + // Pin configuration + .side_set_pin_base(I::DYN.num) + // OSR config + .out_shift_direction(rp2040_hal::pio::ShiftDirection::Left) + .autopull(true) + .pull_threshold(24) + .clock_divisor(div) + .build(sm); + + // Prepare pin's direction. + sm.set_pindirs([(I::DYN.num, rp2040_hal::pio::PinDir::Output)]); + + sm.start(); + + Self { tx, _pin: pin } + } +} + +impl SmartLedsWrite for Ws2812Direct +where + I: PinId, + P: PIOExt + FunctionConfig, + Function

: ValidPinMode, + SM: StateMachineIndex, +{ + type Color = smart_leds_trait::RGB8; + type Error = (); + /// If you call this function, be advised that you will have to wait + /// at least 60 microseconds between calls of this function! + /// That means, either you get hold on a timer and the timing + /// requirements right your self, or rather use [Ws2812]. + /// + /// Please bear in mind, that it still blocks when writing into the + /// PIO FIFO until all data has been transmitted to the LED chain. + fn write(&mut self, iterator: T) -> Result<(), ()> + where + T: Iterator, + J: Into, + { + for item in iterator { + let color: Self::Color = item.into(); + let word = + (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8); + + while !self.tx.write(word) { + cortex_m::asm::nop(); + } + } + Ok(()) + } +} + + +/// Instance of a WS2812 LED chain. +/// +/// Use the [Ws2812::write] method to update the WS2812 LED chain. +/// +/// Typical usage example: +///```ignore +/// use rp2040_hal::clocks::init_clocks_and_plls; +/// let clocks = init_clocks_and_plls(...); +/// let pins = rp2040_hal::gpio::pin::bank0::Pins::new(...); +/// +/// let timer = Timer::new(pac.TIMER, &mut pac.RESETS); +/// +/// let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); +/// let mut ws = Ws2812::new( +/// pins.gpio4.into_mode(), +/// &mut pio, +/// sm0, +/// clocks.peripheral_clock.freq(), +/// timer.count_down(), +/// ); +/// +/// loop { +/// use smart_leds::{SmartLedsWrite, RGB8}; +/// let color : RGB8 = (255, 0, 255).into(); +/// +/// ws.write([color].iter().copied()).unwrap(); +/// +/// // Do other stuff here... +/// }; +///``` +pub struct Ws2812 +where + I: PinId, + C: CountDown, + P: PIOExt + FunctionConfig, + Function

: ValidPinMode, + SM: StateMachineIndex, +{ + driver: Ws2812Direct, + cd: C, +} + +impl Ws2812 +where + I: PinId, + C: CountDown, + P: PIOExt + FunctionConfig, + Function

: ValidPinMode, + SM: StateMachineIndex, +{ + /// Creates a new instance of this driver. + pub fn new( + pin: Pin>, + pio: &mut PIO

, + sm: UninitStateMachine<(P, SM)>, + clock_freq: embedded_time::rate::Hertz, + cd: C, + ) -> Ws2812 { + let driver = Ws2812Direct::new(pin, pio, sm, clock_freq); + + Self { driver, cd } + } +} + +impl SmartLedsWrite for Ws2812 +where + I: PinId, + C: CountDown, + C::Time: From, + P: PIOExt + FunctionConfig, + Function

: ValidPinMode, + SM: StateMachineIndex, +{ + type Color = smart_leds_trait::RGB8; + type Error = (); + fn write(&mut self, iterator: T) -> Result<(), ()> + where + T: Iterator, + J: Into, + { + self.cd.start(60.microseconds()); + let _ = nb::block!(self.cd.wait()); + + self.driver.write(iterator) + } +}