Merge #187
187: Added cascaded IIR with server commands for up to 2 cascaded IIRs per… r=jordens a=nkuh … channel. Note: If the number of cascaded IIRs is set to 1 the still existent server commands for the unused 2nd cascade level will be aliases for the 1st level. Co-authored-by: Niklas Kuhrmeyer <niklas.kuhrmeyer@ptb.de> Co-authored-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
commit
e87376314f
66
src/main.rs
66
src/main.rs
|
@ -60,6 +60,9 @@ const SAMPLE_FREQUENCY_KHZ: u32 = 500;
|
||||||
// The desired ADC sample processing buffer size.
|
// The desired ADC sample processing buffer size.
|
||||||
const SAMPLE_BUFFER_SIZE: usize = 1;
|
const SAMPLE_BUFFER_SIZE: usize = 1;
|
||||||
|
|
||||||
|
// The number of cascaded IIR biquads per channel. Select 1 or 2!
|
||||||
|
const IIR_CASCADE_LENGTH: usize = 1;
|
||||||
|
|
||||||
#[link_section = ".sram3.eth"]
|
#[link_section = ".sram3.eth"]
|
||||||
static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new();
|
static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new();
|
||||||
|
|
||||||
|
@ -210,10 +213,11 @@ const APP: () = {
|
||||||
|
|
||||||
pounder: Option<pounder::PounderDevices<asm_delay::AsmDelay>>,
|
pounder: Option<pounder::PounderDevices<asm_delay::AsmDelay>>,
|
||||||
|
|
||||||
#[init([[0.; 5]; 2])]
|
// Format: iir_state[ch][cascade-no][coeff]
|
||||||
iir_state: [iir::IIRState; 2],
|
#[init([[[0.; 5]; IIR_CASCADE_LENGTH]; 2])]
|
||||||
#[init([iir::IIR { ba: [1., 0., 0., 0., 0.], y_offset: 0., y_min: -SCALE - 1., y_max: SCALE }; 2])]
|
iir_state: [[iir::IIRState; IIR_CASCADE_LENGTH]; 2],
|
||||||
iir_ch: [iir::IIR; 2],
|
#[init([[iir::IIR { ba: [1., 0., 0., 0., 0.], y_offset: 0., y_min: -SCALE - 1., y_max: SCALE }; IIR_CASCADE_LENGTH]; 2])]
|
||||||
|
iir_ch: [[iir::IIR; IIR_CASCADE_LENGTH]; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
|
@ -761,8 +765,11 @@ const APP: () = {
|
||||||
for channel in 0..adc_samples.len() {
|
for channel in 0..adc_samples.len() {
|
||||||
for sample in 0..adc_samples[0].len() {
|
for sample in 0..adc_samples[0].len() {
|
||||||
let x = f32::from(adc_samples[channel][sample] as i16);
|
let x = f32::from(adc_samples[channel][sample] as i16);
|
||||||
let y = c.resources.iir_ch[channel]
|
let mut y = x;
|
||||||
.update(&mut c.resources.iir_state[channel], x);
|
for i in 0..c.resources.iir_state[channel].len() {
|
||||||
|
y = c.resources.iir_ch[channel][i]
|
||||||
|
.update(&mut c.resources.iir_state[channel][i], y);
|
||||||
|
}
|
||||||
// Note(unsafe): The filter limits ensure that the value is in range.
|
// Note(unsafe): The filter limits ensure that the value is in range.
|
||||||
// The truncation introduces 1/2 LSB distortion.
|
// The truncation introduces 1/2 LSB distortion.
|
||||||
let y = unsafe { y.to_int_unchecked::<i16>() };
|
let y = unsafe { y.to_int_unchecked::<i16>() };
|
||||||
|
@ -827,10 +834,23 @@ const APP: () = {
|
||||||
let state = c.resources.iir_state.lock(|iir_state|
|
let state = c.resources.iir_state.lock(|iir_state|
|
||||||
server::Status {
|
server::Status {
|
||||||
t: time,
|
t: time,
|
||||||
x0: iir_state[0][0],
|
x0: iir_state[0][0][0],
|
||||||
y0: iir_state[0][2],
|
y0: iir_state[0][0][2],
|
||||||
x1: iir_state[1][0],
|
x1: iir_state[1][0][0],
|
||||||
y1: iir_state[1][2],
|
y1: iir_state[1][0][2],
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok::<server::Status, ()>(state)
|
||||||
|
}),
|
||||||
|
// "_b" means cascades 2nd IIR
|
||||||
|
"stabilizer/iir_b/state": (|| {
|
||||||
|
let state = c.resources.iir_state.lock(|iir_state|
|
||||||
|
server::Status {
|
||||||
|
t: time,
|
||||||
|
x0: iir_state[0][IIR_CASCADE_LENGTH-1][0],
|
||||||
|
y0: iir_state[0][IIR_CASCADE_LENGTH-1][2],
|
||||||
|
x1: iir_state[1][IIR_CASCADE_LENGTH-1][0],
|
||||||
|
y1: iir_state[1][IIR_CASCADE_LENGTH-1][2],
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok::<server::Status, ()>(state)
|
Ok::<server::Status, ()>(state)
|
||||||
|
@ -880,7 +900,7 @@ const APP: () = {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
iir_ch[req.channel as usize] = req.iir;
|
iir_ch[req.channel as usize][0] = req.iir;
|
||||||
|
|
||||||
Ok::<server::IirRequest, ()>(req)
|
Ok::<server::IirRequest, ()>(req)
|
||||||
})
|
})
|
||||||
|
@ -891,7 +911,29 @@ const APP: () = {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
iir_ch[req.channel as usize] = req.iir;
|
iir_ch[req.channel as usize][0] = req.iir;
|
||||||
|
|
||||||
|
Ok::<server::IirRequest, ()>(req)
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
"stabilizer/iir_b0/state": server::IirRequest, (|req: server::IirRequest| {
|
||||||
|
c.resources.iir_ch.lock(|iir_ch| {
|
||||||
|
if req.channel > 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
iir_ch[req.channel as usize][IIR_CASCADE_LENGTH-1] = req.iir;
|
||||||
|
|
||||||
|
Ok::<server::IirRequest, ()>(req)
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
"stabilizer/iir_b1/state": server::IirRequest,(|req: server::IirRequest| {
|
||||||
|
c.resources.iir_ch.lock(|iir_ch| {
|
||||||
|
if req.channel > 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
iir_ch[req.channel as usize][IIR_CASCADE_LENGTH-1] = req.iir;
|
||||||
|
|
||||||
Ok::<server::IirRequest, ()>(req)
|
Ok::<server::IirRequest, ()>(req)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue