diff --git a/firmware/faderboard/src/main.rs b/firmware/faderboard/src/main.rs index 7d16e02..1becd8a 100644 --- a/firmware/faderboard/src/main.rs +++ b/firmware/faderboard/src/main.rs @@ -11,20 +11,22 @@ use panic_halt as _; use stm32f0xx_hal as hal; use hal::adc::Adc; -use hal::pac::Peripherals; +use hal::delay::Delay; +use hal::pac::{CorePeripherals, Peripherals}; use hal::prelude::*; use hal::pwm; use hal::usb::{Peripheral, UsbBus}; -use touch::Touch; +use touch::{SysCfg, Touch}; use usb::Usb; #[entry] fn main() -> ! { let mut p = Peripherals::take().unwrap(); + let cp = CorePeripherals::take().unwrap(); - let touch = Touch::new(p.SYSCFG, p.EXTI, &mut p.RCC); + let sys_cfg = SysCfg::new(p.SYSCFG, &mut p.RCC); let mut rcc = p .RCC @@ -133,7 +135,10 @@ fn main() -> ! { let mut _pwm6 = pwm::tim1(p.TIM1, pwm6_pin, &mut rcc, 250.khz()); let (mut _pwm8, mut _pwm7) = pwm::tim15(p.TIM15, (pwm8_pin, pwm7_pin), &mut rcc, 250.khz()); - touch.setup(); + let delay = Delay::new(cp.SYST, &mut rcc); + + let touch = Touch::new(sys_cfg, p.EXTI, delay.clone()); + touch.enable(); loop { usb.poll(); diff --git a/firmware/faderboard/src/touch.rs b/firmware/faderboard/src/touch.rs index 0ba875a..729eece 100644 --- a/firmware/faderboard/src/touch.rs +++ b/firmware/faderboard/src/touch.rs @@ -1,79 +1,214 @@ +use core::cell::RefCell; + +use cortex_m::interrupt::{CriticalSection, Mutex}; + +use stm32f0xx_hal::delay::Delay; use stm32f0xx_hal::pac::{interrupt, Interrupt, EXTI, RCC, SYSCFG}; -pub struct Touch { - exti: EXTI, +static GLOBALS: Mutex>> = Mutex::new(RefCell::new(None)); + +pub struct SysCfg { syscfg: SYSCFG, } -impl Touch { - pub fn new(syscfg: SYSCFG, exti: EXTI, rcc: &mut RCC) -> Self { - cortex_m::interrupt::free(|_| rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit())); +impl SysCfg { + pub fn new(syscfg: SYSCFG, rcc: &mut RCC) -> Self { + cortex_m::interrupt::free(|_| { + rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit()); + }); - Self { exti, syscfg } + Self { syscfg } } - pub fn setup(&self) { - cortex_m::interrupt::free(|_| { - self.syscfg.exticr1.modify(|_, w| { - w.exti0().pb0(); - w.exti1().pb1(); - w.exti2().pb2(); - w - }); - self.syscfg.exticr3.modify(|_, w| { - w.exti10().pb10(); - w.exti11().pb11(); - w - }); - self.syscfg.exticr4.modify(|_, w| { - w.exti13().pc13(); - w.exti14().pc14(); - w.exti15().pc15(); - w - }); + fn take(self) -> SYSCFG { + self.syscfg + } +} - self.exti.imr.modify(|_, w| { - w.mr0().unmasked(); - w.mr1().unmasked(); - w.mr2().unmasked(); - w.mr10().unmasked(); - w.mr11().unmasked(); - w.mr13().unmasked(); - w.mr14().unmasked(); - w.mr15().unmasked(); - w - }); +pub struct Touch; - self.exti.rtsr.modify(|_, w| { - w.tr0().enabled(); - w.tr1().enabled(); - w.tr2().enabled(); - w.tr10().enabled(); - w.tr11().enabled(); - w.tr13().enabled(); - w.tr14().enabled(); - w.tr15().enabled(); - w - }); +impl Touch { + pub fn new(sys_cfg: SysCfg, exti: EXTI, delay: Delay) -> Self { + let _ = cortex_m::interrupt::free(|cs| { + GLOBALS + .borrow(cs) + .replace(Some(Globals::new(sys_cfg.take(), exti, delay))) + }); - unsafe { - cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI0_1); - cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI2_3); - cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI4_15); - } + Self + } - cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI0_1); - cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI2_3); - cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI4_15); + pub fn enable(&self) { + cortex_m::interrupt::free(|cs| { + GLOBALS + .borrow(cs) + .borrow() + .as_ref() + .expect("GLOBALS should not be None") + .setup_interrupts(cs) }); } } -#[interrupt] -fn EXTI0_1() {} +struct Globals { + syscfg: SYSCFG, + exti: EXTI, + /// Currently only used to ensure SysTick timer is set up correctly + #[allow(dead_code)] + delay: Delay, +} + +impl Globals { + fn new(syscfg: SYSCFG, exti: EXTI, delay: Delay) -> Self { + Self { + syscfg, + exti, + delay, + } + } + + fn setup_interrupts(&self, _cs: &CriticalSection) { + self.syscfg.exticr1.modify(|_, w| { + w.exti0().pb0(); + w.exti1().pb1(); + w.exti2().pb2(); + w + }); + self.syscfg.exticr3.modify(|_, w| { + w.exti10().pb10(); + w.exti11().pb11(); + w + }); + self.syscfg.exticr4.modify(|_, w| { + w.exti13().pc13(); + w.exti14().pc14(); + w.exti15().pc15(); + w + }); + + self.exti.imr.modify(|_, w| { + w.mr0().unmasked(); + w.mr1().unmasked(); + w.mr2().unmasked(); + w.mr10().unmasked(); + w.mr11().unmasked(); + w.mr13().unmasked(); + w.mr14().unmasked(); + w.mr15().unmasked(); + w + }); + + self.exti.rtsr.modify(|_, w| { + w.tr0().enabled(); + w.tr1().enabled(); + w.tr2().enabled(); + w.tr10().enabled(); + w.tr11().enabled(); + w.tr13().enabled(); + w.tr14().enabled(); + w.tr15().enabled(); + w + }); + + unsafe { + cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI0_1); + cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI2_3); + cortex_m::peripheral::NVIC::unmask(Interrupt::EXTI4_15); + } + + cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI0_1); + cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI2_3); + cortex_m::peripheral::NVIC::unpend(Interrupt::EXTI4_15); + } +} #[interrupt] -fn EXTI2_3() {} +fn EXTI0_1() { + cortex_m::interrupt::free(|cs| { + if let Some(globals) = GLOBALS.borrow(cs).borrow().as_ref() { + let pr = &globals.exti.pr; + + if pr.read().pif0().is_pending() { + pr.write(|w| w.pif0().set_bit()); + } + + if pr.read().pif1().is_pending() { + pr.write(|w| w.pif1().set_bit()); + } + } + }); +} #[interrupt] -fn EXTI4_15() {} +fn EXTI2_3() { + cortex_m::interrupt::free(|cs| { + if let Some(globals) = GLOBALS.borrow(cs).borrow().as_ref() { + let pr = &globals.exti.pr; + + if pr.read().pif2().is_pending() { + pr.write(|w| w.pif2().set_bit()); + } + + if pr.read().pif3().is_pending() { + pr.write(|w| w.pif3().set_bit()); + } + } + }); +} + +#[interrupt] +fn EXTI4_15() { + cortex_m::interrupt::free(|cs| { + if let Some(globals) = GLOBALS.borrow(cs).borrow().as_ref() { + let pr = &globals.exti.pr; + + if pr.read().pif4().is_pending() { + pr.write(|w| w.pif4().set_bit()); + } + + if pr.read().pif5().is_pending() { + pr.write(|w| w.pif5().set_bit()); + } + + if pr.read().pif6().is_pending() { + pr.write(|w| w.pif6().set_bit()); + } + + if pr.read().pif7().is_pending() { + pr.write(|w| w.pif7().set_bit()); + } + + if pr.read().pif8().is_pending() { + pr.write(|w| w.pif8().set_bit()); + } + + if pr.read().pif9().is_pending() { + pr.write(|w| w.pif9().set_bit()); + } + + if pr.read().pif10().is_pending() { + pr.write(|w| w.pif10().set_bit()); + } + + if pr.read().pif11().is_pending() { + pr.write(|w| w.pif11().set_bit()); + } + + if pr.read().pif12().is_pending() { + pr.write(|w| w.pif12().set_bit()); + } + + if pr.read().pif13().is_pending() { + pr.write(|w| w.pif13().set_bit()); + } + + if pr.read().pif14().is_pending() { + pr.write(|w| w.pif14().set_bit()); + } + + if pr.read().pif15().is_pending() { + pr.write(|w| w.pif15().set_bit()); + } + } + }); +}