adc/dac: make the buffer handling more symmetric

This commit is contained in:
Robert Jördens 2020-11-26 13:51:39 +01:00
parent 754ebed50d
commit d8c6f39d0f
3 changed files with 39 additions and 22 deletions

View File

@ -181,27 +181,37 @@ macro_rules! adc_input {
} }
} }
/// Handle a transfer completion. /// Obtain a buffer filled with ADC samples.
/// ///
/// # Returns /// # Returns
/// A reference to the underlying buffer that has been filled with ADC samples. /// A reference to the underlying buffer that has been filled with ADC samples.
pub fn transfer_complete_handler( pub fn acquire_buffer(
&mut self, &mut self,
) -> &[u16; SAMPLE_BUFFER_SIZE] { ) -> &'static mut [u16; SAMPLE_BUFFER_SIZE] {
let next_buffer = self.next_buffer.take().unwrap();
// Wait for the transfer to fully complete before continuing. // Wait for the transfer to fully complete before continuing.
// Note: If a device hangs up, check that this conditional is passing correctly, as there is // Note: If a device hangs up, check that this conditional is passing correctly, as there is
// no time-out checks here in the interest of execution speed. // no time-out checks here in the interest of execution speed.
while self.transfer.get_transfer_complete_flag() == false {} while !self.transfer.get_transfer_complete_flag() {}
let next_buffer = self.next_buffer.take().unwrap();
// Start the next transfer. // Start the next transfer.
self.transfer.clear_interrupts(); self.transfer.clear_interrupts();
let (prev_buffer, _) = let (prev_buffer, _) =
self.transfer.next_transfer(next_buffer).unwrap(); self.transfer.next_transfer(next_buffer).unwrap();
self.next_buffer.replace(prev_buffer); prev_buffer
self.next_buffer.as_ref().unwrap() }
/// Release a buffer of ADC samples to the pool.
///
/// # Args
/// * `next_buffer` - Buffer of ADC samples to be re-used.
pub fn release_buffer(
&mut self,
next_buffer: &'static mut [u16; SAMPLE_BUFFER_SIZE],
) {
self.next_buffer.replace(next_buffer); // .unwrap_none() https://github.com/rust-lang/rust/issues/62633
} }
} }
}; };

View File

@ -116,18 +116,21 @@ macro_rules! dac_output {
} }
} }
/// Mutably borrow the next output buffer to populate it with DAC codes. /// Acquire the next output buffer to populate it with DAC codes.
pub fn prepare_buffer(&mut self) -> &mut [u16; SAMPLE_BUFFER_SIZE] { pub fn acquire_buffer(
self.next_buffer.as_mut().unwrap() &mut self,
) -> &'static mut [u16; SAMPLE_BUFFER_SIZE] {
self.next_buffer.take().unwrap()
} }
/// Enqueue the next buffer for transmission to the DAC. /// Enqueue the next buffer for transmission to the DAC.
/// ///
/// # Args /// # Args
/// * `data` - The next data to write to the DAC. /// * `data` - The next data to write to the DAC.
pub fn commit_buffer(&mut self) { pub fn release_buffer(
let next_buffer = self.next_buffer.take().unwrap(); &mut self,
next_buffer: &'static mut [u16; SAMPLE_BUFFER_SIZE],
) {
// If the last transfer was not complete, we didn't write all our previous DAC codes. // If the last transfer was not complete, we didn't write all our previous DAC codes.
// Wait for all the DAC codes to get written as well. // Wait for all the DAC codes to get written as well.
if self.first_transfer { if self.first_transfer {
@ -135,7 +138,7 @@ macro_rules! dac_output {
} else { } else {
// Note: If a device hangs up, check that this conditional is passing correctly, as // Note: If a device hangs up, check that this conditional is passing correctly, as
// there is no time-out checks here in the interest of execution speed. // there is no time-out checks here in the interest of execution speed.
while self.transfer.get_transfer_complete_flag() == false {} while !self.transfer.get_transfer_complete_flag() {}
} }
// Start the next transfer. // Start the next transfer.
@ -143,6 +146,7 @@ macro_rules! dac_output {
let (prev_buffer, _) = let (prev_buffer, _) =
self.transfer.next_transfer(next_buffer).unwrap(); self.transfer.next_transfer(next_buffer).unwrap();
// .unwrap_none() https://github.com/rust-lang/rust/issues/62633
self.next_buffer.replace(prev_buffer); self.next_buffer.replace(prev_buffer);
} }
} }

View File

@ -745,12 +745,12 @@ const APP: () = {
#[task(binds=DMA1_STR3, resources=[adcs, dacs, iir_state, iir_ch], priority=2)] #[task(binds=DMA1_STR3, resources=[adcs, dacs, iir_state, iir_ch], priority=2)]
fn process(c: process::Context) { fn process(c: process::Context) {
let adc_samples = [ let adc_samples = [
c.resources.adcs.0.transfer_complete_handler(), c.resources.adcs.0.acquire_buffer(),
c.resources.adcs.1.transfer_complete_handler(), c.resources.adcs.1.acquire_buffer(),
]; ];
let dac_samples = [ let dac_samples = [
c.resources.dacs.0.prepare_buffer(), c.resources.dacs.0.acquire_buffer(),
c.resources.dacs.1.prepare_buffer(), c.resources.dacs.1.acquire_buffer(),
]; ];
for channel in 0..adc_samples.len() { for channel in 0..adc_samples.len() {
@ -761,9 +761,12 @@ const APP: () = {
dac_samples[channel][sample] = y as i16 as u16 ^ 0x8000; dac_samples[channel][sample] = y as i16 as u16 ^ 0x8000;
} }
} }
let [adc0, adc1] = adc_samples;
c.resources.dacs.0.commit_buffer(); c.resources.adcs.0.release_buffer(adc0);
c.resources.dacs.1.commit_buffer(); c.resources.adcs.0.release_buffer(adc1);
let [dac0, dac1] = dac_samples;
c.resources.dacs.0.release_buffer(dac0);
c.resources.dacs.1.release_buffer(dac1);
} }
#[idle(resources=[net_interface, pounder, mac_addr, eth_mac, iir_state, iir_ch, afes])] #[idle(resources=[net_interface, pounder, mac_addr, eth_mac, iir_state, iir_ch, afes])]