Skip to content

Commit 027df7a

Browse files
committed
Add adc tests
1 parent 2072f57 commit 027df7a

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

testsuite/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ name = "testsuite"
44
publish = false
55
version = "0.0.0"
66

7+
[[test]]
8+
name = "adc"
9+
harness = false
10+
711
[[test]]
812
name = "uart"
913
harness = false

testsuite/tests/adc.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
// TODO: Get pa9 and pa10 because these also implement spi and uart
5+
use defmt_rtt as _;
6+
use panic_probe as _;
7+
8+
use stm32f3xx_hal as hal;
9+
10+
use hal::gpio::{
11+
gpioa::{PA10, PA2, PA3, PA9},
12+
gpiob::{PB10, PB11},
13+
gpioc::{PC0, PC1},
14+
};
15+
use hal::gpio::{Output, PushPull, Analog};
16+
use hal::adc;
17+
use hal::pac;
18+
use hal::prelude::*;
19+
use hal::serial::{Rx, Serial, Tx};
20+
21+
use core::array::IntoIter;
22+
23+
use hal::serial::Error;
24+
25+
struct State {
26+
adc: adc::Adc<pac::ADC1>,
27+
analog: PC0<Analog>,
28+
output: PC1<Output<PushPull>>,
29+
}
30+
31+
const TEST_MSG: [u8; 8] = [0xD, 0xE, 0xA, 0xD, 0xB, 0xE, 0xE, 0xF];
32+
33+
#[defmt_test::tests]
34+
mod tests {
35+
use super::*;
36+
use defmt::{self, assert, assert_eq, unwrap};
37+
38+
#[init]
39+
fn init() -> State {
40+
let mut dp = unwrap!(pac::Peripherals::take());
41+
42+
let mut rcc = dp.RCC.constrain();
43+
let mut flash = dp.FLASH.constrain();
44+
let clocks = rcc.cfgr.freeze(&mut flash.acr);
45+
let mut gpioc = dp.GPIOC.split(&mut rcc.ahb);
46+
47+
// set up adc1
48+
49+
50+
State {
51+
adc: adc::Adc::adc1(
52+
dp.ADC1, // The ADC we are going to control
53+
// The following is only needed to make sure the clock signal for the ADC is set up
54+
// correctly.
55+
&mut dp.ADC1_2,
56+
&mut rcc.ahb,
57+
adc::CkMode::default(),
58+
clocks,
59+
),
60+
analog: gpioc.pc0.into_analog(&mut gpioc.moder, &mut gpioc.pupdr),
61+
output: gpioc.pc1.into_push_pull_output(&mut gpioc.moder, &mut gpioc.otyper),
62+
}
63+
}
64+
65+
#[test]
66+
fn measure_pin_high_low(state: &mut State) {
67+
// let adc = defmt::unwrap!(state.adc.take());
68+
// let
69+
70+
for _ in 1..10 {
71+
defmt::unwrap!(state.output.set_high());
72+
let adc_level: u16 = defmt::unwrap!(state.adc.read(&mut state.analog).ok());
73+
defmt::info!("{}", adc_level);
74+
defmt::unwrap!(state.output.set_low());
75+
// Vref is 3V so output should reach the maximum.
76+
defmt::assert!(adc_level >= 4070 && adc_level <= 4100);
77+
let adc_level: u16 = defmt::unwrap!(state.adc.read(&mut state.analog).ok());
78+
defmt::info!("{}", adc_level);
79+
defmt::assert_eq!(adc_level, 0);
80+
}
81+
82+
}
83+
84+
// FIXME:
85+
// Problems:
86+
// 1. if we split, we can not join (no runtime informatino which pins where associated with the
87+
// uart)
88+
// 2. if we free, we could crate a new one,
89+
// 3. but to use the serial we **have** to split, so this is useless
90+
// 4. So we have to implement join and than split on the whole uart to gain the uart + pins again.
91+
// 5. We should introduce the builder pattern (config pattern instead of dirtctl setting the
92+
// buad rate)
93+
// 6. No way to set parity etc.
94+
// 7. We have to implement read and write directly on the peripheral
95+
// - Maybe this should also follow
96+
//
97+
// #[test]
98+
// fn send_receive_split_fast(state: &mut super::State) {
99+
// let (usart, pins) = unwrap!(state.serial1.take()).free();
100+
// let mut serial = Serial::usart1(usart, pins, 115200.Bd(), state.clocks, &mut state.apb2);
101+
// let (mut tx, mut rx) = serial.split();
102+
// for i in &TEST_MSG {
103+
// nb::block!(tx.write(*i));
104+
// let c = unwrap!(nb::block!(rx.read()));
105+
// assert_eq!(c, *i);
106+
// }
107+
108+
// state.serial = Some(serial);
109+
// }
110+
111+
// #[test]
112+
// fn send_receive_split(state: &mut super::State) {
113+
// let (mut tx, mut rx) = unwrap!(state.serial1.take()).split();
114+
// for i in IntoIter::new(TEST_MSG) {
115+
// nb::block!(tx.write(i));
116+
// let c = unwrap!(nb::block!(rx.read()));
117+
// assert_eq!(c, i);
118+
// }
119+
120+
// // now provoke an overrun
121+
// // send 5 u8 bytes, which do not fit in the 32 bit buffer
122+
// for i in &TEST_MSG[..4] {
123+
// nb::block!(tx.write(*i));
124+
// }
125+
// let c = nb::block!(rx.read());
126+
// assert!(matches!(c, Err(Error::Overrun)));
127+
// }
128+
129+
// #[test]
130+
// fn send_receive_wrong_baud(state: &mut super::State) {
131+
// let (mut tx_slow, mut rx_slow) = unwrap!(state.serial_slow.take()).split();
132+
// let (mut tx_fast, mut rx_fast) = unwrap!(state.serial_fast.take()).split();
133+
134+
// // provoke an error (framing)
135+
// nb::block!(tx_slow.write(b'a'));
136+
// let c = nb::block!(rx_fast.read());
137+
// defmt::info!("{}", c);
138+
// assert!(matches!(c, Err(Error::Framing)));
139+
140+
// // provoke an error (framing)
141+
// nb::block!(tx_fast.write(b'a'));
142+
// let c = nb::block!(rx_slow.read());
143+
// defmt::info!("{}", c);
144+
// assert!(matches!(c, Err(Error::Framing)));
145+
// }
146+
147+
// TODO: Check the parity. But currently, there is no way to configure the parity
148+
// #[test]
149+
// fn check_parity(state: &mut super::State) { }
150+
}

0 commit comments

Comments
 (0)