use super::{ hal, DMAReq, DmaConfig, MemoryToPeripheral, PeripheralToMemory, Priority, Stream, TargetAddress, Transfer, }; const INPUT_BUFFER_SIZE: usize = 1; #[link_section = ".axisram.buffers"] static mut SPI_START: [u16; 1] = [0x00]; #[link_section = ".axisram.buffers"] static mut ADC0_BUF0: [u16; INPUT_BUFFER_SIZE] = [0; INPUT_BUFFER_SIZE]; #[link_section = ".axisram.buffers"] static mut ADC0_BUF1: [u16; INPUT_BUFFER_SIZE] = [0; INPUT_BUFFER_SIZE]; #[link_section = ".axisram.buffers"] static mut ADC1_BUF0: [u16; INPUT_BUFFER_SIZE] = [0; INPUT_BUFFER_SIZE]; #[link_section = ".axisram.buffers"] static mut ADC1_BUF1: [u16; INPUT_BUFFER_SIZE] = [0; INPUT_BUFFER_SIZE]; struct SPI2 {} impl SPI2 { pub fn new() -> Self { Self {} } } unsafe impl TargetAddress for SPI2 { type MemSize = u16; const REQUEST_LINE: Option = Some(DMAReq::TIM2_UP as u8); fn address(&self) -> u32 { let regs = unsafe { &*hal::stm32::SPI2::ptr() }; ®s.txdr as *const _ as u32 } } struct SPI3 {} impl SPI3 { pub fn new() -> Self { Self {} } } unsafe impl TargetAddress for SPI3 { type MemSize = u16; const REQUEST_LINE: Option = Some(DMAReq::TIM2_UP as u8); fn address(&self) -> u32 { let regs = unsafe { &*hal::stm32::SPI3::ptr() }; ®s.txdr as *const _ as u32 } } pub struct AdcInputs { adc0: Adc0Input, adc1: Adc1Input, } impl AdcInputs { pub fn new(adc0: Adc0Input, adc1: Adc1Input) -> Self { Self { adc0, adc1 } } pub fn transfer_complete_handler( &mut self, ) -> (&[u16; INPUT_BUFFER_SIZE], &[u16; INPUT_BUFFER_SIZE]) { let adc0_buffer = self.adc0.transfer_complete_handler(); let adc1_buffer = self.adc1.transfer_complete_handler(); (adc0_buffer, adc1_buffer) } } pub struct Adc0Input { next_buffer: Option<&'static mut [u16; INPUT_BUFFER_SIZE]>, transfer: Transfer< hal::dma::dma::Stream1, hal::spi::Spi, PeripheralToMemory, &'static mut [u16; INPUT_BUFFER_SIZE], >, } impl Adc0Input { pub fn new( spi: hal::spi::Spi, trigger_stream: hal::dma::dma::Stream0, data_stream: hal::dma::dma::Stream1, ) -> Self { let trigger_config = DmaConfig::default() .memory_increment(false) .peripheral_increment(false) .priority(Priority::High) .circular_buffer(true); let mut trigger_transfer: Transfer<_, _, MemoryToPeripheral, _> = Transfer::init( trigger_stream, &SPI2::new(), unsafe { &mut SPI_START }, None, trigger_config, ); let data_config = DmaConfig::default() .memory_increment(true) .priority(Priority::VeryHigh) .peripheral_increment(false); let mut spi = spi.disable(); spi.listen(hal::spi::Event::Error); let mut data_transfer: Transfer<_, _, PeripheralToMemory, _> = Transfer::init( data_stream, &spi, unsafe { &mut ADC0_BUF0 }, None, data_config, ); spi.enable_dma_rx(); spi.enable_dma_tx(); let spi = spi.enable(); spi.inner().cr1.modify(|_, w| w.cstart().started()); data_transfer.start(); trigger_transfer.start(); Self { next_buffer: unsafe { Some(&mut ADC0_BUF1) }, transfer: data_transfer, } } pub fn transfer_complete_handler(&mut self) -> &[u16; INPUT_BUFFER_SIZE] { let next_buffer = self.next_buffer.take().unwrap(); while hal::dma::dma::Stream1::::is_enabled() {} self.transfer.clear_interrupts(); let (prev_buffer, _) = self.transfer.next_transfer(next_buffer).unwrap(); self.next_buffer.replace(prev_buffer); self.next_buffer.as_ref().unwrap() } } pub struct Adc1Input { next_buffer: Option<&'static mut [u16; INPUT_BUFFER_SIZE]>, transfer: Transfer< hal::dma::dma::Stream3, hal::spi::Spi, PeripheralToMemory, &'static mut [u16; INPUT_BUFFER_SIZE], >, } impl Adc1Input { pub fn new( spi: hal::spi::Spi, trigger_stream: hal::dma::dma::Stream2, data_stream: hal::dma::dma::Stream3, ) -> Self { let trigger_config = DmaConfig::default() .memory_increment(false) .peripheral_increment(false) .priority(Priority::High) .circular_buffer(true); let mut trigger_transfer: Transfer<_, _, MemoryToPeripheral, _> = Transfer::init( trigger_stream, &SPI3::new(), unsafe { &mut SPI_START }, None, trigger_config, ); let data_config = DmaConfig::default() .memory_increment(true) .transfer_complete_interrupt(true) .priority(Priority::VeryHigh) .peripheral_increment(false); let mut spi = spi.disable(); spi.listen(hal::spi::Event::Error); let mut data_transfer: Transfer<_, _, PeripheralToMemory, _> = Transfer::init( data_stream, &spi, unsafe { &mut ADC1_BUF0 }, None, data_config, ); spi.enable_dma_rx(); spi.enable_dma_tx(); let spi = spi.enable(); spi.inner().cr1.modify(|_, w| w.cstart().started()); data_transfer.start(); trigger_transfer.start(); Self { next_buffer: unsafe { Some(&mut ADC1_BUF1) }, transfer: data_transfer, } } pub fn transfer_complete_handler(&mut self) -> &[u16; INPUT_BUFFER_SIZE] { let next_buffer = self.next_buffer.take().unwrap(); while hal::dma::dma::Stream3::::is_enabled() {} self.transfer.clear_interrupts(); let (prev_buffer, _) = self.transfer.next_transfer(next_buffer).unwrap(); self.next_buffer.replace(prev_buffer); self.next_buffer.as_ref().unwrap() } }