/src/peripherals.rs
mod keyboard;
mod usbdev;
use core::cell::RefCell;
use crate::bsp;
use crate::mpu::init_mpu;
use crate::timer::init_timer;
use bsp::hal::clocks::init_clocks_and_plls;
use bsp::hal::gpio;
use bsp::hal::pac;
use bsp::hal::watchdog::Watchdog;
use bsp::hal::Sio;
use bsp::hal::Timer;
use bsp::Pins;
use cortex_m::peripheral::scb::SystemHandler;
use critical_section::Mutex;
use embedded_hal::digital::v2::PinState;
pub use keyboard::Keyboard;
use usbdev::init_usb;
pub use usbdev::with_usb;
const EXTERNAL_XTAL_FREQ_HZ: u32 = 12_000_000;
static PERIPHERALS: Mutex<RefCell<Option<Peripherals>>> = Mutex::new(RefCell::new(None));
type LedPin = gpio::Pin<gpio::bank0::Gpio7, gpio::FunctionSioOutput, gpio::PullNone>;
pub struct Peripherals {
watchdog: Watchdog,
timer: Timer,
led: LedPin,
keyboard: Keyboard,
}
impl Peripherals {
pub fn timer(&mut self) -> &mut Timer {
&mut self.timer
}
pub fn led(&mut self) -> &mut LedPin {
&mut self.led
}
pub fn keyboard(&mut self) -> &mut Keyboard {
&mut self.keyboard
}
}
pub fn init_peripherals() {
let mut core = pac::CorePeripherals::take().unwrap();
// Set some core exception priorities
unsafe {
core.SCB.set_priority(SystemHandler::SysTick, 0xFF);
core.SCB.set_priority(SystemHandler::SVCall, 0xFF);
core.SCB.set_priority(SystemHandler::PendSV, 0xFF);
}
let mut platform = pac::Peripherals::take().unwrap();
let mut watchdog = Watchdog::new(platform.WATCHDOG);
let clocks = init_clocks_and_plls(
EXTERNAL_XTAL_FREQ_HZ,
platform.XOSC,
platform.CLOCKS,
platform.PLL_SYS,
platform.PLL_USB,
&mut platform.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let sio = Sio::new(platform.SIO);
let pins = Pins::new(
platform.IO_BANK0,
platform.PADS_BANK0,
sio.gpio_bank0,
&mut platform.RESETS,
);
let led = pins.led.into_push_pull_output().into_pull_type();
let keyboard = Keyboard::new(
[
pins.kb_c1.into_pull_up_input().into_dyn_pin(),
pins.kb_c2.into_pull_up_input().into_dyn_pin(),
pins.kb_c3.into_pull_up_input().into_dyn_pin(),
pins.kb_c4.into_pull_up_input().into_dyn_pin(),
pins.kb_c5.into_pull_up_input().into_dyn_pin(),
pins.kb_c6.into_pull_up_input().into_dyn_pin(),
pins.kb_c7.into_pull_up_input().into_dyn_pin(),
pins.kb_c8.into_pull_up_input().into_dyn_pin(),
pins.kb_c9.into_pull_up_input().into_dyn_pin(),
],
[
pins.kb_r1
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r2
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r3
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r4
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r5
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r6
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r7
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r8
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
pins.kb_r9
.into_push_pull_output_in_state(PinState::High)
.into_pull_type()
.into_dyn_pin(),
],
);
init_timer(core.SYST);
let timer = Timer::new(platform.TIMER, &mut platform.RESETS, &clocks);
init_usb(
platform.USBCTRL_REGS,
platform.USBCTRL_DPRAM,
clocks.usb_clock,
&mut platform.RESETS,
);
unsafe {
pac::NVIC::unmask(pac::Interrupt::USBCTRL_IRQ);
}
init_mpu(core.MPU);
critical_section::with(|cs| {
let mut peripherals = PERIPHERALS.borrow_ref_mut(cs);
*peripherals = Some(Peripherals {
watchdog,
timer,
led,
keyboard,
});
})
}
pub fn with_peripherals<F, R>(mut f: F) -> R
where
F: FnMut(&mut Peripherals) -> R,
{
critical_section::with(|cs| {
let mut peripherals = PERIPHERALS.borrow_ref_mut(cs);
if let Some(ref mut peripherals) = *peripherals {
f(peripherals)
} else {
panic!("Peripherals not initialized");
}
})
}