use cortex_m::singleton; use stm32f1xx_hal::{afio, dma, pac, prelude::*, rcc, serial}; 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( usart: pac::USART1, pins: PINS, mapr: &mut afio::MAPR, channel: dma::dma1::C4, clocks: &rcc::Clocks, ) -> Self where PINS: serial::Pins, { // Serial config let serial = serial::Serial::new(usart, pins, mapr, 250_000.bps(), &clocks); Self::Idle(DMXIdle { tx: Some(serial.tx.with_dma(channel)), txbuffer: None, }) } pub fn send(&mut self, data: &[u8; 512]) { 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); *self = Self::Busy(Some(tx.write(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), }); } } }