Refactor to remove use of unsafe constructs.

master
Levi Pearson 2020-03-10 22:09:35 -06:00
parent 4d043688d3
commit 3bcca9ff0b
2 changed files with 51 additions and 28 deletions

View File

@ -14,7 +14,6 @@ embedded-hal = "0.2.3"
nb = "0.1.2"
ssd1306 = "0.3.0-alpha.4"
switch-hal = "0.3.2"
rotary-encoder-hal = "0.2.1"
[dependencies.arrayvec]
version = "0.5.1"

View File

@ -1,17 +1,22 @@
#![no_std]
#![no_main]
use core::mem::MaybeUninit;
use core::{
cell::RefCell,
fmt::Write,
};
use panic_halt as _;
use cortex_m_rt::entry;
use cortex_m::peripheral::NVIC;
use cortex_m::{
interrupt::Mutex,
};
use stm32f1xx_hal::{
afio,
device::EXTI,
device::{EXTI, NVIC},
delay::Delay,
i2c::{BlockingI2c, DutyCycle, Mode},
gpio::{
@ -48,11 +53,13 @@ use embedded_graphics::{
};
use arrayvec::ArrayString;
use core::fmt::Write;
static mut CLK_PIN: MaybeUninit<PA8<Input<Floating>>> = MaybeUninit::uninit();
static mut DT_PIN: MaybeUninit<PA9<Input<Floating>>> = MaybeUninit::uninit();
static mut COUNT: i32 = 0;
type CLKPIN = PA8<Input<Floating>>;
type DTPIN = PA9<Input<Floating>>;
static CLK_PIN: Mutex<RefCell<Option<CLKPIN>>> = Mutex::new(RefCell::new(None));
static DT_PIN: Mutex<RefCell<Option<DTPIN>>> = Mutex::new(RefCell::new(None));
static COUNT: Mutex<RefCell<i32>> = Mutex::new(RefCell::new(0));
#[entry]
fn main() -> ! {
@ -162,8 +169,8 @@ fn main() -> ! {
// Microcontroller programs never exit main, so we must loop!
loop {
// Check our inputs
let counter = unsafe { &mut COUNT };
let button = sw.is_active().unwrap();
let counter = cortex_m::interrupt::free(|cs| *COUNT.borrow(cs).borrow());
if button_last && !button {
led.toggle().unwrap();
}
@ -172,20 +179,21 @@ fn main() -> ! {
let c = Circle::new(Point::new(cx, cy), C_RADIUS as u32)
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On));
// Show the position of the knob and thus the ball
let mut textbuf = ArrayString::<[u8; 15]>::new();
write!(&mut textbuf, "count: {}", *counter).unwrap();
write!(&mut textbuf, "count: {}", counter).unwrap();
let count = Text::new(&textbuf, Point::new(20, 36))
.into_styled(TextStyle::new(Font6x8, BinaryColor::On));
display.clear();
c.draw(&mut display);
t.draw(&mut display);
count.draw(&mut display);
display.flush().unwrap();
// Move down+right, come back from the other side if we go off-screen
cx = *counter;
//cx += 1;
//if cx > (DISPLAY_W + C_RADIUS) { cx = -C_RADIUS };
// Control the horizontal position with the knob
cx = counter.min(0).max(DISPLAY_W);
// Wrap the ball back to the top when it falls off the bottom
cy += 1;
if cy > (DISPLAY_H + C_RADIUS) { cy = -C_RADIUS };
@ -193,30 +201,38 @@ fn main() -> ! {
}
fn init_encoder_pins(
clk: PA8<Input<Floating>>,
mut clk: PA8<Input<Floating>>,
dt: PA9<Input<Floating>>,
afio: &mut afio::Parts,
exti: &EXTI,
) {
let clk_pin = unsafe { &mut *CLK_PIN.as_mut_ptr() };
let dt_pin = unsafe { &mut *DT_PIN.as_mut_ptr() };
cortex_m::interrupt::free(|cs| {
clk.make_interrupt_source(afio);
clk.trigger_on_edge(exti, Edge::RISING_FALLING);
clk.enable_interrupt(exti);
*clk_pin = clk;
*dt_pin = dt;
clk_pin.make_interrupt_source(afio);
clk_pin.trigger_on_edge(exti, Edge::RISING_FALLING);
clk_pin.enable_interrupt(exti);
CLK_PIN.borrow(cs).replace(Some(clk)).unwrap();
DT_PIN.borrow(cs).replace(Some(dt)).unwrap();
});
}
#[interrupt]
fn EXTI9_5() {
static mut CLK: Option<CLKPIN> = None;
static mut DT: Option<DTPIN> = None;
static mut PREV_A: bool = false;
static mut PREV_C: bool = false;
let clk_pin = unsafe { &mut *CLK_PIN.as_mut_ptr() };
let dt_pin = unsafe { &mut *DT_PIN.as_mut_ptr() };
let counter = unsafe { &mut COUNT };
let clk_pin = CLK.get_or_insert_with(|| {
cortex_m::interrupt::free(|cs| {
CLK_PIN.borrow(cs).replace(None).unwrap()
})
});
let dt_pin = DT.get_or_insert_with(|| {
cortex_m::interrupt::free(|cs| {
DT_PIN.borrow(cs).replace(None).unwrap()
})
});
if clk_pin.check_interrupt() {
let a = clk_pin.is_high().unwrap();
@ -228,9 +244,17 @@ fn EXTI9_5() {
if b != *PREV_C {
*PREV_C = b;
if a == b { // Up
*counter = counter.wrapping_add(1);
cortex_m::interrupt::free(|cs| {
COUNT
.borrow(cs)
.replace_with(|count| count.wrapping_add(1))
});
} else { // Down
*counter = counter.wrapping_add(-1);
cortex_m::interrupt::free(|cs| {
COUNT
.borrow(cs)
.replace_with(|count| count.wrapping_add(-1))
});
}
}
}