112 lines
2.9 KiB
Rust
112 lines
2.9 KiB
Rust
// 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);
|
|
}
|
|
}
|