adc/dac: make the buffer handling more symmetric

master
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
/// A reference to the underlying buffer that has been filled with ADC samples.
pub fn transfer_complete_handler(
pub fn acquire_buffer(
&mut self,
) -> &[u16; SAMPLE_BUFFER_SIZE] {
let next_buffer = self.next_buffer.take().unwrap();
) -> &'static mut [u16; SAMPLE_BUFFER_SIZE] {
// 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
// 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.
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()
prev_buffer
}
/// 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.
pub fn prepare_buffer(&mut self) -> &mut [u16; SAMPLE_BUFFER_SIZE] {
self.next_buffer.as_mut().unwrap()
/// Acquire the next output buffer to populate it with DAC codes.
pub fn acquire_buffer(
&mut self,
) -> &'static mut [u16; SAMPLE_BUFFER_SIZE] {
self.next_buffer.take().unwrap()
}
/// Enqueue the next buffer for transmission to the DAC.
///
/// # Args
/// * `data` - The next data to write to the DAC.
pub fn commit_buffer(&mut self) {
let next_buffer = self.next_buffer.take().unwrap();
pub fn release_buffer(
&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.
// Wait for all the DAC codes to get written as well.
if self.first_transfer {
@ -135,7 +138,7 @@ macro_rules! dac_output {
} else {
// 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.
while self.transfer.get_transfer_complete_flag() == false {}
while !self.transfer.get_transfer_complete_flag() {}
}
// Start the next transfer.
@ -143,6 +146,7 @@ macro_rules! dac_output {
let (prev_buffer, _) =
self.transfer.next_transfer(next_buffer).unwrap();
// .unwrap_none() https://github.com/rust-lang/rust/issues/62633
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)]
fn process(c: process::Context) {
let adc_samples = [
c.resources.adcs.0.transfer_complete_handler(),
c.resources.adcs.1.transfer_complete_handler(),
c.resources.adcs.0.acquire_buffer(),
c.resources.adcs.1.acquire_buffer(),
];
let dac_samples = [
c.resources.dacs.0.prepare_buffer(),
c.resources.dacs.1.prepare_buffer(),
c.resources.dacs.0.acquire_buffer(),
c.resources.dacs.1.acquire_buffer(),
];
for channel in 0..adc_samples.len() {
@ -761,9 +761,12 @@ const APP: () = {
dac_samples[channel][sample] = y as i16 as u16 ^ 0x8000;
}
}
c.resources.dacs.0.commit_buffer();
c.resources.dacs.1.commit_buffer();
let [adc0, adc1] = adc_samples;
c.resources.adcs.0.release_buffer(adc0);
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])]