Skip to content

Instantly share code, notes, and snippets.

@mikeshultz
Created October 10, 2022 05:43
Show Gist options
  • Save mikeshultz/2166af226c500568c2dba9731ca05cc0 to your computer and use it in GitHub Desktop.
Save mikeshultz/2166af226c500568c2dba9731ca05cc0 to your computer and use it in GitHub Desktop.
Program for LED rotation on STM32DICOVERY
#![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