Mapper tool for decoding charlieplex
This commit is contained in:
185
firmware/src/main.rs
Normal file → Executable file
185
firmware/src/main.rs
Normal file → Executable file
@@ -1,28 +1,48 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use panic_halt as _;
|
||||
use cortex_m_rt::entry;
|
||||
use stm32f0xx_hal::serial::Error;
|
||||
use stm32f0xx_hal as hal;
|
||||
use hal::prelude::*;
|
||||
use hal::stm32;
|
||||
use hal::{
|
||||
delay::Delay,
|
||||
serial::Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use stm32f0xx_hal as hal;
|
||||
|
||||
use defmt::info;
|
||||
use defmt_rtt as _;
|
||||
|
||||
use embedded_midi::Channel;
|
||||
use hal::{delay::Delay, serial::Serial};
|
||||
|
||||
defmt::timestamp!("{=u32}", {
|
||||
static mut COUNTER: u32 = 0;
|
||||
unsafe {
|
||||
COUNTER = COUNTER.wrapping_add(1);
|
||||
COUNTER
|
||||
}
|
||||
});
|
||||
|
||||
struct Bus {
|
||||
latch_en: stm32f0xx_hal::gpio::gpioa::PA0<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
select_en: stm32f0xx_hal::gpio::gpiob::PB8<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::OpenDrain>>,
|
||||
pb0: stm32f0xx_hal::gpio::gpiob::PB0<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb1: stm32f0xx_hal::gpio::gpiob::PB1<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb2: stm32f0xx_hal::gpio::gpiob::PB2<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb3: stm32f0xx_hal::gpio::gpiob::PB3<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb4: stm32f0xx_hal::gpio::gpiob::PB4<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb5: stm32f0xx_hal::gpio::gpiob::PB5<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb6: stm32f0xx_hal::gpio::gpiob::PB6<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb7: stm32f0xx_hal::gpio::gpiob::PB7<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
latch_en:
|
||||
stm32f0xx_hal::gpio::gpioa::PA0<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
select_en: stm32f0xx_hal::gpio::gpiob::PB8<
|
||||
stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::OpenDrain>,
|
||||
>,
|
||||
pb0:
|
||||
stm32f0xx_hal::gpio::gpiob::PB0<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb1:
|
||||
stm32f0xx_hal::gpio::gpiob::PB1<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb2:
|
||||
stm32f0xx_hal::gpio::gpiob::PB2<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb3:
|
||||
stm32f0xx_hal::gpio::gpiob::PB3<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb4:
|
||||
stm32f0xx_hal::gpio::gpiob::PB4<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb5:
|
||||
stm32f0xx_hal::gpio::gpiob::PB5<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb6:
|
||||
stm32f0xx_hal::gpio::gpiob::PB6<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
pb7:
|
||||
stm32f0xx_hal::gpio::gpiob::PB7<stm32f0xx_hal::gpio::Output<stm32f0xx_hal::gpio::PushPull>>,
|
||||
}
|
||||
|
||||
#[entry]
|
||||
@@ -30,9 +50,11 @@ fn main() -> ! {
|
||||
// Get device peripherals
|
||||
let mut dp = stm32::Peripherals::take().unwrap();
|
||||
let cp = cortex_m::Peripherals::take().unwrap();
|
||||
|
||||
|
||||
// Configure the clock to 48 MHz
|
||||
let mut rcc = dp.RCC.configure()
|
||||
let mut rcc = dp
|
||||
.RCC
|
||||
.configure()
|
||||
.hsi48()
|
||||
.enable_crs(dp.CRS)
|
||||
.sysclk(48.mhz())
|
||||
@@ -41,56 +63,105 @@ fn main() -> ! {
|
||||
|
||||
// Set up delay provider
|
||||
let mut delay = Delay::new(cp.SYST, &rcc);
|
||||
|
||||
|
||||
// Configure GPIO
|
||||
let gpioa = dp.GPIOA.split(&mut rcc);
|
||||
let gpiob = dp.GPIOB.split(&mut rcc);
|
||||
|
||||
let mut bus = cortex_m::interrupt::free(|cs| {
|
||||
Bus {
|
||||
latch_en: gpioa.pa0.into_push_pull_output(cs),
|
||||
select_en: gpiob.pb8.into_open_drain_output(cs),
|
||||
pb0: gpiob.pb0.into_push_pull_output(cs),
|
||||
pb1: gpiob.pb1.into_push_pull_output(cs),
|
||||
pb2: gpiob.pb2.into_push_pull_output(cs),
|
||||
pb3: gpiob.pb3.into_push_pull_output(cs),
|
||||
pb4: gpiob.pb4.into_push_pull_output(cs),
|
||||
pb5: gpiob.pb5.into_push_pull_output(cs),
|
||||
pb6: gpiob.pb6.into_push_pull_output(cs),
|
||||
pb7: gpiob.pb7.into_push_pull_output(cs),
|
||||
}
|
||||
let button_1_5 = cortex_m::interrupt::free(|cs| gpiob.pb11.into_floating_input(cs));
|
||||
|
||||
let button_6_10 = cortex_m::interrupt::free(|cs| gpiob.pb13.into_floating_input(cs));
|
||||
|
||||
let mut bus = cortex_m::interrupt::free(|cs| Bus {
|
||||
latch_en: gpioa.pa0.into_push_pull_output(cs),
|
||||
select_en: gpiob.pb8.into_open_drain_output(cs),
|
||||
pb0: gpiob.pb0.into_push_pull_output(cs),
|
||||
pb1: gpiob.pb1.into_push_pull_output(cs),
|
||||
pb2: gpiob.pb2.into_push_pull_output(cs),
|
||||
pb3: gpiob.pb3.into_push_pull_output(cs),
|
||||
pb4: gpiob.pb4.into_push_pull_output(cs),
|
||||
pb5: gpiob.pb5.into_push_pull_output(cs),
|
||||
pb6: gpiob.pb6.into_push_pull_output(cs),
|
||||
pb7: gpiob.pb7.into_push_pull_output(cs),
|
||||
});
|
||||
|
||||
let mut serial = cortex_m::interrupt::free(|cs| {
|
||||
// Configure serial port
|
||||
let serial = cortex_m::interrupt::free(|cs| {
|
||||
let tx = gpioa.pa9.into_alternate_af1(cs);
|
||||
let rx = gpioa.pa10.into_alternate_af1(cs);
|
||||
//dp.USART1.cr1.write(|w| w.uesm().enabled());
|
||||
Serial::usart1(dp.USART1, (tx, rx), 31_250.bps(), &mut rcc)
|
||||
});
|
||||
|
||||
// Loop
|
||||
let (_tx, rx) = serial.split();
|
||||
let mut midi = embedded_midi::MidiIn::new(rx);
|
||||
|
||||
// Main loop
|
||||
let mut ic_03: u8 = 0;
|
||||
let mut ic_10: u8 = 0;
|
||||
let mut ic_11: u8 = 0;
|
||||
|
||||
loop {
|
||||
use stm32f0xx_hal::serial::Error;
|
||||
//type Error = nb::Error<stm32f0xx_hal::serial::Error>;
|
||||
//use embedded_hal::serial::nb::Error;
|
||||
match serial.read() {
|
||||
Ok(_) => {
|
||||
let message = midi.read();
|
||||
match message {
|
||||
Ok(embedded_midi::MidiMessage::ControlChange(channel, control, value))
|
||||
if channel == Channel::new(0) =>
|
||||
{
|
||||
bus.led_button_1(&mut delay);
|
||||
if control == embedded_midi::Control::new(20) {
|
||||
bus.led_button_2(&mut delay);
|
||||
ic_03 = value.into();
|
||||
} else if control == embedded_midi::Control::new(21) {
|
||||
bus.led_button_2(&mut delay);
|
||||
let value: u8 = value.into();
|
||||
ic_03 = 128_u8 + value;
|
||||
} else if control == embedded_midi::Control::new(22) {
|
||||
bus.led_button_2(&mut delay);
|
||||
ic_10 = value.into();
|
||||
} else if control == embedded_midi::Control::new(23) {
|
||||
bus.led_button_2(&mut delay);
|
||||
let value: u8 = value.into();
|
||||
ic_10 = 128_u8 + value;
|
||||
} else if control == embedded_midi::Control::new(24) {
|
||||
bus.led_button_2(&mut delay);
|
||||
ic_11 = value.into();
|
||||
} else if control == embedded_midi::Control::new(25) {
|
||||
bus.led_button_2(&mut delay);
|
||||
let value: u8 = value.into();
|
||||
ic_11 = 128_u8 + value;
|
||||
}
|
||||
bus.output(03, ic_03, &mut delay);
|
||||
bus.output(10, ic_10, &mut delay);
|
||||
bus.output(11, ic_11, &mut delay);
|
||||
}
|
||||
Err(nb::Error::WouldBlock) => {
|
||||
bus.led_button_3(&mut delay);
|
||||
Ok(_) => {
|
||||
info!("unhandled midi message");
|
||||
}
|
||||
Err(nb::Error::Other(Error::Framing)) => {
|
||||
bus.led_button_2(&mut delay);
|
||||
Err(nb::Error::WouldBlock) => {}
|
||||
Err(nb::Error::Other(hal::serial::Error::Framing)) => {
|
||||
info!("Error::Framing");
|
||||
}
|
||||
Err(nb::Error::Other(Error::Noise)) => {
|
||||
bus.led_button_9(&mut delay);
|
||||
Err(nb::Error::Other(hal::serial::Error::Noise)) => {
|
||||
info!("Error::Noise");
|
||||
}
|
||||
Err(nb::Error::Other(hal::serial::Error::Overrun)) => {
|
||||
info!("Error::Overrun");
|
||||
}
|
||||
Err(nb::Error::Other(hal::serial::Error::Parity)) => {
|
||||
info!("Error::Parity");
|
||||
}
|
||||
Err(nb::Error::Other(_)) => {
|
||||
bus.led_button_10(&mut delay);
|
||||
info!("Error::Other");
|
||||
}
|
||||
}
|
||||
delay.delay_ms(1000u16);
|
||||
if button_1_5.is_high().unwrap_or(false) {
|
||||
info!("Button 1-5 pressed");
|
||||
delay.delay_ms(500u16);
|
||||
}
|
||||
|
||||
if button_6_10.is_high().unwrap_or(false) {
|
||||
info!("Button 6-10 pressed");
|
||||
delay.delay_ms(500u16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,11 +174,11 @@ impl Bus {
|
||||
|
||||
_ => self.select(2, delay),
|
||||
}
|
||||
delay.delay_ms(10u16);
|
||||
delay.delay_us(1u16);
|
||||
self.select_en(true);
|
||||
delay.delay_ms(10u16);
|
||||
delay.delay_us(1u16);
|
||||
self.write(data);
|
||||
delay.delay_ms(10u16);
|
||||
delay.delay_us(1u16);
|
||||
self.select_en(false);
|
||||
}
|
||||
|
||||
@@ -128,7 +199,7 @@ impl Bus {
|
||||
|
||||
fn select(&mut self, line: u8, delay: &mut Delay) {
|
||||
self.select_en.set_low().ok();
|
||||
delay.delay_ms(10u16);
|
||||
delay.delay_us(1u16);
|
||||
match line {
|
||||
0 => {
|
||||
self.pb0.set_low().ok();
|
||||
@@ -212,11 +283,11 @@ impl Bus {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
delay.delay_ms(10u16);
|
||||
delay.delay_us(1u16);
|
||||
self.latch_en.set_high().ok();
|
||||
delay.delay_ms(10u16);
|
||||
delay.delay_us(1u16);
|
||||
self.latch_en.set_low().ok();
|
||||
delay.delay_ms(10u16);
|
||||
delay.delay_us(1u16);
|
||||
self.select_en.set_high().ok();
|
||||
}
|
||||
|
||||
@@ -249,4 +320,4 @@ impl Bus {
|
||||
self.output(10, 0b0001_0000, delay);
|
||||
self.output(11, 0b0000_0000, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user