pounder timestmper: don't use DMA
* One sample per batch is typical and sufficient. * DMA has more overhead than direct read for one sample.
This commit is contained in:
parent
f8fa297b20
commit
26b261364f
@ -233,11 +233,6 @@ pub fn setup(
|
||||
let dma_streams =
|
||||
hal::dma::dma::StreamsTuple::new(device.DMA1, ccdr.peripheral.DMA1);
|
||||
|
||||
// Early, before the DMA1 peripherals (#272)
|
||||
#[cfg(feature = "pounder_v1_1")]
|
||||
let dma2_streams =
|
||||
hal::dma::dma::StreamsTuple::new(device.DMA2, ccdr.peripheral.DMA2);
|
||||
|
||||
// Configure timer 2 to trigger conversions for the ADC
|
||||
let mut sampling_timer = {
|
||||
// The timer frequency is manually adjusted below, so the 1KHz setting here is a
|
||||
@ -946,7 +941,6 @@ pub fn setup(
|
||||
|
||||
pounder::timestamp::Timestamper::new(
|
||||
timestamp_timer,
|
||||
dma2_streams.0,
|
||||
tim8_channels.ch1,
|
||||
&mut sampling_timer,
|
||||
etr_pin,
|
||||
|
@ -24,27 +24,12 @@
|
||||
///! schedule.
|
||||
use stm32h7xx_hal as hal;
|
||||
|
||||
use hal::dma::{dma::DmaConfig, PeripheralToMemory, Transfer};
|
||||
|
||||
use crate::hardware::{design_parameters::SAMPLE_BUFFER_SIZE, timers};
|
||||
|
||||
// Three buffers are required for double buffered mode - 2 are owned by the DMA stream and 1 is the
|
||||
// working data provided to the application. These buffers must exist in a DMA-accessible memory
|
||||
// region. Note that AXISRAM is not initialized on boot, so their initial contents are undefined.
|
||||
#[link_section = ".axisram.buffers"]
|
||||
static mut BUF: [[u16; SAMPLE_BUFFER_SIZE]; 3] = [[0; SAMPLE_BUFFER_SIZE]; 3];
|
||||
use crate::hardware::timers;
|
||||
|
||||
/// Software unit to timestamp stabilizer ADC samples using an external pounder reference clock.
|
||||
pub struct Timestamper {
|
||||
next_buffer: Option<&'static mut [u16; SAMPLE_BUFFER_SIZE]>,
|
||||
timer: timers::PounderTimestampTimer,
|
||||
transfer: Transfer<
|
||||
hal::dma::dma::Stream0<hal::stm32::DMA2>,
|
||||
timers::tim8::Channel1InputCapture,
|
||||
PeripheralToMemory,
|
||||
&'static mut [u16; SAMPLE_BUFFER_SIZE],
|
||||
hal::dma::DBTransfer,
|
||||
>,
|
||||
capture_channel: timers::tim8::Channel1InputCapture,
|
||||
}
|
||||
|
||||
impl Timestamper {
|
||||
@ -65,18 +50,12 @@ impl Timestamper {
|
||||
/// The new pounder timestamper in an operational state.
|
||||
pub fn new(
|
||||
mut timestamp_timer: timers::PounderTimestampTimer,
|
||||
stream: hal::dma::dma::Stream0<hal::stm32::DMA2>,
|
||||
capture_channel: timers::tim8::Channel1,
|
||||
sampling_timer: &mut timers::SamplingTimer,
|
||||
_clock_input: hal::gpio::gpioa::PA0<
|
||||
hal::gpio::Alternate<hal::gpio::AF3>,
|
||||
>,
|
||||
) -> Self {
|
||||
let config = DmaConfig::default()
|
||||
.memory_increment(true)
|
||||
.circular_buffer(true)
|
||||
.double_buffer(true);
|
||||
|
||||
// The sampling timer should generate a trigger output when CH1 comparison occurs.
|
||||
sampling_timer.generate_trigger(timers::TriggerGenerator::ComparePulse);
|
||||
|
||||
@ -87,62 +66,29 @@ impl Timestamper {
|
||||
// The capture channel should capture whenever the trigger input occurs.
|
||||
let input_capture = capture_channel
|
||||
.into_input_capture(timers::tim8::CaptureSource1::TRC);
|
||||
input_capture.listen_dma();
|
||||
|
||||
// The data transfer is always a transfer of data from the peripheral to a RAM buffer.
|
||||
let data_transfer: Transfer<_, _, PeripheralToMemory, _, _> =
|
||||
Transfer::init(
|
||||
stream,
|
||||
input_capture,
|
||||
// Note(unsafe): BUF[0] and BUF[1] are "owned" by this peripheral.
|
||||
// They shall not be used anywhere else in the module.
|
||||
unsafe { &mut BUF[0] },
|
||||
unsafe { Some(&mut BUF[1]) },
|
||||
config,
|
||||
);
|
||||
|
||||
Self {
|
||||
timer: timestamp_timer,
|
||||
transfer: data_transfer,
|
||||
|
||||
// Note(unsafe): BUF[2] is "owned" by this peripheral. It shall not be used anywhere
|
||||
// else in the module.
|
||||
next_buffer: unsafe { Some(&mut BUF[2]) },
|
||||
capture_channel: input_capture,
|
||||
}
|
||||
}
|
||||
|
||||
/// Start the DMA transfer for collecting timestamps.
|
||||
#[allow(dead_code)]
|
||||
/// Start collecting timestamps.
|
||||
pub fn start(&mut self) {
|
||||
self.transfer
|
||||
.start(|capture_channel| capture_channel.enable());
|
||||
self.capture_channel.enable();
|
||||
}
|
||||
|
||||
/// Update the period of the underlying timestamp timer.
|
||||
#[allow(dead_code)]
|
||||
pub fn update_period(&mut self, period: u16) {
|
||||
self.timer.set_period_ticks(period);
|
||||
}
|
||||
|
||||
/// Obtain a buffer filled with timestamps.
|
||||
/// Obtain a timestamp.
|
||||
///
|
||||
/// # Returns
|
||||
/// A reference to the underlying buffer that has been filled with timestamps.
|
||||
#[allow(dead_code)]
|
||||
pub fn acquire_buffer(&mut self) -> &[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() {}
|
||||
|
||||
let next_buffer = self.next_buffer.take().unwrap();
|
||||
|
||||
// Start the next transfer.
|
||||
let (prev_buffer, _, _) =
|
||||
self.transfer.next_transfer(next_buffer).unwrap();
|
||||
|
||||
self.next_buffer.replace(prev_buffer); // .unwrap_none() https://github.com/rust-lang/rust/issues/62633
|
||||
|
||||
self.next_buffer.as_ref().unwrap()
|
||||
/// A `Result` potentially indicating capture overflow and containing a `Option` of a captured
|
||||
/// timestamp.
|
||||
pub fn latest_timestamp(&mut self) -> Result<Option<u16>, Option<u16>> {
|
||||
self.capture_channel.latest_capture()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user