lockin: port to fast double buffered DMA
@@ -78,6 +78,15 @@ impl Default for Settings {
}
}
+macro_rules! flatten_closures {
+ ($fn:ident, $e:ident, $fun:block) => {
+ $e.$fn(|$e| $fun ).unwrap()
+ };
+ ($fn:ident, $e:ident, $($es:ident),+, $fun:block) => {
+ $e.$fn(|$e| flatten_closures!($fn, $($es),*, $fun)).unwrap()
+ };
+}
+
#[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = stabilizer::hardware::SystemTimer)]
const APP: () = {
struct Resources {
@@ -159,26 +168,22 @@ const APP: () = {
#[task(binds=DMA1_STR4, resources=[adcs, dacs, lockin, timestamper, pll, settings, telemetry], priority=2)]
#[inline(never)]
#[link_section = ".itcm.process"]
- fn process(c: process::Context) {
- let adc_samples = [
- c.resources.adcs.0.acquire_buffer(),
- c.resources.adcs.1.acquire_buffer(),
- ];
-
- let mut dac_samples = [
- c.resources.dacs.0.acquire_buffer(),
- c.resources.dacs.1.acquire_buffer(),
- ];
-
- let lockin = c.resources.lockin;
- let settings = c.resources.settings;
+ fn process(mut c: process::Context) {
+ let process::Resources {
+ adcs: (ref mut adc0, ref mut adc1),
+ dacs: (ref mut dac0, ref mut dac1),
+ ref settings,
+ ref mut telemetry,
+ ref mut lockin,
+ ref mut pll,
+ ref mut timestamper,
+ } = c.resources;
let (reference_phase, reference_frequency) = match settings.lockin_mode
{
LockinMode::External => {
- let timestamp =
- c.resources.timestamper.latest_timestamp().unwrap_or(None); // Ignore data from timer capture overflows.
- let (pll_phase, pll_frequency) = c.resources.pll.update(
+ let timestamp = timestamper.latest_timestamp().unwrap_or(None); // Ignore data from timer capture overflows.
+ let (pll_phase, pll_frequency) = pll.update(
timestamp.map(|t| t as i32),
settings.pll_tc[0],
settings.pll_tc[1],
@@ -205,6 +210,10 @@ const APP: () = {
reference_phase.wrapping_mul(settings.lockin_harmonic),
);
+ flatten_closures!(with_buffer, adc0, adc1, dac0, dac1, {
+ let adc_samples = [adc0, adc1];
+ let mut dac_samples = [dac0, dac1];
+
let output: Complex<i32> = adc_samples[0]
.iter()
// Zip in the LO phase.
@@ -237,13 +246,13 @@ const APP: () = {
*sample = DacCode::from(value as i16).0;
}
}
-
// Update telemetry measurements.
- c.resources.telemetry.adcs =
+ telemetry.adcs =
[AdcCode(adc_samples[0][0]), AdcCode(adc_samples[1][0])];
- c.resources.telemetry.dacs =
+ telemetry.dacs =
[DacCode(dac_samples[0][0]), DacCode(dac_samples[1][0])];
+ });
}
#[idle(resources=[network], spawn=[settings_update])]
