Created
October 10, 2022 05:43
-
-
Save mikeshultz/2166af226c500568c2dba9731ca05cc0 to your computer and use it in GitHub Desktop.
Program for LED rotation on STM32DICOVERY
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![no_std] | |
#![no_main] | |
// Rotate LEDs on board and allow user to change their direction | |
use panic_semihosting as _; | |
use cortex_m_rt::entry; | |
use cortex_m_semihosting::{dbg, heprint}; | |
use stm32f3_discovery::button::UserButton; | |
use stm32f3_discovery::leds::Leds; | |
use stm32f3_discovery::stm32f3xx_hal::delay::Delay; | |
use stm32f3_discovery::stm32f3xx_hal::gpio::gpioe::PEx; | |
use stm32f3_discovery::stm32f3xx_hal::gpio::{Output, PushPull}; | |
use stm32f3_discovery::stm32f3xx_hal::pac; | |
use stm32f3_discovery::stm32f3xx_hal::prelude::*; | |
use stm32f3_discovery::switch_hal::{ActiveHigh, InputSwitch, OutputSwitch, Switch}; | |
type Led = Switch<PEx<Output<PushPull>>, ActiveHigh>; | |
enum CircularDirection { | |
CW, // Clockwise | |
CCW, // Counterclockwise | |
} | |
struct Sequencer { | |
length: usize, | |
current: usize, | |
dir: CircularDirection, | |
} | |
impl Sequencer { | |
fn new(length: usize) -> Self { | |
Sequencer { | |
length, | |
current: 0, | |
dir: CircularDirection::CW, | |
} | |
} | |
fn set_direction(&mut self, dir: CircularDirection) { | |
self.dir = dir; | |
} | |
fn toggle_direction(&mut self) { | |
self.dir = match self.dir { | |
CircularDirection::CW => CircularDirection::CCW, | |
_ => CircularDirection::CW, | |
} | |
} | |
} | |
impl Iterator for Sequencer { | |
type Item = usize; | |
fn next(&mut self) -> Option<Self::Item> { | |
self.current = match self.dir { | |
CircularDirection::CCW => match self.current > 0 { | |
true => self.current - 1, | |
_ => self.length - 1, | |
}, | |
_ => match self.current < self.length - 1 { | |
true => self.current + 1, | |
_ => 0, | |
}, | |
}; | |
Some(self.current) | |
} | |
} | |
fn flash_led(delay: &mut Delay, led: &mut Led, duration: u16) { | |
led.on().ok(); | |
delay.delay_ms(duration); | |
led.off().ok(); | |
} | |
#[entry] | |
fn main() -> ! { | |
let device = pac::Peripherals::take().unwrap(); | |
let mut rcc = device.RCC.constrain(); | |
let core = cortex_m::Peripherals::take().unwrap(); | |
let mut flash = device.FLASH.constrain(); | |
let clocks = rcc.cfgr.freeze(&mut flash.acr); | |
let mut delay = Delay::new(core.SYST, clocks); | |
let mut gpioa = device.GPIOA.split(&mut rcc.ahb); | |
let mut gpioe = device.GPIOE.split(&mut rcc.ahb); | |
let mut button = UserButton::new(gpioa.pa0, &mut gpioa.moder, &mut gpioa.pupdr); | |
let mut led_seq = Leds::new( | |
gpioe.pe8, | |
gpioe.pe9, | |
gpioe.pe10, | |
gpioe.pe11, | |
gpioe.pe12, | |
gpioe.pe13, | |
gpioe.pe14, | |
gpioe.pe15, | |
&mut gpioe.moder, | |
&mut gpioe.otyper, | |
) | |
.into_array(); | |
let mut seq = Sequencer::new(led_seq.len()); | |
// Whether or not the user button is currently depressed | |
let mut depressed = false; | |
loop { | |
// Handle human input for directional change | |
match button.is_active() { | |
Ok(active) => { | |
if active { | |
// If depressed is set, user is already pressing the button | |
// from the previous tick | |
if !depressed { | |
depressed = true; | |
seq.toggle_direction(); | |
} | |
} else if depressed { | |
depressed = false | |
} | |
} | |
Err(error) => { | |
dbg!(error); | |
} | |
}; | |
// Handle next LED flash in sequence | |
match seq.next() { | |
Some(current) => flash_led(&mut delay, &mut led_seq[current], 50u16), | |
_ => { | |
heprint!("!"); | |
} | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment