diff --git a/examples/accel_pwm.rs b/examples/accel_pwm.rs index f556218..cbae358 100644 --- a/examples/accel_pwm.rs +++ b/examples/accel_pwm.rs @@ -18,7 +18,7 @@ use stm32f3_discovery::compass::Compass; use stm32f3_discovery::stm32f3xx_hal; use stm32f3xx_hal::delay::Delay; use stm32f3xx_hal::pwm::tim1; -use stm32f3xx_hal::{prelude::*, pac}; +use stm32f3xx_hal::{pac, prelude::*}; #[entry] fn main() -> ! { @@ -35,9 +35,18 @@ fn main() -> ! { // Prep the pins we need in their correct alternate function let mut gpioe = device_periphs.GPIOE.split(&mut reset_and_clock_control.ahb); - let led_blue = gpioe.pe8.into_af2_push_pull(&mut gpioe.moder, &mut gpioe.otyper, &mut gpioe.afrh); - let led_green = gpioe.pe11.into_af2_push_pull(&mut gpioe.moder, &mut gpioe.otyper, &mut gpioe.afrh); - let lef_red = gpioe.pe13.into_af2_push_pull(&mut gpioe.moder, &mut gpioe.otyper, &mut gpioe.afrh); + let led_blue = + gpioe + .pe8 + .into_af2_push_pull(&mut gpioe.moder, &mut gpioe.otyper, &mut gpioe.afrh); + let led_green = + gpioe + .pe11 + .into_af2_push_pull(&mut gpioe.moder, &mut gpioe.otyper, &mut gpioe.afrh); + let lef_red = + gpioe + .pe13 + .into_af2_push_pull(&mut gpioe.moder, &mut gpioe.otyper, &mut gpioe.afrh); let max_duty = 4096; diff --git a/examples/blinky.rs b/examples/blinky.rs index 572f7fd..4d77009 100644 --- a/examples/blinky.rs +++ b/examples/blinky.rs @@ -6,8 +6,8 @@ extern crate panic_itm; use cortex_m_rt::entry; use stm32f3_discovery::stm32f3xx_hal::delay::Delay; -use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::stm32f3xx_hal::pac; +use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::leds::Leds; use stm32f3_discovery::switch_hal::{OutputSwitch, ToggleableOutputSwitch}; diff --git a/examples/blinky_int.rs b/examples/blinky_int.rs index 84b6f2c..0f756be 100644 --- a/examples/blinky_int.rs +++ b/examples/blinky_int.rs @@ -10,17 +10,16 @@ use cortex_m::interrupt::{free, Mutex}; use cortex_m_rt::entry; +use stm32f3xx_hal::pac; use stm32f3xx_hal::prelude::*; use stm32f3xx_hal::timer::{Event, Timer}; -use stm32f3xx_hal::pac; use pac::{interrupt, Interrupt}; -use switch_hal::{ToggleableOutputSwitch, IntoSwitch}; +use switch_hal::{IntoSwitch, ToggleableOutputSwitch}; use stm32f3_discovery::wait_for_interrupt; - static TIM: Mutex>>> = Mutex::new(RefCell::new(None)); #[interrupt] @@ -46,13 +45,15 @@ fn main() -> ! { }); let mut gpio = peripherals.GPIOE.split(&mut rcc.ahb); - let pin = gpio.pe9.into_push_pull_output(&mut gpio.moder, &mut gpio.otyper); + let pin = gpio + .pe9 + .into_push_pull_output(&mut gpio.moder, &mut gpio.otyper); let mut led = pin.into_active_high_switch(); unsafe { - pac::NVIC::unmask(Interrupt::TIM7); - } - + pac::NVIC::unmask(Interrupt::TIM7); + } + loop { led.toggle().ok(); wait_for_interrupt(); diff --git a/examples/button.rs b/examples/button.rs index caba1cb..14bef1a 100644 --- a/examples/button.rs +++ b/examples/button.rs @@ -5,8 +5,8 @@ extern crate panic_itm; use cortex_m_rt::entry; use stm32f3_discovery::stm32f3xx_hal::delay::Delay; -use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::stm32f3xx_hal::pac; +use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::button::UserButton; use stm32f3_discovery::leds::Leds; diff --git a/examples/button_int.rs b/examples/button_int.rs index f5f064b..ff6bd9c 100644 --- a/examples/button_int.rs +++ b/examples/button_int.rs @@ -6,8 +6,8 @@ extern crate panic_itm; use cortex_m_rt::entry; use stm32f3_discovery::stm32f3xx_hal::interrupt; -use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::stm32f3xx_hal::pac; +use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::wait_for_interrupt; use core::sync::atomic::{AtomicBool, Ordering}; diff --git a/examples/compass.rs b/examples/compass.rs index 76cb42b..a098552 100644 --- a/examples/compass.rs +++ b/examples/compass.rs @@ -9,8 +9,8 @@ use cortex_m_rt::{entry, exception}; use accelerometer::{Accelerometer, RawAccelerometer}; use stm32f3_discovery::compass::Compass; -use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::stm32f3xx_hal::pac; +use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::wait_for_interrupt; #[entry] diff --git a/examples/leds.rs b/examples/leds.rs index 56f19d6..90d3618 100644 --- a/examples/leds.rs +++ b/examples/leds.rs @@ -6,8 +6,8 @@ extern crate panic_itm; use cortex_m_rt::entry; use stm32f3_discovery::stm32f3xx_hal::delay::Delay; -use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::stm32f3xx_hal::pac; +use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::leds::Leds; use stm32f3_discovery::switch_hal::OutputSwitch; diff --git a/examples/leds_directions.rs b/examples/leds_directions.rs index 7dbcfd8..575b800 100644 --- a/examples/leds_directions.rs +++ b/examples/leds_directions.rs @@ -6,14 +6,14 @@ extern crate panic_itm; use cortex_m_rt::entry; use stm32f3_discovery::stm32f3xx_hal::delay::Delay; -use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::stm32f3xx_hal::pac; +use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3xx_hal::gpio::gpioe; use stm32f3xx_hal::gpio::{Output, PushPull}; use stm32f3_discovery::leds::{Direction, Leds}; -use stm32f3_discovery::switch_hal::{Switch, ActiveHigh, OutputSwitch}; +use stm32f3_discovery::switch_hal::{ActiveHigh, OutputSwitch, Switch}; #[entry] fn main() -> ! { @@ -44,7 +44,7 @@ fn main() -> ! { let fast_delay = 50u16; for direction in Direction::iter() { let led = &mut leds.for_direction(*direction); - + led.on().ok(); delay.delay_ms(fast_delay); led.off().ok(); diff --git a/examples/leds_iterator_test.rs b/examples/leds_iterator_test.rs index 4e1543b..c706011 100644 --- a/examples/leds_iterator_test.rs +++ b/examples/leds_iterator_test.rs @@ -6,8 +6,8 @@ extern crate panic_itm; use cortex_m_rt::entry; use stm32f3_discovery::stm32f3xx_hal::delay::Delay; -use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::stm32f3xx_hal::pac; +use stm32f3_discovery::stm32f3xx_hal::prelude::*; use stm32f3_discovery::leds::Leds; use stm32f3_discovery::switch_hal::OutputSwitch; @@ -71,7 +71,7 @@ fn main() -> ! { // we're in the middle, so panic if either of the next two calls returns a led iter.next().map(|_| panic!("Got a Some!")); iter.next_back().map(|_| panic!("Got a Some!")); - + // turn everything back off for led in &mut leds { led.off().ok(); diff --git a/src/button/mod.rs b/src/button/mod.rs index 6556c01..e1f4e36 100644 --- a/src/button/mod.rs +++ b/src/button/mod.rs @@ -2,7 +2,7 @@ pub mod interrupt; use stm32f3xx_hal::gpio::gpioa::PA0; -use stm32f3xx_hal::gpio::{Input, gpioa}; +use stm32f3xx_hal::gpio::{gpioa, Input}; use switch_hal::{ActiveHigh, InputSwitch, IntoSwitch, Switch}; /// Wrapper struct around `ActiveHighButton>` @@ -16,7 +16,10 @@ impl UserButton { pub fn new(pa0: PA0, moder: &mut gpioa::MODER, pupdr: &mut gpioa::PUPDR) -> Self { // This button is equipped with an external pull-down and so there is // no need to use the internal one. - UserButton(pa0.into_floating_input(moder, pupdr).into_active_high_switch()) + UserButton( + pa0.into_floating_input(moder, pupdr) + .into_active_high_switch(), + ) } } diff --git a/src/compass.rs b/src/compass.rs index 2209ae5..4ca551b 100644 --- a/src/compass.rs +++ b/src/compass.rs @@ -7,9 +7,15 @@ use stm32f3xx_hal::pac; use stm32f3xx_hal::prelude::*; use stm32f3xx_hal::rcc; - -type Lsm303 = - lsm303dlhc::Lsm303dlhc>, gpiob::PB7>)>>; +type Lsm303 = lsm303dlhc::Lsm303dlhc< + i2c::I2c< + pac::I2C1, + ( + gpiob::PB6>, + gpiob::PB7>, + ), + >, +>; pub struct Compass { lsm303dlhc: Lsm303, @@ -69,7 +75,7 @@ impl RawAccelerometer for Compass { } /// Reads Accelerometer data in G-Force -/// +/// /// # Warning /// This is hard coded for the default settings because the driver doesn't provide a way /// to read the necessary registers to calculate it based on current settings. @@ -77,11 +83,11 @@ impl RawAccelerometer for Compass { /// this will not calculate the correct G-Force values. impl Accelerometer for Compass { type Error = i2c::Error; - fn accel_norm(&mut self) -> Result> { + fn accel_norm(&mut self) -> Result> { let reading = self.accel_raw()?; /* * LA_FS (linear acceleration measurment range [full scale]) - * can be +/-2, +/-4, +/-8, or +/- 16 + * can be +/-2, +/-4, +/-8, or +/- 16 * LA_So (Linear acceleration sensitivity) can be 1,2,4, or 12 * and is measured in milli-G / LSB * The driver provides a way to set the range/sensitivy, @@ -89,11 +95,11 @@ impl Accelerometer for Compass { * * At +/-2g, we get 1mg/LSB (1 mg/bit) resolution. * The device returns a 16 bit result. - * magnitude g / (1 mg / bit) = + * magnitude g / (1 mg / bit) = * +/- 2g range = 4g magnitude * 4g / 65535 bits = 4g/(1<<16) = 0.000061 g / bit * 2g / 32768 bits = 2g/(1<<15) = 0.000061 g / bit - * + * * I _think_ the general equation is: * scale_factor = magnitude / #of_bits * sensitivity * scale_factor = (abs(range)*2) / #of_bits * sensitivity @@ -109,14 +115,14 @@ impl Accelerometer for Compass { const NO_OF_BITS: i32 = 1 << 16; const SENSITIVITY: i32 = 1; const SCALE_FACTOR: f32 = (MAGNITUDE as f32 / NO_OF_BITS as f32) * SENSITIVITY as f32; - Ok(F32x3::new ( + Ok(F32x3::new( reading.x as f32 * SCALE_FACTOR, reading.y as f32 * SCALE_FACTOR, reading.z as f32 * SCALE_FACTOR, )) } - fn sample_rate(&mut self) -> Result::Error>> { + fn sample_rate(&mut self) -> Result::Error>> { // we don't expose a way to change this, so hard coded to 400Hz right now // it should really be read from the device in case someone snags the raw lsm303dlhc struct, // but the driver does't give us a way to read it back from the device diff --git a/src/leds.rs b/src/leds.rs index 7ea5897..c013088 100644 --- a/src/leds.rs +++ b/src/leds.rs @@ -1,23 +1,71 @@ -//! Provides access to User LEDs LD3-LD10 +//! Provides access to User LEDs LD3-LD10. +//! +//! # Example +//! +//! The following demonstrates the basic process for going through and turning +//! each LED on, off, and then toggling it to its opposite state. This is +//! obviously contrived, and will happen very quickly with no delay between +//! state changes; take a look at the `leds` example for a more complete +//! demonstration of how this could be used. +//! +//! ``` +//! let device_periphs = pac::Peripherals::take().unwrap(); +//! let mut reset_and_clock_control = device_periphs.RCC.constrain(); +//! +//! // initialize user leds +//! let mut gpioe = device_periphs.GPIOE.split(&mut reset_and_clock_control.ahb); +//! let mut leds = Leds::new( +//! gpioe.pe8, +//! gpioe.pe9, +//! gpioe.pe10, +//! gpioe.pe11, +//! gpioe.pe12, +//! gpioe.pe13, +//! gpioe.pe14, +//! gpioe.pe15, +//! &mut gpioe.moder, +//! &mut gpioe.otyper, +//! ); +//! +//! for led in &mut leds { +//! led.on().ok(); +//! led.off().ok(); +//! led.toggle().ok(); +//! } +//! ``` use stm32f3xx_hal::gpio::gpioe; use stm32f3xx_hal::gpio::{Output, PushPull}; use switch_hal::{ActiveHigh, IntoSwitch, OutputSwitch, Switch}; -use core::slice::Iter; use core::iter::FusedIterator; +use core::slice::Iter; /// LED compass direction as noted on the board #[derive(Clone, Copy, Eq, PartialEq)] -pub enum Direction -{ +pub enum Direction { + /// LED LD3. North, + + /// LED LD5. NorthEast, + + /// LED LD7. East, + + /// LED LD9. SouthEast, + + /// LED LD10. South, + + /// LED LD8. SouthWest, + + /// LED LD6. West, + + /// LED LD4. NorthWest, } @@ -34,14 +82,42 @@ impl Direction { Direction::South, Direction::SouthWest, Direction::West, - Direction::NorthWest + Direction::NorthWest, ]; DIRECTIONS.iter() } } +/// Logical representation of an LED in the compass. Type alias for a +/// `switch_hal::Switch`. type Led = Switch>, ActiveHigh>; +/// Collection of LEDs arranged as a compass on the board. +/// +/// To use, instantiate an `Leds` object and access the leds individually or as +/// an iterator. +/// +/// # Example +/// +/// ``` +/// let device_periphs = pac::Peripherals::take().unwrap(); +/// let mut reset_and_clock_control = device_periphs.RCC.constrain(); +/// +/// // initialize user leds +/// let mut gpioe = device_periphs.GPIOE.split(&mut reset_and_clock_control.ahb); +/// let mut leds = Leds::new( +/// gpioe.pe8, +/// gpioe.pe9, +/// gpioe.pe10, +/// gpioe.pe11, +/// gpioe.pe12, +/// gpioe.pe13, +/// gpioe.pe14, +/// gpioe.pe15, +/// &mut gpioe.moder, +/// &mut gpioe.otyper, +/// ); +/// ``` pub struct Leds { /// North pub ld3: Led, @@ -62,7 +138,7 @@ pub struct Leds { } impl Leds { - /// Initializes the user LEDs to OFF + /// Creates a new `Leds` object and nitializes the compass LEDs to OFF. pub fn new( pe8: gpioe::PE8, pe9: gpioe::PE9, @@ -117,11 +193,20 @@ impl Leds { leds } - /// Mutably borrow a LED by the given direction (as noted on the board) - /// + /// Mutably borrow a LED by the given direction (as noted on the board). + /// /// # Example - /// + /// /// ``` + /// let device_periphs = pac::Peripherals::take().unwrap(); + /// let mut reset_and_clock_control = device_periphs.RCC.constrain(); + /// let mut gpioe = device_periphs.GPIOE.split(&mut reset_and_clock_control.ahb); + /// + /// let mut leds = Leds::new( + /// gpioe.pe8, + /// // See module documentation for details. + /// ); + /// /// let southLed = leds.for_direction(Direction::South); /// southLed.on().ok(); /// ``` @@ -139,13 +224,13 @@ impl Leds { } /// Provides a mutable iterator for iterating over the on board leds. - /// Starts at ld3 (N) and moves clockwise. + /// Starts at ld3 (N) and moves clockwise. /// Stops once it has iterated through all 8 leds. - /// + /// /// # Examples - /// + /// /// Iterate over the leds clockwise - /// + /// /// ``` /// let ms_delay = 50u16; /// for led in &mut leds { @@ -155,9 +240,9 @@ impl Leds { /// delay.delay_ms(ms_delay); /// } /// ``` - /// + /// /// Iterate over the leds counter clockwise - /// + /// /// ``` /// let ms_delay = 50u16; /// for led in leds.iter_mut().rev() { @@ -172,13 +257,13 @@ impl Leds { } /// Consumes the `Leds` struct and returns an array, - /// where index 0 is N and each incrementing index. + /// where index 0 is N and each incrementing index. /// Rotates clockwise around the compass. - /// + /// /// # Warning - /// + /// /// This function is maintained solely for some level of compatibility with the old F3 crate. - /// + /// /// [`Self::iter_mut()`] should be prefered. /// Testing suggests that using [`Self::iter_mut()`] results in an ~800 byte /// reduction in final binary size. @@ -210,12 +295,16 @@ const ITERATOR_SIZE: usize = 8; pub struct LedsMutIterator<'a> { index: usize, index_back: usize, - leds: &'a mut Leds + leds: &'a mut Leds, } impl<'a> LedsMutIterator<'a> { fn new(leds: &'a mut Leds) -> Self { - LedsMutIterator { index: 0, index_back: ITERATOR_SIZE, leds } + LedsMutIterator { + index: 0, + index_back: ITERATOR_SIZE, + leds, + } } fn len(&self) -> usize { @@ -236,21 +325,21 @@ impl<'a> Iterator for LedsMutIterator<'a> { } else { let current = unsafe { //Safety: Each branch is only executed once, - // and only if there are elements left to be returned, + // and only if there are elements left to be returned, // so we can not possibly alias a mutable reference. // This depends on DoubleEndedIterator and ExactSizedIterator being implemented correctly. - // If len() does not return the correct number of remaining elements, + // If len() does not return the correct number of remaining elements, // this becomes unsound. - match self.index { - 0 => Some(&mut *(&mut self.leds.ld3 as *mut _)), //N - 1 => Some(&mut *(&mut self.leds.ld5 as *mut _)), //NE - 2 => Some(&mut *(&mut self.leds.ld7 as *mut _)), //E - 3 => Some(&mut *(&mut self.leds.ld9 as *mut _)), //SE - 4 => Some(&mut *(&mut self.leds.ld10 as *mut _)), //S - 5 => Some(&mut *(&mut self.leds.ld8 as *mut _)), //SW - 6 => Some(&mut *(&mut self.leds.ld6 as *mut _)), //W - 7 => Some(&mut *(&mut self.leds.ld4 as *mut _)), //NW - _ => None + match self.index { + 0 => Some(&mut *(&mut self.leds.ld3 as *mut _)), //N + 1 => Some(&mut *(&mut self.leds.ld5 as *mut _)), //NE + 2 => Some(&mut *(&mut self.leds.ld7 as *mut _)), //E + 3 => Some(&mut *(&mut self.leds.ld9 as *mut _)), //SE + 4 => Some(&mut *(&mut self.leds.ld10 as *mut _)), //S + 5 => Some(&mut *(&mut self.leds.ld8 as *mut _)), //SW + 6 => Some(&mut *(&mut self.leds.ld6 as *mut _)), //W + 7 => Some(&mut *(&mut self.leds.ld4 as *mut _)), //NW + _ => None, } }; self.index += 1; @@ -265,30 +354,30 @@ impl<'a> Iterator for LedsMutIterator<'a> { } impl<'a> DoubleEndedIterator for LedsMutIterator<'a> { - fn next_back(&mut self) -> Option { + fn next_back(&mut self) -> Option { if self.len() == 0 { None } else { let current = unsafe { //Safety: Each branch is only executed once, - // and only if there are elements left to be returned, + // and only if there are elements left to be returned, // so we can not possibly alias a mutable reference. // This depends on Iterator and ExactSizedIterator being implemented correctly. - // If len() does not return the correct number of remaining elements, + // If len() does not return the correct number of remaining elements, // this becomes unsound. - match self.index_back { - // Because we're going backwards and index_back is a usize, - // We use a one based index so we don't go negative - 0 => None, //done - 1 => Some(&mut *(&mut self.leds.ld3 as *mut _)), //N - 2 => Some(&mut *(&mut self.leds.ld5 as *mut _)), //NE - 3 => Some(&mut *(&mut self.leds.ld7 as *mut _)), //E - 4 => Some(&mut *(&mut self.leds.ld9 as *mut _)), //SE - 5 => Some(&mut *(&mut self.leds.ld10 as *mut _)), //S - 6 => Some(&mut *(&mut self.leds.ld8 as *mut _)), //SW - 7 => Some(&mut *(&mut self.leds.ld6 as *mut _)), //W - 8 => Some(&mut *(&mut self.leds.ld4 as *mut _)), //NW - _ => None //can't happen + match self.index_back { + // Because we're going backwards and index_back is a usize, + // We use a one based index so we don't go negative + 0 => None, //done + 1 => Some(&mut *(&mut self.leds.ld3 as *mut _)), //N + 2 => Some(&mut *(&mut self.leds.ld5 as *mut _)), //NE + 3 => Some(&mut *(&mut self.leds.ld7 as *mut _)), //E + 4 => Some(&mut *(&mut self.leds.ld9 as *mut _)), //SE + 5 => Some(&mut *(&mut self.leds.ld10 as *mut _)), //S + 6 => Some(&mut *(&mut self.leds.ld8 as *mut _)), //SW + 7 => Some(&mut *(&mut self.leds.ld6 as *mut _)), //W + 8 => Some(&mut *(&mut self.leds.ld4 as *mut _)), //NW + _ => None, //can't happen } }; self.index_back -= 1; @@ -304,4 +393,4 @@ impl<'a> ExactSizeIterator for LedsMutIterator<'a> { } ///Marker trait that indicates LedsMutIterator never starts returning Some after returning None -impl<'a> FusedIterator for LedsMutIterator<'a> {} \ No newline at end of file +impl<'a> FusedIterator for LedsMutIterator<'a> {}