55
66use panic_halt as _;
77
8- use cortex_m:: { asm, singleton} ;
8+ use cortex_m:: singleton;
9+ use cortex_m_semihosting:: hprintln;
910
1011use 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+ }
1225
1326#[ entry]
1427fn main ( ) -> ! {
@@ -34,21 +47,51 @@ fn main() -> ! {
3447
3548 // Configure pa0 as an analog input
3649 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+ } ;
3783
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 ( ) ;
4089
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 ( ) ;
4792
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+ } ;
5295
5396 loop { }
5497}
0 commit comments