From 027df7ac0c5f63da125d3924b19b75f0880ae6d8 Mon Sep 17 00:00:00 2001 From: Sh3Rm4n Date: Tue, 25 May 2021 23:16:53 +0200 Subject: [PATCH] Add adc tests --- testsuite/Cargo.toml | 4 ++ testsuite/tests/adc.rs | 150 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 testsuite/tests/adc.rs diff --git a/testsuite/Cargo.toml b/testsuite/Cargo.toml index 86ecf8316..50c0984ba 100644 --- a/testsuite/Cargo.toml +++ b/testsuite/Cargo.toml @@ -4,6 +4,10 @@ name = "testsuite" publish = false version = "0.0.0" +[[test]] +name = "adc" +harness = false + [[test]] name = "uart" harness = false diff --git a/testsuite/tests/adc.rs b/testsuite/tests/adc.rs new file mode 100644 index 000000000..f32868732 --- /dev/null +++ b/testsuite/tests/adc.rs @@ -0,0 +1,150 @@ +#![no_std] +#![no_main] + +// TODO: Get pa9 and pa10 because these also implement spi and uart +use defmt_rtt as _; +use panic_probe as _; + +use stm32f3xx_hal as hal; + +use hal::gpio::{ + gpioa::{PA10, PA2, PA3, PA9}, + gpiob::{PB10, PB11}, + gpioc::{PC0, PC1}, +}; +use hal::gpio::{Output, PushPull, Analog}; +use hal::adc; +use hal::pac; +use hal::prelude::*; +use hal::serial::{Rx, Serial, Tx}; + +use core::array::IntoIter; + +use hal::serial::Error; + +struct State { + adc: adc::Adc, + analog: PC0, + output: PC1>, +} + +const TEST_MSG: [u8; 8] = [0xD, 0xE, 0xA, 0xD, 0xB, 0xE, 0xE, 0xF]; + +#[defmt_test::tests] +mod tests { + use super::*; + use defmt::{self, assert, assert_eq, unwrap}; + + #[init] + fn init() -> State { + let mut dp = unwrap!(pac::Peripherals::take()); + + let mut rcc = dp.RCC.constrain(); + let mut flash = dp.FLASH.constrain(); + let clocks = rcc.cfgr.freeze(&mut flash.acr); + let mut gpioc = dp.GPIOC.split(&mut rcc.ahb); + + // set up adc1 + + + State { + adc: adc::Adc::adc1( + dp.ADC1, // The ADC we are going to control + // The following is only needed to make sure the clock signal for the ADC is set up + // correctly. + &mut dp.ADC1_2, + &mut rcc.ahb, + adc::CkMode::default(), + clocks, + ), + analog: gpioc.pc0.into_analog(&mut gpioc.moder, &mut gpioc.pupdr), + output: gpioc.pc1.into_push_pull_output(&mut gpioc.moder, &mut gpioc.otyper), + } + } + + #[test] + fn measure_pin_high_low(state: &mut State) { + // let adc = defmt::unwrap!(state.adc.take()); + // let + + for _ in 1..10 { + defmt::unwrap!(state.output.set_high()); + let adc_level: u16 = defmt::unwrap!(state.adc.read(&mut state.analog).ok()); + defmt::info!("{}", adc_level); + defmt::unwrap!(state.output.set_low()); + // Vref is 3V so output should reach the maximum. + defmt::assert!(adc_level >= 4070 && adc_level <= 4100); + let adc_level: u16 = defmt::unwrap!(state.adc.read(&mut state.analog).ok()); + defmt::info!("{}", adc_level); + defmt::assert_eq!(adc_level, 0); + } + + } + + // FIXME: + // Problems: + // 1. if we split, we can not join (no runtime informatino which pins where associated with the + // uart) + // 2. if we free, we could crate a new one, + // 3. but to use the serial we **have** to split, so this is useless + // 4. So we have to implement join and than split on the whole uart to gain the uart + pins again. + // 5. We should introduce the builder pattern (config pattern instead of dirtctl setting the + // buad rate) + // 6. No way to set parity etc. + // 7. We have to implement read and write directly on the peripheral + // - Maybe this should also follow + // + // #[test] + // fn send_receive_split_fast(state: &mut super::State) { + // let (usart, pins) = unwrap!(state.serial1.take()).free(); + // let mut serial = Serial::usart1(usart, pins, 115200.Bd(), state.clocks, &mut state.apb2); + // let (mut tx, mut rx) = serial.split(); + // for i in &TEST_MSG { + // nb::block!(tx.write(*i)); + // let c = unwrap!(nb::block!(rx.read())); + // assert_eq!(c, *i); + // } + + // state.serial = Some(serial); + // } + + // #[test] + // fn send_receive_split(state: &mut super::State) { + // let (mut tx, mut rx) = unwrap!(state.serial1.take()).split(); + // for i in IntoIter::new(TEST_MSG) { + // nb::block!(tx.write(i)); + // let c = unwrap!(nb::block!(rx.read())); + // assert_eq!(c, i); + // } + + // // now provoke an overrun + // // send 5 u8 bytes, which do not fit in the 32 bit buffer + // for i in &TEST_MSG[..4] { + // nb::block!(tx.write(*i)); + // } + // let c = nb::block!(rx.read()); + // assert!(matches!(c, Err(Error::Overrun))); + // } + + // #[test] + // fn send_receive_wrong_baud(state: &mut super::State) { + // let (mut tx_slow, mut rx_slow) = unwrap!(state.serial_slow.take()).split(); + // let (mut tx_fast, mut rx_fast) = unwrap!(state.serial_fast.take()).split(); + + // // provoke an error (framing) + // nb::block!(tx_slow.write(b'a')); + // let c = nb::block!(rx_fast.read()); + // defmt::info!("{}", c); + // assert!(matches!(c, Err(Error::Framing))); + + // // provoke an error (framing) + // nb::block!(tx_fast.write(b'a')); + // let c = nb::block!(rx_slow.read()); + // defmt::info!("{}", c); + // assert!(matches!(c, Err(Error::Framing))); + // } + + // TODO: Check the parity. But currently, there is no way to configure the parity + // #[test] + // fn check_parity(state: &mut super::State) { } +}