diff --git a/Cargo.toml b/Cargo.toml index 99c2bbac..4475ab17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,10 +22,9 @@ nb = "1" stm32f1 = "0.14.0" embedded-dma = "0.1.2" bxcan = "0.6" -cast = { default-features = false, version = "0.3.0" } void = { default-features = false, version = "1.0.2" } embedded-hal = { features = ["unproven"], version = "0.2.6" } -fugit = "0.3.0" +fugit = "0.3.5" rtic-monotonic = { version = "1.0", optional = true } [dependencies.stm32-usbd] diff --git a/examples/adc-dma-circ.rs b/examples/adc-dma-circ.rs index 88684eec..169aaab5 100644 --- a/examples/adc-dma-circ.rs +++ b/examples/adc-dma-circ.rs @@ -23,7 +23,7 @@ fn main() -> ! { // clock is configurable. So its frequency may be tweaked to meet certain // practical needs. User specified value is be approximated using supported // prescaler values 2/4/6/8. - let clocks = rcc.cfgr.adcclk(2.mhz()).freeze(&mut flash.acr); + let clocks = rcc.cfgr.adcclk(2.MHz()).freeze(&mut flash.acr); let dma_ch1 = p.DMA1.split().1; diff --git a/examples/adc-dma-rx.rs b/examples/adc-dma-rx.rs index 31d1589e..cb48de01 100644 --- a/examples/adc-dma-rx.rs +++ b/examples/adc-dma-rx.rs @@ -23,7 +23,7 @@ fn main() -> ! { // clock is configurable. So its frequency may be tweaked to meet certain // practical needs. User specified value is be approximated using supported // prescaler values 2/4/6/8. - let clocks = rcc.cfgr.adcclk(2.mhz()).freeze(&mut flash.acr); + let clocks = rcc.cfgr.adcclk(2.MHz()).freeze(&mut flash.acr); let dma_ch1 = p.DMA1.split().1; diff --git a/examples/adc.rs b/examples/adc.rs index 24338e14..1f349a0c 100644 --- a/examples/adc.rs +++ b/examples/adc.rs @@ -21,8 +21,8 @@ fn main() -> ! { // clock is configurable. So its frequency may be tweaked to meet certain // practical needs. User specified value is be approximated using supported // prescaler values 2/4/6/8. - let clocks = rcc.cfgr.adcclk(2.mhz()).freeze(&mut flash.acr); - hprintln!("adc freq: {}", clocks.adcclk().0).unwrap(); + let clocks = rcc.cfgr.adcclk(2.MHz()).freeze(&mut flash.acr); + hprintln!("adc freq: {}", clocks.adcclk()).unwrap(); // Setup ADC let mut adc1 = adc::Adc::adc1(p.ADC1, clocks); diff --git a/examples/adc_temperature.rs b/examples/adc_temperature.rs index 15b5d7bb..7655d680 100644 --- a/examples/adc_temperature.rs +++ b/examples/adc_temperature.rs @@ -18,10 +18,10 @@ fn main() -> ! { let clocks = rcc .cfgr - .use_hse(8.mhz()) - .sysclk(56.mhz()) - .pclk1(28.mhz()) - .adcclk(14.mhz()) + .use_hse(8.MHz()) + .sysclk(56.MHz()) + .pclk1(28.MHz()) + .adcclk(14.MHz()) .freeze(&mut flash.acr); /* // Alternative configuration using dividers and multipliers directly @@ -34,8 +34,8 @@ fn main() -> ! { usbpre: rcc::UsbPre::DIV1_5, adcpre: rcc::AdcPre::DIV2, }, &mut flash.acr);*/ - hprintln!("sysclk freq: {}", clocks.sysclk().0).unwrap(); - hprintln!("adc freq: {}", clocks.adcclk().0).unwrap(); + hprintln!("sysclk freq: {}", clocks.sysclk()).unwrap(); + hprintln!("adc freq: {}", clocks.adcclk()).unwrap(); // Setup ADC let mut adc = adc::Adc::adc1(p.ADC1, clocks); diff --git a/examples/blinky.rs b/examples/blinky.rs index 4adbf10d..d1def668 100644 --- a/examples/blinky.rs +++ b/examples/blinky.rs @@ -39,7 +39,7 @@ fn main() -> ! { // in order to configure the port. For pins 0-7, crl should be passed instead. let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh); // Configure the syst timer to trigger an update every second - let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz()); + let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.Hz()); // Wait for the timer to trigger an update and change the state of the LED loop { diff --git a/examples/blinky_generic.rs b/examples/blinky_generic.rs index 9b510a65..3ca160ac 100644 --- a/examples/blinky_generic.rs +++ b/examples/blinky_generic.rs @@ -26,7 +26,7 @@ fn main() -> ! { let mut gpioc = dp.GPIOC.split(); // Configure the syst timer to trigger an update every second - let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz()); + let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.Hz()); // Create an array of LEDS to blink let mut leds = [ diff --git a/examples/blinky_timer_irq.rs b/examples/blinky_timer_irq.rs index 86acad52..9ca85812 100644 --- a/examples/blinky_timer_irq.rs +++ b/examples/blinky_timer_irq.rs @@ -73,8 +73,8 @@ fn main() -> ! { let mut flash = dp.FLASH.constrain(); let clocks = rcc .cfgr - .sysclk(8.mhz()) - .pclk1(8.mhz()) + .sysclk(8.MHz()) + .pclk1(8.MHz()) .freeze(&mut flash.acr); // Configure PC13 pin to blink LED @@ -86,7 +86,7 @@ fn main() -> ! { cortex_m::interrupt::free(|cs| *G_LED.borrow(cs).borrow_mut() = Some(led)); // Set up a timer expiring after 1s - let mut timer = Timer::new(dp.TIM2, &clocks).start_count_down(1.hz()); + let mut timer = Timer::new(dp.TIM2, &clocks).start_count_down(1.Hz()); // Generate an interrupt when the timer expires timer.listen(Event::Update); diff --git a/examples/can-echo.rs b/examples/can-echo.rs index 153bdb97..1d843bb4 100644 --- a/examples/can-echo.rs +++ b/examples/can-echo.rs @@ -21,7 +21,7 @@ fn main() -> ! { // To meet CAN clock accuracy requirements an external crystal or ceramic // resonator must be used. The blue pill has a 8MHz external crystal. // Other boards might have a crystal with another frequency or none at all. - rcc.cfgr.use_hse(8.mhz()).freeze(&mut flash.acr); + rcc.cfgr.use_hse(8.MHz()).freeze(&mut flash.acr); let mut afio = dp.AFIO.constrain(); diff --git a/examples/can-loopback.rs b/examples/can-loopback.rs index a0c8b9c7..96c7355d 100644 --- a/examples/can-loopback.rs +++ b/examples/can-loopback.rs @@ -23,7 +23,7 @@ fn main() -> ! { // To meet CAN clock accuracy requirements, an external crystal or ceramic // resonator must be used. - rcc.cfgr.use_hse(8.mhz()).freeze(&mut flash.acr); + rcc.cfgr.use_hse(8.MHz()).freeze(&mut flash.acr); #[cfg(not(feature = "connectivity"))] let can = Can::new(dp.CAN1, dp.USB); diff --git a/examples/can-rtic.rs b/examples/can-rtic.rs index 2a8f3538..47474b53 100644 --- a/examples/can-rtic.rs +++ b/examples/can-rtic.rs @@ -75,11 +75,11 @@ mod app { let _clocks = rcc .cfgr - .use_hse(8.mhz()) - .sysclk(64.mhz()) - .hclk(64.mhz()) - .pclk1(16.mhz()) - .pclk2(64.mhz()) + .use_hse(8.MHz()) + .sysclk(64.MHz()) + .hclk(64.MHz()) + .pclk1(16.MHz()) + .pclk2(64.MHz()) .freeze(&mut flash.acr); #[cfg(not(feature = "connectivity"))] diff --git a/examples/dynamic_gpio.rs b/examples/dynamic_gpio.rs index 503ac914..e49bf4fd 100644 --- a/examples/dynamic_gpio.rs +++ b/examples/dynamic_gpio.rs @@ -32,7 +32,7 @@ fn main() -> ! { let mut pin = gpioc.pc13.into_dynamic(&mut gpioc.crh); // Configure the syst timer to trigger an update every second - let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz()); + let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.Hz()); // Wait for the timer to trigger an update and change the state of the LED loop { diff --git a/examples/enc28j60-coap.rs.disabled b/examples/enc28j60-coap.rs.disabled index c4a33c8d..723039f4 100644 --- a/examples/enc28j60-coap.rs.disabled +++ b/examples/enc28j60-coap.rs.disabled @@ -90,7 +90,7 @@ fn main() -> ! { (sck, miso, mosi), &mut afio.mapr, enc28j60::MODE, - 1.mhz(), + 1.MHz(), clocks, ); diff --git a/examples/enc28j60.rs.disabled b/examples/enc28j60.rs.disabled index 2ba1cb49..739129ac 100644 --- a/examples/enc28j60.rs.disabled +++ b/examples/enc28j60.rs.disabled @@ -82,7 +82,7 @@ fn main() -> ! { (sck, miso, mosi), &mut afio.mapr, enc28j60::MODE, - 1.mhz(), + 1.MHz(), clocks, ); diff --git a/examples/i2c-bme280/src/main.rs b/examples/i2c-bme280/src/main.rs index 45e24a9d..2d2da13f 100644 --- a/examples/i2c-bme280/src/main.rs +++ b/examples/i2c-bme280/src/main.rs @@ -45,15 +45,15 @@ fn main() -> ! { // Freeze the configuration of all the clocks in the system and store the frozen frequencies in // `clocks` let clocks = if 1 == 1 { - rcc.cfgr.use_hse(8.mhz()).freeze(&mut flash.acr) + rcc.cfgr.use_hse(8.MHz()).freeze(&mut flash.acr) } else { // My blue pill with a stm32f103 clone dose not seem to respect rcc so will not compensate its pulse legths // with a faster clock like this. And so the sensor dose not have time to respond to the START pulse. // I would be interested if others with real stm32f103's can use this program with the faster clocks. rcc.cfgr - .use_hse(8.mhz()) - .sysclk(48.mhz()) - .pclk1(6.mhz()) + .use_hse(8.MHz()) + .sysclk(48.MHz()) + .pclk1(6.MHz()) .freeze(&mut flash.acr) }; @@ -68,7 +68,7 @@ fn main() -> ! { (scl, sda), &mut afio.mapr, Mode::Fast { - frequency: 400_000.hz(), + frequency: 400.kHz(), duty_cycle: DutyCycle::Ratio16to9, }, clocks, diff --git a/examples/mfrc522.rs b/examples/mfrc522.rs index 6d607f38..26fc4b8a 100644 --- a/examples/mfrc522.rs +++ b/examples/mfrc522.rs @@ -33,7 +33,7 @@ fn main() -> ! { (sck, miso, mosi), &mut afio.mapr, mfrc522::MODE, - 1.mhz(), + 1.MHz(), clocks, ); diff --git a/examples/motor.rs.disabled b/examples/motor.rs.disabled index 466394ce..b302ec6a 100644 --- a/examples/motor.rs.disabled +++ b/examples/motor.rs.disabled @@ -51,7 +51,7 @@ fn main() -> ! { let pwm = p.TIM2.pwm( gpioa.pa0.into_alternate_push_pull(&mut gpioa.crl), &mut afio.mapr, - 1.khz(), + 1.kHz(), clocks, ); diff --git a/examples/mpu9250.rs.disabled b/examples/mpu9250.rs.disabled index 34cf55ed..8802f3f1 100644 --- a/examples/mpu9250.rs.disabled +++ b/examples/mpu9250.rs.disabled @@ -51,7 +51,7 @@ fn main() -> ! { (sck, miso, mosi), &mut afio.mapr, mpu9250::MODE, - 1.mhz(), + 1.MHz(), clocks, ); diff --git a/examples/multi_mode_gpio.rs b/examples/multi_mode_gpio.rs index c991d10e..9dda3697 100644 --- a/examples/multi_mode_gpio.rs +++ b/examples/multi_mode_gpio.rs @@ -31,7 +31,7 @@ fn main() -> ! { let mut pin = gpioc.pc13.into_floating_input(&mut gpioc.crh); // Configure the syst timer to trigger an update every second - let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz()); + let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.Hz()); // Wait for the timer to trigger an update and change the state of the LED loop { diff --git a/examples/pwm.rs b/examples/pwm.rs index aefef001..aa84f573 100644 --- a/examples/pwm.rs +++ b/examples/pwm.rs @@ -13,7 +13,7 @@ use stm32f1xx_hal::{ pac, prelude::*, pwm::Channel, - time::U32Ext, + time::ms, timer::{Tim2NoRemap, Timer}, }; @@ -52,7 +52,7 @@ fn main() -> ! { // let c4 = gpiob.pb9.into_alternate_push_pull(&mut gpiob.crh); let mut pwm = - Timer::new(p.TIM2, &clocks).pwm::(pins, &mut afio.mapr, 1.khz()); + Timer::new(p.TIM2, &clocks).pwm::(pins, &mut afio.mapr, 1.kHz()); // Enable clock on each of the channels pwm.enable(Channel::C1); @@ -62,12 +62,12 @@ fn main() -> ! { //// Operations affecting all defined channels on the Timer // Adjust period to 0.5 seconds - pwm.set_period(500.ms()); + pwm.set_period(ms(500).into_rate()); asm::bkpt(); // Return to the original frequency - pwm.set_period(1.khz()); + pwm.set_period(1.kHz()); asm::bkpt(); diff --git a/examples/pwm_custom.rs b/examples/pwm_custom.rs index 85e93741..ada0209c 100644 --- a/examples/pwm_custom.rs +++ b/examples/pwm_custom.rs @@ -30,7 +30,7 @@ fn main() -> ! { let p0 = pb4.into_alternate_push_pull(&mut gpiob.crl); let p1 = gpiob.pb5.into_alternate_push_pull(&mut gpiob.crl); - let pwm = Timer::new(p.TIM3, &clocks).pwm((p0, p1), &mut afio.mapr, 1.khz()); + let pwm = Timer::new(p.TIM3, &clocks).pwm((p0, p1), &mut afio.mapr, 1.kHz()); let max = pwm.get_max_duty(); diff --git a/examples/pwm_input.rs b/examples/pwm_input.rs index 1d8f9dce..7b48d933 100644 --- a/examples/pwm_input.rs +++ b/examples/pwm_input.rs @@ -31,7 +31,7 @@ fn main() -> ! { (pb4, pb5), &mut afio.mapr, &mut dbg, - Configuration::Frequency(10.khz()), + Configuration::Frequency(10.kHz()), ); loop { diff --git a/examples/spi-dma.rs b/examples/spi-dma.rs index 1a803fb7..e4245efe 100644 --- a/examples/spi-dma.rs +++ b/examples/spi-dma.rs @@ -40,7 +40,7 @@ fn main() -> ! { polarity: Polarity::IdleLow, phase: Phase::CaptureOnFirstTransition, }; - let spi = Spi::spi2(dp.SPI2, pins, spi_mode, 100.khz(), clocks); + let spi = Spi::spi2(dp.SPI2, pins, spi_mode, 100.kHz(), clocks); // Set up the DMA device let dma = dp.DMA1.split(); diff --git a/examples/spi.rs b/examples/spi.rs index 030ba008..e5335181 100644 --- a/examples/spi.rs +++ b/examples/spi.rs @@ -45,7 +45,7 @@ fn setup() -> ( (sck, miso, mosi), &mut afio.mapr, MODE, - 1_u32.mhz(), + 1.MHz(), clocks, ); diff --git a/examples/timer-interrupt-rtic.rs b/examples/timer-interrupt-rtic.rs index 204ce091..c2cb85fd 100644 --- a/examples/timer-interrupt-rtic.rs +++ b/examples/timer-interrupt-rtic.rs @@ -49,7 +49,7 @@ mod app { .pc13 .into_push_pull_output_with_state(&mut gpioc.crh, PinState::High); // Configure the syst timer to trigger an update every second and enables interrupt - let mut timer = Timer::new(cx.device.TIM1, &clocks).start_count_down(1.hz()); + let mut timer = Timer::new(cx.device.TIM1, &clocks).start_count_down(1.Hz()); timer.listen(Event::Update); // Init the static resources to use them later through RTIC @@ -93,9 +93,9 @@ mod app { if *cx.local.count == 4 { // Changes timer update frequency - cx.local.timer_handler.start(2.hz()); + cx.local.timer_handler.start(2.Hz()); } else if *cx.local.count == 12 { - cx.local.timer_handler.start(1.hz()); + cx.local.timer_handler.start(1.Hz()); *cx.local.count = 0; } diff --git a/examples/usb_serial.rs b/examples/usb_serial.rs index 3f2f8824..0de920fe 100644 --- a/examples/usb_serial.rs +++ b/examples/usb_serial.rs @@ -27,9 +27,9 @@ fn main() -> ! { let clocks = rcc .cfgr - .use_hse(8.mhz()) - .sysclk(48.mhz()) - .pclk1(24.mhz()) + .use_hse(8.MHz()) + .sysclk(48.MHz()) + .pclk1(24.MHz()) .freeze(&mut flash.acr); assert!(clocks.usbclk_valid()); @@ -47,7 +47,7 @@ fn main() -> ! { // will not reset your device when you upload new firmware. let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh); usb_dp.set_low(); - delay(clocks.sysclk().0 / 100); + delay(clocks.sysclk().raw() / 100); let usb = Peripheral { usb: dp.USB, diff --git a/examples/usb_serial_interrupt.rs b/examples/usb_serial_interrupt.rs index a891d453..102b9f82 100644 --- a/examples/usb_serial_interrupt.rs +++ b/examples/usb_serial_interrupt.rs @@ -26,9 +26,9 @@ fn main() -> ! { let clocks = rcc .cfgr - .use_hse(8.mhz()) - .sysclk(48.mhz()) - .pclk1(24.mhz()) + .use_hse(8.MHz()) + .sysclk(48.MHz()) + .pclk1(24.MHz()) .freeze(&mut flash.acr); assert!(clocks.usbclk_valid()); @@ -41,7 +41,7 @@ fn main() -> ! { // will not reset your device when you upload new firmware. let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh); usb_dp.set_low(); - delay(clocks.sysclk().0 / 100); + delay(clocks.sysclk().raw() / 100); let usb_dm = gpioa.pa11; let usb_dp = usb_dp.into_floating_input(&mut gpioa.crh); diff --git a/examples/usb_serial_rtic.rs b/examples/usb_serial_rtic.rs index b32b1590..48b8506c 100644 --- a/examples/usb_serial_rtic.rs +++ b/examples/usb_serial_rtic.rs @@ -31,9 +31,9 @@ mod app { let clocks = rcc .cfgr - .use_hse(8.mhz()) - .sysclk(48.mhz()) - .pclk1(24.mhz()) + .use_hse(8.MHz()) + .sysclk(48.MHz()) + .pclk1(24.MHz()) .freeze(&mut flash.acr); assert!(clocks.usbclk_valid()); @@ -46,7 +46,7 @@ mod app { // will not reset your device when you upload new firmware. let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh); usb_dp.set_low(); - delay(clocks.sysclk().0 / 100); + delay(clocks.sysclk().raw() / 100); let usb_dm = gpioa.pa11; let usb_dp = usb_dp.into_floating_input(&mut gpioa.crh); diff --git a/src/adc.rs b/src/adc.rs index e94ae159..816e0e65 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -11,6 +11,7 @@ use crate::gpio::gpiof; use crate::gpio::Analog; use crate::gpio::{gpioa, gpiob, gpioc}; use crate::rcc::{Clocks, Enable, Reset}; +use crate::time::kHz; use core::sync::atomic::{self, Ordering}; use cortex_m::asm::delay; use embedded_dma::StaticWriteBuffer; @@ -205,9 +206,9 @@ macro_rules! adc_hal { // The manual states that we need to wait two ADC clocks cycles after power-up // before starting calibration, we already delayed in the power-up process, but // if the adc clock is too low that was not enough. - if s.clocks.adcclk().0 < 2_500_000 { - let two_adc_cycles = s.clocks.sysclk().0 / s.clocks.adcclk().0 *2; - let already_delayed = s.clocks.sysclk().0 / 800_000; + if s.clocks.adcclk() < kHz(2500) { + let two_adc_cycles = s.clocks.sysclk() / s.clocks.adcclk() * 2; + let already_delayed = s.clocks.sysclk() / kHz(800); if two_adc_cycles > already_delayed { delay(two_adc_cycles - already_delayed); } @@ -269,7 +270,7 @@ macro_rules! adc_hal { // this time can be found in the datasheets. // Here we are delaying for approximately 1us, considering 1.25 instructions per // cycle. Do we support a chip which needs more than 1us ? - delay(self.clocks.sysclk().0 / 800_000); + delay(self.clocks.sysclk() / kHz(800)); } fn power_down(&mut self) { @@ -469,7 +470,7 @@ impl Adc { // sensor, this time can be found in the datasheets. // Here we are delaying for approximately 10us, considering 1.25 instructions per // cycle. Do we support a chip which needs more than 10us ? - delay(self.clocks.sysclk().0 / 80_000); + delay(self.clocks.sysclk().raw() / 80_000); true } else { false @@ -509,7 +510,7 @@ impl Adc { // recommended ADC sampling for temperature sensor is 17.1 usec, // so use the following approximate settings // to support all ADC frequencies - let sample_time = match self.clocks.adcclk().0 { + let sample_time = match self.clocks.adcclk().raw() { 0..=1_200_000 => SampleTime::T_1, 1_200_001..=1_500_000 => SampleTime::T_7, 1_500_001..=2_400_000 => SampleTime::T_13, diff --git a/src/delay.rs b/src/delay.rs index 1ecc50a7..94257cd5 100644 --- a/src/delay.rs +++ b/src/delay.rs @@ -1,6 +1,5 @@ //! # Delays -use cast::u32; use cortex_m::peripheral::syst::SystClkSource; use cortex_m::peripheral::SYST; @@ -35,13 +34,13 @@ impl DelayMs for Delay { impl DelayMs for Delay { fn delay_ms(&mut self, ms: u16) { - self.delay_ms(u32(ms)); + self.delay_ms(ms as u32); } } impl DelayMs for Delay { fn delay_ms(&mut self, ms: u8) { - self.delay_ms(u32(ms)); + self.delay_ms(ms as u32); } } @@ -50,7 +49,7 @@ impl DelayUs for Delay { // The SysTick Reload Value register supports values between 1 and 0x00FFFFFF. const MAX_RVR: u32 = 0x00FF_FFFF; - let mut total_rvr = us * (self.clocks.sysclk().0 / 1_000_000); + let mut total_rvr = us * (self.clocks.sysclk().raw() / 1_000_000); while total_rvr != 0 { let current_rvr = if total_rvr <= MAX_RVR { @@ -75,12 +74,12 @@ impl DelayUs for Delay { impl DelayUs for Delay { fn delay_us(&mut self, us: u16) { - self.delay_us(u32(us)) + self.delay_us(us as u32) } } impl DelayUs for Delay { fn delay_us(&mut self, us: u8) { - self.delay_us(u32(us)) + self.delay_us(us as u32) } } diff --git a/src/dma.rs b/src/dma.rs index f930e24b..857e8781 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -122,7 +122,7 @@ macro_rules! dma { }),)+) => { $( pub mod $dmaX { - use core::{sync::atomic::{self, Ordering}, ptr, mem}; + use core::{sync::atomic::{self, Ordering}, ptr, mem, convert::TryFrom}; use crate::pac::{RCC, $DMAX, dma1}; @@ -157,7 +157,7 @@ macro_rules! dma { /// Number of bytes to transfer pub fn set_transfer_length(&mut self, len: usize) { - self.ch().ndtr.write(|w| w.ndt().bits(cast::u16(len).unwrap())); + self.ch().ndtr.write(|w| w.ndt().bits(u16::try_from(len).unwrap())); } /// Starts the DMA transfer diff --git a/src/i2c.rs b/src/i2c.rs index 295a5529..9fe03af8 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -10,7 +10,7 @@ use crate::gpio::{Alternate, OpenDrain}; use crate::hal::blocking::i2c::{Read, Write, WriteRead}; use crate::pac::{DWT, I2C1, I2C2, RCC}; use crate::rcc::{BusClock, Clocks, Enable, Reset}; -use crate::time::Hertz; +use crate::time::{kHz, Hertz}; use core::ops::Deref; use nb::Error::{Other, WouldBlock}; use nb::{Error as NbError, Result as NbResult}; @@ -53,15 +53,13 @@ pub enum Mode { } impl Mode { - pub fn standard>(frequency: F) -> Self { - Mode::Standard { - frequency: frequency.into(), - } + pub fn standard(frequency: Hertz) -> Self { + Mode::Standard { frequency } } - pub fn fast>(frequency: F, duty_cycle: DutyCycle) -> Self { + pub fn fast(frequency: Hertz, duty_cycle: DutyCycle) -> Self { Mode::Fast { - frequency: frequency.into(), + frequency, duty_cycle, } } @@ -74,13 +72,9 @@ impl Mode { } } -impl From for Mode -where - F: Into, -{ - fn from(frequency: F) -> Self { - let frequency: Hertz = frequency.into(); - if frequency.0 <= 100_000 { +impl From for Mode { + fn from(frequency: Hertz) -> Self { + if frequency <= kHz(100) { Self::Standard { frequency } } else { Self::Fast { @@ -113,7 +107,7 @@ pub struct I2c { i2c: I2C, pins: PINS, mode: Mode, - pclk1: u32, + pclk1: Hertz, } pub trait Instance: @@ -162,9 +156,9 @@ where I2C::enable(rcc); I2C::reset(rcc); - let pclk1 = I2C::clock(&clocks).0; + let pclk1 = I2C::clock(&clocks); - assert!(mode.get_frequency().0 <= 400_000); + assert!(mode.get_frequency() <= kHz(400)); let mut i2c = I2c { i2c, @@ -185,7 +179,7 @@ where /// according to the system frequency and I2C mode. fn init(&mut self) { let freq = self.mode.get_frequency(); - let pclk1_mhz = (self.pclk1 / 1000000) as u16; + let pclk1_mhz = self.pclk1.to_MHz() as u16; self.i2c .cr2 @@ -197,9 +191,9 @@ where self.i2c .trise .write(|w| w.trise().bits((pclk1_mhz + 1) as u8)); - self.i2c.ccr.write(|w| unsafe { - w.ccr().bits(((self.pclk1 / (freq.0 * 2)) as u16).max(4)) - }); + self.i2c + .ccr + .write(|w| unsafe { w.ccr().bits(((self.pclk1 / (freq * 2)) as u16).max(4)) }); } Mode::Fast { ref duty_cycle, .. } => { self.i2c @@ -208,12 +202,8 @@ where self.i2c.ccr.write(|w| { let (freq, duty) = match duty_cycle { - DutyCycle::Ratio2to1 => { - (((self.pclk1 / (freq.0 * 3)) as u16).max(1), false) - } - DutyCycle::Ratio16to9 => { - (((self.pclk1 / (freq.0 * 25)) as u16).max(1), true) - } + DutyCycle::Ratio2to1 => (((self.pclk1 / (freq * 3)) as u16).max(1), false), + DutyCycle::Ratio16to9 => (((self.pclk1 / (freq * 25)) as u16).max(1), true), }; unsafe { w.ccr().bits(freq).duty().bit(duty).f_s().set_bit() } diff --git a/src/i2c/blocking.rs b/src/i2c/blocking.rs index 801b8658..c0fbcf10 100644 --- a/src/i2c/blocking.rs +++ b/src/i2c/blocking.rs @@ -87,7 +87,7 @@ impl I2c { data_timeout_us: u32, clocks: Clocks, ) -> BlockingI2c { - let sysclk_mhz = clocks.sysclk().0 / 1_000_000; + let sysclk_mhz = clocks.sysclk().to_MHz(); BlockingI2c { nb: self, start_retries, @@ -99,7 +99,7 @@ impl I2c { } } pub fn blocking_default(self, clocks: Clocks) -> BlockingI2c { - let sysclk_mhz = clocks.sysclk().0 / 1_000_000; + let sysclk_mhz = clocks.sysclk().to_MHz(); BlockingI2c { nb: self, start_retries: 10, diff --git a/src/prelude.rs b/src/prelude.rs index 05c353e1..4ca3cd74 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -14,3 +14,5 @@ pub use crate::hal::digital::v2::ToggleableOutputPin as _embedded_hal_digital_To pub use crate::hal::prelude::*; pub use crate::rcc::RccExt as _stm32_hal_rcc_RccExt; pub use crate::time::U32Ext as _stm32_hal_time_U32Ext; +pub use fugit::ExtU32 as _fugit_ExtU32; +pub use fugit::RateExtU32 as _fugit_RateExtU32; diff --git a/src/pwm.rs b/src/pwm.rs index db29ee42..af6fe19e 100644 --- a/src/pwm.rs +++ b/src/pwm.rs @@ -62,14 +62,13 @@ use crate::pac::TIM1; #[cfg(feature = "medium")] use crate::pac::TIM4; use crate::pac::{TIM2, TIM3}; -use cast::{u16, u32}; use crate::afio::MAPR; use crate::bb; use crate::gpio::{self, Alternate}; -use crate::time::Hertz; -use crate::time::U32Ext; use crate::timer::Timer; +use core::convert::TryFrom; +use fugit::HertzU32 as Hertz; pub trait Pins { const C1: bool = false; @@ -141,16 +140,15 @@ pins_impl!( #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] impl Timer { - pub fn pwm( + pub fn pwm( self, _pins: PINS, mapr: &mut MAPR, - freq: T, + freq: Hertz, ) -> Pwm where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) }); @@ -159,65 +157,62 @@ impl Timer { self.tim.bdtr.modify(|_, w| w.aoe().set_bit()); let Self { tim, clk } = self; - tim1(tim, _pins, freq.into(), clk) + tim1(tim, _pins, freq, clk) } } impl Timer { - pub fn pwm( + pub fn pwm( self, _pins: PINS, mapr: &mut MAPR, - freq: T, + freq: Hertz, ) -> Pwm where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) }); let Self { tim, clk } = self; - tim2(tim, _pins, freq.into(), clk) + tim2(tim, _pins, freq, clk) } } impl Timer { - pub fn pwm( + pub fn pwm( self, _pins: PINS, mapr: &mut MAPR, - freq: T, + freq: Hertz, ) -> Pwm where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) }); let Self { tim, clk } = self; - tim3(tim, _pins, freq.into(), clk) + tim3(tim, _pins, freq, clk) } } #[cfg(feature = "medium")] impl Timer { - pub fn pwm( + pub fn pwm( self, _pins: PINS, mapr: &mut MAPR, - freq: T, + freq: Hertz, ) -> Pwm where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1)); let Self { tim, clk } = self; - tim4(tim, _pins, freq.into(), clk) + tim4(tim, _pins, freq, clk) } } @@ -282,10 +277,10 @@ macro_rules! hal { tim.ccmr2_output() .modify(|_, w| w.oc4pe().set_bit().oc4m().pwm_mode1() ); } - let ticks = clk.0 / freq.0; - let psc = u16(ticks / (1 << 16)).unwrap(); + let ticks = clk / freq; + let psc = u16::try_from(ticks / (1 << 16)).unwrap(); tim.psc.write(|w| w.psc().bits(psc) ); - let arr = u16(ticks / u32(psc + 1)).unwrap(); + let arr = u16::try_from(ticks / (psc + 1) as u32).unwrap(); tim.arr.write(|w| w.arr().bits(arr)); // The psc register is buffered, so we trigger an update event to update it @@ -378,16 +373,16 @@ macro_rules! hal { let arr: u16 = unsafe{(*$TIMX::ptr()).arr.read().arr().bits()}; // Length in ms of an internal clock pulse - (clk.0 / u32(psc * arr)).hz() + (clk / (psc * arr) as u32) } fn set_period(&mut self, period: T) where T: Into { let clk = self.clk; - let ticks = clk.0 / period.into().0; - let psc = u16(ticks / (1 << 16)).unwrap(); - let arr = u16(ticks / u32(psc + 1)).unwrap(); + let ticks = clk / period.into(); + let psc = u16::try_from(ticks / (1 << 16)).unwrap(); + let arr = u16::try_from(ticks / (psc + 1) as u32).unwrap(); unsafe { (*$TIMX::ptr()).psc.write(|w| w.psc().bits(psc)); (*$TIMX::ptr()).arr.write(|w| w.arr().bits(arr)); diff --git a/src/pwm_input.rs b/src/pwm_input.rs index f35db817..17fb3648 100644 --- a/src/pwm_input.rs +++ b/src/pwm_input.rs @@ -53,10 +53,7 @@ pub enum Error { } /// Which frequency the timer will try to sample -pub enum Configuration -where - T: Into, -{ +pub enum Configuration { /// In this mode an algorithm calculates the optimal value for the autoreload register and the /// prescaler register in order to be able to sample a wide range of frequency, at the expense /// of resolution. @@ -64,19 +61,19 @@ where /// The minimum frequency that can be sampled is 20% the provided frequency. /// /// Use this mode if you do not know what to choose. - Frequency(T), + Frequency(Hertz), /// In this mode an algorithm calculates the optimal value for the autoreload register and the /// prescaler register in order to sample the duty cycle with a high resolution. /// This will limit the frequency range where the timer can operate. /// /// The minimum frequency that can be sampled is 90% the provided frequency - DutyCycle(T), + DutyCycle(Hertz), /// In this mode an algorithm calculates the optimal value for the autoreload register and the /// prescaler register in order to be able to sample signal with a frequency higher than the /// provided value : there is no margin for lower frequencies. - RawFrequency(T), + RawFrequency(Hertz), /// In this mode, the provided arr and presc are directly programmed in the register. RawValues { arr: u16, presc: u16 }, @@ -84,17 +81,16 @@ where #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, - mode: Configuration, + mode: Configuration, ) -> PwmInput where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) }); self.stop_in_debug(dbg, false); @@ -104,17 +100,16 @@ impl Timer { } impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, - mode: Configuration, + mode: Configuration, ) -> PwmInput where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) }); self.stop_in_debug(dbg, false); @@ -124,17 +119,16 @@ impl Timer { } impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, - mode: Configuration, + mode: Configuration, ) -> PwmInput where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) }); self.stop_in_debug(dbg, false); @@ -145,17 +139,16 @@ impl Timer { #[cfg(feature = "medium")] impl Timer { - pub fn pwm_input( + pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, - mode: Configuration, + mode: Configuration, ) -> PwmInput where REMAP: Remap, PINS: Pins, - T: Into, { mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1)); self.stop_in_debug(dbg, false); @@ -176,16 +169,15 @@ fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u16) { macro_rules! hal { ($($TIMX:ident: ($timX:ident),)+) => { $( - fn $timX( + fn $timX( tim: $TIMX, _pins: PINS, clk: Hertz, - mode : Configuration, + mode : Configuration, ) -> PwmInput<$TIMX, REMAP, PINS> where REMAP: Remap, PINS: Pins, - T : Into { use crate::pwm_input::Configuration::*; // Disable capture on both channels during setting @@ -210,22 +202,22 @@ macro_rules! hal { match mode { Frequency(f) => { - let freq = f.into().0; + let freq = f.raw(); let max_freq = if freq > 5 {freq/5} else {1}; - let (arr,presc) = compute_arr_presc(max_freq, clk.0); + let (arr,presc) = compute_arr_presc(max_freq, clk.raw()); tim.arr.write(|w| w.arr().bits(arr)); tim.psc.write(|w| w.psc().bits(presc) ); }, DutyCycle(f) => { - let freq = f.into().0; + let freq = f.raw(); let max_freq = if freq > 2 {freq/2 + freq/4 + freq/8} else {1}; - let (arr,presc) = compute_arr_presc(max_freq, clk.0); + let (arr,presc) = compute_arr_presc(max_freq, clk.raw()); tim.arr.write(|w| w.arr().bits(arr)); tim.psc.write(|w| w.psc().bits(presc) ); }, RawFrequency(f) => { - let freq = f.into().0; - let (arr,presc) = compute_arr_presc(freq, clk.0); + let freq = f.raw(); + let (arr,presc) = compute_arr_presc(freq, clk.raw()); tim.arr.write(|w| w.arr().bits(arr)); tim.psc.write(|w| w.psc().bits(presc) ); } @@ -273,8 +265,8 @@ macro_rules! hal { if ccr1 == 0 { Err(Error::FrequencyTooLow) } else { - let clk : u32 = <$TIMX>::timer_clock(&clocks).0; - Ok(Hertz(clk/((presc+1) as u32*(ccr1 + 1)as u32))) + let clk = <$TIMX>::timer_clock(&clocks); + Ok(clk/((presc+1) as u32*(ccr1 + 1)as u32)) } } diff --git a/src/rcc.rs b/src/rcc.rs index f6469b2a..2834dfa0 100644 --- a/src/rcc.rs +++ b/src/rcc.rs @@ -3,7 +3,8 @@ use crate::pac::{rcc, PWR, RCC}; use crate::flash::ACR; -use crate::time::Hertz; +use crate::time::MHz; +use fugit::{HertzU32 as Hertz, RateExtU32}; use crate::backup_domain::BackupDomain; @@ -120,61 +121,43 @@ impl CFGR { /// Will result in a hang if an external oscillator is not connected or it fails to start. /// The frequency specified must be the frequency of the external oscillator #[inline(always)] - pub fn use_hse(mut self, freq: F) -> Self - where - F: Into, - { - self.hse = Some(freq.into().0); + pub fn use_hse(mut self, freq: Hertz) -> Self { + self.hse = Some(freq.raw()); self } /// Sets the desired frequency for the HCLK clock #[inline(always)] - pub fn hclk(mut self, freq: F) -> Self - where - F: Into, - { - self.hclk = Some(freq.into().0); + pub fn hclk(mut self, freq: Hertz) -> Self { + self.hclk = Some(freq.raw()); self } /// Sets the desired frequency for the PCKL1 clock #[inline(always)] - pub fn pclk1(mut self, freq: F) -> Self - where - F: Into, - { - self.pclk1 = Some(freq.into().0); + pub fn pclk1(mut self, freq: Hertz) -> Self { + self.pclk1 = Some(freq.raw()); self } /// Sets the desired frequency for the PCLK2 clock #[inline(always)] - pub fn pclk2(mut self, freq: F) -> Self - where - F: Into, - { - self.pclk2 = Some(freq.into().0); + pub fn pclk2(mut self, freq: Hertz) -> Self { + self.pclk2 = Some(freq.raw()); self } /// Sets the desired frequency for the SYSCLK clock #[inline(always)] - pub fn sysclk(mut self, freq: F) -> Self - where - F: Into, - { - self.sysclk = Some(freq.into().0); + pub fn sysclk(mut self, freq: Hertz) -> Self { + self.sysclk = Some(freq.raw()); self } /// Sets the desired frequency for the ADCCLK clock #[inline(always)] - pub fn adcclk(mut self, freq: F) -> Self - where - F: Into, - { - self.adcclk = Some(freq.into().0); + pub fn adcclk(mut self, freq: Hertz) -> Self { + self.adcclk = Some(freq.raw()); self } @@ -209,9 +192,9 @@ impl CFGR { #[cfg(any(feature = "stm32f103", feature = "connectivity"))] unsafe { acr.acr().write(|w| { - w.latency().bits(if clocks.sysclk.0 <= 24_000_000 { + w.latency().bits(if clocks.sysclk <= MHz(24) { 0b000 - } else if clocks.sysclk.0 <= 48_000_000 { + } else if clocks.sysclk <= MHz(48) { 0b001 } else { 0b010 @@ -381,12 +364,12 @@ impl Clocks { /// Returns the frequency of the APB1 Timers pub const fn pclk1_tim(&self) -> Hertz { - Hertz(self.pclk1.0 * if self.ppre1() == 1 { 1 } else { 2 }) + Hertz::from_raw(self.pclk1.raw() * if self.ppre1() == 1 { 1 } else { 2 }) } /// Returns the frequency of the APB2 Timers pub const fn pclk2_tim(&self) -> Hertz { - Hertz(self.pclk2.0 * if self.ppre2() == 1 { 1 } else { 2 }) + Hertz::from_raw(self.pclk2.raw() * if self.ppre2() == 1 { 1 } else { 2 }) } pub(crate) const fn ppre1(&self) -> u8 { @@ -723,13 +706,13 @@ impl Config { ); Clocks { - hclk: Hertz(hclk), - pclk1: Hertz(pclk1), - pclk2: Hertz(pclk2), + hclk: hclk.Hz(), + pclk1: pclk1.Hz(), + pclk2: pclk2.Hz(), ppre1, ppre2, - sysclk: Hertz(sysclk), - adcclk: Hertz(adcclk), + sysclk: sysclk.Hz(), + adcclk: adcclk.Hz(), #[cfg(any(feature = "stm32f103", feature = "connectivity"))] usbclk_valid, } @@ -740,9 +723,9 @@ impl Config { fn rcc_config_usb() { use crate::time::U32Ext; let cfgr = CFGR::default() - .use_hse(8.mhz()) - .sysclk(48.mhz()) - .pclk1(24.mhz()); + .use_hse(8.MHz()) + .sysclk(48.MHz()) + .pclk1(24.MHz()); let config = Config::from_cfgr(cfgr); let config_expected = Config { @@ -759,13 +742,13 @@ fn rcc_config_usb() { let clocks = config.get_clocks(); let clocks_expected = Clocks { - hclk: 48.mhz().into(), - pclk1: 24.mhz().into(), - pclk2: 48.mhz().into(), + hclk: 48.MHz(), + pclk1: 24.MHz(), + pclk2: 48.MHz(), ppre1: 2, ppre2: 1, - sysclk: 48.mhz().into(), - adcclk: 6.mhz().into(), + sysclk: 48.MHz(), + adcclk: 6.MHz(), #[cfg(any(feature = "stm32f103", feature = "connectivity"))] usbclk_valid: true, }; diff --git a/src/rtc.rs b/src/rtc.rs index 6f0d25ef..85a398d1 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -4,14 +4,14 @@ use crate::pac::{RCC, RTC}; use crate::backup_domain::BackupDomain; -use crate::time::Hertz; +use crate::time::{Hertz, Hz}; use core::convert::Infallible; use core::marker::PhantomData; // The LSE runs at at 32 768 hertz unless an external clock is provided -const LSE_HERTZ: u32 = 32_768; -const LSI_HERTZ: u32 = 40_000; +const LSE_HERTZ: Hertz = Hz(32_768); +const LSI_HERTZ: Hertz = Hz(40_000); /// RTC clock source HSE clock divided by 128 (type state) pub struct RtcClkHseDiv128; @@ -62,7 +62,7 @@ impl Rtc { Self::enable_rtc(bkp); // Set the prescaler to make it count up once every second. - let prl = LSE_HERTZ - 1; + let prl = LSE_HERTZ.raw() - 1; assert!(prl < 1 << 20); result.perform_write(|s| { s.regs.prlh.write(|w| unsafe { w.bits(prl >> 16) }); @@ -102,7 +102,7 @@ impl Rtc { Self::enable_rtc(bkp); // Set the prescaler to make it count up once every second. - let prl = LSI_HERTZ - 1; + let prl = LSI_HERTZ.raw() - 1; assert!(prl < 1 << 20); result.perform_write(|s| { s.regs.prlh.write(|w| unsafe { w.bits(prl >> 16) }); @@ -136,10 +136,7 @@ impl Rtc { } impl Rtc { - pub fn new_hse(regs: RTC, bkp: &mut BackupDomain, hse: F) -> Self - where - F: Into, - { + pub fn new_hse(regs: RTC, bkp: &mut BackupDomain, hse: Hertz) -> Self { let mut result = Rtc { regs, _clock_source: PhantomData, @@ -148,7 +145,7 @@ impl Rtc { Self::enable_rtc(bkp); // Set the prescaler to make it count up once every second. - let prl = hse.into().0 / 128 - 1; + let prl = hse.raw() / 128 - 1; assert!(prl < 1 << 20); result.perform_write(|s| { s.regs.prlh.write(|w| unsafe { w.bits(prl >> 16) }); @@ -181,9 +178,7 @@ impl Rtc { impl Rtc { /// Selects the frequency of the RTC Timer /// NOTE: Maximum frequency of 16384 Hz using the internal LSE - pub fn select_frequency(&mut self, timeout: impl Into) { - let frequency = timeout.into().0; - + pub fn select_frequency(&mut self, frequency: Hertz) { // The manual says that the zero value for the prescaler is not recommended, thus the // minimum division factor is 2 (prescaler + 1) assert!(frequency <= LSE_HERTZ / 2); diff --git a/src/serial.rs b/src/serial.rs index 62073ba2..5575063b 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -315,7 +315,7 @@ where fn apply_config(&self, config: Config, clocks: Clocks) { // Configure baud rate - let brr = USART::clock(&clocks).0 / config.baudrate.0; + let brr = USART::clock(&clocks).raw() / config.baudrate.0; assert!(brr >= 16, "impossible baud rate"); self.usart.brr.write(|w| unsafe { w.bits(brr) }); diff --git a/src/spi.rs b/src/spi.rs index 0e35737c..a18691f6 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -159,21 +159,20 @@ impl Spi { You can also use `NoSck`, `NoMiso` or `NoMosi` if you don't want to use the pins */ - pub fn spi1( + pub fn spi1( spi: SPI1, pins: PINS, mapr: &mut MAPR, mode: Mode, - freq: F, + freq: Hertz, clocks: Clocks, ) -> Self where - F: Into, REMAP: Remap, PINS: Pins, { mapr.modify_mapr(|_, w| w.spi1_remap().bit(REMAP::REMAP)); - Spi::::configure(spi, pins, mode, freq.into(), clocks) + Spi::::configure(spi, pins, mode, freq, clocks) } } @@ -185,13 +184,12 @@ impl Spi { You can also use `NoSck`, `NoMiso` or `NoMosi` if you don't want to use the pins */ - pub fn spi2(spi: SPI2, pins: PINS, mode: Mode, freq: F, clocks: Clocks) -> Self + pub fn spi2(spi: SPI2, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self where - F: Into, REMAP: Remap, PINS: Pins, { - Spi::::configure(spi, pins, mode, freq.into(), clocks) + Spi::::configure(spi, pins, mode, freq, clocks) } } @@ -205,13 +203,12 @@ impl Spi { You can also use `NoSck`, `NoMiso` or `NoMosi` if you don't want to use the pins */ #[cfg(not(feature = "connectivity"))] - pub fn spi3(spi: SPI3, pins: PINS, mode: Mode, freq: F, clocks: Clocks) -> Self + pub fn spi3(spi: SPI3, pins: PINS, mode: Mode, freq: Hertz, clocks: Clocks) -> Self where - F: Into, REMAP: Remap, PINS: Pins, { - Spi::::configure(spi, pins, mode, freq.into(), clocks) + Spi::::configure(spi, pins, mode, freq, clocks) } /** @@ -222,21 +219,20 @@ impl Spi { You can also use `NoSck`, `NoMiso` or `NoMosi` if you don't want to use the pins */ #[cfg(feature = "connectivity")] - pub fn spi3( + pub fn spi3( spi: SPI3, pins: PINS, mapr: &mut MAPR, mode: Mode, - freq: F, + freq: Hertz, clocks: Clocks, ) -> Self where - F: Into, REMAP: Remap, PINS: Pins, { mapr.modify_mapr(|_, w| w.spi3_remap().bit(REMAP::REMAP)); - Spi::::configure(spi, pins, mode, freq.into(), clocks) + Spi::::configure(spi, pins, mode, freq, clocks) } } @@ -342,7 +338,7 @@ where // disable SS output spi.cr2.write(|w| w.ssoe().clear_bit()); - let br = match SPI::clock(&clocks).0 / freq.0 { + let br = match SPI::clock(&clocks) / freq { 0 => unreachable!(), 1..=2 => 0b000, 3..=5 => 0b001, diff --git a/src/time.rs b/src/time.rs index 35ff32b8..02531a06 100644 --- a/src/time.rs +++ b/src/time.rs @@ -2,7 +2,7 @@ //! //! See [`Hertz`], [`KiloHertz`] and [`MegaHertz`] for creating increasingly higher frequencies. //! -//! The [`U32Ext`] trait adds various methods like `.hz()`, `.mhz()`, etc to the `u32` primitive type, +//! The [`fugit::ExtU32`] [`U32Ext`] trait adds various methods like `.Hz()`, `.MHz()`, etc to the `u32` primitive type, //! allowing it to be converted into frequencies. //! //! # Examples @@ -10,7 +10,7 @@ //! ## Create a 2 MHz frequency //! //! This example demonstrates various ways of creating a 2 MHz (2_000_000 Hz) frequency. They are -//! all equivalent, however the `2.mhz()` variant should be preferred for readability. +//! all equivalent, however the `2.MHz()` variant should be preferred for readability. //! //! ```rust //! use stm32f1xx_hal::{ @@ -19,14 +19,16 @@ //! prelude::*, //! }; //! -//! let freq_hz = 2_000_000.hz(); -//! let freq_khz = 2_000.khz(); -//! let freq_mhz = 2.mhz(); +//! let freq_hz = 2_000_000.Hz(); +//! let freq_khz = 2_000.kHz(); +//! let freq_mhz = 2.MHz(); //! //! assert_eq!(freq_hz, freq_khz); //! assert_eq!(freq_khz, freq_mhz); //! ``` +#![allow(non_snake_case)] + use core::ops; use cortex_m::peripheral::{DCB, DWT}; @@ -36,150 +38,41 @@ use crate::rcc::Clocks; #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] pub struct Bps(pub u32); -/// Hertz -/// -/// Create a frequency specified in [Hertz](https://en.wikipedia.org/wiki/Hertz). -/// -/// See also [`KiloHertz`] and [`MegaHertz`] for semantically correct ways of creating higher -/// frequencies. -/// -/// # Examples -/// -/// ## Create an 60 Hz frequency -/// -/// ```rust -/// use stm32f1xx_hal::time::Hertz; -/// -/// let freq = 60.hz(); -/// ``` -#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] -pub struct Hertz(pub u32); - -/// Kilohertz -/// -/// Create a frequency specified in kilohertz. -/// -/// See also [`Hertz`] and [`MegaHertz`] for semantically correct ways of creating lower or higher -/// frequencies. -/// -/// # Examples -/// -/// ## Create a 100 Khz frequency -/// -/// This example creates a 100 KHz frequency. This could be used to set an I2C data rate or PWM -/// frequency, etc. -/// -/// ```rust -/// use stm32f1xx_hal::time::Hertz; -/// -/// let freq = 100.khz(); -/// ``` -#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] -pub struct KiloHertz(pub u32); - -/// Megahertz -/// -/// Create a frequency specified in megahertz. -/// -/// See also [`Hertz`] and [`KiloHertz`] for semantically correct ways of creating lower -/// frequencies. -/// -/// # Examples -/// -/// ## Create a an 8 MHz frequency -/// -/// This example creates an 8 MHz frequency that could be used to configure an SPI peripheral, etc. -/// -/// ```rust -/// use stm32f1xx_hal::time::Hertz; -/// -/// let freq = 8.mhz(); -/// ``` -#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] -pub struct MegaHertz(pub u32); - -/// Time unit -#[derive(PartialEq, PartialOrd, Clone, Copy)] -pub struct MilliSeconds(pub u32); - -#[derive(PartialEq, PartialOrd, Clone, Copy)] -pub struct MicroSeconds(pub u32); +pub use fugit::{ + HertzU32 as Hertz, KilohertzU32 as KiloHertz, MegahertzU32 as MegaHertz, + MicrosDurationU32 as MicroSeconds, MillisDurationU32 as MilliSeconds, +}; /// Extension trait that adds convenience methods to the `u32` type pub trait U32Ext { /// Wrap in `Bps` fn bps(self) -> Bps; - - /// Wrap in `Hertz` - fn hz(self) -> Hertz; - - /// Wrap in `KiloHertz` - fn khz(self) -> KiloHertz; - - /// Wrap in `MegaHertz` - fn mhz(self) -> MegaHertz; - - /// Wrap in `MilliSeconds` - fn ms(self) -> MilliSeconds; - - /// Wrap in `MicroSeconds` - fn us(self) -> MicroSeconds; } impl U32Ext for u32 { fn bps(self) -> Bps { Bps(self) } - - fn hz(self) -> Hertz { - Hertz(self) - } - - fn khz(self) -> KiloHertz { - KiloHertz(self) - } - - fn mhz(self) -> MegaHertz { - MegaHertz(self) - } - - fn ms(self) -> MilliSeconds { - MilliSeconds(self) - } - - fn us(self) -> MicroSeconds { - MicroSeconds(self) - } } -impl From for Hertz { - fn from(val: KiloHertz) -> Self { - Self(val.0 * 1_000) - } +pub const fn Hz(val: u32) -> Hertz { + Hertz::from_raw(val) } -impl From for Hertz { - fn from(val: MegaHertz) -> Self { - Self(val.0 * 1_000_000) - } +pub const fn kHz(val: u32) -> KiloHertz { + KiloHertz::from_raw(val) } -impl From for KiloHertz { - fn from(val: MegaHertz) -> Self { - Self(val.0 * 1_000) - } +pub const fn MHz(val: u32) -> MegaHertz { + MegaHertz::from_raw(val) } -impl From for Hertz { - fn from(val: MilliSeconds) -> Self { - Self(1_000 / val.0) - } +pub const fn ms(val: u32) -> MilliSeconds { + MilliSeconds::from_ticks(val) } -impl From for Hertz { - fn from(val: MicroSeconds) -> Self { - Self(1_000_000 / val.0) - } +pub const fn us(val: u32) -> MicroSeconds { + MicroSeconds::from_ticks(val) } /// Macro to implement arithmetic operations (e.g. multiplication, division) @@ -221,9 +114,6 @@ macro_rules! impl_arithmetic { }; } -impl_arithmetic!(Hertz, u32); -impl_arithmetic!(KiloHertz, u32); -impl_arithmetic!(MegaHertz, u32); impl_arithmetic!(Bps, u32); /// A monotonic non-decreasing timer diff --git a/src/timer.rs b/src/timer.rs index 46ee70a9..86ad2457 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -69,7 +69,7 @@ use crate::pac::{DBGMCU as DBG, TIM2, TIM3}; use crate::pac::{TIM15, TIM16, TIM17}; use crate::rcc::{self, Clocks}; -use cast::{u16, u32, u64}; +use core::convert::TryFrom; use cortex_m::peripheral::syst::SystClkSource; use cortex_m::peripheral::SYST; use void::Void; @@ -175,10 +175,7 @@ impl Timer { } } - pub fn start_count_down(self, timeout: T) -> CountDownTimer - where - T: Into, - { + pub fn start_count_down(self, timeout: Hertz) -> CountDownTimer { let Self { tim, clk } = self; let mut timer = CountDownTimer { tim, clk }; timer.start(timeout); @@ -217,12 +214,12 @@ impl CountDownTimer { /// it is very easy to lose an update event. pub fn micros_since(&self) -> u32 { let reload_value = SYST::get_reload(); - let timer_clock = u64(self.clk.0); - let ticks = u64(reload_value - SYST::get_current()); + let timer_clock = self.clk.raw() as u64; + let ticks = (reload_value - SYST::get_current()) as u64; // It is safe to make this cast since the maximum ticks is (2^24 - 1) and the minimum sysclk // is 4Mhz, which gives a maximum period of ~4.2 seconds which is < (2^32 - 1) microseconds - u32(1_000_000 * ticks / timer_clock).unwrap() + u32::try_from(1_000_000 * ticks / timer_clock).unwrap() } /// Stops the timer @@ -245,7 +242,7 @@ impl CountDown for CountDownTimer { where T: Into, { - let rvr = self.clk.0 / timeout.into().0 - 1; + let rvr = self.clk / timeout.into() - 1; assert!(rvr < (1 << 24)); @@ -325,10 +322,7 @@ macro_rules! hal { } /// Starts timer in count down mode at a given frequency - pub fn start_count_down(self, timeout: T) -> CountDownTimer<$TIMX> - where - T: Into, - { + pub fn start_count_down(self, timeout: Hertz) -> CountDownTimer<$TIMX> { let Self { tim, clk } = self; let mut timer = CountDownTimer { tim, clk }; timer.start(timeout); @@ -337,10 +331,7 @@ macro_rules! hal { $( /// Starts timer in count down mode at a given frequency and additionally configures the timers master mode - pub fn start_master(self, timeout: T, mode: crate::pac::$master_timbase::cr2::MMS_A) -> CountDownTimer<$TIMX> - where - T: Into, - { + pub fn start_master(self, timeout: Hertz, mode: crate::pac::$master_timbase::cr2::MMS_A) -> CountDownTimer<$TIMX> { let Self { tim, clk } = self; let mut timer = CountDownTimer { tim, clk }; timer.tim.cr2.modify(|_,w| w.mms().variant(mode)); @@ -435,17 +426,17 @@ macro_rules! hal { /// *NOTE:* This method is not a very good candidate to keep track of time, because /// it is very easy to lose an update event. pub fn micros_since(&self) -> u32 { - let timer_clock = self.clk.0; - let psc = u32(self.tim.psc.read().psc().bits()); + let timer_clock = self.clk.raw(); + let psc = self.tim.psc.read().psc().bits() as u32; // freq_divider is always bigger than 0, since (psc + 1) is always less than // timer_clock - let freq_divider = u64(timer_clock / (psc + 1)); - let cnt = u64(self.tim.cnt.read().cnt().bits()); + let freq_divider = (timer_clock / (psc + 1)) as u64; + let cnt = self.tim.cnt.read().cnt().bits() as u64; // It is safe to make this cast, because the maximum timer period in this HAL is // 1s (1Hz), then 1 second < (2^32 - 1) microseconds - u32(1_000_000 * cnt / freq_divider).unwrap() + u32::try_from(1_000_000 * cnt / freq_divider).unwrap() } /// Resets the counter @@ -466,7 +457,7 @@ macro_rules! hal { where T: Into, { - let (psc, arr) = compute_arr_presc(timeout.into().0, self.clk.0); + let (psc, arr) = compute_arr_presc(timeout.into().raw(), self.clk.raw()); self.restart_raw(psc, arr); } @@ -504,8 +495,8 @@ macro_rules! hal { #[inline(always)] fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u16) { let ticks = clock / freq; - let psc = u16((ticks - 1) / (1 << 16)).unwrap(); - let arr = u16(ticks / u32(psc + 1)).unwrap(); + let psc = u16::try_from((ticks - 1) / (1 << 16)).unwrap(); + let arr = u16::try_from(ticks / (psc + 1) as u32).unwrap(); (psc, arr) } diff --git a/src/watchdog.rs b/src/watchdog.rs index f1bf3888..da553b7c 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -5,6 +5,7 @@ use crate::{ pac::{DBGMCU as DBG, IWDG}, time::MilliSeconds, }; +use fugit::ExtU32; /// Wraps the Independent Watchdog (IWDG) peripheral pub struct IndependentWatchdog { @@ -56,7 +57,7 @@ impl IndependentWatchdog { let pr = self.iwdg.pr.read().pr().bits(); let rl = self.iwdg.rlr.read().rl().bits(); let ms = Self::timeout_period(pr, rl); - MilliSeconds(ms) + ms.millis() } /// pr: Prescaler divider bits, rl: reload value @@ -86,20 +87,28 @@ impl IndependentWatchdog { self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_RELOAD) }); a } + + pub fn start(&mut self, period: MilliSeconds) { + self.setup(period.ticks()); + + self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_START) }); + } + + pub fn feed(&mut self) { + self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_RELOAD) }); + } } impl WatchdogEnable for IndependentWatchdog { type Time = MilliSeconds; fn start>(&mut self, period: T) { - self.setup(period.into().0); - - self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_START) }); + self.start(period.into()); } } impl Watchdog for IndependentWatchdog { fn feed(&mut self) { - self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_RELOAD) }); + self.feed(); } }