Updating after review

This commit is contained in:
Ryan Summers 2021-05-07 13:02:14 +02:00
parent 89eaefd8d5
commit 7b76b1f14c
4 changed files with 50 additions and 50 deletions

View File

@ -26,7 +26,9 @@ pub struct Settings {
iir_ch: [[iir::IIR; IIR_CASCADE_LENGTH]; 2],
allow_hold: bool,
force_hold: bool,
telemetry_period_secs: u16,
// The telemetry period in seconds.
telemetry_period: u16,
}
impl Default for Settings {
@ -44,7 +46,7 @@ impl Default for Settings {
allow_hold: false,
// Force suppress filter output updates.
force_hold: false,
telemetry_period_secs: 10,
telemetry_period: 10,
}
}
}
@ -130,9 +132,13 @@ const APP: () = {
c.resources.dacs.1.acquire_buffer(),
];
let digital_inputs = [
c.resources.digital_inputs.0.is_high().unwrap(),
c.resources.digital_inputs.1.is_high().unwrap(),
];
let hold = c.resources.settings.force_hold
|| (c.resources.digital_inputs.1.is_high().unwrap()
&& c.resources.settings.allow_hold);
|| (digital_inputs[1] && c.resources.settings.allow_hold);
for channel in 0..adc_samples.len() {
for sample in 0..adc_samples[0].len() {
@ -153,16 +159,12 @@ const APP: () = {
}
// Update telemetry measurements.
c.resources.telemetry.latest_samples =
c.resources.telemetry.adcs =
[adc_samples[0][0] as i16, adc_samples[1][0] as i16];
c.resources.telemetry.latest_outputs =
[dac_samples[0][0], dac_samples[1][0]];
c.resources.telemetry.dacs = [dac_samples[0][0], dac_samples[1][0]];
c.resources.telemetry.digital_inputs = [
c.resources.digital_inputs.0.is_high().unwrap(),
c.resources.digital_inputs.1.is_high().unwrap(),
];
c.resources.telemetry.digital_inputs = digital_inputs;
}
#[idle(resources=[network], spawn=[settings_update])]
@ -202,7 +204,7 @@ const APP: () = {
let telemetry_period = c
.resources
.settings
.lock(|settings| settings.telemetry_period_secs);
.lock(|settings| settings.telemetry_period);
// Schedule the telemetry task in the future.
c.schedule

View File

@ -56,7 +56,9 @@ pub struct Settings {
lockin_phase: i32,
output_conf: [Conf; 2],
telemetry_period_secs: u16,
// The telemetry period in seconds.
telemetry_period: u16,
}
impl Default for Settings {
@ -73,7 +75,7 @@ impl Default for Settings {
lockin_phase: 0, // Demodulation LO phase offset
output_conf: [Conf::InPhase, Conf::Quadrature],
telemetry_period_secs: 10,
telemetry_period: 10,
}
}
}
@ -237,11 +239,10 @@ const APP: () = {
}
// Update telemetry measurements.
c.resources.telemetry.latest_samples =
c.resources.telemetry.adcs =
[adc_samples[0][0] as i16, adc_samples[1][0] as i16];
c.resources.telemetry.latest_outputs =
[dac_samples[0][0], dac_samples[1][0]];
c.resources.telemetry.dacs = [dac_samples[0][0], dac_samples[1][0]];
}
#[idle(resources=[network], spawn=[settings_update])]
@ -285,7 +286,7 @@ const APP: () = {
let telemetry_period = c
.resources
.settings
.lock(|settings| settings.telemetry_period_secs);
.lock(|settings| settings.telemetry_period);
// Schedule the telemetry task in the future.
c.schedule

View File

@ -69,12 +69,12 @@ impl rtic::Monotonic for SystemTimer {
// is taken when reading and modifying register values.
let regs = unsafe { &*hal::device::TIM15::ptr() };
cortex_m::interrupt::free(|_cs| {
loop {
// Checking for overflows of the current counter must be performed atomically. Any
// other task that is accessing the current time could potentially race for the
// registers. Note that this is only required for writing to global state (e.g. timer
// registers and overflow counter)
if let Some(time) = cortex_m::interrupt::free(|_cs| {
// Check for overflows and clear the overflow bit atomically. This must be done in
// a critical section to prevent race conditions on the status register.
if regs.sr.read().uif().bit_is_set() {
@ -91,14 +91,12 @@ impl rtic::Monotonic for SystemTimer {
if regs.sr.read().uif().bit_is_clear() {
// Note(unsafe): We are in a critical section, so it is safe to read the
// global variable.
unsafe { Some((OVERFLOWS * 65535 + current_value) as i32) }
} else {
None
}
}) {
return time;
return unsafe {
((OVERFLOWS << 16) + current_value) as i32
};
}
}
})
}
/// Reset the timer count.

View File

@ -33,9 +33,9 @@ pub struct TelemetryClient<T: Serialize> {
#[derive(Copy, Clone)]
pub struct TelemetryBuffer {
/// The latest input sample on ADC0/ADC1.
pub latest_samples: [i16; 2],
pub adcs: [i16; 2],
/// The latest output code on DAC0/DAC1.
pub latest_outputs: [u16; 2],
pub dacs: [u16; 2],
/// The latest digital input states during processing.
pub digital_inputs: [bool; 2],
}
@ -47,16 +47,16 @@ pub struct TelemetryBuffer {
/// overhead.
#[derive(Serialize)]
pub struct Telemetry {
input_levels: [f32; 2],
output_levels: [f32; 2],
adcs: [f32; 2],
dacs: [f32; 2],
digital_inputs: [bool; 2],
}
impl Default for TelemetryBuffer {
fn default() -> Self {
Self {
latest_samples: [0, 0],
latest_outputs: [0, 0],
adcs: [0, 0],
dacs: [0, 0],
digital_inputs: [false, false],
}
}
@ -79,30 +79,29 @@ impl TelemetryBuffer {
// input signal has a fixed gain of 1/5 through a static input active filter. Finally, at
// the very front-end of the signal, there's an analog input multiplier that is
// configurable by the user.
let adc_volts_per_lsb = 5.0 * 4.096 / 2.0 / i16::MAX as f32;
let in0_volts =
(self.latest_samples[0] as f32 / i16::MAX as f32) * 4.096 / 2.0
* 5.0
/ afe0.as_multiplier();
(adc_volts_per_lsb * self.adcs[0] as f32) / afe0.as_multiplier();
let in1_volts =
(self.latest_samples[1] as f32 / i16::MAX as f32) * 4.096 / 2.0
* 5.0
/ afe1.as_multiplier();
(adc_volts_per_lsb * self.adcs[1] as f32) / afe1.as_multiplier();
// The output voltage is generated by the DAC with an output range of +/- 4.096 V. This
// signal then passes through a 2.5x gain stage. Note that the DAC operates using unsigned
// integers, and u16::MAX / 2 is considered zero voltage output. Thus, the dynamic range of
// the output stage is +/- 10.24 V. At a DAC code of zero, there is an output of -10.24 V,
// and at a max DAC code, there is an output of 10.24 V.
let out0_volts = (10.24 * 2.0)
* (self.latest_outputs[0] as f32 / (u16::MAX as f32))
- 10.24;
let out1_volts = (10.24 * 2.0)
* (self.latest_outputs[1] as f32 / (u16::MAX as f32))
- 10.24;
//
// Note: The MAX code corresponding to +VREF is not programmable, as it is 1 bit larger
// than full-scale.
let dac_volts_per_lsb = 10.24 * 2.0 / (u16::MAX as u32 + 1) as f32;
let dac_offset = -10.24;
let out0_volts = dac_volts_per_lsb * self.dacs[0] as f32 + dac_offset;
let out1_volts = dac_volts_per_lsb * self.dacs[1] as f32 + dac_offset;
Telemetry {
input_levels: [in0_volts, in1_volts],
output_levels: [out0_volts, out1_volts],
adcs: [in0_volts, in1_volts],
dacs: [out0_volts, out1_volts],
digital_inputs: self.digital_inputs,
}
}