Skip to content

Commit 05117e6

Browse files
committed
Add methods to measure voltage instead of raw value.
1 parent 38d5219 commit 05117e6

File tree

2 files changed

+73
-112
lines changed

2 files changed

+73
-112
lines changed

embedded-hal-async/src/adc.rs

+38-100
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
44

55
/// Read data from an ADC.
66
///
7+
/// # Note for Implementers
8+
///
9+
/// This should wait until data is ready and then read it.
10+
///
711
/// # Examples
812
///
913
/// In the first naive example, [`read`](crate::adc::AdcChannel::read) is implemented
@@ -21,7 +25,7 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
2125
/// }
2226
///
2327
/// pub fn data(&mut self) -> u32 {
24-
/// 42
28+
/// 3300
2529
/// }
2630
/// }
2731
///
@@ -30,12 +34,16 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
3034
/// }
3135
///
3236
/// impl AdcChannel for MySpinningAdc {
33-
/// async fn read(&mut self) -> Result<u32, Self::Error> {
37+
/// async fn measure_nv(&mut self) -> Result<i64, Self::Error> {
38+
/// Ok(self.measure_mv().await? as i64 * 1_000_000)
39+
/// }
40+
///
41+
/// async fn measure_mv(&mut self) -> Result<i32, Self::Error> {
3442
/// while !self.is_ready() {
3543
/// core::hint::spin_loop();
3644
/// }
3745
///
38-
/// Ok(self.data())
46+
/// Ok(self.data() as i32)
3947
/// }
4048
/// }
4149
/// ```
@@ -52,7 +60,7 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
5260
///
5361
/// impl<T> MyWaitingAdc<T> {
5462
/// pub fn data(&mut self) -> u32 {
55-
/// 42
63+
/// 3300
5664
/// }
5765
/// }
5866
///
@@ -61,7 +69,11 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
6169
/// }
6270
///
6371
/// impl<T: Wait> AdcChannel for MyWaitingAdc<T> {
64-
/// async fn read(&mut self) -> Result<u32, Self::Error> {
72+
/// async fn measure_nv(&mut self) -> Result<i64, Self::Error> {
73+
/// Ok(self.measure_mv().await? as i64 * 1_000_000)
74+
/// }
75+
///
76+
/// async fn measure_mv(&mut self) -> Result<i32, Self::Error> {
6577
/// match self.ready_pin.wait_for_high().await {
6678
/// Ok(()) => (),
6779
/// Err(err) => return Err(match err.kind() {
@@ -70,115 +82,41 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
7082
/// })
7183
/// }
7284
///
73-
/// Ok(self.data())
85+
/// Ok(self.data() as i32)
7486
/// }
7587
/// }
7688
/// ```
7789
pub trait AdcChannel: ErrorType {
78-
/// Reads data from the ADC.
79-
///
80-
/// # Note for Implementers
81-
///
82-
/// This should wait until data is ready and then read it.
83-
/// If the ADC's precision is less than 32 bits, the value must be scaled accordingly.
84-
async fn read(&mut self) -> Result<u32, Self::Error>;
90+
/// Take a measurement in nV (nanovolts).
91+
async fn measure_nv(&mut self) -> Result<i64, Self::Error>;
92+
93+
/// Take a measurement in mV (microvolts).
94+
async fn measure_uv(&mut self) -> Result<i32, Self::Error> {
95+
Ok((self.measure_nv().await? / 1_000) as i32)
96+
}
97+
98+
/// Take a measurement in mV (millivolts).
99+
async fn measure_mv(&mut self) -> Result<i32, Self::Error> {
100+
Ok((self.measure_uv().await? / 1_000) as i32)
101+
}
85102
}
86103

