From c67479ba92b8341b368996db836c760ecf83a740 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 9 Oct 2023 11:44:50 -0700 Subject: [PATCH 1/3] Rename to is31fl3743a A version is with I2C support, B with SPI. Signed-off-by: Daniel Schaefer --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 16f515a..418ac70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "is31fl3743" +name = "is31fl3743a" version = "0.1.0" edition = "2021" authors = ["Daniel Schaefer"] From c6e07100bd4921933897c5abc26a2d118c9bfaa3 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 9 Oct 2023 11:45:14 -0700 Subject: [PATCH 2/3] Remove matrix version support for now Need to map the LEDs properly to positions. Signed-off-by: Daniel Schaefer --- src/devices.rs | 48 ++++-------------------------------------------- src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 45 deletions(-) diff --git a/src/devices.rs b/src/devices.rs index 99dba94..9793c53 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -12,48 +12,6 @@ pub struct UnknownDevice { pub device: IS31FL3743, } -#[cfg(feature = "embedded_graphics")] -use embedded_graphics_core::{pixelcolor::Rgb888, prelude::*, primitives::Rectangle}; - -#[cfg(feature = "embedded_graphics")] -impl Dimensions for UnknownDevice -where - I2C: Write, - I2C: Read, -{ - fn bounding_box(&self) -> Rectangle { - Rectangle::new(Point::zero(), Size::new(13, 9)) - } -} - -#[cfg(feature = "embedded_graphics")] -impl DrawTarget for UnknownDevice -where - I2C: Write, - I2C: Read, - I2cError:, -{ - type Color = Rgb888; - type Error = Error; - - fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> - where - I: IntoIterator>, - { - for Pixel(coord, color) in pixels.into_iter() { - // Check if the pixel coordinates are out of bounds (negative or greater than - // (63,63)). `DrawTarget` implementation are required to discard any out of bounds - // pixels without returning an error or causing a panic. - if let Ok((x @ 0..=13, y @ 0..=9)) = coord.try_into() { - // Calculate the index in the framebuffer. - self.pixel_rgb(x as u8, y as u8, color.r(), color.g(), color.b())? - } - } - - Ok(()) - } -} - impl UnknownDevice where I2C: Write, @@ -72,11 +30,13 @@ where device: IS31FL3743 { i2c, address: 0b0100000, + // Dummy values, not used width: 18 * 11, + // Dummy values, not used height: 1, - calc_pixel: |x: u8, y: u8| -> u8 { + calc_pixel: |_x: u8, _y: u8| -> u8 { // Dummy value, don't use this function - 0x00 + unimplemented!("No Matrix support yet") }, }, } diff --git a/src/lib.rs b/src/lib.rs index 6b4beee..04de5d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #![no_std] #![doc = include_str!("../README.md")] /// Preconfigured devices -//pub mod devices; +pub mod devices; use embedded_hal::blocking::delay::DelayMs; use embedded_hal::blocking::i2c::Read; use embedded_hal::blocking::i2c::Write; From f215351c8d9264cad74dfc9c3ec0da24503bb52c Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 9 Oct 2023 11:46:11 -0700 Subject: [PATCH 3/3] Add RP2040 QT PY Example Signed-off-by: Daniel Schaefer --- .gitignore | 2 +- examples/qt-py-rp2040/.cargo/config.toml | 12 ++++ examples/qt-py-rp2040/Cargo.toml | 19 ++++++ examples/qt-py-rp2040/build.rs | 31 ++++++++++ examples/qt-py-rp2040/memory.x | 15 +++++ examples/qt-py-rp2040/src/main.rs | 77 ++++++++++++++++++++++++ examples/stm32.rs | 46 -------------- 7 files changed, 155 insertions(+), 47 deletions(-) create mode 100644 examples/qt-py-rp2040/.cargo/config.toml create mode 100644 examples/qt-py-rp2040/Cargo.toml create mode 100644 examples/qt-py-rp2040/build.rs create mode 100644 examples/qt-py-rp2040/memory.x create mode 100644 examples/qt-py-rp2040/src/main.rs delete mode 100644 examples/stm32.rs diff --git a/.gitignore b/.gitignore index 22d3516..12b5246 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Generated by Cargo # will have compiled files and executables -/target/ +target # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html diff --git a/examples/qt-py-rp2040/.cargo/config.toml b/examples/qt-py-rp2040/.cargo/config.toml new file mode 100644 index 0000000..a5a2872 --- /dev/null +++ b/examples/qt-py-rp2040/.cargo/config.toml @@ -0,0 +1,12 @@ +[build] +target = "thumbv6m-none-eabi" + +[target.thumbv6m-none-eabi] +runner = "elf2uf2-rs -d" +# runner = "picotool load -x -t elf" +# runner = "probe-run --chip RP2040" + +rustflags = [ + "-C", "link-arg=-Tlink.x", + "-C", "link-arg=--nmagic", +] diff --git a/examples/qt-py-rp2040/Cargo.toml b/examples/qt-py-rp2040/Cargo.toml new file mode 100644 index 0000000..8dcbe86 --- /dev/null +++ b/examples/qt-py-rp2040/Cargo.toml @@ -0,0 +1,19 @@ +[package] +edition = "2021" +name = "is31fl3741-qt-py-rp2040" +version = "0.3.0" + +[dependencies] +embedded-hal = "0.2.7" +embedded-graphics-core = { optional = true, version = "0.4.0" } + +cortex-m-rt = "0.7.3" +cortex-m = "0.7.7" +panic-halt = "0.2.0" +rp-pico = "0.7.0" +adafruit-qt-py-rp2040 = {version = "0.6.0", features = ["rt"]} +tinybmp = "0.5.0" +embedded-graphics = "0.8.1" +fugit = "0.3.7" + +is31fl3743a = { path = "../.." } diff --git a/examples/qt-py-rp2040/build.rs b/examples/qt-py-rp2040/build.rs new file mode 100644 index 0000000..d534cc3 --- /dev/null +++ b/examples/qt-py-rp2040/build.rs @@ -0,0 +1,31 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/examples/qt-py-rp2040/memory.x b/examples/qt-py-rp2040/memory.x new file mode 100644 index 0000000..070eac7 --- /dev/null +++ b/examples/qt-py-rp2040/memory.x @@ -0,0 +1,15 @@ +MEMORY { + BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} + +EXTERN(BOOT2_FIRMWARE) + +SECTIONS { + /* ### Boot loader */ + .boot2 ORIGIN(BOOT2) : + { + KEEP(*(.boot2)); + } > BOOT2 +} INSERT BEFORE .text; \ No newline at end of file diff --git a/examples/qt-py-rp2040/src/main.rs b/examples/qt-py-rp2040/src/main.rs new file mode 100644 index 0000000..021f952 --- /dev/null +++ b/examples/qt-py-rp2040/src/main.rs @@ -0,0 +1,77 @@ +#![no_std] +#![no_main] + +// pick a panicking behavior +use panic_halt as _; + +use adafruit_qt_py_rp2040::entry; +use adafruit_qt_py_rp2040::{ + hal::{ + clocks::{init_clocks_and_plls, Clock}, + i2c::I2C, + pac, + watchdog::Watchdog, + Sio, + }, + Pins, XOSC_CRYSTAL_FREQ, +}; +use fugit::RateExtU32; +use is31fl3743a::devices::UnknownDevice; + +#[entry] +fn main() -> ! { + let mut pac = pac::Peripherals::take().unwrap(); + let core = pac::CorePeripherals::take().unwrap(); + + let mut watchdog = Watchdog::new(pac.WATCHDOG); + + let clocks = init_clocks_and_plls( + XOSC_CRYSTAL_FREQ, + pac.XOSC, + pac.CLOCKS, + pac.PLL_SYS, + pac.PLL_USB, + &mut pac.RESETS, + &mut watchdog, + ) + .ok() + .unwrap(); + + let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); + let sio = Sio::new(pac.SIO); + let pins = Pins::new( + pac.IO_BANK0, + pac.PADS_BANK0, + sio.gpio_bank0, + &mut pac.RESETS, + ); + + // Using STEMMA QT connector + let sda = pins.sda1.into_mode(); // gpio22 + let scl = pins.scl1.into_mode(); // gpio23 + + //let sda = pins.sda.into_mode(); // gpio24 + //let scl = pins.scl.into_mode(); // gpio25 + + let i2c = I2C::i2c1( + pac.I2C1, + sda, + scl, + 400.kHz(), + &mut pac.RESETS, + 125_000_000.Hz(), + ); + + let mut matrix = UnknownDevice::configure(i2c); + matrix + .setup(&mut delay) + .expect("failed to setup rgb controller"); + + matrix.set_scaling(0xFF).expect("failed to set scaling"); + + loop { + matrix.device.fill(0xFF).expect("couldn't turn on"); + delay.delay_ms(100u32); + matrix.device.fill(0x00).expect("couldn't turn off"); + } +} diff --git a/examples/stm32.rs b/examples/stm32.rs deleted file mode 100644 index 6588569..0000000 --- a/examples/stm32.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![no_std] -#![no_main] - -// pick a panicking behavior -use panic_halt as _; - -// use cortex_m::delay::Delay; -use cortex_m_rt::entry; -use is31fl3743::devices::AdafruitRGB13x9; - -use stm32g0xx_hal::{ - prelude::*, - rcc::{Config, Prescaler}, - stm32, -}; - -#[entry] -fn main() -> ! { - let dp = stm32::Peripherals::take().expect("cannot take peripherals"); - let mut rcc = dp.RCC.freeze(Config::hsi(Prescaler::NotDivided)); - let mut delay = dp.TIM15.delay(&mut rcc); - - // let cp = cortex_m::Peripherals::take().unwrap(); - // let dp = pac::Peripherals::take().unwrap(); - let gpiob = dp.GPIOB.split(&mut rcc); - - let sda = gpiob.pb9.into_open_drain_output_in_state(PinState::High); - let scl = gpiob.pb8.into_open_drain_output_in_state(PinState::High); - - let i2c = dp.I2C1.i2c(sda, scl, 100.khz(), &mut rcc); - - // // https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3741/blob/main/adafruit_is31fl3 741/adafruit_rgbmatrixqt.py#L53-L65 - - let mut matrix = AdafruitRGB13x9::configure(i2c); - matrix - .setup(&mut delay) - .expect("failed to setup rgb controller"); - - matrix.set_scaling(0xFF).expect("failed to set scaling"); - - loop { - matrix.fill(0xFF).expect("failed to turn on all LEDs"); - delay.delay_ms(100u8); - matrix.fill(0x00).expect("failed to turn off all LEDs"); - } -}