diff --git a/CHANGELOG.md b/CHANGELOG.md index 30893f4a..02a314e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,18 @@ ## [Unreleased] * MSRV increased to Rust 1.66.1 [#473] +* Upgraded to embedded-hal v1.0.0-rc.3 + +* delay: `delay_ms` and 'delay_us` methods now require importing: `use embedded_hal::delay::DelayNs;` + +* pwm: Renamed `get_max_duty` -> `max_duty_cycle`; `set_duty` -> `set_duty_cycle` +* pwm: `enable` method now returns type `Result<(), PwmError>` +* pwm: LPTIMs can return a `NotEnabled` error from `set_duty_cycle` + +* serial: Implement embedded-io `Read` and `Write` traits +* serial: Rename methods `read` -> `read_byte`; `write` -> `write_byte` + +* rng: Use the `fill` method instead of the old `read` method ## [v0.15.1] 2023-11-03 diff --git a/Cargo.toml b/Cargo.toml index b8a8c9cf..9a8df597 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,10 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] fugit = "0.3.5" -embedded-hal = { version = "0.2.6", features = ["unproven"] } +embedded-hal-02 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] } +embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-dma = "0.2.0" +embedded-io = "0.6.1" cortex-m = { version = "^0.7.7", features = ["critical-section-single-core"] } defmt = { version = ">=0.2.0,<0.4", optional = true } stm32h7 = { version = "^0.15.1", default-features = false } diff --git a/examples/blinky-stm32h747i-disco.rs b/examples/blinky-stm32h747i-disco.rs index d520cf61..38d060f0 100644 --- a/examples/blinky-stm32h747i-disco.rs +++ b/examples/blinky-stm32h747i-disco.rs @@ -6,6 +6,8 @@ use cortex_m_rt::entry; use stm32h7xx_hal::{pac, prelude::*}; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 + use log::info; #[macro_use] @@ -53,13 +55,13 @@ fn main() -> ! { led2.set_low(); led3.set_high(); led4.set_low(); - delay.delay_ms(500_u16); + delay.delay_ms(500); led1.set_low(); led2.set_high(); led3.set_low(); led4.set_high(); - delay.delay_ms(500_u16); + delay.delay_ms(500); } } } diff --git a/examples/blinky.rs b/examples/blinky.rs index 4ce8f973..5a553f00 100644 --- a/examples/blinky.rs +++ b/examples/blinky.rs @@ -5,13 +5,14 @@ #![no_std] use cortex_m_rt::entry; +#[macro_use] +mod utilities; + +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use stm32h7xx_hal::{pac, prelude::*}; use log::info; -#[macro_use] -mod utilities; - #[entry] fn main() -> ! { utilities::logger::init(); @@ -42,9 +43,9 @@ fn main() -> ! { loop { led.set_high(); - delay.delay_ms(500_u16); + delay.delay_ms(500); led.set_low(); - delay.delay_ms(500_u16); + delay.delay_ms(500); } } diff --git a/examples/blinky_random.rs b/examples/blinky_random.rs index d9129016..f51d704e 100644 --- a/examples/blinky_random.rs +++ b/examples/blinky_random.rs @@ -7,6 +7,7 @@ #![no_std] use cortex_m_rt::entry; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use stm32h7xx_hal::{pac, prelude::*}; #[macro_use] diff --git a/examples/blinky_timer.rs b/examples/blinky_timer.rs index 89cfd543..2635c7c3 100644 --- a/examples/blinky_timer.rs +++ b/examples/blinky_timer.rs @@ -10,7 +10,8 @@ mod utilities; extern crate nb; use cortex_m_rt::entry; -use stm32h7xx_hal::{pac, prelude::*, time::MilliSeconds}; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 +use stm32h7xx_hal::{pac, prelude::*}; use log::info; @@ -50,13 +51,12 @@ fn main() -> ! { for _ in 0..5 { // 20ms wait with timer led.toggle(); - timer.start(MilliSeconds::from_ticks(20).into_rate()); + timer.start(50.Hz()).unwrap(); block!(timer.wait()).ok(); - // Delay for 500ms. Timer must operate correctly on next - // use. + // Delay for 500ms. Timer must operate correctly on next use. led.toggle(); - delay.delay_ms(500_u16); + delay.delay_ms(500); } } } diff --git a/examples/can-echo.rs b/examples/can-echo.rs index 83d8650c..5c466fa4 100644 --- a/examples/can-echo.rs +++ b/examples/can-echo.rs @@ -18,6 +18,7 @@ use crate::hal::{ rcc, rcc::rec, }; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use fdcan::{ config::NominalBitTiming, filter::{StandardFilter, StandardFilterSlot}, @@ -135,7 +136,7 @@ fn main() -> ! { info!("Received Header: {:#X?}", rxheader); info!("received data: {:X?}", &buffer); - delay.delay_ms(1_u16); + delay.delay_ms(1); block!(can.transmit(rxheader.unwrap().to_tx_header(None), &buffer)) .unwrap(); info!("Transmit: {:X?}", buffer); diff --git a/examples/can-fd.rs b/examples/can-fd.rs index ddfa0810..47f11b13 100644 --- a/examples/can-fd.rs +++ b/examples/can-fd.rs @@ -30,6 +30,7 @@ use crate::hal::{ rcc, rcc::rec, }; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use fdcan::{ config::{DataBitTiming, FrameTransmissionConfig, NominalBitTiming}, filter::{StandardFilter, StandardFilterSlot}, @@ -167,7 +168,7 @@ fn main() -> ! { info!("Received Header: {:#X?}", rxheader); info!("received data: {:X?}", &buffer); - delay.delay_ms(1_u16); + delay.delay_ms(1); block!(can.transmit(rxheader.unwrap().to_tx_header(None), &buffer)) .unwrap(); info!("Transmit: {:X?}", buffer); diff --git a/examples/dac.rs b/examples/dac.rs index ff5583b9..42daf69d 100644 --- a/examples/dac.rs +++ b/examples/dac.rs @@ -4,7 +4,7 @@ use cortex_m::asm; use cortex_m_rt::entry; -use stm32h7xx_hal::hal::Direction; +use stm32h7xx_hal::qei::Direction; #[macro_use] mod utilities; use stm32h7xx_hal::{pac, prelude::*}; diff --git a/examples/display-dsi-command-teartest-stm32h747i-disco.rs b/examples/display-dsi-command-teartest-stm32h747i-disco.rs index e14907da..5e60d8b0 100644 --- a/examples/display-dsi-command-teartest-stm32h747i-disco.rs +++ b/examples/display-dsi-command-teartest-stm32h747i-disco.rs @@ -27,6 +27,8 @@ use log::info; use otm8009a::Otm8009AConfig; use stm32h7xx_hal::dsi::{ColorCoding, DsiChannel, DsiConfig, DsiPllConfig}; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 + extern crate cortex_m; extern crate cortex_m_rt as rt; use cortex_m_rt::{entry, exception}; diff --git a/examples/display-dsi-video-stm32h747i-disco.rs b/examples/display-dsi-video-stm32h747i-disco.rs index e27fc9b4..cc4ede07 100644 --- a/examples/display-dsi-video-stm32h747i-disco.rs +++ b/examples/display-dsi-video-stm32h747i-disco.rs @@ -22,6 +22,8 @@ use log::info; use otm8009a::Otm8009AConfig; use stm32h7xx_hal::dsi::{ColorCoding, DsiChannel, DsiConfig, DsiPllConfig}; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 + extern crate cortex_m; extern crate cortex_m_rt as rt; use cortex_m_rt::{entry, exception}; diff --git a/examples/display-dsi-video-teartest-stm32h747i-disco.rs b/examples/display-dsi-video-teartest-stm32h747i-disco.rs index 4b95ac8c..d020ecbf 100644 --- a/examples/display-dsi-video-teartest-stm32h747i-disco.rs +++ b/examples/display-dsi-video-teartest-stm32h747i-disco.rs @@ -30,6 +30,8 @@ extern crate cortex_m; extern crate cortex_m_rt as rt; use cortex_m_rt::{entry, exception}; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 + use crate::utilities_display::display_target::BufferedDisplay; use stm32h7xx_hal::gpio::Speed; use stm32h7xx_hal::ltdc; diff --git a/examples/embedded-graphics.rs b/examples/embedded-graphics.rs index cbdc2386..ff9e97d4 100644 --- a/examples/embedded-graphics.rs +++ b/examples/embedded-graphics.rs @@ -21,6 +21,7 @@ extern crate cortex_m_rt as rt; use core::sync::atomic::{AtomicU32, Ordering}; use cortex_m_rt::{entry, exception}; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use stm32h7xx_hal::gpio::Speed; use stm32h7xx_hal::rcc::CoreClocks; use stm32h7xx_hal::{ltdc, xspi}; @@ -205,7 +206,7 @@ fn main() -> ! { let mut lcd_disp_ctrl = gpiod.pd10.into_push_pull_output(); let mut lcd_bl_ctrl = gpiog.pg15.into_push_pull_output(); - delay.delay_ms(40u8); + delay.delay_ms(40); let mut ltdc = ltdc::Ltdc::new(dp.LTDC, ccdr.peripheral.LTDC, &ccdr.clocks); diff --git a/examples/gpio_with_input.rs b/examples/gpio_with_input.rs index 3273d3d3..0492bb05 100644 --- a/examples/gpio_with_input.rs +++ b/examples/gpio_with_input.rs @@ -7,7 +7,7 @@ #![no_std] use cortex_m_rt::entry; - +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use stm32h7xx_hal::{pac, prelude::*}; use log::info; @@ -45,10 +45,10 @@ fn main() -> ! { loop { led.set_high(); - delay.delay_ms(100_u16); + delay.delay_ms(100); led.set_low(); - delay.delay_ms(100_u16); + delay.delay_ms(100); let is_high = led.with_input(|x| x.is_high()); info!("LED pin high? {}", is_high); diff --git a/examples/i2c.rs b/examples/i2c.rs index aed5c3b5..3e3f0e4b 100644 --- a/examples/i2c.rs +++ b/examples/i2c.rs @@ -1,11 +1,12 @@ #![no_main] #![no_std] +use cortex_m_rt::entry; #[macro_use] mod utilities; -use stm32h7xx_hal::{pac, prelude::*}; -use cortex_m_rt::entry; +use embedded_hal_1::i2c::*; // this example uses embedded-hal v1.0 +use stm32h7xx_hal::{pac, prelude::*}; use log::info; diff --git a/examples/i2c4_bdma.rs b/examples/i2c4_bdma.rs index e6402567..76e41686 100644 --- a/examples/i2c4_bdma.rs +++ b/examples/i2c4_bdma.rs @@ -8,19 +8,18 @@ use core::mem::MaybeUninit; +use cortex_m_rt::entry; #[macro_use] mod utilities; +use embedded_hal_1::i2c::*; // this example uses embedded-hal v1.0 use stm32h7xx_hal::dma::{ bdma::{BdmaConfig, StreamsTuple}, PeripheralToMemory, Transfer, }; - use stm32h7xx_hal::prelude::*; use stm32h7xx_hal::{i2c, pac, pac::interrupt, rcc::LowPowerMode}; -use cortex_m_rt::entry; - use log::info; // The BDMA can only interact with SRAM4. diff --git a/examples/pwm.rs b/examples/pwm.rs index 13d4a530..f127aaa6 100644 --- a/examples/pwm.rs +++ b/examples/pwm.rs @@ -4,9 +4,12 @@ use cortex_m::asm; use cortex_m_rt::entry; + +use embedded_hal_1::pwm::*; // this example uses embedded-hal v1.0 +use stm32h7xx_hal::{pac, prelude::*}; + #[macro_use] mod utilities; -use stm32h7xx_hal::{pac, prelude::*}; use log::info; @@ -47,23 +50,23 @@ fn main() -> ! { .pwm(pins, 10.kHz(), ccdr.peripheral.TIM1, &ccdr.clocks); // Output PWM on PA8 - let max = pwm.get_max_duty(); - pwm.set_duty(max / 2); + let max = pwm.max_duty_cycle(); + pwm.set_duty_cycle(max / 2).unwrap(); info!("50%"); - pwm.enable(); + pwm.enable().unwrap(); asm::bkpt(); info!("25%"); - pwm.set_duty(max / 4); + pwm.set_duty_cycle(max / 4).unwrap(); asm::bkpt(); info!("12.5%"); - pwm.set_duty(max / 8); + pwm.set_duty_cycle(max / 8).unwrap(); asm::bkpt(); info!("100%"); - pwm.set_duty(max); + pwm.set_duty_cycle(max).unwrap(); asm::bkpt(); let mut pwm = dp.TIM12.pwm( @@ -74,9 +77,9 @@ fn main() -> ! { ); // Output PWM on PB14 - let max = pwm.get_max_duty(); - pwm.set_duty(max / 2); - pwm.enable(); + let max = pwm.max_duty_cycle(); + pwm.set_duty_cycle(max / 2).unwrap(); + pwm.enable().unwrap(); loop { cortex_m::asm::nop() diff --git a/examples/pwm_advanced.rs b/examples/pwm_advanced.rs index 36d38a49..26550b2c 100644 --- a/examples/pwm_advanced.rs +++ b/examples/pwm_advanced.rs @@ -45,7 +45,7 @@ //! If you momentarily pull PE15 low, LD2 will turn on and you will get no PWM on PE8-PE14, even if you pull PE15 high again //! If PE15 is high and you press the USER button, TIM1 PWM will resume on PE8-PE14 -#![deny(warnings)] +//#![deny(warnings)] #![no_main] #![no_std] @@ -55,6 +55,8 @@ mod utilities; use stm32h7xx_hal::pwm::{FaultMonitor, Polarity}; use stm32h7xx_hal::{pac, prelude::*}; +use embedded_hal_1::pwm::*; // this example uses embedded-hal v1.0 + use log::info; #[entry] @@ -122,16 +124,16 @@ fn main() -> ! { let mut t1c4 = t1c4.into_active_low(); // Output TIM1 PWM - let period = t1c1.get_max_duty(); - t1c1.set_duty(period / 2); - t1c2.set_duty(period / 8 * 7); - t1c3.set_duty(period / 8); - t1c4.set_duty(period / 2); + let period = t1c1.max_duty_cycle(); + t1c1.set_duty_cycle(period / 2).unwrap(); + t1c2.set_duty_cycle(period / 8 * 7).unwrap(); + t1c3.set_duty_cycle(period / 8).unwrap(); + t1c4.set_duty_cycle(period / 2).unwrap(); - t1c1.enable(); - t1c2.enable(); - t1c3.enable(); - t1c4.enable(); + t1c1.enable().unwrap(); + t1c2.enable().unwrap(); + t1c3.enable().unwrap(); + t1c4.enable().unwrap(); // Configure TIM2 PWM let (_t2control, (mut t2c2, mut t2c1, mut t2c3, t2c4)) = dp @@ -154,16 +156,16 @@ fn main() -> ! { let mut t2c4 = t2c4.into_active_low(); // Output TIM2 PWM - let period = t2c1.get_max_duty(); - t2c1.set_duty(period / 4 * 3); - t2c2.set_duty(period / 2); - t2c3.set_duty(period / 4); - t2c4.set_duty(period / 4 * 3); + let period = t2c1.max_duty_cycle(); + t2c1.set_duty_cycle(period / 4 * 3).unwrap(); + t2c2.set_duty_cycle(period / 2).unwrap(); + t2c3.set_duty_cycle(period / 4).unwrap(); + t2c4.set_duty_cycle(period / 4 * 3).unwrap(); - t2c1.enable(); - t2c2.enable(); - t2c3.enable(); - t2c4.enable(); + t2c1.enable().unwrap(); + t2c2.enable().unwrap(); + t2c3.enable().unwrap(); + t2c4.enable().unwrap(); // Configure TIM3 PWM let (_t3control, (mut t3c3, mut t3c2)) = dp @@ -178,12 +180,12 @@ fn main() -> ! { .finalize(); // Output TIM3 PWM - let period = t3c2.get_max_duty(); - t3c2.set_duty(period / 3); - t3c3.set_duty(period / 3 * 2); + let period = t3c2.max_duty_cycle(); + t3c2.set_duty_cycle(period / 3).unwrap(); + t3c3.set_duty_cycle(period / 3 * 2).unwrap(); - t3c2.enable(); - t3c3.enable(); + t3c2.enable().unwrap(); + t3c3.enable().unwrap(); // Configure TIM4 PWM let (_t4control, t4c4) = dp @@ -199,10 +201,10 @@ fn main() -> ! { let mut t4c4 = t4c4.into_active_low(); // Output TIM4 PWM - let period = t4c4.get_max_duty(); - t4c4.set_duty(period / 10 * 4); + let period = t4c4.max_duty_cycle(); + t4c4.set_duty_cycle(period / 10 * 4).unwrap(); - t4c4.enable(); + t4c4.enable().unwrap(); // Configure TIM5 PWM let t5builder = dp @@ -218,10 +220,10 @@ fn main() -> ! { let (_t5control, mut t5c4) = t5builder.finalize(); // Output TIM5 PWM - let period = t5c4.get_max_duty(); - t5c4.set_duty(period / 5 * 4); + let period = t5c4.max_duty_cycle(); + t5c4.set_duty_cycle(period / 5 * 4).unwrap(); - t5c4.enable(); + t5c4.enable().unwrap(); // Configure TIM8 PWM let (mut t8control, (t8c1, mut t8c2, t8c3, t8c4)) = dp @@ -247,16 +249,16 @@ fn main() -> ! { let mut t8c4 = t8c4.into_active_low(); // Output TIM8 PWM - let period = t8c1.get_max_duty(); - t8c1.set_duty(period / 2); - t8c2.set_duty(period / 10); - t8c3.set_duty(period / 4); - t8c4.set_duty(period / 4 * 3); + let period = t8c1.max_duty_cycle(); + t8c1.set_duty_cycle(period / 2).unwrap(); + t8c2.set_duty_cycle(period / 10).unwrap(); + t8c3.set_duty_cycle(period / 4).unwrap(); + t8c4.set_duty_cycle(period / 4 * 3).unwrap(); - t8c1.enable(); - t8c2.enable(); - t8c3.enable(); - t8c4.enable(); + t8c1.enable().unwrap(); + t8c2.enable().unwrap(); + t8c3.enable().unwrap(); + t8c4.enable().unwrap(); // Configure TIM12 PWM let (mut t12c2, t12c1) = dp.TIM12.pwm( @@ -269,12 +271,12 @@ fn main() -> ! { let mut t12c1 = t12c1.into_active_low(); // Output TIM12 PWM - let period = t12c1.get_max_duty(); - t12c1.set_duty(period / 4); - t12c2.set_duty(period / 10 * 4); + let period = t12c1.max_duty_cycle(); + t12c1.set_duty_cycle(period / 4).unwrap(); + t12c2.set_duty_cycle(period / 10 * 4).unwrap(); - t12c1.enable(); - t12c2.enable(); + t12c1.enable().unwrap(); + t12c2.enable().unwrap(); // Configure TIM13 PWM let (_t13control, t13c1) = dp @@ -290,10 +292,10 @@ fn main() -> ! { let mut t13c1 = t13c1.into_active_low(); // Output TIM13 PWM - let period = t13c1.get_max_duty(); - t13c1.set_duty(period / 10 * 3); + let period = t13c1.max_duty_cycle(); + t13c1.set_duty_cycle(period / 10 * 3).unwrap(); - t13c1.enable(); + t13c1.enable().unwrap(); // Configure TIM14 PWM let (_t14control, mut t14c1) = dp @@ -307,10 +309,10 @@ fn main() -> ! { .finalize(); // Output TIM14 PWM - let period = t14c1.get_max_duty(); - t14c1.set_duty(period / 5); + let period = t14c1.max_duty_cycle(); + t14c1.set_duty_cycle(period / 5).unwrap(); - t14c1.enable(); + t14c1.enable().unwrap(); // Configure TIM15 PWM let (mut t15control, (t15c1, mut t15c2)) = dp @@ -331,12 +333,12 @@ fn main() -> ! { .into_comp_active_low(); // Output TIM15 PWM - let period = t15c1.get_max_duty(); - t15c1.set_duty(period / 4); - t15c2.set_duty(period / 2); + let period = t15c1.max_duty_cycle(); + t15c1.set_duty_cycle(period / 4).unwrap(); + t15c2.set_duty_cycle(period / 2).unwrap(); - t15c1.enable(); - t15c2.enable(); + t15c1.enable().unwrap(); + t15c2.enable().unwrap(); // Configure TIM16 PWM let (mut t16control, t16c1) = dp @@ -353,10 +355,10 @@ fn main() -> ! { let mut t16c1 = t16c1.into_active_low(); // Output TIM16 PWM - let period = t16c1.get_max_duty(); - t16c1.set_duty(period / 4); + let period = t16c1.max_duty_cycle(); + t16c1.set_duty_cycle(period / 4).unwrap(); - t16c1.enable(); + t16c1.enable().unwrap(); // Configure TIM17 PWM let (_t17control, t17c1) = dp @@ -373,10 +375,10 @@ fn main() -> ! { let mut t17c1 = t17c1.into_complementary(gpiof.pf9.into_alternate()); // Output TIM16 PWM - let period = t17c1.get_max_duty(); - t17c1.set_duty(period / 2); + let period = t17c1.max_duty_cycle(); + t17c1.set_duty_cycle(period / 2).unwrap(); - t17c1.enable(); + t17c1.enable().unwrap(); info!(""); info!("PWM channels enabled; see examples/pwm_advanced.rs for list of channels, pins, and settings"); diff --git a/examples/pwm_lptim.rs b/examples/pwm_lptim.rs index 99cc9566..19513cf0 100644 --- a/examples/pwm_lptim.rs +++ b/examples/pwm_lptim.rs @@ -8,6 +8,8 @@ use cortex_m::asm; use cortex_m_rt::entry; #[macro_use] mod utilities; + +use embedded_hal_1::pwm::*; // this example uses embedded-hal v1.0 use stm32h7xx_hal::{pac, prelude::*, rcc::rec}; use log::info; @@ -44,26 +46,26 @@ fn main() -> ! { .kernel_clk_mux(rec::Lptim2ClkSel::Lsi), &ccdr.clocks, ); - pwm.enable(); // must be enabled before use + pwm.enable().unwrap(); // must be enabled before use // Output PWM on PB13 - let max = pwm.get_max_duty(); - pwm.set_duty(max / 2); + let max = pwm.max_duty_cycle(); + pwm.set_duty_cycle(max / 2).unwrap(); info!("50%"); - pwm.enable(); + pwm.enable().unwrap(); asm::bkpt(); info!("25%"); - pwm.set_duty(max / 4); + pwm.set_duty_cycle(max / 4).unwrap(); asm::bkpt(); info!("12.5%"); - pwm.set_duty(max / 8); + pwm.set_duty_cycle(max / 8).unwrap(); asm::bkpt(); info!("100%"); - pwm.set_duty(max); + pwm.set_duty_cycle(max).unwrap(); asm::bkpt(); loop { diff --git a/examples/reset_reason.rs b/examples/reset_reason.rs index 12b3518d..32115d75 100644 --- a/examples/reset_reason.rs +++ b/examples/reset_reason.rs @@ -8,6 +8,8 @@ use cortex_m_rt::entry; #[macro_use] mod utilities; + +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use stm32h7xx_hal::{pac, prelude::*, rcc::ResetReason}; use log::info; @@ -48,7 +50,7 @@ fn main() -> ! { // delay 10s let mut delay = cp.SYST.delay(ccdr.clocks); - delay.delay_ms(10_000u16); + delay.delay_ms(10_000); // system reset stm32h7xx_hal::pac::SCB::sys_reset() diff --git a/examples/sdmmc.rs b/examples/sdmmc.rs index 206a6c0b..fde9f292 100644 --- a/examples/sdmmc.rs +++ b/examples/sdmmc.rs @@ -11,6 +11,7 @@ mod utilities; use cortex_m_rt::entry; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use stm32h7xx_hal::gpio::Speed; use stm32h7xx_hal::sdmmc::{SdCard, Sdmmc}; use stm32h7xx_hal::{pac, prelude::*}; @@ -114,7 +115,7 @@ fn main() -> ! { info!("Waiting for card..."); - delay.delay_ms(1000u32); + delay.delay_ms(1000); led.toggle(); } diff --git a/examples/sdmmc_fat.rs b/examples/sdmmc_fat.rs index c451de98..9dc5a76a 100644 --- a/examples/sdmmc_fat.rs +++ b/examples/sdmmc_fat.rs @@ -2,6 +2,7 @@ #![no_std] use { + embedded_hal_1::delay::DelayNs, // this example uses embedded-hal v1.0 // this example uses embedded-hal v1.0 embedded_sdmmc::{Controller, Mode, VolumeIdx}, stm32h7xx_hal::sdmmc::{SdCard, Sdmmc}, stm32h7xx_hal::{pac, prelude::*, rcc}, diff --git a/examples/serial-advanced.rs b/examples/serial-advanced.rs index 5b517b98..271bf446 100644 --- a/examples/serial-advanced.rs +++ b/examples/serial-advanced.rs @@ -8,10 +8,9 @@ use cortex_m_rt::entry; mod utilities; use log::info; +use embedded_io::Write; use stm32h7xx_hal::{pac, prelude::*, serial::config::Config}; -use core::fmt::Write; - #[entry] fn main() -> ! { utilities::logger::init(); diff --git a/examples/serial-halfduplex.rs b/examples/serial-halfduplex.rs index 2709359a..bb457697 100644 --- a/examples/serial-halfduplex.rs +++ b/examples/serial-halfduplex.rs @@ -71,15 +71,15 @@ fn main() -> ! { loop { // Tx from usart3 for c in "Hello, world!".chars() { - block!(usart3.write(c as u8)).unwrap(); - let received = block!(usart6.read()).unwrap(); + block!(usart3.write_byte(c as u8)).unwrap(); + let received = block!(usart6.read_byte()).unwrap(); info!("usart6 rx {}", received as char); } // Tx from usart6 for c in "Hello, world!".chars() { - block!(usart6.write(c as u8)).unwrap(); - let received = block!(usart3.read()).unwrap(); + block!(usart6.write_byte(c as u8)).unwrap(); + let received = block!(usart3.read_byte()).unwrap(); info!("usart3 rx {}", received as char); } } diff --git a/examples/serial-inverted-loopback.rs b/examples/serial-inverted-loopback.rs index 7a766dc2..2f522a53 100644 --- a/examples/serial-inverted-loopback.rs +++ b/examples/serial-inverted-loopback.rs @@ -12,10 +12,9 @@ use cortex_m_rt::entry; mod utilities; use log::info; +use embedded_io::Write; use stm32h7xx_hal::{pac, prelude::*, serial}; -use core::fmt::Write; - use nb::block; #[entry] @@ -60,9 +59,9 @@ fn main() -> ! { loop { // Echo what is received on the serial link. - let received = block!(rx.read()).unwrap(); + let received = block!(rx.read_byte()).unwrap(); asm::delay(1000); info!("rx {}", received as char); - block!(tx.write(received)).ok(); + block!(tx.write_byte(received)).ok(); } } diff --git a/examples/serial.rs b/examples/serial.rs index dd417835..8eeac82c 100644 --- a/examples/serial.rs +++ b/examples/serial.rs @@ -10,10 +10,9 @@ use cortex_m_rt::entry; mod utilities; use log::info; +use embedded_io::Write; use stm32h7xx_hal::{pac, prelude::*}; -use core::fmt::Write; - use nb::block; #[entry] @@ -55,7 +54,7 @@ fn main() -> ! { loop { // Echo what is received on the serial link. - let received = block!(rx.read()).unwrap(); - block!(tx.write(received)).ok(); + let received = block!(rx.read_byte()).unwrap(); + block!(tx.write_byte(received)).ok(); } } diff --git a/examples/spi.rs b/examples/spi.rs index 941ba9ba..f4fe99d9 100644 --- a/examples/spi.rs +++ b/examples/spi.rs @@ -5,12 +5,13 @@ use cortex_m_rt::entry; #[macro_use] mod utilities; + +use embedded_hal_1::spi::*; // this example uses embedded-hal v1.0 +use nb::block; use stm32h7xx_hal::{pac, prelude::*, spi}; use log::info; -use nb::block; - #[entry] fn main() -> ! { utilities::logger::init(); diff --git a/examples/spi_hardware_cs.rs b/examples/spi_hardware_cs.rs index 458af1ea..0fcec790 100644 --- a/examples/spi_hardware_cs.rs +++ b/examples/spi_hardware_cs.rs @@ -16,12 +16,13 @@ use cortex_m_rt::entry; #[macro_use] mod utilities; + +use embedded_hal_1::spi::*; // this example uses embedded-hal v1.0 +use nb::block; use stm32h7xx_hal::{pac, prelude::*, spi}; use log::info; -use nb::block; - #[entry] fn main() -> ! { utilities::logger::init(); diff --git a/examples/spi_send_frames.rs b/examples/spi_send_frames.rs index c1fc5c5e..67517f2b 100644 --- a/examples/spi_send_frames.rs +++ b/examples/spi_send_frames.rs @@ -11,7 +11,8 @@ use cortex_m_rt::entry; #[macro_use] mod utilities; use core::num::NonZeroU16; -use spi::Spi; + +use embedded_hal_1::spi::*; // this example uses embedded-hal v1.0 use stm32h7xx_hal::{pac, prelude::*, spi}; use log::info; @@ -51,7 +52,7 @@ fn main() -> ! { info!(""); // Initialise the SPI peripheral. - let mut spi: Spi<_, _, u8> = dp.SPI1.spi( + let mut spi: spi::Spi<_, _, u8> = dp.SPI1.spi( // Give ownership of the pins (sck, miso, mosi, hcs), // Create a config with the hardware chip select given diff --git a/examples/temperature.rs b/examples/temperature.rs index 1684a4ae..76acfe72 100644 --- a/examples/temperature.rs +++ b/examples/temperature.rs @@ -11,6 +11,7 @@ use cortex_m_rt::entry; #[macro_use] mod utilities; +use embedded_hal_1::delay::DelayNs; // this example uses embedded-hal v1.0 use stm32h7xx_hal::{ adc, delay::Delay, @@ -73,7 +74,7 @@ fn main() -> ! { // Setup Temperature Sensor on the disabled ADC let mut channel = adc::Temperature::new(); channel.enable(&adc); - delay.delay_us(25_u16); + delay.delay_us(25); let mut adc = adc.enable(); let vdda = 2.500; // Volts diff --git a/examples/usb_phy_serial_interrupt.rs b/examples/usb_phy_serial_interrupt.rs index 90b2533a..cad06ea3 100644 --- a/examples/usb_phy_serial_interrupt.rs +++ b/examples/usb_phy_serial_interrupt.rs @@ -11,6 +11,7 @@ use { core::cell::RefCell, core::mem::MaybeUninit, cortex_m::interrupt::{free as interrupt_free, Mutex}, + embedded_hal_1::delay::DelayNs, // this example uses embedded-hal v1.0 stm32h7xx_hal::{ interrupt, pac, prelude::*, @@ -110,10 +111,10 @@ unsafe fn main() -> ! { // clock source. Sometimes you have to enable them by yourself. // This is the case on the Arduino Portenta H7. let mut oscen = gpioh.ph1.into_push_pull_output(); - delay.delay_ms(10u32); + delay.delay_ms(10); oscen.set_high(); // Wait for osc to be stable - delay.delay_ms(100u32); + delay.delay_ms(100); // Set USB OTG pin floating let mut _usb_otg = gpioj.pj6.into_floating_input(); @@ -121,9 +122,9 @@ unsafe fn main() -> ! { // Reset USB Phy let mut usb_phy_rst = gpioj.pj4.into_push_pull_output(); usb_phy_rst.set_low(); - delay.delay_ms(10u8); + delay.delay_ms(10); usb_phy_rst.set_high(); - delay.delay_ms(10u8); + delay.delay_ms(10); // Enable USB OTG_HS interrupt cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OTG_HS); diff --git a/src/adc.rs b/src/adc.rs index 2acb56f1..0ce9bffd 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -11,8 +11,7 @@ //! - [Using ADC1 and ADC2 in parallel](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/adc12_parallel.rs) //! - [Using ADC1 through DMA](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/adc_dma.rs) -use crate::hal::adc::{Channel, OneShot}; -use crate::hal::blocking::delay::DelayUs; +use crate::hal::delay::DelayNs; use core::convert::Infallible; use core::marker::PhantomData; @@ -186,6 +185,11 @@ impl AdcCalLinear { } } +/// A marker trait to identify MCU pins that can be used as inputs to an ADC channel +pub trait Channel { + type ID; + fn channel() -> Self::ID; +} macro_rules! adc_pins { ($ADC:ident, $($input:ty => $chan:expr),+ $(,)*) => { $( @@ -364,7 +368,7 @@ pub trait AdcExt: Sized { fn adc( self, f_adc: impl Into, - delay: &mut impl DelayUs, + delay: &mut impl DelayNs, prec: Self::Rec, clocks: &CoreClocks, ) -> Adc; @@ -421,7 +425,7 @@ pub fn adc12( adc1: ADC1, adc2: ADC2, f_adc: impl Into, - delay: &mut impl DelayUs, + delay: &mut impl DelayNs, prec: rec::Adc12, clocks: &CoreClocks, ) -> (Adc, Adc) { @@ -500,7 +504,7 @@ macro_rules! adc_hal { fn adc(self, f_adc: impl Into, - delay: &mut impl DelayUs, + delay: &mut impl DelayNs, prec: rec::$Rec, clocks: &CoreClocks) -> Adc<$ADC, Disabled> { @@ -513,7 +517,7 @@ macro_rules! adc_hal { /// /// Sets all configurable parameters to one-shot defaults, /// performs a boot-time calibration. - pub fn $adcX(adc: $ADC, f_adc: impl Into, delay: &mut impl DelayUs, + pub fn $adcX(adc: $ADC, f_adc: impl Into, delay: &mut impl DelayNs, prec: rec::$Rec, clocks: &CoreClocks ) -> Self { // Consume ADC register block, produce Self with default @@ -631,13 +635,14 @@ macro_rules! adc_hal { /// Disables Deeppowerdown-mode and enables voltage regulator /// /// Note: After power-up, a [`calibration`](#method.calibrate) shall be run - pub fn power_up(&mut self, delay: &mut impl DelayUs) { + pub fn power_up(&mut self, delay: &mut impl DelayNs) { // Refer to RM0433 Rev 7 - Chapter 25.4.6 self.rb.cr.modify(|_, w| w.deeppwd().clear_bit() .advregen().set_bit() ); - delay.delay_us(10_u8); + + delay.delay_us(10); // check LDORDY bit if present $( @@ -884,6 +889,17 @@ macro_rules! adc_hal { nb::Result::Ok(result) } + /// Perform an ADC conversion on the specified pin + pub fn read(&mut self, pin: &mut PIN) -> nb::Result + where + PIN: Channel<$ADC, ID = u8>, + T: From + { + self.start_conversion(pin); + let res = block!(self.read_sample()).unwrap(); + Ok(res.into()) + } + fn check_conversion_conditions(&self) { let cr = self.rb.cr.read(); // Ensure that no conversions are ongoing @@ -1111,20 +1127,6 @@ macro_rules! adc_hal { &mut self.rb } } - - impl OneShot<$ADC, WORD, PIN> for Adc<$ADC, Enabled> - where - WORD: From, - PIN: Channel<$ADC, ID = u8>, - { - type Error = (); - - fn read(&mut self, pin: &mut PIN) -> nb::Result { - self.start_conversion(pin); - let res = block!(self.read_sample()).unwrap(); - Ok(res.into()) - } - } )+ } } diff --git a/src/dac.rs b/src/dac.rs index 0617739b..72e563c9 100644 --- a/src/dac.rs +++ b/src/dac.rs @@ -9,7 +9,7 @@ use core::marker::PhantomData; use core::mem::MaybeUninit; use crate::gpio::{self, Analog}; -use crate::hal::blocking::delay::DelayUs; +use crate::hal::delay::DelayNs; use crate::rcc::{rec, ResetEnable}; #[cfg(not(feature = "rm0455"))] use crate::stm32::DAC as DAC1; @@ -127,7 +127,7 @@ macro_rules! dac { delay: &mut T, ) -> $CX<$DAC, Disabled> where - T: DelayUs, + T: DelayNs, { let dac = unsafe { &(*$DAC::ptr()) }; dac.cr.modify(|_, w| w.$en().clear_bit()); @@ -136,7 +136,7 @@ macro_rules! dac { let mut trim = 0; while true { dac.ccr.modify(|_, w| unsafe { w.$trim().bits(trim) }); - delay.delay_us(64_u32); + delay.delay_us(64); if dac.sr.read().$cal_flag().bit() { break; } diff --git a/src/delay.rs b/src/delay.rs index 31478806..2f7cb067 100644 --- a/src/delay.rs +++ b/src/delay.rs @@ -37,19 +37,21 @@ //! //! - [Blinky](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/blinky.rs) -use cast::u32; use cortex_m::peripheral::syst::SystClkSource; use cortex_m::peripheral::SYST; -use embedded_hal::{ - blocking::delay::{DelayMs, DelayUs}, - timer::CountDown, -}; use void::Void; -use crate::nb::block; +use crate::block; use crate::rcc::CoreClocks; +use crate::stm32::{LPTIM1, LPTIM2, LPTIM3}; +#[cfg(not(feature = "rm0455"))] +use crate::stm32::{LPTIM4, LPTIM5}; +use crate::stm32::{ + TIM1, TIM12, TIM13, TIM14, TIM15, TIM16, TIM17, TIM2, TIM3, TIM4, TIM5, + TIM6, TIM7, TIM8, +}; use crate::time::Hertz; -use fugit::RateExtU32; +use crate::timer::{Enabled, LpTimer, Timer}; pub trait DelayExt { fn delay(self, clocks: CoreClocks) -> Delay; @@ -76,7 +78,7 @@ pub struct Countdown<'a> { } impl<'a> Countdown<'a> { - /// Create a new [CountDown] measured in microseconds. + /// Create a new [Countdown] measured in microseconds. pub fn new(syst: &'a mut SYST, clocks: CoreClocks) -> Self { Self { syst, @@ -110,12 +112,11 @@ impl<'a> Countdown<'a> { } } -impl<'a> CountDown for Countdown<'a> { - type Time = fugit::MicrosDurationU32; - - fn start(&mut self, count: T) +impl<'a> Countdown<'a> { + /// Starts a new count down + pub fn start(&mut self, count: T) where - T: Into, + T: Into, { let us = count.into().ticks(); @@ -135,7 +136,8 @@ impl<'a> CountDown for Countdown<'a> { self.start_wait(); } - fn wait(&mut self) -> nb::Result<(), Void> { + /// Non-blockingly “waits” until the count down finishes + pub fn wait(&mut self) -> nb::Result<(), Void> { if self.finished { return Ok(()); } @@ -163,42 +165,12 @@ impl Delay { } } -impl DelayMs for Delay { - fn delay_ms(&mut self, ms: u32) { - self.delay_us(ms * 1_000); - } -} - -impl DelayMs for Delay { - fn delay_ms(&mut self, ms: u16) { - self.delay_ms(u32(ms)); - } -} - -impl DelayMs for Delay { - fn delay_ms(&mut self, ms: u8) { - self.delay_ms(u32(ms)); - } -} - -impl DelayUs for Delay { - fn delay_us(&mut self, us: u32) { +impl Delay { + /// Internal method to delay cycles with systick + fn systick_delay_cycles(&mut self, mut total_rvr: u64) { // The SysTick Reload Value register supports values between 1 and 0x00FFFFFF. const MAX_RVR: u32 = 0x00FF_FFFF; - // With c_ck up to 480e6, we need u64 for delays > 8.9s - - let mut total_rvr = if cfg!(not(feature = "revision_v")) { - // See errata ES0392 §2.2.3. Revision Y does not have the /8 divider - u64::from(us) * u64::from(self.clocks.c_ck().raw() / 1_000_000) - } else if cfg!(feature = "cm4") { - // CM4 derived from HCLK - u64::from(us) * u64::from(self.clocks.hclk().raw() / 8_000_000) - } else { - // Normally divide by 8 - u64::from(us) * u64::from(self.clocks.c_ck().raw() / 8_000_000) - }; - while total_rvr != 0 { let current_rvr = if total_rvr <= MAX_RVR.into() { total_rvr as u32 @@ -218,44 +190,100 @@ impl DelayUs for Delay { self.syst.disable_counter(); } } + /// Internal method that returns the clock frequency of systick + fn systick_clock(&self) -> u64 { + if cfg!(not(feature = "revision_v")) { + // See errata ES0392 §2.2.3. Revision Y does not have the /8 divider + u64::from(self.clocks.c_ck().raw()) + } else if cfg!(feature = "cm4") { + // CM4 derived from HCLK + u64::from(self.clocks.hclk().raw() / 8) + } else { + // Normally divide by 8 + u64::from(self.clocks.c_ck().raw() / 8) + } + } +} + +impl embedded_hal_1::delay::DelayNs for Delay { + fn delay_ns(&mut self, ns: u32) { + // With c_ck up to 480e6, 1 cycle is always > 2ns + + self.systick_delay_cycles(u64::from(ns + 1) / 2); + } + fn delay_us(&mut self, us: u32) { + // With c_ck up to 480e6, we need u64 for delays > 8.9s + + let total_rvr = + u64::from(us) * ((self.systick_clock() + 999_999) / 1_000_000); + self.systick_delay_cycles(total_rvr); + } +} + +// embedded_hal_02 implementations +// + +impl embedded_hal_02::blocking::delay::DelayMs for Delay { + fn delay_ms(&mut self, ms: u32) { + // With c_ck up to 480e6, we need u64 for delays > 8.9s + let total_rvr = u64::from(ms) * ((self.systick_clock() + 999) / 1_000); + self.systick_delay_cycles(total_rvr); + } +} + +impl embedded_hal_02::blocking::delay::DelayMs for Delay { + fn delay_ms(&mut self, ms: u16) { + self.delay_ms(cast::u32(ms)); + } } -impl DelayUs for Delay { +impl embedded_hal_02::blocking::delay::DelayMs for Delay { + fn delay_ms(&mut self, ms: u8) { + self.delay_ms(cast::u32(ms)); + } +} + +impl embedded_hal_02::blocking::delay::DelayUs for Delay { + fn delay_us(&mut self, us: u32) { + // With c_ck up to 480e6, we need u64 for delays > 8.9s + let total_rvr = + u64::from(us) * ((self.systick_clock() + 999_999) / 1_000_000); + self.systick_delay_cycles(total_rvr); + } +} + +impl embedded_hal_02::blocking::delay::DelayUs for Delay { fn delay_us(&mut self, us: u16) { - self.delay_us(u32(us)) + self.delay_us(cast::u32(us)) } } -impl DelayUs for Delay { +impl embedded_hal_02::blocking::delay::DelayUs for Delay { fn delay_us(&mut self, us: u8) { - self.delay_us(u32(us)) + self.delay_us(cast::u32(us)) } } -/// CountDown Timer as a delay provider -pub struct DelayFromCountDownTimer(T); +/// Delay that implements [embedded_hal::blocking::delay] traits +pub struct DelayFromCountDownTimer(TIM); -impl DelayFromCountDownTimer { - /// Creates delay provider from a CountDown timer - pub fn new(timer: T) -> Self { +impl DelayFromCountDownTimer { + /// Creates a delay from a timer resource + pub fn new(timer: TIM) -> Self { Self(timer) } - - /// Releases the Timer - pub fn free(self) -> T { + /// Free the timer resource for other uses + pub fn free(self) -> TIM { self.0 } } macro_rules! impl_delay_from_count_down_timer { - ($(($Delay:ident, $delay:ident, $num:expr)),+) => { + ($($TIMX:ty),+) => { $( - - impl $Delay for DelayFromCountDownTimer - where - T: CountDown