87104
impl<T> AdcChannel for &mut T
88105
where
89106
T: AdcChannel + ?Sized,
90107
{
91108
#[inline]
92-
async fn read(&mut self) -> Result<u32, Self::Error> {
93-
(*self).read().await
94-
}
95-
}
96-
97-
#[cfg(test)]
98-
mod test {
99-
use super::*;
100-
101-
/// Scale an integer containing `bits` bits to 32 bits.
102-
fn scale_bits(raw_data: u32, bits: u32) -> u32 {
103-
let mut scaled_data: u32 = 0;
104-
105-
let mut remaining_bits = u32::BITS;
106-
while remaining_bits > 0 {
107-
let shl = bits.min(remaining_bits);
108-
scaled_data = (scaled_data.wrapping_shl(shl)) | (raw_data.wrapping_shr(bits - shl));
109-
remaining_bits -= shl;
110-
}
111-
112-
scaled_data
113-
}
114-
115-
#[test]
116-
fn scale_bits_i8_to_i32() {
117-
let raw_data = u32::from(i8::MIN as u8);
118-
let scaled_data = scale_bits(raw_data, 8);
119-
assert!(i32::MIN <= (scaled_data as i32) && (scaled_data as i32) <= (i32::MIN + 1 << 8));
109+
async fn measure_nv(&mut self) -> Result<i64, Self::Error> {
110+
(*self).measure_nv().await
120111
}
121112

122-
macro_rules! impl_adc {
123-
($Adc:ident, $bits:literal, $uint:ty) => {
124-
struct $Adc($uint);
125-
126-
impl $Adc {
127-
const MAX: $uint = !(<$uint>::MAX.wrapping_shl($bits - 1).wrapping_shl(1));
128-
129-
pub fn data(&mut self) -> $uint {
130-
self.0
131-
}
132-
}
133-
134-
impl ErrorType for $Adc {
135-
type Error = core::convert::Infallible;
136-
}
137-
138-
impl AdcChannel for $Adc {
139-
async fn read(&mut self) -> Result<u32, Self::Error> {
140-
Ok(scale_bits(u32::from(self.data()), $bits))
141-
}
142-
}
143-
};
144-
}
145-
146-
macro_rules! test_adc {
147-
($Adc:ident, $bits:literal, $uint:ty) => {{
148-
impl_adc!($Adc, $bits, $uint);
149-
150-
// 0 should always be scaled to 0.
151-
let mut adc_0 = $Adc(0);
152-
assert_eq!(adc_0.read().await, Ok(0));
153-
154-
// `$Adc::MAX` should always be scaled to `u32::MAX`.
155-
let mut adc_max = $Adc($Adc::MAX);
156-
assert_eq!(adc_max.read().await, Ok(u32::MAX));
157-
}};
158-
}
159-
160-
#[tokio::test]
161-
async fn test_8_bit() {
162-
test_adc!(Adc8, 8, u8);
163-
}
164-
165-
#[tokio::test]
166-
async fn test_12_bit() {
167-
test_adc!(Adc12, 12, u16);
168-
}
169-
170-
#[tokio::test]
171-
async fn test_16_bit() {
172-
test_adc!(Adc16, 16, u16);
173-
}
174-
175-
#[tokio::test]
176-
async fn test_24_bit() {
177-
test_adc!(Adc24, 24, u32);
113+
#[inline]
114+
async fn measure_uv(&mut self) -> Result<i32, Self::Error> {
115+
(*self).measure_uv().await
178116
}
179117

180-
#[tokio::test]
181-
async fn test_32_bit() {
182-
test_adc!(Adc32, 32, u32);
118+
#[inline]
119+
async fn measure_mv(&mut self) -> Result<i32, Self::Error> {
120+
(*self).measure_mv().await
183121
}
184122
}

embedded-hal/src/adc.rs

+35-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ use crate::defmt;
77

88
/// Read data from an ADC.
99
///
10+
/// # Note for Implementers
11+
///
12+
/// This should wait until data is ready and then read it.
13+
///
1014
/// # Examples
1115
///
1216
/// In the first naive example, [`read`](crate::adc::AdcChannel::read) is implemented
@@ -24,7 +28,7 @@ use crate::defmt;
2428
/// }
2529
///
2630
/// pub fn data(&mut self) -> u32 {
27-
/// 42
31+
/// 3300
2832
/// }
2933
/// }
3034
///
@@ -33,32 +37,51 @@ use crate::defmt;
3337
/// }
3438
///
3539
/// impl AdcChannel for MySpinningAdc {
36-
/// fn read(&mut self) -> Result<u32, Self::Error> {
40+
/// fn measure_nv(&mut self) -> Result<i64, Self::Error> {
41+
/// Ok(self.measure_mv()? as i64 * 1_000_000)
42+
/// }
43+
///
44+
/// fn measure_mv(&mut self) -> Result<i32, Self::Error> {
3745
/// while !self.is_ready() {
3846
/// core::hint::spin_loop();
3947
/// }
4048
///
41-
/// Ok(self.data())
49+
/// Ok(self.data() as i32)
4250
/// }
4351
/// }
4452
/// ```
4553
pub trait AdcChannel: ErrorType {
46-
/// Reads data from the ADC.
47-
///
48-
/// # Note for Implementers
49-
///
50-
/// This should wait until data is ready and then read it.
51-
/// If the ADC's precision is less than 32 bits, the value must be scaled accordingly.
52-
fn read(&mut self) -> Result<u32, Self::Error>;
54+
/// Take a measurement in nV (nanovolts).
55+
fn measure_nv(&mut self) -> Result<i64, Self::Error>;
56+
57+
/// Take a measurement in mV (microvolts).
58+
fn measure_uv(&mut self) -> Result<i32, Self::Error> {
59+
Ok((self.measure_nv()? / 1_000) as i32)
60+
}
61+
62+
/// Take a measurement in mV (millivolts).
63+
fn measure_mv(&mut self) -> Result<i32, Self::Error> {
64+
Ok(self.measure_uv()? / 1_000)
65+
}
5366
}
5467

5568
impl<T> AdcChannel for &mut T
5669
where
5770
T: AdcChannel + ?Sized,
5871
{
5972
#[inline]
60-
fn read(&mut self) -> Result<u32, Self::Error> {
61-
(*self).read()
73+
fn measure_nv(&mut self) -> Result<i64, Self::Error> {
74+
(*self).measure_nv()
75+
}
76+
77+
#[inline]
78+
fn measure_uv(&mut self) -> Result<i32, Self::Error> {
79+
(*self).measure_uv()
80+
}
81+
82+
#[inline]
83+
fn measure_mv(&mut self) -> Result<i32, Self::Error> {
84+
(*self).measure_mv()
6285
}
6386
}
6487

0 commit comments

Comments
 (0)