diff --git a/bluepill-rs/src/dmx2.rs b/bluepill-rs/src/dmx2.rs index 88d9c8d..595759d 100644 --- a/bluepill-rs/src/dmx2.rs +++ b/bluepill-rs/src/dmx2.rs @@ -1,4 +1,4 @@ -use stm32f1xx_hal::{dma, pac, prelude::*, serial}; +use stm32f1xx_hal::{afio, dma, pac, prelude::*, rcc, serial}; type TxDma = dma::TxDma, dma::dma1::C4>; type DMXUniverse = &'static mut [u8; DMX_LEN]; @@ -79,7 +79,18 @@ pub struct DMX { } impl DMX { - pub fn new(mem: &'static mut [u8]) -> Self { + pub fn new( + mem: &'static mut [u8], + mut dma_channel: dma::dma1::C4, + nvic: &mut pac::NVIC, + usart: pac::USART1, + pins: PINS, + mapr: &mut afio::MAPR, + clocks: &rcc::Clocks, + ) -> Self + where + PINS: serial::Pins, + { // use provided memory region assert!(mem.len() >= DMX_LEN * 2); @@ -93,39 +104,16 @@ impl DMX { (tx_universe, tx_buffer) }; - // Peripherals - let dp = unsafe { pac::Peripherals::steal() }; - let mut cp = unsafe { pac::CorePeripherals::steal() }; - - let clocks = dp - .RCC - .constrain() - .cfgr - .freeze(&mut dp.FLASH.constrain().acr); - - let mut gpioa = dp.GPIOA.split(); - let mut afio = dp.AFIO.constrain(); - let mut dma1 = dp.DMA1.split(); - // setup DMA1_CHANNEL4 interrupt on TransferComplete - dma1.4.listen(dma::Event::TransferComplete); - unsafe { cp.NVIC.set_priority(pac::Interrupt::DMA1_CHANNEL4, 1) }; + dma_channel.listen(dma::Event::TransferComplete); + unsafe { nvic.set_priority(pac::Interrupt::DMA1_CHANNEL4, 1) }; // Serial config - let serial = serial::Serial::new( - dp.USART1, - ( - gpioa.pa9.into_alternate_open_drain(&mut gpioa.crh), - gpioa.pa10, //.into_pull_up_input(&mut gpioa.crh), - ), - &mut afio.mapr, - 250_000.bps(), - &clocks, - ); + let serial = serial::Serial::new(usart, pins, mapr, 250_000.bps(), &clocks); Self { tx_universe, - sender: TxDMA::new(serial.tx.with_dma(dma1.4), tx_buffer), + sender: TxDMA::new(serial.tx.with_dma(dma_channel), tx_buffer), } } diff --git a/bluepill-rs/src/main.rs b/bluepill-rs/src/main.rs index 922e808..7980488 100644 --- a/bluepill-rs/src/main.rs +++ b/bluepill-rs/src/main.rs @@ -4,7 +4,7 @@ // mod i2c_reg_slave; // mod i2c_slave; -mod dmx; +// mod dmx; mod dmx2; // extern crate panic_halt; @@ -12,13 +12,12 @@ extern crate panic_semihosting; #[rtic::app(device = stm32f1xx_hal::pac, dispatchers = [SPI1, SPI2, SPI3])] mod app { - use crate::dmx::DMX; - use cortex_m::singleton; + use crate::dmx2::DMX; use stm32f1xx_hal::{ gpio::{self, ExtiPin}, pac, prelude::*, - serial, timer, + timer, }; use systick_monotonic::Systick; @@ -30,9 +29,8 @@ mod app { #[shared] struct Shared { - buffer: &'static mut [u8], - delay_us: timer::DelayUs, dmx: DMX, + delay_us: timer::DelayUs, int_led: gpio::gpiob::PB0>, } @@ -42,7 +40,7 @@ mod app { int_pin: gpio::gpiob::PB10>, } - #[init] + #[init(local = [buffer: [u8; DMX_LEN * 2] = [0b01010101; DMX_LEN * 2]])] fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics) { // Take ownership over the raw flash and rcc devices and convert them into the corresponding // HAL structs @@ -68,7 +66,7 @@ mod app { let mut gpioc = cx.device.GPIOC.split(); let mut afio = cx.device.AFIO.constrain(); - let mut dma1 = cx.device.DMA1.split(); + let dma1 = cx.device.DMA1.split(); // setup EXTI10 for Pin B10 let mut int_pin = gpiob.pb10.into_pull_up_input(&mut gpiob.crh); @@ -77,33 +75,26 @@ mod app { int_pin.trigger_on_edge(&mut cx.device.EXTI, gpio::Edge::Falling); unsafe { cx.core.NVIC.set_priority(pac::Interrupt::EXTI15_10, 1) }; // EXTI10 priority - // setup DMA1_CHANNEL4 interrupt on TransferComplete - dma1.4.listen(stm32f1xx_hal::dma::Event::TransferComplete); - unsafe { cx.core.NVIC.set_priority(pac::Interrupt::DMA1_CHANNEL4, 1) }; - - // Serial config - let serial = serial::Serial::new( - cx.device.USART1, - ( - gpioa.pa9.into_alternate_open_drain(&mut gpioa.crh), - gpioa.pa10, //.into_pull_up_input(&mut gpioa.crh), - ), - &mut afio.mapr, - serial::Config::default(), - &clocks, - ); - sender::spawn().unwrap(); ( Shared { - buffer: singleton!(: [u8; DMX_LEN] = [0b01010101; DMX_LEN]).unwrap(), + dmx: DMX::new( + cx.local.buffer, + dma1.4, + &mut cx.core.NVIC, + cx.device.USART1, + ( + gpioa.pa9.into_alternate_open_drain(&mut gpioa.crh), + gpioa.pa10, //.into_pull_up_input(&mut gpioa.crh), + ), + &mut afio.mapr, + &clocks, + ), // Configure timer delay_us: cx.device.TIM2.delay_us(&clocks), - dmx: DMX::new(serial, dma1.4, &clocks), - int_led: gpiob .pb0 .into_open_drain_output_with_state(&mut gpiob.crl, gpio::PinState::Low), @@ -128,9 +119,9 @@ mod app { } } - #[task(local = [led], shared = [&buffer, delay_us, dmx])] + #[task(local = [led], shared = [delay_us, dmx])] fn sender(mut cx: sender::Context) { - cx.shared.dmx.lock(|dmx| dmx.send(cx.shared.buffer)); + cx.shared.dmx.lock(|dmx| dmx.start_tx()); cx.local.led.toggle(); cx.shared.delay_us.lock(|d| d.delay(1.secs())); @@ -141,7 +132,7 @@ mod app { #[task(binds = DMA1_CHANNEL4, shared = [dmx, int_led])] fn waiter(cx: waiter::Context) { (cx.shared.dmx, cx.shared.int_led).lock(|dmx, int_led| { - dmx.wait(); + assert!(dmx.tx_is_idle()); int_led.toggle(); }); }