@@ -4,6 +4,10 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
4
4
5
5
/// Read data from an ADC.
6
6
///
7
+ /// # Note for Implementers
8
+ ///
9
+ /// This should wait until data is ready and then read it.
10
+ ///
7
11
/// # Examples
8
12
///
9
13
/// In the first naive example, [`read`](crate::adc::AdcChannel::read) is implemented
@@ -21,7 +25,7 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
21
25
/// }
22
26
///
23
27
/// pub fn data(&mut self) -> u32 {
24
- /// 42
28
+ /// 3300
25
29
/// }
26
30
/// }
27
31
///
@@ -30,12 +34,16 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
30
34
/// }
31
35
///
32
36
/// 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> {
34
42
/// while !self.is_ready() {
35
43
/// core::hint::spin_loop();
36
44
/// }
37
45
///
38
- /// Ok(self.data())
46
+ /// Ok(self.data() as i32 )
39
47
/// }
40
48
/// }
41
49
/// ```
@@ -52,7 +60,7 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
52
60
///
53
61
/// impl<T> MyWaitingAdc<T> {
54
62
/// pub fn data(&mut self) -> u32 {
55
- /// 42
63
+ /// 3300
56
64
/// }
57
65
/// }
58
66
///
@@ -61,7 +69,11 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
61
69
/// }
62
70
///
63
71
/// 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> {
65
77
/// match self.ready_pin.wait_for_high().await {
66
78
/// Ok(()) => (),
67
79
/// Err(err) => return Err(match err.kind() {
@@ -70,115 +82,41 @@ pub use embedded_hal::adc::{Error, ErrorKind, ErrorType};
70
82
/// })
71
83
/// }
72
84
///
73
- /// Ok(self.data())
85
+ /// Ok(self.data() as i32 )
74
86
/// }
75
87
/// }
76
88
/// ```
77
89
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
+ }
85
102
}
86
103
87
104
impl < T > AdcChannel for & mut T
88
105
where
89
106
T : AdcChannel + ?Sized ,
90
107
{
91
108
#[ 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
120
111
}
121
112
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
178
116
}
179
117
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
183
121
}
184
122
}
0 commit comments