@@ -4,10 +4,10 @@ use embedded_hal::adc::{Channel, OneShot};
4
4
5
5
use crate :: gpio:: Analog ;
6
6
use crate :: gpio:: { gpioa, gpiob, gpioc} ;
7
- use crate :: rcc:: APB2 ;
8
- use crate :: time:: Hertz ;
7
+ use crate :: rcc:: { APB2 , Clocks } ;
9
8
use crate :: dma:: { Receive , TransferPayload , dma1:: C1 , CircBuffer , Transfer , W , RxDma } ;
10
9
use core:: sync:: atomic:: { self , Ordering } ;
10
+ use cortex_m:: asm:: delay;
11
11
12
12
use crate :: stm32:: ADC1 ;
13
13
#[ cfg( any(
@@ -20,7 +20,7 @@ pub struct Adc<ADC> {
20
20
rb : ADC ,
21
21
sample_time : AdcSampleTime ,
22
22
align : AdcAlign ,
23
- clk : Hertz
23
+ clocks : Clocks
24
24
}
25
25
26
26
#[ derive( Clone , Copy , Debug , PartialEq ) ]
@@ -175,18 +175,29 @@ macro_rules! adc_hal {
175
175
///
176
176
/// Sets all configurable parameters to one-shot defaults,
177
177
/// performs a boot-time calibration.
178
- pub fn $init( adc: $ADC, apb2: & mut APB2 , clk : Hertz ) -> Self {
178
+ pub fn $init( adc: $ADC, apb2: & mut APB2 , clocks : Clocks ) -> Self {
179
179
let mut s = Self {
180
180
rb: adc,
181
181
sample_time: AdcSampleTime :: default ( ) ,
182
182
align: AdcAlign :: default ( ) ,
183
- clk : clk ,
183
+ clocks ,
184
184
} ;
185
185
s. enable_clock( apb2) ;
186
186
s. power_down( ) ;
187
187
s. reset( apb2) ;
188
188
s. setup_oneshot( ) ;
189
189
s. power_up( ) ;
190
+
191
+ // The manual states that we need to wait two ADC clocks cycles after power-up
192
+ // before starting calibration, we already delayed in the power-up process, but
193
+ // if the adc clock is too low that was not enough.
194
+ if s. clocks. adcclk( ) . 0 < 2_500_000 {
195
+ let two_adc_cycles = s. clocks. sysclk( ) . 0 / s. clocks. adcclk( ) . 0 * 2 ;
196
+ let already_delayed = s. clocks. sysclk( ) . 0 / 800_000 ;
197
+ if two_adc_cycles > already_delayed {
198
+ delay( two_adc_cycles - already_delayed) ;
199
+ }
200
+ }
190
201
s. calibrate( ) ;
191
202
s
192
203
}
@@ -234,6 +245,12 @@ macro_rules! adc_hal {
234
245
235
246
fn power_up( & mut self ) {
236
247
self . rb. cr2. modify( |_, w| w. adon( ) . set_bit( ) ) ;
248
+
249
+ // The reference manual says that a stabilization time is needed after power_up,
250
+ // this time can be found in the datasheets.
251
+ // Here we are delaying for approximately 1us, considering 1.25 instructions per
252
+ // cycle. Do we support a chip which needs more than 1us ?
253
+ delay( self . clocks. sysclk( ) . 0 / 800_000 ) ;
237
254
}
238
255
239
256
fn power_down( & mut self ) {
@@ -249,6 +266,10 @@ macro_rules! adc_hal {
249
266
apb2. enr( ) . modify( |_, w| w. $adcxen( ) . set_bit( ) ) ;
250
267
}
251
268
269
+ fn disable_clock( & mut self , apb2: & mut APB2 ) {
270
+ apb2. enr( ) . modify( |_, w| w. $adcxen( ) . clear_bit( ) ) ;
271
+ }
272
+
252
273
fn calibrate( & mut self ) {
253
274
/* reset calibration */
254
275
self . rb. cr2. modify( |_, w| w. rstcal( ) . set_bit( ) ) ;
@@ -365,6 +386,13 @@ macro_rules! adc_hal {
365
386
let res = self . rb. dr. read( ) . data( ) . bits( ) ;
366
387
res
367
388
}
389
+
390
+ /// Powers down the ADC, disables the ADC clock and releases the ADC Peripheral
391
+ pub fn release( mut self , apb2: & mut APB2 ) -> $ADC {
392
+ self . power_down( ) ;
393
+ self . disable_clock( apb2) ;
394
+ self . rb
395
+ }
368
396
}
369
397
370
398
impl <WORD , PIN > OneShot <$ADC, WORD , PIN > for Adc <$ADC>
@@ -375,9 +403,7 @@ macro_rules! adc_hal {
375
403
type Error = ( ) ;
376
404
377
405
fn read( & mut self , _pin: & mut PIN ) -> nb:: Result <WORD , Self :: Error > {
378
- self . power_up( ) ;
379
406
let res = self . convert( PIN :: channel( ) ) ;
380
- self . power_down( ) ;
381
407
Ok ( res. into( ) )
382
408
}
383
409
}
@@ -390,14 +416,18 @@ impl Adc<ADC1> {
390
416
fn read_aux ( & mut self , chan : u8 ) -> u16 {
391
417
let tsv_off = if self . rb . cr2 . read ( ) . tsvrefe ( ) . bit_is_clear ( ) {
392
418
self . rb . cr2 . modify ( |_, w| w. tsvrefe ( ) . set_bit ( ) ) ;
419
+
420
+ // The reference manual says that a stabilization time is needed after the powering the
421
+ // sensor, this time can be found in the datasheets.
422
+ // Here we are delaying for approximately 10us, considering 1.25 instructions per
423
+ // cycle. Do we support a chip which needs more than 10us ?
424
+ delay ( self . clocks . sysclk ( ) . 0 / 80_000 ) ;
393
425
true
394
426
} else {
395
427
false
396
428
} ;
397
429
398
- self . power_up ( ) ;
399
430
let val = self . convert ( chan) ;
400
- self . power_down ( ) ;
401
431
402
432
if tsv_off {
403
433
self . rb . cr2 . modify ( |_, w| w. tsvrefe ( ) . clear_bit ( ) ) ;
@@ -431,14 +461,14 @@ impl Adc<ADC1> {
431
461
// recommended ADC sampling for temperature sensor is 17.1 usec,
432
462
// so use the following approximate settings
433
463
// to support all ADC frequencies
434
- let sample_time = match self . clk . 0 {
464
+ let sample_time = match self . clocks . adcclk ( ) . 0 {
435
465
0 ... 1_200_000 => AdcSampleTime :: T_1 ,
436
466
1_200_001 ... 1_500_000 => AdcSampleTime :: T_7 ,
437
467
1_500_001 ... 2_400_000 => AdcSampleTime :: T_13 ,
438
468
2_400_001 ... 3_100_000 => AdcSampleTime :: T_28 ,
439
469
3_100_001 ... 4_000_000 => AdcSampleTime :: T_41 ,
440
470
4_000_001 ... 5_000_000 => AdcSampleTime :: T_55 ,
441
- 5_000_001 ... 10_000_000 => AdcSampleTime :: T_71 ,
471
+ 5_000_001 ... 14_000_000 => AdcSampleTime :: T_71 ,
442
472
_ => AdcSampleTime :: T_239 ,
443
473
} ;
444
474
0 commit comments