diff options
| author | JuliDi <[email protected]> | 2023-07-27 19:04:43 +0200 |
|---|---|---|
| committer | JuliDi <[email protected]> | 2023-07-27 19:04:43 +0200 |
| commit | 93864610ce5d9127eb415f8020ec43c26fb20804 (patch) | |
| tree | 5a626239abb24e40aa3f1f07b61a5ff2d1416bd6 /tests | |
| parent | bbd2563e138ce83314ea008547940428617a5798 (diff) | |
Add DAC HIL test with ADC
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/stm32/Cargo.toml | 13 | ||||
| -rw-r--r-- | tests/stm32/src/bin/dac.rs | 81 | ||||
| -rw-r--r-- | tests/stm32/src/common.rs | 1 |
3 files changed, 92 insertions, 3 deletions
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 3007cd1e6..17320649e 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -7,11 +7,11 @@ autobins = false | |||
| 7 | 7 | ||
| 8 | [features] | 8 | [features] |
| 9 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill | 9 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill |
| 10 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "can", "not-gpdma"] # Nucleo "sdmmc" | 10 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" |
| 11 | stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma"] # Nucleo | 11 | stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo |
| 12 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo | 12 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo |
| 13 | stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo | 13 | stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo |
| 14 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma"] # Nucleo | 14 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma", "dac-adc-pin"] # Nucleo |
| 15 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo | 15 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo |
| 16 | stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo | 16 | stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo |
| 17 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board | 17 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board |
| @@ -23,6 +23,7 @@ ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"] | |||
| 23 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] | 23 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] |
| 24 | embassy-stm32-wpan = [] | 24 | embassy-stm32-wpan = [] |
| 25 | not-gpdma = [] | 25 | not-gpdma = [] |
| 26 | dac-adc-pin = [] | ||
| 26 | 27 | ||
| 27 | [dependencies] | 28 | [dependencies] |
| 28 | teleprobe-meta = "1" | 29 | teleprobe-meta = "1" |
| @@ -42,6 +43,7 @@ cortex-m-rt = "0.7.0" | |||
| 42 | embedded-hal = "0.2.6" | 43 | embedded-hal = "0.2.6" |
| 43 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } | 44 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } |
| 44 | embedded-hal-async = { version = "=0.2.0-alpha.2" } | 45 | embedded-hal-async = { version = "=0.2.0-alpha.2" } |
| 46 | micromath = "2.0.0" | ||
| 45 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 47 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 46 | rand_core = { version = "0.6", default-features = false } | 48 | rand_core = { version = "0.6", default-features = false } |
| 47 | rand_chacha = { version = "0.3", default-features = false } | 49 | rand_chacha = { version = "0.3", default-features = false } |
| @@ -56,6 +58,11 @@ path = "src/bin/can.rs" | |||
| 56 | required-features = [ "can",] | 58 | required-features = [ "can",] |
| 57 | 59 | ||
| 58 | [[bin]] | 60 | [[bin]] |
| 61 | name = "dac" | ||
| 62 | path = "src/bin/dac.rs" | ||
| 63 | required-features = [ "dac-adc-pin",] | ||
| 64 | |||
| 65 | [[bin]] | ||
| 59 | name = "gpio" | 66 | name = "gpio" |
| 60 | path = "src/bin/gpio.rs" | 67 | path = "src/bin/gpio.rs" |
| 61 | required-features = [] | 68 | required-features = [] |
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs new file mode 100644 index 000000000..67a7d5b59 --- /dev/null +++ b/tests/stm32/src/bin/dac.rs | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | // required-features: dac-adc-pin | ||
| 6 | |||
| 7 | #[path = "../common.rs"] | ||
| 8 | mod common; | ||
| 9 | use common::*; | ||
| 10 | use defmt::assert; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_stm32::adc::Adc; | ||
| 13 | use embassy_stm32::dac::{DacCh1, DacChannel, Value}; | ||
| 14 | use embassy_stm32::dma::NoDma; | ||
| 15 | use embassy_time::{Delay, Duration, Timer}; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | ||
| 17 | |||
| 18 | #[embassy_executor::main] | ||
| 19 | async fn main(_spawner: Spawner) { | ||
| 20 | // Initialize the board and obtain a Peripherals instance | ||
| 21 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | ||
| 22 | |||
| 23 | #[cfg(feature = "stm32f429zi")] | ||
| 24 | let dac_peripheral = p.DAC; | ||
| 25 | |||
| 26 | #[cfg(any(feature = "stm32h755zi", feature = "stm32g071rb"))] | ||
| 27 | let dac_peripheral = p.DAC1; | ||
| 28 | |||
| 29 | let mut dac: DacCh1<'_, _, NoDma> = DacCh1::new(dac_peripheral, NoDma, p.PA4); | ||
| 30 | unwrap!(dac.set_trigger_enable(false)); | ||
| 31 | |||
| 32 | let mut adc = Adc::new(p.ADC1, &mut Delay); | ||
| 33 | |||
| 34 | #[cfg(feature = "stm32h755zi")] | ||
| 35 | let normalization_factor = 256; | ||
| 36 | #[cfg(any(feature = "stm32f429zi", feature = "stm32g071rb"))] | ||
| 37 | let normalization_factor: i32 = 16; | ||
| 38 | |||
| 39 | unwrap!(dac.set(Value::Bit8(0))); | ||
| 40 | // Now wait a little to obtain a stable value | ||
| 41 | Timer::after(Duration::from_millis(30)).await; | ||
| 42 | let offset = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); | ||
| 43 | |||
| 44 | for v in 0..=255 { | ||
| 45 | // First set the DAC output value | ||
| 46 | let dac_output_val = to_sine_wave(v); | ||
| 47 | unwrap!(dac.set(Value::Bit8(dac_output_val))); | ||
| 48 | |||
| 49 | // Now wait a little to obtain a stable value | ||
| 50 | Timer::after(Duration::from_millis(30)).await; | ||
| 51 | |||
| 52 | // Need to steal the peripherals here because PA4 is obviously in use already | ||
| 53 | let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); | ||
| 54 | // Calibrate and normalize the measurement to get close to the dac_output_val | ||
| 55 | let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; | ||
| 56 | |||
| 57 | info!("value / measured: {} / {}", dac_output_val, measured_normalized); | ||
| 58 | |||
| 59 | // The deviations are quite enormous but that does not matter since this is only a quick test | ||
| 60 | assert!((dac_output_val as i16 - measured_normalized).abs() < 15); | ||
| 61 | } | ||
| 62 | |||
| 63 | info!("Test OK"); | ||
| 64 | cortex_m::asm::bkpt(); | ||
| 65 | } | ||
| 66 | |||
| 67 | use core::f32::consts::PI; | ||
| 68 | |||
| 69 | use micromath::F32Ext; | ||
| 70 | |||
| 71 | fn to_sine_wave(v: u8) -> u8 { | ||
| 72 | if v >= 128 { | ||
| 73 | // top half | ||
| 74 | let r = PI * ((v - 128) as f32 / 128.0); | ||
| 75 | (r.sin() * 128.0 + 127.0) as u8 | ||
| 76 | } else { | ||
| 77 | // bottom half | ||
| 78 | let r = PI + PI * (v as f32 / 128.0); | ||
| 79 | (r.sin() * 128.0 + 127.0) as u8 | ||
| 80 | } | ||
| 81 | } | ||
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 3d2a9b8ef..ca5cb43ac 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -33,6 +33,7 @@ pub fn config() -> Config { | |||
| 33 | { | 33 | { |
| 34 | config.rcc.sys_ck = Some(Hertz(400_000_000)); | 34 | config.rcc.sys_ck = Some(Hertz(400_000_000)); |
| 35 | config.rcc.pll1.q_ck = Some(Hertz(100_000_000)); | 35 | config.rcc.pll1.q_ck = Some(Hertz(100_000_000)); |
| 36 | config.rcc.adc_clock_source = embassy_stm32::rcc::AdcClockSource::PerCk; | ||
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | #[cfg(feature = "stm32u585ai")] | 39 | #[cfg(feature = "stm32u585ai")] |
