Initial commit
This commit is contained in:
111
src/bin/06_button_events.rs
Normal file
111
src/bin/06_button_events.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
// Button events.
|
||||
// Turn the 5-way button into robot meaning.
|
||||
// Keep raw input separate from behaviour.
|
||||
|
||||
#![deny(unsafe_code)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use panic_probe as _;
|
||||
use stm32f1xx_hal::{pac, prelude::*};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
enum ButtonDirection {
|
||||
None,
|
||||
Center,
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
enum RobotEvent {
|
||||
NoEvent,
|
||||
StartStop,
|
||||
BallLeft,
|
||||
BallRight,
|
||||
BallCentered,
|
||||
ObstacleDetected,
|
||||
}
|
||||
|
||||
/// Turn raw button states into one direction.
|
||||
fn read_direction(center: bool, up: bool, down: bool, left: bool, right: bool) -> ButtonDirection {
|
||||
if center {
|
||||
ButtonDirection::Center
|
||||
} else if up {
|
||||
ButtonDirection::Up
|
||||
} else if down {
|
||||
ButtonDirection::Down
|
||||
} else if left {
|
||||
ButtonDirection::Left
|
||||
} else if right {
|
||||
ButtonDirection::Right
|
||||
} else {
|
||||
ButtonDirection::None
|
||||
}
|
||||
// Q: Why not match?
|
||||
}
|
||||
|
||||
/// Turn one button direction into one robot event.
|
||||
fn direction_to_event(direction: ButtonDirection) -> RobotEvent {
|
||||
match direction {
|
||||
ButtonDirection::None => RobotEvent::NoEvent,
|
||||
ButtonDirection::Center => RobotEvent::StartStop,
|
||||
ButtonDirection::Left => RobotEvent::BallLeft,
|
||||
ButtonDirection::Right => RobotEvent::BallRight,
|
||||
ButtonDirection::Up => RobotEvent::BallCentered,
|
||||
ButtonDirection::Down => RobotEvent::ObstacleDetected,
|
||||
}
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
let cp = cortex_m::Peripherals::take().unwrap();
|
||||
|
||||
let mut rcc = dp.RCC.constrain();
|
||||
let mut gpioa = dp.GPIOA.split(&mut rcc);
|
||||
let mut gpiob = dp.GPIOB.split(&mut rcc);
|
||||
let mut gpioc = dp.GPIOC.split(&mut rcc);
|
||||
let mut delay = cp.SYST.delay(&rcc.clocks);
|
||||
|
||||
let center = gpioa.pa8.into_pull_down_input(&mut gpioa.crh);
|
||||
let up = gpioa.pa9.into_pull_down_input(&mut gpioa.crh);
|
||||
let mut vcc = gpioa.pa10.into_push_pull_output(&mut gpioa.crh);
|
||||
let right = gpiob.pb13.into_pull_down_input(&mut gpiob.crh);
|
||||
let down = gpiob.pb14.into_pull_down_input(&mut gpiob.crh);
|
||||
let left = gpiob.pb15.into_pull_down_input(&mut gpiob.crh);
|
||||
let mut gnd = gpiob.pb12.into_push_pull_output(&mut gpiob.crh);
|
||||
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
|
||||
|
||||
vcc.set_high();
|
||||
gnd.set_low();
|
||||
led.set_high();
|
||||
|
||||
let mut last_event = RobotEvent::NoEvent;
|
||||
|
||||
loop {
|
||||
let direction = read_direction(
|
||||
center.is_high(),
|
||||
up.is_high(),
|
||||
down.is_high(),
|
||||
left.is_high(),
|
||||
right.is_high(),
|
||||
);
|
||||
let event = direction_to_event(direction);
|
||||
|
||||
if event != last_event {
|
||||
last_event = event;
|
||||
|
||||
if event == RobotEvent::NoEvent {
|
||||
led.set_high();
|
||||
} else {
|
||||
led.set_low();
|
||||
}
|
||||
}
|
||||
|
||||
delay.delay_ms(25u32);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user