Merge #355
355: dsp/lowpass,lockin: const generics r=jordens a=jordens Co-authored-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
commit
76b9be6d93
|
@ -9,8 +9,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
* Telemetry
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
* Const generics bumping the MSRV to 1.51.0
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
## [v0.5.0] - 2021-04-21
|
## [v0.5.0] - 2021-04-21
|
||||||
|
|
|
@ -215,7 +215,6 @@ name = "dsp"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"easybench",
|
"easybench",
|
||||||
"generic-array 0.14.4",
|
|
||||||
"libm",
|
"libm",
|
||||||
"miniconf",
|
"miniconf",
|
||||||
"ndarray",
|
"ndarray",
|
||||||
|
|
|
@ -37,6 +37,7 @@ to implement different use cases. Several applications are provides by default
|
||||||
* Get [rustup](https://rustup.rs/)
|
* Get [rustup](https://rustup.rs/)
|
||||||
* `rustup target add thumbv7em-none-eabihf`
|
* `rustup target add thumbv7em-none-eabihf`
|
||||||
* `cargo build --release`
|
* `cargo build --release`
|
||||||
|
* Minimum supported Rust version (MSRV) is 1.51.0
|
||||||
* When using debug (non `--release`) mode, increase the sample interval significantly.
|
* When using debug (non `--release`) mode, increase the sample interval significantly.
|
||||||
The added error checking code and missing optimizations may lead to the code
|
The added error checking code and missing optimizations may lead to the code
|
||||||
missing deadlines and panicing.
|
missing deadlines and panicing.
|
||||||
|
|
|
@ -7,7 +7,6 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libm = "0.2.1"
|
libm = "0.2.1"
|
||||||
serde = { version = "1.0", features = ["derive"], default-features = false }
|
serde = { version = "1.0", features = ["derive"], default-features = false }
|
||||||
generic-array = "0.14"
|
|
||||||
num = { version = "0.4.0", default-features = false }
|
num = { version = "0.4.0", default-features = false }
|
||||||
miniconf = "0.1"
|
miniconf = "0.1"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use core::f32::consts::PI;
|
use core::f32::consts::PI;
|
||||||
|
|
||||||
use easybench::bench_env;
|
use easybench::bench_env;
|
||||||
use generic_array::typenum::U4;
|
|
||||||
|
|
||||||
use dsp::{atan2, cossin, iir, iir_int, Lowpass, PLL, RPLL};
|
use dsp::{atan2, cossin, iir, iir_int, Lowpass, PLL, RPLL};
|
||||||
|
|
||||||
|
@ -72,13 +71,13 @@ fn iir_bench() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lowpass_bench() {
|
fn lowpass_bench() {
|
||||||
let mut dut = Lowpass::<U4>::default();
|
let mut dut = Lowpass::<4>::default();
|
||||||
println!(
|
println!(
|
||||||
"Lowpass::<U4>::update(x, k): {}",
|
"Lowpass::<4>::update(x, k): {}",
|
||||||
bench_env((0x32421, 14), |(x, k)| dut.update(*x, *k))
|
bench_env((0x32421, 14), |(x, k)| dut.update(*x, *k))
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"Lowpass::<U4>::update(x, 14): {}",
|
"Lowpass::<4>::update(x, 14): {}",
|
||||||
bench_env(0x32421, |x| dut.update(*x, 14))
|
bench_env(0x32421, |x| dut.update(*x, 14))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
use super::{Complex, ComplexExt, Lowpass, MulScaled};
|
use super::{Complex, ComplexExt, Lowpass, MulScaled};
|
||||||
use generic_array::ArrayLength;
|
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Lockin<N: ArrayLength<i32>> {
|
pub struct Lockin<const N: usize> {
|
||||||
state: [Lowpass<N>; 2],
|
state: [Lowpass<N>; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ArrayLength<i32>> Lockin<N> {
|
impl<const N: usize> Lockin<N> {
|
||||||
/// Update the lockin with a sample taken at a given phase.
|
/// Update the lockin with a sample taken at a given phase.
|
||||||
pub fn update(&mut self, sample: i32, phase: i32, k: u8) -> Complex<i32> {
|
pub fn update(&mut self, sample: i32, phase: i32, k: u8) -> Complex<i32> {
|
||||||
// Get the LO signal for demodulation and mix the sample;
|
// Get the LO signal for demodulation and mix the sample;
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
use generic_array::{ArrayLength, GenericArray};
|
|
||||||
|
|
||||||
/// Arbitrary order, high dynamic range, wide coefficient range,
|
/// Arbitrary order, high dynamic range, wide coefficient range,
|
||||||
/// lowpass filter implementation. DC gain is 1.
|
/// lowpass filter implementation. DC gain is 1.
|
||||||
///
|
///
|
||||||
/// Type argument N is the filter order.
|
/// Type argument N is the filter order.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone)]
|
||||||
pub struct Lowpass<N: ArrayLength<i32>> {
|
pub struct Lowpass<const N: usize> {
|
||||||
// IIR state storage
|
// IIR state storage
|
||||||
y: GenericArray<i32, N>,
|
y: [i32; N],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ArrayLength<i32>> Lowpass<N> {
|
impl<const N: usize> Default for Lowpass<N> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Lowpass { y: [0i32; N] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Lowpass<N> {
|
||||||
/// Update the filter with a new sample.
|
/// Update the filter with a new sample.
|
||||||
///
|
///
|
||||||
/// # Args
|
/// # Args
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal::digital::v2::InputPin;
|
use embedded_hal::digital::v2::InputPin;
|
||||||
use generic_array::typenum::U4;
|
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ const APP: () = {
|
||||||
|
|
||||||
timestamper: InputStamper,
|
timestamper: InputStamper,
|
||||||
pll: RPLL,
|
pll: RPLL,
|
||||||
lockin: Lockin<U4>,
|
lockin: Lockin<4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[init(spawn=[settings_update, telemetry])]
|
#[init(spawn=[settings_update, telemetry])]
|
||||||
|
|
Loading…
Reference in New Issue