5
5
6
6
use panic_halt as _;
7
7
8
- use cortex_m:: { asm, singleton} ;
8
+ use cortex_m:: singleton;
9
+ use cortex_m_semihosting:: hprintln;
9
10
10
11
use cortex_m_rt:: entry;
11
- use stm32f1xx_hal:: { adc, pac, prelude:: * } ;
12
+ use stm32f1xx_hal:: gpio:: gpioa:: { PA0 , PA2 } ;
13
+ use stm32f1xx_hal:: { adc, gpio:: Analog , pac, prelude:: * } ;
14
+
15
+ pub struct AdcPins ( PA0 < Analog > , PA2 < Analog > ) ;
16
+ impl adc:: SetChannels < AdcPins > for adc:: Adc < pac:: ADC1 > {
17
+ fn set_samples ( & mut self ) {
18
+ self . set_channel_sample_time ( 0 , adc:: SampleTime :: T_28 ) ;
19
+ self . set_channel_sample_time ( 2 , adc:: SampleTime :: T_28 ) ;
20
+ }
21
+ fn set_sequence ( & mut self ) {
22
+ self . set_regular_sequence ( & [ 0 , 2 , 0 , 2 ] ) ;
23
+ }
24
+ }
12
25
13
26
#[ entry]
14
27
fn main ( ) -> ! {
@@ -34,21 +47,51 @@ fn main() -> ! {
34
47
35
48
// Configure pa0 as an analog input
36
49
let adc_ch0 = gpioa. pa0 . into_analog ( & mut gpioa. crl ) ;
50
+ let adc_ch2 = gpioa. pa2 . into_analog ( & mut gpioa. crl ) ;
51
+
52
+ // single-channel continuous conversion
53
+ let ( adc1, adc_ch0, dma_ch1) = {
54
+ let adc_dma = adc1. with_dma ( adc_ch0, dma_ch1) ;
55
+ let buf = singleton ! ( : [ u16 ; 8 ] = [ 0 ; 8 ] ) . unwrap ( ) ;
56
+
57
+ // The read method consumes the buf and self, starts the adc and dma transfer and returns a
58
+ // RxDma struct. The wait method consumes the RxDma struct, waits for the whole transfer to
59
+ // be completed and then returns the updated buf and underlying adc_dma struct. For non
60
+ // blocking, one can call the is_done method of RxDma and only call wait after that method
61
+ // returns true.
62
+ let ( _buf, adc_dma) = adc_dma. read ( buf) . wait ( ) ;
63
+ hprintln ! ( "single-channel continuous conversion={:?}" , _buf) . ok ( ) ;
64
+
65
+ // Consumes the AdcDma struct, restores adc configuration to previous state and returns the
66
+ // Adc struct in normal mode.
67
+ adc_dma. split ( )
68
+ } ;
69
+
70
+ // multi-channel single-shot conversion
71
+ let ( adc1, AdcPins ( adc_ch0, adc_ch2) , dma_ch1) = {
72
+ let pins = AdcPins ( adc_ch0, adc_ch2) ;
73
+ let adc_dma = adc1. with_scan_dma :: < _ , adc:: Single > ( pins, dma_ch1) ;
74
+
75
+ // TODO: should match with # of conversions specified by AdcPins
76
+ let buf = singleton ! ( : [ u16 ; 4 ] = [ 0 ; 4 ] ) . unwrap ( ) ;
77
+
78
+ let ( _buf, adc_dma) = adc_dma. read ( buf) . wait ( ) ;
79
+ hprintln ! ( "multi-channel single-shot conversion={:?}" , _buf) . ok ( ) ;
80
+
81
+ adc_dma. split ( )
82
+ } ;
37
83
38
- let adc_dma = adc1. with_dma ( adc_ch0, dma_ch1) ;
39
- let buf = singleton ! ( : [ u16 ; 8 ] = [ 0 ; 8 ] ) . unwrap ( ) ;
84
+ // multi-channel continuous conversion
85
+ let ( _adc1, AdcPins ( _adc_ch0, _adc_ch2) , _dma_ch1) = {
86
+ let pins = AdcPins ( adc_ch0, adc_ch2) ;
87
+ let adc_dma = adc1. with_scan_dma :: < _ , adc:: Continuous > ( pins, dma_ch1) ;
88
+ let buf = singleton ! ( : [ u16 ; 8 ] = [ 0 ; 8 ] ) . unwrap ( ) ;
40
89
41
- // The read method consumes the buf and self, starts the adc and dma transfer and returns a
42
- // RxDma struct. The wait method consumes the RxDma struct, waits for the whole transfer to be
43
- // completed and then returns the updated buf and underlying adc_dma struct. For non blocking,
44
- // one can call the is_done method of RxDma and only call wait after that method returns true.
45
- let ( _buf, adc_dma) = adc_dma. read ( buf) . wait ( ) ;
46
- asm:: bkpt ( ) ;
90
+ let ( _buf, adc_dma) = adc_dma. read ( buf) . wait ( ) ;
91
+ hprintln ! ( "multi-channel continuous conversion={:?}" , _buf) . ok ( ) ;
47
92
48
- // Consumes the AdcDma struct, restores adc configuration to previous state and returns the
49
- // Adc struct in normal mode.
50
- let ( _adc1, _adc_ch0, _dma_ch1) = adc_dma. split ( ) ;
51
- asm:: bkpt ( ) ;
93
+ adc_dma. split ( )
94
+ } ;
52
95
53
96
loop { }
54
97
}
0 commit comments