diff --git a/Cargo.lock b/Cargo.lock index 6cc14bb..16e2f77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + [[package]] name = "bare-metal" version = "0.2.5" @@ -29,6 +41,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + [[package]] name = "byteorder" version = "1.5.0" @@ -73,6 +91,24 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +[[package]] +name = "display-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba2aab1ef3793e6f7804162debb5ac5edb93b3d650fbcc5aeb72fcd0e6c03a0" + +[[package]] +name = "display-interface-spi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9ec30048b1955da2038fcc3c017f419ab21bb0001879d16c0a3749dc6b7a" +dependencies = [ + "byte-slice-cast", + "display-interface", + "embedded-hal 1.0.0", + "embedded-hal-async", +] + [[package]] name = "either" version = "1.13.0" @@ -88,6 +124,29 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "embedded-graphics" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0" +dependencies = [ + "az", + "byteorder", + "embedded-graphics-core", + "float-cmp", + "micromath", +] + +[[package]] +name = "embedded-graphics-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044" +dependencies = [ + "az", + "byteorder", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -113,6 +172,16 @@ dependencies = [ "embedded-hal 1.0.0", ] +[[package]] +name = "embedded-hal-bus" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513e0b3a8fb7d3013a8ae17a834283f170deaf7d0eeab0a7c1a36ad4dd356d22" +dependencies = [ + "critical-section", + "embedded-hal 1.0.0", +] + [[package]] name = "embedded-hal-nb" version = "1.0.0" @@ -129,6 +198,15 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "frunk" version = "0.4.3" @@ -217,6 +295,12 @@ version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +[[package]] +name = "micromath" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" + [[package]] name = "nb" version = "0.1.3" @@ -232,6 +316,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_enum" version = "0.5.11" @@ -263,11 +356,14 @@ name = "pico-enviro-sensor" version = "0.1.0" dependencies = [ "critical-section", + "embedded-graphics", "embedded-hal 1.0.0", + "embedded-hal-bus", "fugit", "rp235x-hal", "rtt-target", "scd4x", + "ssd1351", ] [[package]] @@ -476,6 +572,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" +[[package]] +name = "ssd1351" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21c426aced0940ed7c25b8134d6a0bf9745ade9f788ca54bec14c99e67120d6a" +dependencies = [ + "display-interface", + "display-interface-spi", + "embedded-graphics-core", + "embedded-hal 1.0.0", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index b697393..d7d37d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,9 @@ scd4x = { git = "https://github.com/twokilohertz/scd4x-rs.git", branch = "conver "scd41", ] } rtt-target = "0.6.1" +ssd1351 = "0.5.0" +embedded-hal-bus = "0.3.0" +embedded-graphics = "0.8.1" # Super-optimised release build, maximum performance, minimal debuggability # Build with cargo build --profile dist diff --git a/src/main.rs b/src/main.rs index a824c7c..9d7f03f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,32 @@ #![no_std] #![no_main] -use embedded_hal::delay::DelayNs; -use fugit::RateExtU32; -use rtt_target::{rprintln, rtt_init_print}; - // RP235x HAL use rp235x_hal as hal; +use hal::gpio::FunctionSpi; +use hal::spi::Spi; + +// Display +use ssd1351::{ + mode::GraphicsMode, + prelude::SPIInterface, + properties::{DisplayRotation, DisplaySize}, +}; + // Sensor -use scd4x::Scd4x; +// use scd4x::Scd4x; + +use embedded_graphics::{ + pixelcolor::Rgb565, + prelude::{Point, Primitive, RgbColor, Size}, + primitives::{PrimitiveStyleBuilder, Rectangle}, + Drawable, +}; + +use embedded_hal::spi::MODE_0; +use fugit::RateExtU32; +use rtt_target::{rprintln, rtt_init_print}; mod constants; @@ -50,63 +67,97 @@ fn main() -> ! { rprintln!("Core RP2350 hardware initialisation successful"); - // Initialise SCD41 sensor - let i2c0 = hal::I2C::i2c0( - peripherals.I2C0, - pins.gpio4.reconfigure(), // Pin 6 on Pico 2 (SDA) - pins.gpio5.reconfigure(), // Pin 7 on Pico 2 (SCL) - 400.kHz(), + // Display + + let mosi_pin = pins.gpio19.into_function::<FunctionSpi>(); + let sclk_pin = pins.gpio18.into_function::<FunctionSpi>(); + let cs_pin = pins.gpio17.into_push_pull_output(); + let dc_pin = pins.gpio20.into_push_pull_output(); + let mut rst_pin = pins.gpio21.into_push_pull_output(); + + // SPI initialisation + let spi_pins = (mosi_pin, sclk_pin); + let spi = Spi::<_, _, _, 8>::new(peripherals.SPI0, spi_pins).init( &mut peripherals.RESETS, &clocks.peripheral_clock, + 16_u32.MHz(), + MODE_0, ); + let spi_device = embedded_hal_bus::spi::ExclusiveDevice::new_no_delay(spi, cs_pin).unwrap(); + let spi_interface = SPIInterface::new(spi_device, dc_pin); - timer.delay_ms(30); // Power-up delay - let mut scd41 = Scd4x::new(i2c0, timer); - scd41.wake_up(); + let mut display: GraphicsMode<_> = ssd1351::builder::Builder::new() + .with_size(DisplaySize::Display128x128) + .with_rotation(DisplayRotation::Rotate0) + .connect_interface(spi_interface) + .into(); + display.reset(&mut rst_pin, &mut timer).unwrap(); + display.init().unwrap(); - match scd41.reinit() { - Ok(_) => rprintln!("Initialised SCD41"), - Err(error) => rprintln!("Failed to initialise SCD41: {:?}", error), - } - timer.delay_ms(30); // Soft reset delay + let rect = Rectangle::new(Point::new(0, 40), Size::new(40, 20)).into_styled( + PrimitiveStyleBuilder::new() + .fill_color(Rgb565::CYAN) + .build(), + ); + rect.draw(&mut display).unwrap(); - match scd41.serial_number() { - Ok(serial) => rprintln!("SCD41 serial number: {}", serial), - Err(error) => rprintln!("SCD41 did not respond to get_serial_number: {:?}", error), - } + // // Initialise SCD41 sensor + // let i2c0 = hal::I2C::i2c0( + // peripherals.I2C0, + // pins.gpio4.reconfigure(), // Pin 6 on Pico 2 (SDA) + // pins.gpio5.reconfigure(), // Pin 7 on Pico 2 (SCL) + // 400.kHz(), + // &mut peripherals.RESETS, + // &clocks.peripheral_clock, + // ); - match scd41.self_test_is_ok() { - Ok(ok) => { - if ok { - rprintln!("SCD41 reported successful self-test") - } else { - rprintln!("SCD41 reported unsuccessful self-test!") - } - } - Err(_) => rprintln!("SCD41 failed to perform self-test"), - } + // timer.delay_ms(30); // Power-up delay + // let mut scd41 = Scd4x::new(i2c0, timer); + // scd41.wake_up(); - match scd41.start_periodic_measurement() { - Ok(_) => rprintln!("Configured sensor to measure every 5 seconds"), - Err(error) => rprintln!("SCD41 start_periodic_measurement() failed: {:?}", error), - } + // match scd41.reinit() { + // Ok(_) => rprintln!("Initialised SCD41"), + // Err(error) => rprintln!("Failed to initialise SCD41: {:?}", error), + // } + // timer.delay_ms(30); // Soft reset delay - loop { - timer.delay_ms(5010); - match scd41.measurement() { - Ok(data) => rprintln!( - "CO2: {}, temperature: {}, humidity: {}", - data.co2, - data.temperature, - data.humidity - ), - Err(error) => rprintln!("SCD41 get_measurement() failed: {:?}", error), - } - } + // match scd41.serial_number() { + // Ok(serial) => rprintln!("SCD41 serial number: {}", serial), + // Err(error) => rprintln!("SCD41 did not respond to get_serial_number: {:?}", error), + // } + + // match scd41.self_test_is_ok() { + // Ok(ok) => { + // if ok { + // rprintln!("SCD41 reported successful self-test") + // } else { + // rprintln!("SCD41 reported unsuccessful self-test!") + // } + // } + // Err(_) => rprintln!("SCD41 failed to perform self-test"), + // } + + // match scd41.start_periodic_measurement() { + // Ok(_) => rprintln!("Configured sensor to measure every 5 seconds"), + // Err(error) => rprintln!("SCD41 start_periodic_measurement() failed: {:?}", error), + // } // loop { - // hal::arch::wfi(); + // timer.delay_ms(5010); + // match scd41.measurement() { + // Ok(data) => rprintln!( + // "CO2: {}, temperature: {}, humidity: {}", + // data.co2, + // data.temperature, + // data.humidity + // ), + // Err(error) => rprintln!("SCD41 get_measurement() failed: {:?}", error), + // } // } + + loop { + hal::arch::wfi(); + } } #[inline(never)]