diff --git a/src/adc.rs b/src/adc.rs index dd006f1..9c3aa01 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -1,9 +1,8 @@ use super::{ - hal, DMAReq, DmaConfig, MemoryToPeripheral, PeripheralToMemory, Stream, - TargetAddress, Transfer, + hal, DMAReq, DmaConfig, MemoryToPeripheral, PeripheralToMemory, TargetAddress, Transfer, }; -const INPUT_BUFFER_SIZE: usize = 1; +const INPUT_BUFFER_SIZE: usize = 25; #[link_section = ".axisram.buffers"] static mut SPI_START: [u16; 1] = [0x00]; diff --git a/src/dac.rs b/src/dac.rs index 575320d..2c747ae 100644 --- a/src/dac.rs +++ b/src/dac.rs @@ -4,27 +4,37 @@ use heapless::consts; pub struct Dac0Output { outputs: heapless::spsc::Queue, spi: hal::spi::Spi, + timer: hal::timer::Timer, } impl Dac0Output { pub fn new( spi: hal::spi::Spi, + mut timer: hal::timer::Timer, ) -> Self { spi.inner().cr1.modify(|_, w| w.cstart().started()); + timer.pause(); + timer.reset_counter(); + timer.clear_irq(); + timer.listen(hal::timer::Event::TimeOut); + Self { spi, outputs: heapless::spsc::Queue::new(), + timer, } } pub fn push(&mut self, value: u16) { self.outputs.enqueue(value).unwrap(); + self.timer.resume(); } pub fn update(&mut self) { + self.timer.clear_irq(); match self.outputs.dequeue() { Some(value) => self.write(value), - None => {} + None => self.timer.pause(), } } @@ -41,28 +51,37 @@ impl Dac0Output { pub struct Dac1Output { outputs: heapless::spsc::Queue, spi: hal::spi::Spi, + timer: hal::timer::Timer, } impl Dac1Output { pub fn new( spi: hal::spi::Spi, + mut timer: hal::timer::Timer, ) -> Self { spi.inner().cr1.modify(|_, w| w.cstart().started()); + timer.pause(); + timer.reset_counter(); + timer.clear_irq(); + timer.listen(hal::timer::Event::TimeOut); Self { spi, outputs: heapless::spsc::Queue::new(), + timer, } } pub fn push(&mut self, value: u16) { self.outputs.enqueue(value).unwrap(); + self.timer.resume(); } pub fn update(&mut self) { + self.timer.clear_irq(); match self.outputs.dequeue() { Some(value) => self.write(value), - None => {} + None => self.timer.pause(), } } diff --git a/src/main.rs b/src/main.rs index 72d0db2..a314513 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ use embedded_hal::digital::v2::{InputPin, OutputPin}; use hal::{ dma::{ dma::{DMAReq, DmaConfig}, - traits::{Stream, TargetAddress}, + traits::TargetAddress, MemoryToPeripheral, PeripheralToMemory, Transfer, }, ethernet::{self, PHY}, @@ -46,6 +46,8 @@ use smoltcp as net; use heapless::{consts::*, String}; +const SAMPLE_FREQUENCY_KHZ: u32 = 800; + #[link_section = ".sram3.eth"] static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new(); @@ -362,7 +364,8 @@ const APP: () = { ) }; - Dac0Output::new(dac0_spi) + let timer = dp.TIM3.timer(SAMPLE_FREQUENCY_KHZ.khz(), ccdr.peripheral.TIM3, &ccdr.clocks); + Dac0Output::new(dac0_spi, timer) }; let dac1 = { @@ -398,7 +401,8 @@ const APP: () = { ) }; - Dac1Output::new(dac1_spi) + let timer = dp.TIM4.timer(SAMPLE_FREQUENCY_KHZ.khz(), ccdr.peripheral.TIM4, &ccdr.clocks); + Dac1Output::new(dac1_spi, timer) }; let mut fp_led_0 = gpiod.pd5.into_push_pull_output(); @@ -679,7 +683,7 @@ const APP: () = { // Configure timer 2 to trigger conversions for the ADC let timer2 = - dp.TIM2.timer(50.khz(), ccdr.peripheral.TIM2, &ccdr.clocks); + dp.TIM2.timer(SAMPLE_FREQUENCY_KHZ.khz(), ccdr.peripheral.TIM2, &ccdr.clocks); { let t2_regs = unsafe { &*hal::stm32::TIM2::ptr() }; t2_regs.dier.modify(|_, w| w.ude().set_bit()); @@ -704,36 +708,30 @@ const APP: () = { } } - #[task(binds=DMA1_STR3, resources=[adc1, dac1, iir_state, iir_ch], priority=2)] - fn adc1(c: adc1::Context) { - let samples = c.resources.adc1.transfer_complete_handler(); - - let mut last_result: u16 = 0; - for sample in samples { - let x0 = f32::from(*sample as i16); - let y0 = - c.resources.iir_ch[1].update(&mut c.resources.iir_state[1], x0); - last_result = y0 as i16 as u16 ^ 0x8000; - //c.resources.dac0.push(last_result); - } - - c.resources.dac1.write(last_result); - } - #[task(binds=DMA1_STR1, resources=[adc0, dac0, iir_state, iir_ch], priority=2)] - fn adc0(c: adc0::Context) { + fn adc0(mut c: adc0::Context) { let samples = c.resources.adc0.transfer_complete_handler(); - let mut last_result: u16 = 0; for sample in samples { let x0 = f32::from(*sample as i16); let y0 = c.resources.iir_ch[0].update(&mut c.resources.iir_state[0], x0); - last_result = y0 as i16 as u16 ^ 0x8000; - //c.resources.dac0.push(last_result); + let result = y0 as i16 as u16 ^ 0x8000; + c.resources.dac0.lock(|dac| dac.push(result)); } + } - c.resources.dac0.write(last_result); + #[task(binds=DMA1_STR3, resources=[adc1, dac1, iir_state, iir_ch], priority=2)] + fn adc1(mut c: adc1::Context) { + let samples = c.resources.adc1.transfer_complete_handler(); + + for sample in samples { + let x0 = f32::from(*sample as i16); + let y0 = + c.resources.iir_ch[1].update(&mut c.resources.iir_state[1], x0); + let result = y0 as i16 as u16 ^ 0x8000; + c.resources.dac1.lock(|dac| dac.push(result)); + } } #[idle(resources=[net_interface, pounder, mac_addr, eth_mac, iir_state, iir_ch, afe0, afe1])] @@ -936,6 +934,16 @@ const APP: () = { panic!("ADC0 input overrun"); } + #[task(binds = TIM3, resources=[dac0], priority = 3)] + fn dac0(c: dac0::Context) { + c.resources.dac0.update(); + } + + #[task(binds = TIM4, resources=[dac1], priority = 3)] + fn dac1(c: dac1::Context) { + c.resources.dac1.update(); + } + extern "C" { // hw interrupt handlers for RTIC to use for scheduling tasks // one per priority