diff --git a/.gdbinit b/.gdbinit index 85aae410edf40562cf3261c60d80015e13638ff8..e308fae8802f3e7b80a63e4a9d8b2b9278573125 100644 --- a/.gdbinit +++ b/.gdbinit @@ -1,18 +1,19 @@ target remote :3333 -monitor arm semihosting enable +monitor reset halt +# monitor arm semihosting enable # # send captured ITM to the file itm.fifo # # (the microcontroller SWO pin must be connected to the programmer SWO pin) # # 8000000 must match the core clock frequency -# monitor tpiu config internal itm.fifo uart off 8000000 +monitor tpiu config internal itm.fifo uart off 16000000 # # OR: make the microcontroller SWO pin output compatible with UART (8N1) # # 2000000 is the frequency of the SWO pin # monitor tpiu config external uart off 8000000 2000000 # # enable ITM port 0 -# monitor itm port 0 on +monitor itm port 0 on load # step diff --git a/examples/blinky.rs b/examples/blinky.rs index 8e45401609f70db4f7723908b24d7d5fdeeeebe1..fdf857e26f99a8079d61c1e8cf344065086a80bb 100644 --- a/examples/blinky.rs +++ b/examples/blinky.rs @@ -4,9 +4,9 @@ #![feature(proc_macro)] #![no_std] -extern crate f4; extern crate cortex_m; extern crate cortex_m_rtfm as rtfm; +extern crate f4; use cortex_m::peripheral::SystClkSource; use f4::led::{self, LED}; diff --git a/examples/capture4.rs b/examples/capture4.rs new file mode 100644 index 0000000000000000000000000000000000000000..108fb4ff5b6f3c56eddec9f7871c5adf3c2b7170 --- /dev/null +++ b/examples/capture4.rs @@ -0,0 +1,57 @@ +//! Input capture using TIM4 +#![deny(unsafe_code)] +#![deny(warnings)] +#![feature(proc_macro)] +#![no_std] + +#[macro_use] +extern crate cortex_m; +extern crate cortex_m_rtfm as rtfm; +extern crate f4; +extern crate nb; + +use f4::time::Milliseconds; +use f4::{Capture, Channel}; +use f4::prelude::*; +use rtfm::{app, Threshold}; + +const RESOLUTION: Milliseconds = Milliseconds(1); + +app! { + device: f4::stm32f40x, + + idle: { + resources: [ITM, TIM4], + }, +} + +fn init(p: init::Peripherals) { + let capture = Capture(p.TIM4); + + capture.init(RESOLUTION, p.GPIOA, p.GPIOB, p.GPIOC, p.RCC); +} + +fn idle(_t: &mut Threshold, r: idle::Resources) -> ! { + const CHANNELS: [Channel; 4] = [Channel::_1, Channel::_2, Channel::_3, Channel::_4]; + + let capture = Capture(&*r.TIM4); + + for c in &CHANNELS { + capture.enable(*c); + } + + loop { + for c in &CHANNELS { + match capture.capture(*c) { + Ok(snapshot) => { + iprintln!(&r.ITM.stim[0], "{:?}: {:?} ms", c, snapshot); + } + Err(nb::Error::WouldBlock) => {} + Err(nb::Error::Other(e)) => { + iprintln!(&r.ITM.stim[0], "{:?}: {:?}", c, e); + panic!("{:?}", e); + } + } + } + } +} diff --git a/examples/preemption.rs b/examples/preemption.rs index 62e7d3623f2b5c693ea20c19fb845f55a260554f..bf374acdb057d7fa3a2272f02888960f2cf71447 100644 --- a/examples/preemption.rs +++ b/examples/preemption.rs @@ -21,7 +21,7 @@ extern crate heapless; use cast::{usize, u8}; use cortex_m::peripheral::SystClkSource; use f4::Serial; -use f4::leds::{LEDS}; +use f4::leds::LEDS; use f4::prelude::*; use f4::serial::Event; use heapless::Vec; @@ -96,14 +96,14 @@ fn receive(t: &mut Threshold, mut r: USART2::Resources) { match &***r.BUFFER { b"bounce" => { - r.SHARED - .claim_mut(t, |shared, _| { shared.mode = Mode::Bounce; }); + r.SHARED.claim_mut(t, |shared, _| { + shared.mode = Mode::Bounce; + }); } b"continuous" => { - r.SHARED.claim_mut( - t, - |shared, _| { shared.mode = Mode::Continuous; }, - ); + r.SHARED.claim_mut(t, |shared, _| { + shared.mode = Mode::Continuous; + }); } b"reverse" => { r.SHARED.claim_mut(t, |shared, _| { diff --git a/examples/pwm-control.rs b/examples/pwm-control.rs index 8f3a4ccb0ba75a93b87a64bfde6ef7b9d87d0160..391d51f12d30da66694685f400899a929091f63f 100644 --- a/examples/pwm-control.rs +++ b/examples/pwm-control.rs @@ -9,8 +9,8 @@ #![feature(proc_macro)] #![no_std] -extern crate f4; extern crate cortex_m_rtfm as rtfm; +extern crate f4; use core::u32; @@ -87,4 +87,4 @@ fn rx(_t: &mut Threshold, r: USART2::Resources) { } _ => {} } -} \ No newline at end of file +} diff --git a/examples/pwm1.rs b/examples/pwm1.rs index 60ca459dd83fa5325ed000dd73349035c7351e40..2b45f300a6b858bdc54be4af357decbceeb20c28 100644 --- a/examples/pwm1.rs +++ b/examples/pwm1.rs @@ -6,8 +6,8 @@ #![feature(proc_macro)] #![no_std] -extern crate f4; extern crate cortex_m_rtfm as rtfm; +extern crate f4; use f4::prelude::*; use f4::time::Hertz; @@ -23,7 +23,7 @@ app! { fn init(p: init::Peripherals) { let pwm = Pwm(p.TIM1); - pwm.init(FREQUENCY.invert(), None, p.GPIOA,p.GPIOB,p.GPIOC, p.RCC); + pwm.init(FREQUENCY.invert(), None, p.GPIOA, p.GPIOB, p.GPIOC, p.RCC); let duty = pwm.get_max_duty() / 16; const CHANNELS: [Channel; 4] = [Channel::_1, Channel::_2, Channel::_3, Channel::_4]; diff --git a/examples/resource.rs b/examples/resource.rs index 51127fd1dfd39b253f8afd7031c00ae7821d0c98..1e3356d3ed4a6f0a7893d135c59fe225fb939426 100644 --- a/examples/resource.rs +++ b/examples/resource.rs @@ -24,7 +24,7 @@ extern crate heapless; use cast::{usize, u8}; use cortex_m::peripheral::SystClkSource; use f4::Serial; -use f4::leds::{LEDS}; +use f4::leds::LEDS; use f4::prelude::*; use f4::serial::Event; use f4::time::Hertz; @@ -33,7 +33,7 @@ use rtfm::{app, Threshold}; // CONFIGURATION const BAUD_RATE: Hertz = Hertz(115_200); -const DIVISOR: u32 = 4; +const DIVISOR: u32 = 4; // TASKS & RESOURCES app! { diff --git a/examples/roulette.rs b/examples/roulette.rs index 1d090a2347680a21a5fb90b03791366604bf0a97..d866334a00ffd33c95c0d85eee102bf30de3c3ef 100644 --- a/examples/roulette.rs +++ b/examples/roulette.rs @@ -5,13 +5,13 @@ #![no_std] extern crate cast; -extern crate f4; extern crate cortex_m; extern crate cortex_m_rtfm as rtfm; +extern crate f4; use cast::{usize, u8}; use cortex_m::peripheral::SystClkSource; -use f4::leds::{LEDS}; +use f4::leds::LEDS; use rtfm::{app, Threshold}; // CONFIGURATION diff --git a/src/capture.rs b/src/capture.rs new file mode 100644 index 0000000000000000000000000000000000000000..94cdfc2c07096eef7417e76f49276b057580b13e --- /dev/null +++ b/src/capture.rs @@ -0,0 +1,380 @@ +//! Input capture interface +//! +//! You can use the `Capture` interface with these TIM instances: +//! +//! # TIM1 +//! +//! - CH1 = PA8 (5V tolerant) +//! - CH2 = PA9 (5V tolerant) +//! - CH3 = PA10 (5V tolerant) +//! - CH4 = PA11 (5V tolerant) +//! +//! # TIM2 +//! +//! - CH1 = PA0 +//! - CH2 = PA1 +//! - CH3 = PB10 +//! - CH4 = PA3 (Unimplemented: conflicts with USB USART2_RX) +//! +//! # TIM3 +//! +//! - CH1 = PA6 +//! - CH2 = PA7 +//! - CH3 = PB0 +//! - CH4 = PB1 +//! +//! **WARNING** Do not use channels 3 and 4 with the `Capture.capture` API or +//! you'll get junk values. +//! +//! # TIM4 +//! +//! - CH1 = PB6 (5V tolerant) +//! - CH2 = PB7 (5V tolerant) +//! - CH3 = PB8 (5V tolerant) +//! - CH4 = PB9 (5V tolerant) + +use core::any::{Any, TypeId}; +use core::u32; + +use cast::{u16, u32}; +use hal; +use nb; +use stm32f40x::{TIM1, TIM2, TIM3, TIM4, GPIOA, GPIOB, GPIOC, RCC}; + +use timer::Channel; + +/// Input / capture error +#[derive(Debug)] +pub enum Error { + /// Previous capture value was overwritten + Overcapture, + #[doc(hidden)] _Extensible, +} + +/// Interrupt event +pub enum Event { + /// Capture on channel 1 + Capture1, + /// Capture on channel 2 + Capture2, + /// Capture on channel 3 + Capture3, + /// Capture on channel 4 + Capture4, +} + +/// Input capture interface +pub struct Capture<'a, T>(pub &'a T) +where + T: 'a; + +impl<'a, T> Clone for Capture<'a, T> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a, T> Copy for Capture<'a, T> {} + +// TODO: TIM1 is a 16 bit timer, must have its own implementation + +macro_rules! impl_Capture { + ($TIM:ident, $APB:ident) => { + impl<'a> Capture<'a, $TIM> + { + /// Initializes the input capture interface + /// + /// `resolution` is the resolution of the capture timer + pub fn init<R>( + &self, + resolution: R, + gpioa: &GPIOA, // TODO: Make these optional/implement custom init for each TIM + gpiob: &GPIOB, + gpioc: &GPIOC, + rcc: &RCC) + where + R: Into<::$APB::Ticks>, + { + self._init(resolution.into(), gpioa, gpiob, gpioc, rcc) + } + + fn _init( + &self, + resolution: ::$APB::Ticks, + gpioa: &GPIOA, + gpiob: &GPIOB, + gpioc: &GPIOC, + rcc: &RCC) { + let tim = self.0; + + if tim.get_type_id() == TypeId::of::<TIM2>() { + rcc.apb1enr.modify(|_, w| w.tim2en().set_bit()); + } else if tim.get_type_id() == TypeId::of::<TIM3>() { + rcc.apb1enr.modify(|_, w| w.tim3en().set_bit()); + } else if tim.get_type_id() == TypeId::of::<TIM4>() { + rcc.apb1enr.modify(|_, w| w.tim4en().set_bit()); + } + + // enable AFIO, GPIOx and TIMx + rcc.ahb1enr.modify(|_, w| { + if tim.get_type_id() == TypeId::of::<TIM2>() { + w.gpioaen().set_bit().gpioben().set_bit() + } else if tim.get_type_id() == TypeId::of::<TIM3>() { + w.gpioaen().set_bit().gpioben().set_bit().gpiocen().set_bit() + } else if tim.get_type_id() == TypeId::of::<TIM4>() { + w.gpioben().set_bit() + } else { + unreachable!() + } + }); + + // don't remap TIM pins + if tim.get_type_id() == TypeId::of::<TIM2>() { + // CH1 = PA0 = floating input + // CH2 = PA1 = floating input + // CH3 = PB10 = floating input + // CH4 = PA3 = floating input (Unimplemented: conflicts with USB USART2_RX) + + // See datasheet DM00115249 Table 9. Alternate function mapping + gpioa.afrl.modify(|_, w| { + w.afrl0().bits(1) + .afrl1().bits(1) + }); + gpioa.moder.modify(|_, w| { + w.moder0().bits(2) + .moder1().bits(2) + }); + gpiob.afrh.modify(|_, w| { unsafe { + w.afrh10().bits(1) + }}); + gpiob.moder.modify(|_, w| { unsafe { + w.moder10().bits(2) + }}); + } else if tim.get_type_id() == TypeId::of::<TIM3>() { + // CH1 = PA6 = floating input + // CH2 = PC7 = floating input + // CH3 = PB0 = floating input + // CH4 = PB1 = floating input + gpioa.afrl.modify(|_, w| { + w.afrl6().bits(2) + }); + gpioa.moder.modify(|_, w| { + w.moder6().bits(2) + }); + gpiob.afrl.modify(|_, w| { unsafe { + w.afrl0().bits(2) + .afrl1().bits(2) + }}); + gpiob.moder.modify(|_, w| { unsafe { + w.moder0().bits(2) + .moder1().bits(2) + }}); + gpioc.afrl.modify(|_, w| { unsafe { + w.afrl7().bits(2) + }}); + gpioc.moder.modify(|_, w| { unsafe { + w.moder7().bits(2) + }}); + } else if tim.get_type_id() == TypeId::of::<TIM4>() { + // CH1 = PB6 = alternate push-pull + // CH2 = PB7 = alternate push-pull + // CH3 = PB8 = alternate push-pull + // CH4 = PB9 = alternate push-pull + gpiob.afrl.modify(|_, w| { unsafe { + w.afrl6().bits(2) + .afrl7().bits(2) + } + }); + gpiob.moder.modify(|_, w| { unsafe { + w.moder6().bits(2) + .moder7().bits(2) + } + }); + gpiob.afrh.modify(|_, w| { unsafe { + w.afrh8().bits(2) + .afrh9().bits(2) + } + }); + gpiob.moder.modify(|_, w| { unsafe { + w.moder8().bits(2) + .moder9().bits(2) + } + }); + gpiob.pupdr.modify(|_, w| { unsafe { + w.pupdr6().bits(2) + .pupdr7().bits(2) + .pupdr8().bits(2) + .pupdr9().bits(2) + } + }); + } + + tim.smcr.write(|w| unsafe { + w.bits(3) + }); + // configure CC{1,2,3,4} as input and wire it to TI{1,2,3,4} + // apply the heaviest filter + tim.ccmr1_output.write(|w| unsafe { + w.bits((0b1111 << 12) | (0b01 << 8) | (0b1111 << 4) | (0b01 << 0)) + }); + // if tim.get_type_id() != TypeId::of::<TIM3>() { + // tim.ccmr2_output.write(|w| unsafe { + // w.bits(0) + // }); + // } + + // enable capture on rising edge + // capture pins disabled by default + if tim.get_type_id() == TypeId::of::<TIM2>() { + tim.ccer.modify(|_, w| { + w.cc1p() + .clear_bit() + .cc1e() + .clear_bit() + .cc2p() + .clear_bit() + .cc2e() + .clear_bit() + .cc3p() + .clear_bit() + .cc3e() + .clear_bit() + }); + } else { + tim.ccer.modify(|_, w| { + w.cc1p() + .clear_bit() + .cc1e() + .clear_bit() + .cc2p() + .clear_bit() + .cc2e() + .clear_bit() + .cc3p() + .clear_bit() + .cc3e() + .clear_bit() + .cc4p() + .clear_bit() + .cc4e() + .clear_bit() + }); + } + + self._set_resolution(resolution); + + tim.arr.write(|w| unsafe{ w.bits(u32::MAX) }); + + // configure timer as a continuous upcounter and start + tim.cr1.write(|w| w.dir().bit(false).opm().bit(false).cen().set_bit()); + } + + /// Starts listening for an interrupt `event` + pub fn listen(&self, event: Event) { + let tim = self.0; + + match event { + Event::Capture1 => tim.dier.modify(|_, w| w.cc1ie().set_bit()), + Event::Capture2 => tim.dier.modify(|_, w| w.cc2ie().set_bit()), + Event::Capture3 => tim.dier.modify(|_, w| w.cc3ie().set_bit()), + Event::Capture4 => tim.dier.modify(|_, w| w.cc4ie().set_bit()), + } + } + + /// Stops listening for an interrupt `event` + pub fn unlisten(&self, event: Event) { + let tim = self.0; + + match event { + Event::Capture1 => tim.dier.modify(|_, w| w.cc1ie().clear_bit()), + Event::Capture2 => tim.dier.modify(|_, w| w.cc2ie().clear_bit()), + Event::Capture3 => tim.dier.modify(|_, w| w.cc3ie().clear_bit()), + Event::Capture4 => tim.dier.modify(|_, w| w.cc4ie().clear_bit()), + } + } + + fn _set_resolution(&self, resolution: ::$APB::Ticks) { + let psc = resolution.0.checked_sub(1).expect("impossible resolution"); + + self.0.psc.write(|w| unsafe{ w.bits(psc)}); + } + } + + impl<'a> hal::Capture for Capture<'a, $TIM> + { + type Capture = u32; + type Channel = Channel; + type Error = Error; + type Time = ::$APB::Ticks; + + fn capture(&self, channel: Channel) -> nb::Result<u32, Error> { + let tim = self.0; + let sr = tim.sr.read(); + + match channel { + Channel::_1 => if sr.cc1of().bit_is_set() { + Err(nb::Error::Other(Error::Overcapture)) + } else if sr.cc1if().bit_is_set() { + Ok(tim.ccr1.read().bits()) + } else { + Err(nb::Error::WouldBlock) + }, + Channel::_2 => if sr.cc2of().bit_is_set() { + Err(nb::Error::Other(Error::Overcapture)) + } else if sr.cc2if().bit_is_set() { + Ok(tim.ccr2.read().bits()) + } else { + Err(nb::Error::WouldBlock) + }, + Channel::_3 => if sr.cc3of().bit_is_set() { + Err(nb::Error::Other(Error::Overcapture)) + } else if sr.cc3if().bit_is_set() { + Ok(tim.ccr3.read().bits()) + } else { + Err(nb::Error::WouldBlock) + }, + Channel::_4 => if sr.cc4of().bit_is_set() { + Err(nb::Error::Other(Error::Overcapture)) + } else if sr.cc4if().bit_is_set() { + Ok(tim.ccr4.read().bits()) + } else { + Err(nb::Error::WouldBlock) + }, + } + } + + fn disable(&self, channel: Channel) { + match channel { + Channel::_1 => self.0.ccer.modify(|_, w| w.cc1e().clear_bit()), + Channel::_2 => self.0.ccer.modify(|_, w| w.cc2e().clear_bit()), + Channel::_3 => self.0.ccer.modify(|_, w| w.cc3e().clear_bit()), + Channel::_4 => self.0.ccer.modify(|_, w| w.cc4e().clear_bit()), + } + } + + fn enable(&self, channel: Channel) { + match channel { + Channel::_1 => self.0.ccer.modify(|_, w| w.cc1e().set_bit()), + Channel::_2 => self.0.ccer.modify(|_, w| w.cc2e().set_bit()), + Channel::_3 => self.0.ccer.modify(|_, w| w.cc3e().set_bit()), + Channel::_4 => self.0.ccer.modify(|_, w| w.cc4e().set_bit()), + } + } + + fn get_resolution(&self) -> ::$APB::Ticks { + ::$APB::Ticks(u32(self.0.psc.read().psc().bits())) + } + + fn set_resolution<R>(&self, resolution: R) + where + R: Into<::$APB::Ticks>, + { + self._set_resolution(resolution.into()) + } + } + } +} + +impl_Capture!(TIM2, apb1); +impl_Capture!(TIM3, apb1); +impl_Capture!(TIM4, apb1); diff --git a/src/dma.rs b/src/dma.rs index 443f41cc54dbc4c6cc0aa560175ba741223b6008..5e0f9aec1f6d7b0a7444ee0e4a23eadf40c1ad49 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -381,4 +381,4 @@ impl<B> CircBuffer<B, Dma1Channel1> { } } } -} \ No newline at end of file +} diff --git a/src/examples/_0_hello.rs b/src/examples/_0_hello.rs index 7656cc60b00b178297993ffb72ad7e50c25f1c90..b3fa8a7c83c777cbc4855ea010f71defdcf5177b 100644 --- a/src/examples/_0_hello.rs +++ b/src/examples/_0_hello.rs @@ -5,28 +5,28 @@ //! #![deny(warnings)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate cortex_m_rtfm as rtfm; //! extern crate cortex_m_semihosting as semihosting; //! extern crate f4; -//! +//! //! use core::fmt::Write; -//! +//! //! use rtfm::app; //! use semihosting::hio; -//! +//! //! // TASKS & RESOURCES //! app! { //! device: f4::stm32f40x, //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(_p: init::Peripherals) {} -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! writeln!(hio::hstdout().unwrap(), "Hello, world!").unwrap(); -//! +//! //! loop { //! rtfm::wfi(); //! } diff --git a/src/examples/_1_itm.rs b/src/examples/_1_itm.rs index a5b687ba6d01905867ea6fd7a009e8f7a60a1bf3..46f7bd8a5481f3c97935a535d435a8a760eb4199 100644 --- a/src/examples/_1_itm.rs +++ b/src/examples/_1_itm.rs @@ -10,32 +10,32 @@ //! #![deny(warnings)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! #[macro_use] //! extern crate cortex_m; //! extern crate cortex_m_rtfm as rtfm; //! extern crate f4; -//! +//! //! use rtfm::{app, Threshold}; -//! +//! //! // TASK & RESOURCES //! app! { //! device: f4::stm32f40x, -//! +//! //! idle: { //! resources: [ITM], //! }, //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals) { //! iprintln!(&p.ITM.stim[0], "Hello"); //! } -//! +//! //! // IDLE LOOP //! fn idle(_t: &mut Threshold, r: idle::Resources) -> ! { //! iprintln!(&r.ITM.stim[0], "World"); -//! +//! //! // Sleep //! loop { //! rtfm::wfi(); diff --git a/src/examples/_2_led.rs b/src/examples/_2_led.rs index e5ee63663478ec8551b4b296566ce42494a64ba0..b058f6173f477d2da15ee4eb3be5bd15408d3c38 100644 --- a/src/examples/_2_led.rs +++ b/src/examples/_2_led.rs @@ -5,29 +5,29 @@ //! #![deny(warnings)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate cortex_m_rtfm as rtfm; //! extern crate f4; -//! +//! //! use f4::led::{self, LEDS}; //! use rtfm::app; -//! +//! //! // TASKS & RESOURCES //! app! { //! device: f4::stm32f40x, //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals) { //! led::init(&p.GPIOA, &p.RCC); //! } -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! for led in &LEDS { //! led.on(); //! } -//! +//! //! // Sleep //! loop { //! rtfm::wfi(); diff --git a/src/examples/_3_blinky.rs b/src/examples/_3_blinky.rs index 932aa2f72e2a2e466d61c51936738714df88fe37..4ecbfd489838c52ed5da263c1926b76ed367e9b4 100644 --- a/src/examples/_3_blinky.rs +++ b/src/examples/_3_blinky.rs @@ -5,26 +5,26 @@ //! #![deny(warnings)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate f4; //! extern crate cortex_m; //! extern crate cortex_m_rtfm as rtfm; -//! +//! //! use cortex_m::peripheral::SystClkSource; //! use f4::led::{self, LEDS}; //! use rtfm::{app, Threshold}; -//! +//! //! // CONFIGURATION //! const FREQUENCY: u32 = 4; // Hz -//! +//! //! // TASKS & RESOURCES //! app! { //! device: f4::stm32f40x, -//! +//! //! resources: { //! static ON: bool = false; //! }, -//! +//! //! tasks: { //! SYS_TICK: { //! path: toggle, @@ -32,17 +32,17 @@ //! }, //! }, //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals, _r: init::Resources) { //! led::init(p.GPIOA, p.RCC); -//! +//! //! p.SYST.set_clock_source(SystClkSource::Core); //! p.SYST.set_reload(16_000_000 / FREQUENCY); //! p.SYST.enable_interrupt(); //! p.SYST.enable_counter(); //! } -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! // Sleep @@ -50,12 +50,12 @@ //! rtfm::wfi(); //! } //! } -//! +//! //! // TASKS //! // Toggle the state of the LED //! fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) { //! **r.ON = !**r.ON; -//! +//! //! if **r.ON { //! LEDS[0].on(); //! } else { diff --git a/src/examples/_4_roulette.rs b/src/examples/_4_roulette.rs index 9cfce2a5fb4dcb0ac4c7df33d44eab189d0d544f..076b1e11642dd4ce382462332e1ac36d60e9ba00 100644 --- a/src/examples/_4_roulette.rs +++ b/src/examples/_4_roulette.rs @@ -5,28 +5,28 @@ //! #![deny(warnings)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate cast; //! extern crate f4; //! extern crate cortex_m; //! extern crate cortex_m_rtfm as rtfm; -//! +//! //! use cast::{usize, u8}; //! use cortex_m::peripheral::SystClkSource; //! use f4::led::{self, LEDS}; //! use rtfm::{app, Threshold}; -//! +//! //! // CONFIGURATION //! const DIVISOR: u32 = 4; -//! +//! //! // TASKS & RESOURCES //! app! { //! device: f4::stm32f40x, -//! +//! //! resources: { //! static STATE: u8 = 0; //! }, -//! +//! //! tasks: { //! SYS_TICK: { //! path: roulette, @@ -34,17 +34,17 @@ //! }, //! }, //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals, _r: init::Resources) { //! led::init(p.GPIOA, p.RCC); -//! +//! //! p.SYST.set_clock_source(SystClkSource::Core); //! p.SYST.set_reload(16_000_000 / DIVISOR); //! p.SYST.enable_interrupt(); //! p.SYST.enable_counter(); //! } -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! // Sleep @@ -52,15 +52,15 @@ //! rtfm::wfi(); //! } //! } -//! +//! //! // TASKS //! fn roulette(_t: &mut Threshold, r: SYS_TICK::Resources) { //! let curr = **r.STATE; //! let next = (curr + 1) % u8(LEDS.len()).unwrap(); -//! +//! //! LEDS[usize(curr)].off(); //! LEDS[usize(next)].on(); -//! +//! //! **r.STATE = next; //! } //! ``` diff --git a/src/examples/_5_loopback.rs b/src/examples/_5_loopback.rs index 3bede5e9908d43813302d3dbd19bd2eaa5818570..aa111a334da1484c3d7ab54a782ad3b7efa3ce4d 100644 --- a/src/examples/_5_loopback.rs +++ b/src/examples/_5_loopback.rs @@ -5,23 +5,23 @@ //! #![deny(warnings)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate cortex_m_rtfm as rtfm; //! extern crate f4; -//! +//! //! use f4::prelude::*; //! use f4::Serial; //! use f4::serial::Event; //! use f4::time::Hertz; //! use rtfm::{app, Threshold}; -//! +//! //! // CONFIGURATION //! const BAUD_RATE: Hertz = Hertz(115_200); -//! +//! //! // TASKS & RESOURCES //! app! { //! device: f4::stm32f40x, -//! +//! //! tasks: { //! USART2: { //! path: loopback, @@ -29,15 +29,15 @@ //! }, //! } //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals) { //! let serial = Serial(p.USART2); -//! +//! //! serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); //! serial.listen(Event::Rxne); //! } -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! // Sleep @@ -45,12 +45,12 @@ //! rtfm::wfi(); //! } //! } -//! +//! //! // TASKS //! // Send back the received byte //! fn loopback(_t: &mut Threshold, r: USART2::Resources) { //! let serial = Serial(&**r.USART2); -//! +//! //! let byte = serial.read().unwrap(); //! serial.write(byte).unwrap(); //! } diff --git a/src/examples/_6_concurrency.rs b/src/examples/_6_concurrency.rs index bb61b4c882b197f899f812832901c15adad4d859..bae72b26ec3cf791350318862ef7a6575914e011 100644 --- a/src/examples/_6_concurrency.rs +++ b/src/examples/_6_concurrency.rs @@ -5,12 +5,12 @@ //! #![deny(warnings)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate cast; //! extern crate cortex_m; //! extern crate cortex_m_rtfm as rtfm; //! extern crate f4; -//! +//! //! use f4::Serial; //! use f4::led::{self, LEDS}; //! use f4::prelude::*; @@ -19,47 +19,47 @@ //! use cortex_m::peripheral::SystClkSource; //! use cast::{usize, u8}; //! use rtfm::{app, Threshold}; -//! +//! //! // CONFIGURATION //! const BAUD_RATE: Hertz = Hertz(115_200); //! const DIVISOR: u32 = 4; -//! -//! +//! +//! //! // TASKS & RESOURCES //! app! { //! device: f4::stm32f40x, -//! +//! //! resources: { //! static STATE: u8 = 0; //! }, -//! +//! //! tasks: { //! SYS_TICK: { //! path: roulette, //! resources: [STATE], //! }, -//! +//! //! USART2: { //! path: loopback, //! resources: [USART2], //! }, //! } //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals, _r: init::Resources) { //! led::init(p.GPIOA, p.RCC); -//! +//! //! let serial = Serial(p.USART2); //! serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); //! serial.listen(Event::Rxne); -//! +//! //! p.SYST.set_clock_source(SystClkSource::Core); //! p.SYST.set_reload(16_000_000 / DIVISOR); //! p.SYST.enable_interrupt(); //! p.SYST.enable_counter(); //! } -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! // Sleep @@ -67,11 +67,11 @@ //! rtfm::wfi(); //! } //! } -//! +//! //! // TASKS //! fn loopback(_t: &mut Threshold, r: USART2::Resources) { //! let serial = Serial(&**r.USART2); -//! +//! //! if let Ok(byte) = serial.read() { //! if serial.write(byte).is_err() { //! // As we are echoing the bytes as soon as they arrive, it should @@ -85,14 +85,14 @@ //! unreachable!() //! } //! } -//! +//! //! fn roulette(_t: &mut Threshold, r: SYS_TICK::Resources) { //! let curr = **r.STATE; //! let next = (curr + 1) % u8(LEDS.len()).unwrap(); -//! +//! //! LEDS[usize(curr)].off(); //! LEDS[usize(next)].on(); -//! +//! //! **r.STATE = next; //! } //! ``` diff --git a/src/examples/_7_resource.rs b/src/examples/_7_resource.rs index 98b87186a50e406f51c88fec5b4c266c987e3fa4..19c674e391ff8c7e9a49528d543004c13098ac9b 100644 --- a/src/examples/_7_resource.rs +++ b/src/examples/_7_resource.rs @@ -16,13 +16,13 @@ //! #![feature(const_fn)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate cast; //! extern crate cortex_m; //! extern crate cortex_m_rtfm as rtfm; //! extern crate f4; //! extern crate heapless; -//! +//! //! use cast::{usize, u8}; //! use cortex_m::peripheral::SystClkSource; //! use f4::Serial; @@ -32,50 +32,50 @@ //! use f4::time::Hertz; //! use heapless::Vec; //! use rtfm::{app, Threshold}; -//! +//! //! // CONFIGURATION //! const BAUD_RATE: Hertz = Hertz(115_200); -//! const DIVISOR: u32 = 4; -//! +//! const DIVISOR: u32 = 4; +//! //! // TASKS & RESOURCES //! app! { //! device: f4::stm32f40x, -//! +//! //! resources: { //! // 16 byte buffer //! static BUFFER: Vec<u8, [u8; 16]> = Vec::new([0; 16]); //! static SHARED: State = State::new(); //! static STATE: u8 = 0; //! }, -//! +//! //! tasks: { //! USART2: { //! path: receive, //! resources: [BUFFER, SHARED, USART2], //! }, -//! +//! //! SYS_TICK: { //! path: roulette, //! resources: [SHARED, STATE], //! }, //! } //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals, _r: init::Resources) { //! led::init(&p.GPIOA, &p.RCC); -//! +//! //! let serial = Serial(p.USART2); //! serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); //! serial.listen(Event::Rxne); -//! -//! +//! +//! //! p.SYST.set_clock_source(SystClkSource::Core); //! p.SYST.set_reload(16_000_000 / DIVISOR); //! p.SYST.enable_interrupt(); //! p.SYST.enable_counter(); //! } -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! // Sleep @@ -83,18 +83,18 @@ //! rtfm::wfi(); //! } //! } -//! +//! //! // TASKS //! fn receive(_t: &mut Threshold, r: USART2::Resources) { //! let serial = Serial(&**r.USART2); -//! +//! //! let byte = serial.read().unwrap(); -//! +//! //! serial.write(byte).unwrap(); -//! +//! //! if byte == b'r' { //! // end of command -//! +//! //! match &***r.BUFFER { //! b"bounce" => r.SHARED.mode = Mode::Bounce, //! b"continuous" => r.SHARED.mode = Mode::Continuous, @@ -103,12 +103,12 @@ //! } //! _ => {} //! } -//! +//! //! // clear the buffer to prepare for the next command //! r.BUFFER.clear(); //! } else { //! // push the byte into the buffer -//! +//! //! if r.BUFFER.push(byte).is_err() { //! // error: buffer full //! // KISS: we just clear the buffer when it gets full @@ -116,34 +116,34 @@ //! } //! } //! } -//! +//! //! fn roulette(_t: &mut Threshold, r: SYS_TICK::Resources) { //! let curr = **r.STATE; -//! +//! //! let mut direction = r.SHARED.direction; //! if curr == 0 && r.SHARED.mode == Mode::Bounce { //! direction = direction.reverse(); //! r.SHARED.direction = direction; //! } -//! +//! //! let n = u8(LEDS.len()).unwrap(); //! let next = match direction { //! Direction::Clockwise => (curr + 1) % n, //! Direction::Counterclockwise => curr.checked_sub(1).unwrap_or(n - 1), //! }; -//! +//! //! LEDS[usize(curr)].off(); //! LEDS[usize(next)].on(); -//! +//! //! **r.STATE = next; //! } -//! +//! //! // SUPPORT CODE //! pub struct State { //! direction: Direction, //! mode: Mode, //! } -//! +//! //! impl State { //! const fn new() -> Self { //! State { @@ -152,13 +152,13 @@ //! } //! } //! } -//! +//! //! #[derive(Clone, Copy)] //! enum Direction { //! Clockwise, //! Counterclockwise, //! } -//! +//! //! impl Direction { //! fn reverse(self) -> Self { //! match self { @@ -167,7 +167,7 @@ //! } //! } //! } -//! +//! //! #[derive(Clone, Copy, PartialEq)] //! enum Mode { //! Bounce, diff --git a/src/examples/_8_preemption.rs b/src/examples/_8_preemption.rs index cdbc99dbdc136cd85db8d65ae111422a159455bb..549b86b6f0562318f210f79f6f152d572b4dcae1 100644 --- a/src/examples/_8_preemption.rs +++ b/src/examples/_8_preemption.rs @@ -13,13 +13,13 @@ //! #![feature(const_fn)] //! #![feature(proc_macro)] //! #![no_std] -//! +//! //! extern crate cast; //! extern crate cortex_m; //! extern crate cortex_m_rtfm as rtfm; //! extern crate f4; //! extern crate heapless; -//! +//! //! use cast::{usize, u8}; //! use cortex_m::peripheral::SystClkSource; //! use f4::Serial; @@ -29,28 +29,28 @@ //! use heapless::Vec; //! use rtfm::{app, Resource, Threshold}; //! use f4::time::Hertz; -//! +//! //! // CONFIGURATION //! const BAUD_RATE: Hertz = Hertz(115_200); //! const DIVISOR: u32 = 4; -//! +//! //! // TASK & RESOURCES //! app!{ //! device: f4::stm32f40x, -//! +//! //! resources: { //! static BUFFER: Vec<u8, [u8; 16]> = Vec::new([0; 16]); //! static SHARED: State = State::new(); //! static STATE: u8 = 0; //! }, -//! +//! //! tasks: { //! USART2: { //! path: receive, //! priority: 1, //! resources: [BUFFER, SHARED, USART2], //! }, -//! +//! //! SYS_TICK: { //! path: roulette, //! priority: 2, @@ -58,21 +58,21 @@ //! }, //! }, //! } -//! +//! //! // INITIALIZATION PHASE //! fn init(p: init::Peripherals, _r: init::Resources) { //! led::init(&p.GPIOA, &p.RCC); -//! +//! //! let serial = Serial(p.USART2); //! serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); //! serial.listen(Event::Rxne); -//! +//! //! p.SYST.set_clock_source(SystClkSource::Core); //! p.SYST.set_reload(8_000_000 / DIVISOR); //! p.SYST.enable_interrupt(); //! p.SYST.enable_counter(); //! } -//! +//! //! // IDLE LOOP //! fn idle() -> ! { //! // Sleep @@ -80,11 +80,11 @@ //! rtfm::wfi(); //! } //! } -//! +//! //! // TASKS //! fn receive(t: &mut Threshold, mut r: USART2::Resources) { //! let serial = Serial(&**r.USART2); -//! +//! //! let byte = serial.read().unwrap(); //! if serial.write(byte).is_err() { //! // As we are echoing the bytes as soon as they arrive, it should @@ -92,10 +92,10 @@ //! #[cfg(debug_assertions)] //! unreachable!() //! } -//! +//! //! if byte == b'r' { //! // end of command -//! +//! //! match &***r.BUFFER { //! b"bounce" => { //! r.SHARED @@ -114,7 +114,7 @@ //! } //! _ => {} //! } -//! +//! //! r.BUFFER.clear(); //! } else { //! if r.BUFFER.push(byte).is_err() { @@ -124,36 +124,36 @@ //! } //! } //! } -//! +//! //! fn roulette(_t: &mut Threshold, r: SYS_TICK::Resources) { //! let curr = **r.STATE; -//! +//! //! let mut direction = r.SHARED.direction; -//! +//! //! if curr == 0 && r.SHARED.mode == Mode::Bounce { //! direction = direction.reverse(); //! r.SHARED.direction = direction; //! } -//! +//! //! let n = u8(LEDS.len()).unwrap(); //! let next = match direction { //! Direction::Clockwise => (curr + 1) % n, //! Direction::Counterclockwise => curr.checked_sub(1).unwrap_or(n - 1), //! }; -//! +//! //! LEDS[usize(curr)].off(); //! LEDS[usize(next)].on(); -//! +//! //! **r.STATE = next; //! } -//! +//! //! // SUPPORT CODE //! #[derive(Clone, Copy)] //! enum Direction { //! Clockwise, //! Counterclockwise, //! } -//! +//! //! impl Direction { //! fn reverse(self) -> Self { //! match self { @@ -162,18 +162,18 @@ //! } //! } //! } -//! +//! //! #[derive(Clone, Copy, PartialEq)] //! enum Mode { //! Bounce, //! Continuous, //! } -//! +//! //! pub struct State { //! direction: Direction, //! mode: Mode, //! } -//! +//! //! impl State { //! const fn new() -> Self { //! State { diff --git a/src/led.rs b/src/led.rs index eb3e7119614d9ce93d52f87b70ca344953204929..7cc56b95f516c49a5f2e6dc8dbd6ce8679329ee8 100644 --- a/src/led.rs +++ b/src/led.rs @@ -17,7 +17,6 @@ pub fn init(gpioa: &GPIOA, rcc: &RCC) { // configure PC13 as output gpioa.moder.write(|w| w.moder5().bits(1)); - } impl PA5 { @@ -34,4 +33,4 @@ impl PA5 { (*GPIOA.get()).odr.write(|w| w.odr5().bit(true)); } } -} \ No newline at end of file +} diff --git a/src/leds.rs b/src/leds.rs index bf814c4450fb1d7e9d7e8681e7461529233942f3..1cf8a68d1c59fb3fc6da40ad0982293883b374df 100644 --- a/src/leds.rs +++ b/src/leds.rs @@ -39,19 +39,22 @@ pub fn init(gpioa: &GPIOB, rcc: &RCC) { rcc.ahb1enr.modify(|_, w| w.gpioben().set_bit()); // Configure pins 8-15 as outputs - gpioa - .moder - .modify( - |_, w| {unsafe { - w.moder2().bits(1) - .moder1().bits(1) - .moder15().bits(1) - .moder14().bits(1) - .moder13().bits(1) - .moder5().bits(1) - .moder4().bits(1) - .moder10().bits(1) - } - }, - ); + gpioa.moder.modify(|_, w| unsafe { + w.moder2() + .bits(1) + .moder1() + .bits(1) + .moder15() + .bits(1) + .moder14() + .bits(1) + .moder13() + .bits(1) + .moder5() + .bits(1) + .moder4() + .bits(1) + .moder10() + .bits(1) + }); } diff --git a/src/lib.rs b/src/lib.rs index 2d776ef37dc37d7995fb82c30bc440564e5f57eb..31c9f13d030a9e199abd0e22a50770c6a13a327b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ pub mod serial; pub mod timer; pub mod time; pub mod pwm; +pub mod capture; pub mod frequency; use frequency::*; @@ -50,3 +51,4 @@ pub use hal::prelude; pub use serial::Serial; pub use timer::{Channel, Timer}; pub use pwm::Pwm; +pub use capture::Capture; diff --git a/src/pwm.rs b/src/pwm.rs index 41362e46bdde01d55b8dec879dc2a93e4c821dee..93000a5636864e5463bd003d9f1da5016de9ca2d 100644 --- a/src/pwm.rs +++ b/src/pwm.rs @@ -39,7 +39,7 @@ use static_ref::Static; use stm32f40x::{DMA1, TIM1, TIM2, TIM3, TIM4, GPIOA, GPIOB, GPIOC, RCC}; use dma::{self, Buffer, Dma1Channel2}; -use timer::{Channel}; +use timer::Channel; /// PWM driver pub struct Pwm<'a, T>(pub &'a T) @@ -47,13 +47,14 @@ where T: 'a; impl<'a> Pwm<'a, TIM1> { /// Initializes the PWM module - pub fn init<P>(&self, + pub fn init<P>( + &self, period: P, dma1: Option<&DMA1>, - gpioa: &GPIOA, + gpioa: &GPIOA, // TODO: Make these optional/implement custom init for each TIM gpiob: &GPIOB, gpioc: &GPIOC, - rcc: &RCC + rcc: &RCC, ) where P: Into<::apb2::Ticks>, { @@ -79,20 +80,28 @@ impl<'a> Pwm<'a, TIM1> { // CH3 = PA10 = alternate push-pull // CH4 = PA11 = alternate push-pull gpioa.afrh.modify(|_, w| { - w.afrh8().bits(1) - .afrh9().bits(1) - .afrh10().bits(1) - .afrh11().bits(1) + w.afrh8() + .bits(1) + .afrh9() + .bits(1) + .afrh10() + .bits(1) + .afrh11() + .bits(1) }); gpioa.moder.modify(|_, w| { - w.moder8().bits(2) - .moder9().bits(2) - .moder10().bits(2) - .moder11().bits(2) + w.moder8() + .bits(2) + .moder9() + .bits(2) + .moder10() + .bits(2) + .moder11() + .bits(2) }); // PWM mode 1 - tim1.ccmr1_output.modify(|_, w| unsafe{ + tim1.ccmr1_output.modify(|_, w| unsafe { w.oc1pe() .set_bit() .oc1m() @@ -102,7 +111,7 @@ impl<'a> Pwm<'a, TIM1> { .oc2m() .bits(0b110) }); - tim1.ccmr2_output.modify(|_, w| unsafe{ + tim1.ccmr2_output.modify(|_, w| unsafe { w.oc3pe() .set_bit() .oc3m() @@ -122,7 +131,7 @@ impl<'a> Pwm<'a, TIM1> { .cc4p() .clear_bit() }); - + tim1.bdtr.modify(|_, w| w.moe().set_bit()); self._set_period(period); @@ -143,10 +152,10 @@ impl<'a> Pwm<'a, TIM1> { let period = period.0; let psc = u16((period - 1) / (1 << 16)).unwrap(); - self.0.psc.write(|w| unsafe{w.psc().bits(psc)}); + self.0.psc.write(|w| unsafe { w.psc().bits(psc) }); let arr = u16(period / u32(psc + 1)).unwrap(); - self.0.arr.write(|w| unsafe{w.arr().bits(arr)}); + self.0.arr.write(|w| unsafe { w.arr().bits(arr) }); } } @@ -192,10 +201,10 @@ impl<'a> hal::Pwm for Pwm<'a, TIM1> { fn set_duty(&self, channel: Channel, duty: u16) { match channel { - Channel::_1 => self.0.ccr1.write(|w| unsafe{w.ccr1().bits(duty)}), - Channel::_2 => self.0.ccr2.write(|w| unsafe{w.ccr2().bits(duty)}), - Channel::_3 => self.0.ccr3.write(|w| unsafe{w.ccr3().bits(duty)}), - Channel::_4 => self.0.ccr4.write(|w| unsafe{w.ccr4().bits(duty)}), + Channel::_1 => self.0.ccr1.write(|w| unsafe { w.ccr1().bits(duty) }), + Channel::_2 => self.0.ccr2.write(|w| unsafe { w.ccr2().bits(duty) }), + Channel::_3 => self.0.ccr3.write(|w| unsafe { w.ccr3().bits(duty) }), + Channel::_4 => self.0.ccr4.write(|w| unsafe { w.ccr4().bits(duty) }), } } @@ -242,9 +251,7 @@ macro_rules! impl_Pwm { rcc.ahb1enr.modify(|_, w| w.dma1en().set_bit()); } - if tim.get_type_id() == TypeId::of::<TIM1>() { - rcc.apb2enr.modify(|_, w| w.tim1en().set_bit()); - } else if tim.get_type_id() == TypeId::of::<TIM2>() { + if tim.get_type_id() == TypeId::of::<TIM2>() { rcc.apb1enr.modify(|_, w| w.tim2en().set_bit()); } else if tim.get_type_id() == TypeId::of::<TIM3>() { rcc.apb1enr.modify(|_, w| w.tim3en().set_bit()); @@ -253,9 +260,7 @@ macro_rules! impl_Pwm { } rcc.ahb1enr.modify(|_, w| { - if tim.get_type_id() == TypeId::of::<TIM1>() { - w.gpioaen().set_bit() - } else if tim.get_type_id() == TypeId::of::<TIM2>() { + if tim.get_type_id() == TypeId::of::<TIM2>() { w.gpioaen().set_bit().gpioben().set_bit() } else if tim.get_type_id() == TypeId::of::<TIM3>() { w.gpioaen().set_bit().gpioben().set_bit().gpiocen().set_bit() @@ -320,7 +325,7 @@ macro_rules! impl_Pwm { gpioc.moder.modify(|_, w| { unsafe { w.moder7().bits(2) } - }); + }); } else if tim.get_type_id() == TypeId::of::<TIM4>() { // CH1 = PB6 = alternate push-pull @@ -518,10 +523,14 @@ macro_rules! impl_Pwm { fn get_duty(&self, channel: Channel) -> u32 { match channel { - Channel::_1 => u32(self.0.ccr1.read().ccr1_h().bits()) << 16 | u32(self.0.ccr1.read().ccr1_l().bits()), - Channel::_2 => u32(self.0.ccr2.read().ccr2_h().bits()) << 16 | u32(self.0.ccr2.read().ccr2_l().bits()), - Channel::_3 => u32(self.0.ccr3.read().ccr3_h().bits()) << 16 | u32(self.0.ccr3.read().ccr3_l().bits()), - Channel::_4 => u32(self.0.ccr4.read().ccr4_h().bits()) << 16 | u32(self.0.ccr4.read().ccr4_l().bits()), + Channel::_1 => u32(self.0.ccr1.read().ccr1_h().bits()) + << 16 | u32(self.0.ccr1.read().ccr1_l().bits()), + Channel::_2 => u32(self.0.ccr2.read().ccr2_h().bits()) + << 16 | u32(self.0.ccr2.read().ccr2_l().bits()), + Channel::_3 => u32(self.0.ccr3.read().ccr3_h().bits()) + << 16 | u32(self.0.ccr3.read().ccr3_l().bits()), + Channel::_4 => u32(self.0.ccr4.read().ccr4_h().bits()) + << 16 | u32(self.0.ccr4.read().ccr4_l().bits()), } } @@ -555,10 +564,14 @@ macro_rules! impl_Pwm { let dutyl : u16 = u16(duty).unwrap(); let dutyh : u16 = u16(duty >> 16).unwrap(); match channel { - Channel::_1 => self.0.ccr1.write(|w| unsafe{w.ccr1_h().bits(dutyh).ccr1_l().bits(dutyl)}), - Channel::_2 => self.0.ccr2.write(|w| unsafe{w.ccr2_h().bits(dutyh).ccr2_l().bits(dutyl)}), - Channel::_3 => self.0.ccr3.write(|w| unsafe{w.ccr3_h().bits(dutyh).ccr3_l().bits(dutyl)}), - Channel::_4 => self.0.ccr4.write(|w| unsafe{w.ccr4_h().bits(dutyh).ccr4_l().bits(dutyl)}), + Channel::_1 => self.0.ccr1.write(|w| unsafe{ + w.ccr1_h().bits(dutyh).ccr1_l().bits(dutyl)}), + Channel::_2 => self.0.ccr2.write(|w| unsafe{ + w.ccr2_h().bits(dutyh).ccr2_l().bits(dutyl)}), + Channel::_3 => self.0.ccr3.write(|w| unsafe{ + w.ccr3_h().bits(dutyh).ccr3_l().bits(dutyl)}), + Channel::_4 => self.0.ccr4.write(|w| unsafe{ + w.ccr4_h().bits(dutyh).ccr4_l().bits(dutyl)}), } } @@ -572,6 +585,6 @@ macro_rules! impl_Pwm { } } -impl_Pwm!(TIM2,apb1); -impl_Pwm!(TIM3,apb1); -impl_Pwm!(TIM4,apb1); \ No newline at end of file +impl_Pwm!(TIM2, apb1); +impl_Pwm!(TIM3, apb1); +impl_Pwm!(TIM4, apb1); diff --git a/src/serial.rs b/src/serial.rs index 1039e0835f85df198801243db51dc7956d695982..2ed28cffa90d81b5b660d54d042f51ce44b0a5b3 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -17,10 +17,9 @@ use cast::u16; use hal; use nb; use static_ref::Static; -use stm32f40x::{gpioa, DMA1, USART2, usart6, GPIOA, - RCC}; +use stm32f40x::{gpioa, DMA1, USART2, usart6, GPIOA, RCC}; -use dma::{self, Buffer, Dma1Channel6, Dma1Channel5}; +use dma::{self, Buffer, Dma1Channel5, Dma1Channel6}; /// Specialized `Result` type pub type Result<T> = ::core::result::Result<T, nb::Error<Error>>; @@ -47,8 +46,7 @@ pub enum Error { Noise, /// RX buffer overrun Overrun, - #[doc(hidden)] - _Extensible, + #[doc(hidden)] _Extensible, } /// Interrupt event @@ -94,25 +92,14 @@ where /// /// The serial interface will be configured to use 8 bits of data, 1 stop /// bit, no hardware control and to omit parity checking - pub fn init<B>( - &self, - baud_rate: B, - dma1: Option<&DMA1>, - gpio: &U::GPIO, - rcc: &RCC, - ) where + pub fn init<B>(&self, baud_rate: B, dma1: Option<&DMA1>, gpio: &U::GPIO, rcc: &RCC) + where B: Into<U::Ticks>, { self._init(baud_rate.into(), dma1, gpio, rcc) } - fn _init( - &self, - baud_rate: U::Ticks, - dma1: Option<&DMA1>, - gpio: &U::GPIO, - rcc: &RCC, - ) { + fn _init(&self, baud_rate: U::Ticks, dma1: Option<&DMA1>, gpio: &U::GPIO, rcc: &RCC) { let usart = self.0; // power up peripherals @@ -120,22 +107,16 @@ where rcc.ahb1enr.modify(|_, w| w.dma1en().set_bit()); } if usart.get_type_id() == TypeId::of::<USART2>() { - rcc.apb1enr.modify(|_, w| { - w.usart2en().set_bit() - }); + rcc.apb1enr.modify(|_, w| w.usart2en().set_bit()); } rcc.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); if usart.get_type_id() == TypeId::of::<USART2>() { // PA2. = TX, PA3 = RX - gpio.afrl.modify(|_, w| { - w.afrl2().bits(7).afrl3().bits(7) - }); - gpio.moder.modify(|_, w| { - w.moder2().bits(2) - .moder3().bits(2) - }); + gpio.afrl.modify(|_, w| w.afrl2().bits(7).afrl3().bits(7)); + gpio.moder + .modify(|_, w| w.moder2().bits(2).moder3().bits(2)); } if let Some(dma1) = dma1 { @@ -288,9 +269,7 @@ where } else if sr.rxne().bit_is_set() { // NOTE(read_volatile) the register is 9 bits big but we'll only // work with the first 8 bits - Ok(unsafe { - ptr::read_volatile(&usart2.dr as *const _ as *const u8) - }) + Ok(unsafe { ptr::read_volatile(&usart2.dr as *const _ as *const u8) }) } else { Err(nb::Error::WouldBlock) } @@ -315,9 +294,7 @@ where Err(nb::Error::Other(Error::Framing)) } else if sr.txe().bit_is_set() { // NOTE(write_volatile) see NOTE in the `read` method - unsafe { - ptr::write_volatile(&usart2.dr as *const _ as *mut u8, byte) - } + unsafe { ptr::write_volatile(&usart2.dr as *const _ as *mut u8, byte) } Ok(()) } else { Err(nb::Error::WouldBlock) diff --git a/src/time.rs b/src/time.rs index 3922a718896a763b4f82205ba985939198affac5..eea0e286208fd92cba1335e479be3d506794c442 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,4 +1,3 @@ - //! Units of time macro_rules! map { diff --git a/src/timer.rs b/src/timer.rs index 65d1e89a6d537a2c141d25e390bbcd7fac928355..d1f727e9bf3b6a6accd33d365d863d8019bf064a 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -5,7 +5,7 @@ use core::any::{Any, TypeId}; use cast::{u16, u32}; use hal; use nb::{self, Error}; -use stm32f40x::{TIM1, TIM2, TIM3, TIM4, TIM5, TIM9, TIM10, TIM11, RCC}; +use stm32f40x::{TIM1, TIM10, TIM11, TIM2, TIM3, TIM4, TIM5, TIM9, RCC}; /// Channel associated to a timer #[derive(Clone, Copy, Debug)] @@ -92,7 +92,7 @@ macro_rules! impl_Timer { } impl<'a> hal::Timer for Timer<'a, $TIM> - { + { type Time = ::$APB::Ticks; fn get_timeout(&self) -> ::$APB::Ticks { @@ -100,36 +100,36 @@ macro_rules! impl_Timer { u32(self.0.psc.read().psc().bits() + 1) * u32(self.0.arr.read().bits()), ) - } + } - fn pause(&self) { - self.0.cr1.modify(|_, w| w.cen().clear_bit()); - } + fn pause(&self) { + self.0.cr1.modify(|_, w| w.cen().clear_bit()); + } - fn restart(&self) { - self.0.cnt.write(|w| unsafe{w.bits(0)}); - } + fn restart(&self) { + self.0.cnt.write(|w| unsafe{w.bits(0)}); + } - fn resume(&self) { - self.0.cr1.modify(|_, w| w.cen().set_bit()); - } + fn resume(&self) { + self.0.cr1.modify(|_, w| w.cen().set_bit()); + } - fn set_timeout<TO>(&self, timeout: TO) - where - TO: Into<::$APB::Ticks>, - { - self._set_timeout(timeout.into()) - } + fn set_timeout<TO>(&self, timeout: TO) + where + TO: Into<::$APB::Ticks>, + { + self._set_timeout(timeout.into()) + } - fn wait(&self) -> nb::Result<(), !> { - if self.0.sr.read().uif().bit_is_clear() { - Err(Error::WouldBlock) - } else { - self.0.sr.modify(|_, w| w.uif().clear_bit()); - Ok(()) - } + fn wait(&self) -> nb::Result<(), !> { + if self.0.sr.read().uif().bit_is_clear() { + Err(Error::WouldBlock) + } else { + self.0.sr.modify(|_, w| w.uif().clear_bit()); + Ok(()) } } + } } }