From dce3e3600dfa9377183fffd32189fe7538b74c42 Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Sat, 1 Nov 2025 09:32:33 -0400 Subject: [PATCH] WIP --- esp/rust/02_esp-gen-no-std/.cargo/config.toml | 1 + esp/rust/02_esp-gen-no-std/Cargo.lock | 18 ++++++- esp/rust/02_esp-gen-no-std/Cargo.toml | 7 ++- esp/rust/02_esp-gen-no-std/src/bin/main.rs | 22 ++++++++- esp/rust/03_no-std-lcd/src/main.rs | 1 + esp/rust/04_no-std-aht20/Cargo.toml | 27 +---------- esp/rust/04_no-std-aht20/src/main.rs | 48 ++++++++----------- 7 files changed, 65 insertions(+), 59 deletions(-) diff --git a/esp/rust/02_esp-gen-no-std/.cargo/config.toml b/esp/rust/02_esp-gen-no-std/.cargo/config.toml index f00ab5f..5307d68 100644 --- a/esp/rust/02_esp-gen-no-std/.cargo/config.toml +++ b/esp/rust/02_esp-gen-no-std/.cargo/config.toml @@ -2,6 +2,7 @@ runner = "espflash flash --monitor --chip esp32" [env] +ESP_LOG = "info" [build] rustflags = [ diff --git a/esp/rust/02_esp-gen-no-std/Cargo.lock b/esp/rust/02_esp-gen-no-std/Cargo.lock index d3ab6e1..8f704dd 100644 --- a/esp/rust/02_esp-gen-no-std/Cargo.lock +++ b/esp/rust/02_esp-gen-no-std/Cargo.lock @@ -268,12 +268,15 @@ dependencies = [ ] [[package]] -name = "esp-gen-test" +name = "esp-gen-no-std" version = "0.1.0" dependencies = [ "critical-section", "esp-bootloader-esp-idf", "esp-hal", + "esp-println", + "fugit", + "log", ] [[package]] @@ -356,6 +359,19 @@ dependencies = [ "esp-metadata", ] +[[package]] +name = "esp-println" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e7e3ab41e96093d7fd307e93bfc88bd646a8ff23036ebf809e116b18869f719" +dependencies = [ + "critical-section", + "document-features", + "esp-metadata-generated", + "log", + "portable-atomic", +] + [[package]] name = "esp-riscv-rt" version = "0.12.0" diff --git a/esp/rust/02_esp-gen-no-std/Cargo.toml b/esp/rust/02_esp-gen-no-std/Cargo.toml index 2fd1b2b..26e7e97 100644 --- a/esp/rust/02_esp-gen-no-std/Cargo.toml +++ b/esp/rust/02_esp-gen-no-std/Cargo.toml @@ -1,11 +1,11 @@ [package] edition = "2021" -name = "esp-gen-test" +name = "esp-gen-no-std" rust-version = "1.86" version = "0.1.0" [[bin]] -name = "esp-gen-test" +name = "blinky-i2c-scanner" path = "./src/bin/main.rs" [dependencies] @@ -13,6 +13,9 @@ esp-bootloader-esp-idf = { version = "0.2.0", features = ["esp32"] } esp-hal = { version = "=1.0.0-rc.0", features = ["esp32"] } critical-section = "1.2.0" +esp-println = { version = "0.15.0", features = ["esp32", "log-04"] } +log = "0.4.28" +fugit = "0.3.7" [profile.dev] diff --git a/esp/rust/02_esp-gen-no-std/src/bin/main.rs b/esp/rust/02_esp-gen-no-std/src/bin/main.rs index 870239a..867f6b2 100644 --- a/esp/rust/02_esp-gen-no-std/src/bin/main.rs +++ b/esp/rust/02_esp-gen-no-std/src/bin/main.rs @@ -6,12 +6,14 @@ holding buffers for the duration of a data transfer." )] +use esp_hal::i2c::master::BusTimeout; use esp_hal::{ clock::CpuClock, gpio::{Level, Output, OutputConfig}, main, - time::{Duration, Instant} + time::{Duration, Instant}, }; +use fugit::RateExtU32; #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { @@ -25,11 +27,29 @@ esp_bootloader_esp_idf::esp_app_desc!(); #[main] fn main() -> ! { // generator version: 0.5.0 + esp_println::logger::init_logger_from_env(); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); + let i2c_config = esp_hal::i2c::master::Config::default().with_timeout(BusTimeout::Maximum); + let mut i2c = esp_hal::i2c::master::I2c::new(peripherals.I2C0, i2c_config) + .unwrap() + .with_sda(peripherals.GPIO21) + .with_scl(peripherals.GPIO22); let mut led = Output::new(peripherals.GPIO2, Level::High, OutputConfig::default()); loop { + log::info!("Scanning for I2C devices.."); + for i in 0..=127u8 { + let res = i2c.read(i, &mut [0]); + match res { + Ok(_) => { + log::info!("Device found at address: {}", i); + } + Err(err) => { + log::warn!("Failed to read device address: {:?}", err); + } + } + } led.toggle(); let delay_start = Instant::now(); while delay_start.elapsed() < Duration::from_millis(500) {} diff --git a/esp/rust/03_no-std-lcd/src/main.rs b/esp/rust/03_no-std-lcd/src/main.rs index 82f2dd5..986d66e 100644 --- a/esp/rust/03_no-std-lcd/src/main.rs +++ b/esp/rust/03_no-std-lcd/src/main.rs @@ -5,6 +5,7 @@ use esp_idf_hal::prelude::*; const SSD1306_ADDRESS: u8 = 0x3c; +// TODO: This is not no-std; This is using ESP-IDF-HAL, which uses std fn main() -> anyhow::Result<()> { esp_idf_hal::sys::link_patches(); diff --git a/esp/rust/04_no-std-aht20/Cargo.toml b/esp/rust/04_no-std-aht20/Cargo.toml index b38be98..7908b47 100644 --- a/esp/rust/04_no-std-aht20/Cargo.toml +++ b/esp/rust/04_no-std-aht20/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Shaun Reed "] edition = "2021" resolver = "2" rust-version = "1.77" -description = "test" +description = "Reading from AHT20 sensor and drawing to OLED display" publish = false [[bin]] @@ -27,8 +27,6 @@ esp32 = [ "esp-bootloader-esp-idf/esp32", ] -#experimental = ["esp-idf-svc/experimental"] - [dependencies] log = "0.4" embedded-hal = "1.0.0" @@ -36,29 +34,6 @@ esp-backtrace = { version = "0.17.0", features = ["esp32", "println", "panic-han esp-hal = { version = "1.0.0-rc.0", features = ["esp32", "unstable"] } esp-println = { version = "0.15.0", features = ["auto", "log-04"] } esp-bootloader-esp-idf = { version = "0.2.0", default-features = false, features = ["esp-rom-sys", "log-04", "esp32"] } -#esp-rom-sys = { version = "0.1.1", features = ["esp32"] } -#esp-idf-svc = { version = "0.51", features = [""], default-features = false} -#esp-idf-hal = "0.45.2" -#anyhow = "1.0.98" -#fugit = "0.3.7" -#esp-rom-sys = { version = "0.1.1", features = ["esp32"] } - -# --- Optional Embassy Integration --- -# esp-idf-svc = { version = "0.51", features = ["critical-section", "embassy-time-driver", "embassy-sync"] } - -# If you enable embassy-time-driver, you MUST also add one of: - -# a) Standalone Embassy libs ( embassy-time, embassy-sync etc) with a foreign async runtime: -# embassy-time = { version = "0.4.0", features = ["generic-queue-8"] } # NOTE: any generic-queue variant will work - -# b) With embassy-executor: -# embassy-executor = { version = "0.7", features = ["executor-thread", "arch-std"] } - -# NOTE: if you use embassy-time with embassy-executor you don't need the generic-queue-8 feature - -# --- Temporary workaround for embassy-executor < 0.8 --- -# esp-idf-svc = { version = "0.51", features = ["embassy-time-driver", "embassy-sync"] } -# critical-section = { version = "1.1", features = ["std"], default-features = false } [build-dependencies] embuild = "0.33" diff --git a/esp/rust/04_no-std-aht20/src/main.rs b/esp/rust/04_no-std-aht20/src/main.rs index 73a92c1..9ed5122 100644 --- a/esp/rust/04_no-std-aht20/src/main.rs +++ b/esp/rust/04_no-std-aht20/src/main.rs @@ -1,12 +1,10 @@ #![no_std] #![no_main] +use embedded_hal::i2c::ErrorType; use embedded_hal::{delay::DelayNs, i2c::I2c as I2cEmbedded}; use esp_backtrace as _; -use esp_hal::{ - delay::Delay, - xtensa_lx_rt::entry, -}; +use esp_hal::{delay::Delay, xtensa_lx_rt::entry}; /// Represents a reading from the sensor. pub struct SensorReading { @@ -14,14 +12,6 @@ pub struct SensorReading { pub temperature: T, } -/// Possible errors when interacting with the sensor. -#[derive(Debug)] -pub enum SensorError { - ChecksumMismatch, - Timeout, - PinError, -} - pub struct Dht20 { pub i2c: I, pub delay: D, @@ -34,31 +24,30 @@ impl Dht20 { Self { i2c, delay } } - pub fn read(&mut self) -> Result, SensorError> { - // Check status + pub fn read(&mut self) -> Result, ::Error> { + log::info!("Checking status"); let mut status_response: [u8; 1] = [0; 1]; - let _ = self - .i2c - .write_read(Self::SENSOR_ADDRESS, &[0x71], &mut status_response); + self.i2c + .write_read(Self::SENSOR_ADDRESS, &[0x71], &mut status_response)?; // Calibration if needed if status_response[0] & 0x18 != 0x18 { - let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0x1B, 0, 0]); - let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0x1C, 0, 0]); - let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0x1E, 0, 0]); + log::info!("Calibrating sensor {:?}", status_response); + for b in [0x1B, 0x1C, 0x1E] { + self.i2c.write(Self::SENSOR_ADDRESS, &[b, 0, 0])?; + } } // Trigger the measurement self.delay.delay_ms(10); - let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0xAC, 0x33, 0x00]); + self.i2c.write(Self::SENSOR_ADDRESS, &[0xAC, 0x33, 0x00])?; // Read the measurement status self.delay.delay_ms(80); loop { let mut measurement_status_response: [u8; 1] = [0; 1]; - let _ = self - .i2c - .read(Self::SENSOR_ADDRESS, &mut measurement_status_response); + self.i2c + .read(Self::SENSOR_ADDRESS, &mut measurement_status_response)?; let status_word = measurement_status_response[0]; if status_word & 0b1000_0000 == 0 { break; @@ -68,28 +57,30 @@ impl Dht20 { // Read the measurement (1 status + 5 data + 1 crc) let mut measurement_response: [u8; 7] = [0; 7]; - let _ = self - .i2c - .read(Self::SENSOR_ADDRESS, &mut measurement_response); + self.i2c + .read(Self::SENSOR_ADDRESS, &mut measurement_response)?; // Humidity 20 bits (8 + 8 + 4) let mut raw_humidity = measurement_response[1] as u32; + // log::info!("Raw Humidity: {:#018b}", raw_humidity); raw_humidity = (raw_humidity << 8) + measurement_response[2] as u32; raw_humidity = (raw_humidity << 4) + (measurement_response[3] >> 4) as u32; let humidity_percentage = (raw_humidity as f32 / ((1 << 20) as f32)) * 100.0; // Temperature 20 bits let mut raw_temperature = (measurement_response[3] & 0b1111) as u32; + // log::info!("Raw Temperature: {:#018b}", raw_temperature); raw_temperature = (raw_temperature << 8) + measurement_response[4] as u32; raw_temperature = (raw_temperature << 8) + measurement_response[5] as u32; let temperature_percentage = (raw_temperature as f32 / ((1 << 20) as f32)) * 200.0 - 50.0; + // TODO: Do we even need to do this? I think hal handles the checksum in the write / read // Compare the calculated CRC with the received CRC let data = &measurement_response[..6]; let received_crc = measurement_response[6]; let calculated_crc = Self::calculate_crc(data); if received_crc != calculated_crc { - return Err(SensorError::ChecksumMismatch); + log::error!("Calculated CRC {:#018b}", received_crc); } Ok(SensorReading { @@ -126,7 +117,6 @@ impl Dht20 { esp_bootloader_esp_idf::esp_app_desc!(); #[entry] fn main() -> ! { - let peripherals = esp_hal::init(esp_hal::Config::default()); esp_println::logger::init_logger_from_env(); let mut delay = Delay::new();