use cortex_m::singleton; use stm32f1xx_hal::{dma, pac, prelude::*, rcc, serial}; type _TxDma = dma::TxDma, dma::dma1::C4>; type _DMXUniverse = &'static mut [u8; DMX_LEN]; type _DMXTransfer = dma::Transfer, _TxDma>; pub enum DMX { Idle(Option<_TxDma>, Option<_DMXUniverse>), Busy(Option<_DMXTransfer>), } impl DMX { pub fn new( mut serial: serial::Serial, channel: dma::dma1::C4, clocks: &rcc::Clocks, ) -> Self where PINS: serial::Pins, { serial.reconfigure(250_000.bps(), &clocks).unwrap(); Self::Idle(Some(serial.tx.with_dma(channel)), None) } pub fn send(&mut self, data: &[u8; DMX_LEN]) { if let Self::Busy(_) = self { self.wait(); } let Self::Idle(tx, txbuffer) = self else { panic!("Broken DMX State!") }; let txbuffer = txbuffer.take().unwrap_or_else(|| { let foo = singleton!(: [u8; 512] = [0u8; 512]).unwrap(); (&mut foo[..DMX_LEN]).try_into().unwrap() }); let tx = tx.take().unwrap(); txbuffer.copy_from_slice(data); *self = Self::Busy(Some(tx.write(txbuffer))); } pub fn wait(&mut self) { let Self::Busy(xfer) = self else { return }; let xfer = xfer.take().unwrap(); let (txbuffer, tx) = xfer.wait(); *self = Self::Idle(Some(tx), Some(txbuffer)); } }