Skip to content

Instantly share code, notes, and snippets.

@brandonros
Created May 8, 2022 00:58
Show Gist options
  • Save brandonros/1408557cc44606d92e7a3a15640d6c50 to your computer and use it in GitHub Desktop.
Save brandonros/1408557cc44606d92e7a3a15640d6c50 to your computer and use it in GitHub Desktop.
#![no_main]
#![no_std]
use panic_probe as _;
use core::{cell::RefCell, ops::Deref};
use cortex_m::interrupt::{Mutex, free};
use cortex_m_rt::entry;
use stm32f4xx_hal::{
gpio::{Alternate, PA8, PC6},
pac::{interrupt, Interrupt, Peripherals, TIM1, TIM8},
prelude::*,
timer::{Timer, PwmInput}
};
use rtt_target::{rprintln, rtt_init_print};
/*
FS-IA6B receiver
PC6 = CH1 = right joystick left + right
PC8 = CH2 = right joystick up + down
x = CH3 = left joystick up + down
x = CH4 = left joystick left + right
x = CH5 = VRA dial
x = CH6 = VRB dial
*/
static PC6_MONITOR: Mutex<RefCell<Option<PwmInput<TIM8, PC6<Alternate<3>>>>>> = Mutex::new(RefCell::new(None));
static PA8_MONITOR: Mutex<RefCell<Option<PwmInput<TIM1, PA8<Alternate<1>>>>>> = Mutex::new(RefCell::new(None));
#[interrupt]
fn TIM8_CC() {
free(|cs| {
let pc6_monitor_ref = PC6_MONITOR.borrow(cs).borrow();
if let Some(ref pc6_monitor) = pc6_monitor_ref.deref() {
// TODO: clear interrupt?
// throw out invalid captures
if pc6_monitor.is_valid_capture() == false {
return;
}
// read PWM input
let duty_cycle = pc6_monitor.get_duty_cycle();
rprintln!("pc6: {}", duty_cycle);
}
});
}
#[interrupt]
fn TIM1_CC() {
free(|cs| {
let pa8_monitor_ref = PA8_MONITOR.borrow(cs).borrow();
if let Some(ref pa8_monitor) = pa8_monitor_ref.deref() {
// TODO: clear interrupt?
// throw out invalid captures
if pa8_monitor.is_valid_capture() == false {
return;
}
// read PWM input
let duty_cycle = pa8_monitor.get_duty_cycle();
rprintln!("pa8: {}", duty_cycle);
}
});
}
#[entry]
fn main() -> ! {
// enable console
rtt_init_print!();
// get peripherals + clocks
let dp = Peripherals::take().unwrap();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze();
let gpioa = dp.GPIOA.split();
let gpioc = dp.GPIOC.split();
// setup GIPOC.PC6 as PWM input on TIM8_CH1
let tim8_timer = Timer::new(dp.TIM8, &clocks);
let pc6_pin = gpioc.pc6.into_alternate();
let pc6_frequency = 1.Hz();
let pc6_monitor = tim8_timer.pwm_input(pc6_frequency, pc6_pin);
free(|cs| {
PC6_MONITOR.borrow(cs).replace(Some(pc6_monitor));
});
// setup GIPOC.PA8 as PWM input on TIM1_CH1
let tim1_timer = Timer::new(dp.TIM1, &clocks);
let pa8_pin = gpioa.pa8.into_alternate();
let pa8_frequency = 1.Hz();
let pa8_monitor = tim1_timer.pwm_input(pa8_frequency, pa8_pin);
free(|cs| {
PA8_MONITOR.borrow(cs).replace(Some(pa8_monitor));
});
// enable interrupts
unsafe {
cortex_m::peripheral::NVIC::unmask(Interrupt::TIM1_CC);
cortex_m::peripheral::NVIC::unmask(Interrupt::TIM8_CC);
}
// do not do wfi, it messes with debugger
loop {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment