diff --git a/bluepill-rs/src/dmx.rs b/bluepill-rs/src/dmx.rs new file mode 100644 index 0000000..b1112ce --- /dev/null +++ b/bluepill-rs/src/dmx.rs @@ -0,0 +1,46 @@ +#![allow(unsafe_code)] + +use cortex_m::singleton; +use stm32f1xx_hal::{afio, dma, gpio, pac, prelude::*, rcc, serial}; + +pub struct DMX { + tx: Option, dma::dma1::C4>>, + txbuffer: Option<&'static mut [u8; 512]>, +} + +impl DMX { + pub fn new( + usart: pac::USART1, + pins: ( + gpio::Pin<'A', 9, gpio::Alternate>, + gpio::Pin<'A', 10>, + ), + mapr: &mut afio::MAPR, + channel: dma::dma1::C4, + clocks: &rcc::Clocks, + ) -> Self { + // Serial config + let serial = serial::Serial::new(usart, pins, mapr, 250_000.bps(), &clocks); + + Self { + 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(), + }; + + txbuffer.copy_from_slice(data); + let xfer = tx.write(txbuffer); + + (txbuffer, tx) = xfer.wait(); + self.tx.replace(tx); + self.txbuffer.replace(txbuffer); + } + } +} diff --git a/bluepill-rs/src/main.rs b/bluepill-rs/src/main.rs index 333c3db..b15891b 100644 --- a/bluepill-rs/src/main.rs +++ b/bluepill-rs/src/main.rs @@ -2,18 +2,21 @@ #![no_std] #![no_main] -mod i2c_reg_slave; -mod i2c_slave; +// mod i2c_reg_slave; +// mod i2c_slave; +mod dmx; // extern crate panic_halt; extern crate panic_semihosting; -#[rtic::app(device = stm32f1xx_hal::pac)] +#[rtic::app(device = stm32f1xx_hal::pac, dispatchers = [DMA1_CHANNEL4])] mod app { use cortex_m::singleton; - use stm32f1xx_hal::{dma, gpio, pac, prelude::*, serial, timer}; + use stm32f1xx_hal::{gpio, pac, prelude::*, timer}; use systick_monotonic::Systick; + use crate::dmx::DMX; + // A monotonic timer to enable scheduling in RTIC #[monotonic(binds = SysTick, default = true)] type MyMono = Systick<100>; // 100 Hz / 10 ms granularity @@ -25,8 +28,7 @@ mod app { #[local] struct Local { - tx: Option, dma::dma1::C4>>, - txbuffer: Option<&'static mut [u8; 512]>, + dmx: DMX, delay_us: timer::DelayUs, led: gpio::gpioc::PC13, } @@ -59,14 +61,14 @@ mod app { let dma1 = cx.device.DMA1.split(); // Serial config - let serial = serial::Serial::new( + let dmx = DMX::new( cx.device.USART1, ( - gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh), + gpioa.pa9.into_alternate_open_drain(&mut gpioa.crh), gpioa.pa10, //.into_pull_up_input(&mut gpioa.crh), ), &mut afio.mapr, - 250_000.bps(), + dma1.4, &clocks, ); @@ -75,8 +77,7 @@ mod app { buffer: singleton!(: [u8; 512] = [0b01010101; 512]).unwrap(), }, Local { - tx: Some(serial.tx.with_dma(dma1.4)), - txbuffer: Some(singleton!(: [u8; 512] = [0; 512]).unwrap()), + dmx: dmx, // Configure timer delay_us: cx.device.TIM2.delay_us(&clocks), @@ -89,24 +90,16 @@ mod app { ) } - #[idle(local = [tx, txbuffer, delay_us, led], shared = [&buffer])] + #[idle(local = [dmx, delay_us, led], shared = [&buffer])] fn idle(cx: idle::Context) -> ! { loop { - let mut tx = cx.local.tx.take().unwrap(); - let mut txbuffer = cx.local.txbuffer.take().unwrap(); - - txbuffer.copy_from_slice(*cx.shared.buffer); - let xfer = tx.write(txbuffer); + cx.local.dmx.send(cx.shared.buffer); cx.local.delay_us.delay(1.secs()); cx.local.led.set_high(); cx.local.delay_us.delay(1.secs()); cx.local.led.set_low(); - - (txbuffer, tx) = xfer.wait(); - cx.local.tx.replace(tx); - cx.local.txbuffer.replace(txbuffer); } } }