diff --git a/bluepill-rs/src/dmx.rs b/bluepill-rs/src/dmx.rs index b1112ce..3b1ce54 100644 --- a/bluepill-rs/src/dmx.rs +++ b/bluepill-rs/src/dmx.rs @@ -1,46 +1,60 @@ -#![allow(unsafe_code)] - use cortex_m::singleton; -use stm32f1xx_hal::{afio, dma, gpio, pac, prelude::*, rcc, serial}; +use stm32f1xx_hal::{afio, dma, pac, prelude::*, rcc, serial}; -pub struct DMX { - tx: Option, dma::dma1::C4>>, +type _TxDma = dma::TxDma, dma::dma1::C4>; + +pub struct DMXIdle { + tx: Option<_TxDma>, txbuffer: Option<&'static mut [u8; 512]>, } +pub enum DMX { + Idle(DMXIdle), + Busy(Option>), +} + impl DMX { - pub fn new( + pub fn new( usart: pac::USART1, - pins: ( - gpio::Pin<'A', 9, gpio::Alternate>, - gpio::Pin<'A', 10>, - ), + pins: PINS, mapr: &mut afio::MAPR, channel: dma::dma1::C4, clocks: &rcc::Clocks, - ) -> Self { + ) -> Self + where + PINS: serial::Pins, + { // Serial config let serial = serial::Serial::new(usart, pins, mapr, 250_000.bps(), &clocks); - Self { + Self::Idle(DMXIdle { tx: Some(serial.tx.with_dma(channel)), txbuffer: None, - } + }) } pub fn send(&mut self, data: &[u8; 512]) { - if let Some(mut tx) = self.tx.take() { - let mut txbuffer = match self.txbuffer.take() { - Some(buf) => buf, - None => singleton!(: [u8; 512] = [0; 512]).unwrap(), - }; + if let Self::Idle(idle) = self { + let txbuffer = idle + .txbuffer + .take() + .unwrap_or_else(|| singleton!(: [u8; 512] = [0; 512]).unwrap()); + let tx = idle.tx.take().unwrap(); txbuffer.copy_from_slice(data); - let xfer = tx.write(txbuffer); + *self = Self::Busy(Some(tx.write(txbuffer))) + } + } - (txbuffer, tx) = xfer.wait(); - self.tx.replace(tx); - self.txbuffer.replace(txbuffer); + pub fn wait(&mut self) { + if let Self::Busy(xfer) = self { + let xfer = xfer.take().unwrap(); + let (txbuffer, tx) = xfer.wait(); + + *self = Self::Idle(DMXIdle { + tx: Some(tx), + txbuffer: Some(txbuffer), + }); } } } diff --git a/bluepill-rs/src/main.rs b/bluepill-rs/src/main.rs index b15891b..6dc0c4d 100644 --- a/bluepill-rs/src/main.rs +++ b/bluepill-rs/src/main.rs @@ -100,6 +100,8 @@ mod app { cx.local.delay_us.delay(1.secs()); cx.local.led.set_low(); + + cx.local.dmx.wait(); } } }