Create task for outputting to SSD1351 display
This commit is contained in:
parent
58d8327ed2
commit
17b309af43
77
Cargo.lock
generated
77
Cargo.lock
generated
@ -83,6 +83,12 @@ version = "2.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byte-slice-cast"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.21.0"
|
version = "1.21.0"
|
||||||
@ -232,6 +238,24 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "document-features"
|
name = "document-features"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
@ -400,6 +424,29 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970"
|
checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970"
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "embedded-hal"
|
name = "embedded-hal"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
@ -498,6 +545,15 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "float-cmp"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -697,6 +753,12 @@ version = "2.7.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "micromath"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nb"
|
name = "nb"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@ -800,13 +862,16 @@ name = "pico-enviro-sensor"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cortex-m-rt",
|
"cortex-m-rt",
|
||||||
|
"display-interface-spi",
|
||||||
"embassy-embedded-hal",
|
"embassy-embedded-hal",
|
||||||
"embassy-executor",
|
"embassy-executor",
|
||||||
"embassy-rp",
|
"embassy-rp",
|
||||||
"embassy-sync",
|
"embassy-sync",
|
||||||
"embassy-time",
|
"embassy-time",
|
||||||
|
"embedded-graphics",
|
||||||
"rtt-target",
|
"rtt-target",
|
||||||
"scd4x",
|
"scd4x",
|
||||||
|
"ssd1351",
|
||||||
"static_cell",
|
"static_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1113,6 +1178,18 @@ dependencies = [
|
|||||||
"rgb",
|
"rgb",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -25,6 +25,7 @@ embassy-time = "0.4.0"
|
|||||||
embassy-sync = "0.6.2"
|
embassy-sync = "0.6.2"
|
||||||
embassy-embedded-hal = "0.3.0"
|
embassy-embedded-hal = "0.3.0"
|
||||||
static_cell = "2.1.0"
|
static_cell = "2.1.0"
|
||||||
|
embedded-graphics = "0.8.1"
|
||||||
|
|
||||||
# System
|
# System
|
||||||
cortex-m-rt = "0.7.5"
|
cortex-m-rt = "0.7.5"
|
||||||
@ -34,6 +35,8 @@ rtt-target = "0.6.1"
|
|||||||
scd4x = { git = "https://github.com/twokilohertz/scd4x-rs.git", branch = "conversion-fixes", features = [
|
scd4x = { git = "https://github.com/twokilohertz/scd4x-rs.git", branch = "conversion-fixes", features = [
|
||||||
"scd41",
|
"scd41",
|
||||||
] }
|
] }
|
||||||
|
ssd1351 = "0.5.0"
|
||||||
|
display-interface-spi = "0.5.0"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
|
51
src/display_task.rs
Normal file
51
src/display_task.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// System
|
||||||
|
use embassy_embedded_hal::shared_bus::blocking::spi::SpiDeviceWithConfig;
|
||||||
|
use embassy_rp::{gpio::Output, spi::Config};
|
||||||
|
use rtt_target::rprintln;
|
||||||
|
|
||||||
|
// Display
|
||||||
|
use display_interface_spi::SPIInterface;
|
||||||
|
use ssd1351::{
|
||||||
|
builder::Builder,
|
||||||
|
mode::GraphicsMode,
|
||||||
|
properties::{DisplayRotation, DisplaySize},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Graphics
|
||||||
|
use embedded_graphics::{
|
||||||
|
pixelcolor::Rgb565,
|
||||||
|
prelude::{Point, Primitive, WebColors},
|
||||||
|
primitives::{Circle, PrimitiveStyle},
|
||||||
|
Drawable,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::Spi0BusMutex;
|
||||||
|
|
||||||
|
/// Output to the SSD1351 display
|
||||||
|
#[embassy_executor::task]
|
||||||
|
pub async fn display_output_task(
|
||||||
|
spi_bus: &'static Spi0BusMutex,
|
||||||
|
cs: Output<'static>,
|
||||||
|
dc: Output<'static>,
|
||||||
|
rst: &'static mut Output<'static>,
|
||||||
|
spi_config: Config,
|
||||||
|
) {
|
||||||
|
rprintln!("Display output task started");
|
||||||
|
|
||||||
|
let spi_dev = SpiDeviceWithConfig::new(spi_bus, cs, spi_config);
|
||||||
|
let interface = SPIInterface::new(spi_dev, dc);
|
||||||
|
|
||||||
|
let mut display: GraphicsMode<_> = Builder::new()
|
||||||
|
.with_size(DisplaySize::Display128x128)
|
||||||
|
.with_rotation(DisplayRotation::Rotate0)
|
||||||
|
.connect_interface(interface)
|
||||||
|
.into();
|
||||||
|
|
||||||
|
display.reset(rst, &mut embassy_time::Delay).unwrap();
|
||||||
|
display.init().unwrap();
|
||||||
|
|
||||||
|
Circle::new(Point::new(0, 0), 128)
|
||||||
|
.into_styled(PrimitiveStyle::with_fill(Rgb565::CSS_CHARTREUSE))
|
||||||
|
.draw(&mut display)
|
||||||
|
.unwrap();
|
||||||
|
}
|
41
src/main.rs
41
src/main.rs
@ -1,6 +1,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
mod display_task;
|
||||||
mod sensor_task;
|
mod sensor_task;
|
||||||
|
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
@ -8,18 +9,26 @@ use core::cell::RefCell;
|
|||||||
use rtt_target::{rprintln, rtt_init_print};
|
use rtt_target::{rprintln, rtt_init_print};
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::{block::ImageDef, i2c::Blocking, i2c::I2c, peripherals::I2C0};
|
use embassy_rp::{
|
||||||
|
block::ImageDef,
|
||||||
|
gpio::{Level, Output},
|
||||||
|
i2c,
|
||||||
|
peripherals::{I2C0, SPI0},
|
||||||
|
spi,
|
||||||
|
};
|
||||||
use embassy_sync::blocking_mutex::{raw::NoopRawMutex, Mutex};
|
use embassy_sync::blocking_mutex::{raw::NoopRawMutex, Mutex};
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
|
|
||||||
|
use display_task::display_output_task;
|
||||||
use sensor_task::sensor_read_task;
|
use sensor_task::sensor_read_task;
|
||||||
|
|
||||||
embassy_rp::bind_interrupts!(struct Irqs {
|
embassy_rp::bind_interrupts!(struct Irqs {
|
||||||
I2C0_IRQ => embassy_rp::i2c::InterruptHandler<embassy_rp::peripherals::I2C0>;
|
I2C0_IRQ => embassy_rp::i2c::InterruptHandler<embassy_rp::peripherals::I2C0>;
|
||||||
});
|
});
|
||||||
|
|
||||||
type I2c0BusType = Mutex<NoopRawMutex, RefCell<I2c<'static, I2C0, Blocking>>>;
|
type I2c0BusMutex = Mutex<NoopRawMutex, RefCell<i2c::I2c<'static, I2C0, i2c::Blocking>>>;
|
||||||
|
type Spi0BusMutex = Mutex<NoopRawMutex, RefCell<spi::Spi<'static, SPI0, spi::Blocking>>>;
|
||||||
|
|
||||||
/// Entrypoint
|
/// Entrypoint
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -31,17 +40,41 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
let peripherals = embassy_rp::init(Default::default());
|
let peripherals = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
// Initialise I2C0 on pins 4 & 5 for the SCD41 sensor
|
// Initialise I2C0 (SDA: pin 4, SCL: pin 5)
|
||||||
let sda = peripherals.PIN_4;
|
let sda = peripherals.PIN_4;
|
||||||
let scl = peripherals.PIN_5;
|
let scl = peripherals.PIN_5;
|
||||||
let mut i2c_config = embassy_rp::i2c::Config::default();
|
let mut i2c_config = embassy_rp::i2c::Config::default();
|
||||||
i2c_config.frequency = 400_000u32; // 400 kHz
|
i2c_config.frequency = 400_000u32; // 400 kHz
|
||||||
let i2c_bus = embassy_rp::i2c::I2c::new_blocking(peripherals.I2C0, scl, sda, i2c_config);
|
let i2c_bus = embassy_rp::i2c::I2c::new_blocking(peripherals.I2C0, scl, sda, i2c_config);
|
||||||
static I2C0_BUS: StaticCell<I2c0BusType> = StaticCell::new();
|
static I2C0_BUS: StaticCell<I2c0BusMutex> = StaticCell::new();
|
||||||
let shared_i2c0_bus = I2C0_BUS.init(Mutex::new(RefCell::new(i2c_bus)));
|
let shared_i2c0_bus = I2C0_BUS.init(Mutex::new(RefCell::new(i2c_bus)));
|
||||||
|
|
||||||
|
// Start new task for reading data from the sensor
|
||||||
spawner.must_spawn(sensor_read_task(shared_i2c0_bus));
|
spawner.must_spawn(sensor_read_task(shared_i2c0_bus));
|
||||||
|
|
||||||
|
// Initialise SPI0 (MOSI: pin 19, SCLK: pin 18, CS: pin 17, DC: pin 14, RST: pin 15)
|
||||||
|
let mosi = peripherals.PIN_19;
|
||||||
|
let sclk = peripherals.PIN_18;
|
||||||
|
let cs = Output::new(peripherals.PIN_17, Level::Low);
|
||||||
|
let dc = Output::new(peripherals.PIN_14, Level::Low);
|
||||||
|
static SPI0_RST_PIN: StaticCell<Output<'_>> = StaticCell::new(); // Initialised before launching task
|
||||||
|
let rst = SPI0_RST_PIN.init(Output::new(peripherals.PIN_15, Level::Low));
|
||||||
|
|
||||||
|
let mut spi_config = spi::Config::default();
|
||||||
|
spi_config.frequency = 4_000_000u32; // 4 MHz
|
||||||
|
let spi_bus = spi::Spi::new_blocking_txonly(peripherals.SPI0, sclk, mosi, spi_config.clone());
|
||||||
|
static SPI0_BUS: StaticCell<Spi0BusMutex> = StaticCell::new();
|
||||||
|
let shared_spi0_bus = SPI0_BUS.init(Mutex::new(RefCell::new(spi_bus)));
|
||||||
|
|
||||||
|
// Start new task for outputting to the display
|
||||||
|
spawner.must_spawn(display_output_task(
|
||||||
|
shared_spi0_bus,
|
||||||
|
cs,
|
||||||
|
dc,
|
||||||
|
rst,
|
||||||
|
spi_config.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
Timer::after_secs(1).await;
|
Timer::after_secs(1).await;
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,11 @@ use rtt_target::rprintln;
|
|||||||
// Sensor
|
// Sensor
|
||||||
use scd4x::Scd4x;
|
use scd4x::Scd4x;
|
||||||
|
|
||||||
use crate::I2c0BusType;
|
use crate::I2c0BusMutex;
|
||||||
|
|
||||||
|
/// Read CO2/temp./humidity data from the sensor
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn sensor_read_task(i2c_bus: &'static I2c0BusType) {
|
pub async fn sensor_read_task(i2c_bus: &'static I2c0BusMutex) {
|
||||||
rprintln!("Sensor read task started");
|
rprintln!("Sensor read task started");
|
||||||
|
|
||||||
Timer::after_millis(30).await; // SCD41 power-up delay
|
Timer::after_millis(30).await; // SCD41 power-up delay
|
||||||
@ -30,7 +31,7 @@ pub async fn sensor_read_task(i2c_bus: &'static I2c0BusType) {
|
|||||||
scd41.start_periodic_measurement().unwrap();
|
scd41.start_periodic_measurement().unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
Timer::after_secs(5).await; // start_periodic_measurement() returns new sensor data every 5 seconds
|
Timer::after_secs(5).await; // start_periodic_measurement returns new sensor data every 5 seconds
|
||||||
|
|
||||||
match scd41.measurement() {
|
match scd41.measurement() {
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user