@@ -4,6 +4,7 @@ use core::sync::atomic::{Ordering, compiler_fence};
44#[ allow( unused_imports) ]
55use embassy_hal_internal:: Peri ;
66
7+ use crate :: adc:: Adc ;
78#[ allow( unused_imports) ]
89use crate :: adc:: { Instance , RxDma } ;
910#[ allow( unused_imports) ]
@@ -13,21 +14,12 @@ use crate::rcc;
1314#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
1415pub struct OverrunError ;
1516
16- #[ cfg( adc_v2) ]
17- fn clear_interrupt_flags ( r : crate :: pac:: adc:: Adc ) {
18- r. sr ( ) . modify ( |regs| {
19- regs. set_eoc ( false ) ;
20- regs. set_ovr ( false ) ;
21- } ) ;
22- }
23-
2417pub struct RingBufferedAdc < ' d , T : Instance > {
25- pub _phantom : PhantomData < T > ,
26- pub ring_buf : ReadableRingBuffer < ' d , u16 > ,
18+ _phantom : PhantomData < T > ,
19+ ring_buf : ReadableRingBuffer < ' d , u16 > ,
2720}
2821
2922impl < ' d , T : Instance > RingBufferedAdc < ' d , T > {
30- #[ cfg( not( adc_v2) ) ]
3123 pub ( crate ) fn new ( dma : Peri < ' d , impl RxDma < T > > , dma_buf : & ' d mut [ u16 ] ) -> Self {
3224 //dma side setup
3325 let opts = TransferOptions {
@@ -48,161 +40,24 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
4840 }
4941 }
5042
51- #[ cfg( adc_v2) ]
52- fn is_on ( ) -> bool {
53- T :: regs ( ) . cr2 ( ) . read ( ) . adon ( )
54- }
55-
56- #[ cfg( adc_v2) ]
5743 /// Turns on ADC if it is not already turned on and starts continuous DMA transfer.
58- pub fn start ( & mut self ) -> Result < ( ) , OverrunError > {
59- self . setup_adc ( ) ;
60- self . ring_buf . clear ( ) ;
61-
62- Ok ( ( ) )
63- }
44+ pub fn start ( & mut self ) {
45+ compiler_fence ( Ordering :: SeqCst ) ;
46+ self . ring_buf . start ( ) ;
6447
65- #[ cfg( adc_v2) ]
66- fn stop ( & mut self , err : OverrunError ) -> Result < usize , OverrunError > {
67- self . teardown_adc ( ) ;
68- Err ( err)
48+ Adc :: < T > :: start ( ) ;
6949 }
7050
71- #[ cfg( adc_v2) ]
72- /// Stops DMA transfer.
73- /// It does not turn off ADC.
74- /// Calling `start` restarts continuous DMA transfer.
75- ///
76- /// [`start`]: #method.start
77- pub fn teardown_adc ( & mut self ) {
78- // Stop the DMA transfer
51+ pub fn stop ( & mut self ) {
7952 self . ring_buf . request_pause ( ) ;
8053
81- let r = T :: regs ( ) ;
82-
83- // Stop ADC
84- r. cr2 ( ) . modify ( |reg| {
85- // Stop ADC
86- reg. set_swstart ( false ) ;
87- // Stop DMA
88- reg. set_dma ( false ) ;
89- } ) ;
90-
91- r. cr1 ( ) . modify ( |w| {
92- // Disable interrupt for end of conversion
93- w. set_eocie ( false ) ;
94- // Disable interrupt for overrun
95- w. set_ovrie ( false ) ;
96- } ) ;
97-
98- clear_interrupt_flags ( r) ;
54+ Adc :: < T > :: stop ( ) ;
9955
10056 compiler_fence ( Ordering :: SeqCst ) ;
10157 }
10258
103- #[ cfg( adc_v2) ]
104- fn setup_adc ( & mut self ) {
105- use crate :: pac:: adc:: vals;
106-
107- compiler_fence ( Ordering :: SeqCst ) ;
108-
109- self . ring_buf . start ( ) ;
110-
111- let r = T :: regs ( ) ;
112-
113- // Enable ADC
114- let was_on = Self :: is_on ( ) ;
115- if !was_on {
116- r. cr2 ( ) . modify ( |reg| {
117- reg. set_adon ( false ) ;
118- reg. set_swstart ( false ) ;
119- } ) ;
120- }
121-
122- // Clear all interrupts
123- r. sr ( ) . modify ( |regs| {
124- regs. set_eoc ( false ) ;
125- regs. set_ovr ( false ) ;
126- regs. set_strt ( false ) ;
127- } ) ;
128-
129- r. cr1 ( ) . modify ( |w| {
130- // Enable interrupt for end of conversion
131- w. set_eocie ( true ) ;
132- // Enable interrupt for overrun
133- w. set_ovrie ( true ) ;
134- // Scanning converisons of multiple channels
135- w. set_scan ( true ) ;
136- // Continuous conversion mode
137- w. set_discen ( false ) ;
138- } ) ;
139-
140- r. cr2 ( ) . modify ( |w| {
141- // Enable DMA mode
142- w. set_dma ( true ) ;
143- // Enable continuous conversions
144- w. set_cont ( true ) ;
145- // DMA requests are issues as long as DMA=1 and data are converted.
146- w. set_dds ( vals:: Dds :: CONTINUOUS ) ;
147- // EOC flag is set at the end of each conversion.
148- w. set_eocs ( vals:: Eocs :: EACH_CONVERSION ) ;
149- } ) ;
150-
151- // Begin ADC conversions
152- T :: regs ( ) . cr2 ( ) . modify ( |reg| {
153- reg. set_adon ( true ) ;
154- reg. set_swstart ( true ) ;
155- } ) ;
156-
157- super :: blocking_delay_us ( 3 ) ;
158- }
159-
160- #[ cfg( any( adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0) ) ]
161- #[ inline]
162- fn start_continuous_sampling ( & mut self ) {
163- // Start adc conversion
164- T :: regs ( ) . cr ( ) . modify ( |reg| {
165- reg. set_adstart ( true ) ;
166- } ) ;
167- self . ring_buf . start ( ) ;
168- }
169-
170- #[ cfg( any( adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0) ) ]
171- #[ inline]
172- pub fn stop_continuous_sampling ( & mut self ) {
173- // Stop adc conversion
174- if T :: regs ( ) . cr ( ) . read ( ) . adstart ( ) && !T :: regs ( ) . cr ( ) . read ( ) . addis ( ) {
175- T :: regs ( ) . cr ( ) . modify ( |reg| {
176- reg. set_adstp ( true ) ;
177- } ) ;
178- while T :: regs ( ) . cr ( ) . read ( ) . adstart ( ) { }
179- }
180- }
181-
182- #[ cfg( any( adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0) ) ]
183- pub fn disable_adc ( & mut self ) {
184- self . stop_continuous_sampling ( ) ;
59+ pub fn clear ( & mut self ) {
18560 self . ring_buf . clear ( ) ;
186- self . ring_buf . request_pause ( ) ;
187- }
188-
189- #[ cfg( any( adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0) ) ]
190- pub fn teardown_adc ( & mut self ) {
191- self . disable_adc ( ) ;
192-
193- //disable dma control
194- #[ cfg( not( any( adc_g0, adc_u0) ) ) ]
195- T :: regs ( ) . cfgr ( ) . modify ( |reg| {
196- reg. set_dmaen ( false ) ;
197- } ) ;
198- #[ cfg( any( adc_g0, adc_u0) ) ]
199- T :: regs ( ) . cfgr1 ( ) . modify ( |reg| {
200- reg. set_dmaen ( false ) ;
201- } ) ;
202-
203- //TODO: do we need to cleanup the DMA request here?
204-
205- compiler_fence ( Ordering :: SeqCst ) ;
20661 }
20762
20863 /// Reads measurements from the DMA ring buffer.
@@ -257,31 +112,17 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
257112 "Buffer size must be half the size of the ring buffer"
258113 ) ;
259114
260- let r = T :: regs ( ) ;
115+ if !self . ring_buf . is_running ( ) {
116+ self . start ( ) ;
117+ }
261118
262119 #[ cfg( adc_v2) ]
263120 {
264- // Start background receive if it was not already started
265- if !r. cr2 ( ) . read ( ) . dma ( ) {
266- self . start ( ) ?;
267- }
268-
269121 // Clear overrun flag if set.
270- if r. sr ( ) . read ( ) . ovr ( ) {
271- return self . stop ( OverrunError ) ;
272- }
273-
274- // Start background receive if it was not already started
275- if !r. cr ( ) . read ( ) . adstart ( ) {
276- self . start_continuous_sampling ( ) ;
277- }
278- }
122+ if T :: regs ( ) . sr ( ) . read ( ) . ovr ( ) {
123+ self . stop ( ) ;
279124
280- #[ cfg( not( adc_v2) ) ]
281- {
282- // Start background receive if it was not already started
283- if !r. cr ( ) . read ( ) . adstart ( ) {
284- self . start_continuous_sampling ( ) ;
125+ return Err ( OverrunError ) ;
285126 }
286127 }
287128
@@ -297,50 +138,29 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
297138 /// Receive in the background is terminated if an error is returned.
298139 /// It must then manually be started again by calling `start_continuous_sampling()` or by re-calling `blocking_read()`.
299140 pub fn blocking_read ( & mut self , buf : & mut [ u16 ] ) -> Result < usize , OverrunError > {
300- let r = T :: regs ( ) ;
141+ if !self . ring_buf . is_running ( ) {
142+ self . start ( ) ;
143+ }
301144
302145 #[ cfg( adc_v2) ]
303146 {
304- // Start background receive if it was not already started
305- if !r. cr2 ( ) . read ( ) . dma ( ) {
306- self . start ( ) ?;
307- }
308-
309147 // Clear overrun flag if set.
310- if r. sr ( ) . read ( ) . ovr ( ) {
311- return self . stop ( OverrunError ) ;
312- }
148+ if T :: regs ( ) . sr ( ) . read ( ) . ovr ( ) {
149+ self . stop ( ) ;
313150
314- loop {
315- match self . ring_buf . read ( buf) {
316- Ok ( ( 0 , _) ) => { }
317- Ok ( ( len, _) ) => {
318- return Ok ( len) ;
319- }
320- Err ( _) => {
321- return self . stop ( OverrunError ) ;
322- }
323- }
151+ return Err ( OverrunError ) ;
324152 }
325153 }
154+ loop {
155+ match self . ring_buf . read ( buf) {
156+ Ok ( ( 0 , _) ) => { }
157+ Ok ( ( len, _) ) => {
158+ return Ok ( len) ;
159+ }
160+ Err ( _) => {
161+ self . stop ( ) ;
326162
327- #[ cfg( not( adc_v2) ) ]
328- {
329- // Start background receive if it was not already started
330- if !r. cr ( ) . read ( ) . adstart ( ) {
331- self . start_continuous_sampling ( ) ;
332- }
333-
334- loop {
335- match self . ring_buf . read ( buf) {
336- Ok ( ( 0 , _) ) => { }
337- Ok ( ( len, _) ) => {
338- return Ok ( len) ;
339- }
340- Err ( _) => {
341- self . stop_continuous_sampling ( ) ;
342- return Err ( OverrunError ) ;
343- }
163+ return Err ( OverrunError ) ;
344164 }
345165 }
346166 }
@@ -349,7 +169,11 @@ impl<'d, T: Instance> RingBufferedAdc<'d, T> {
349169
350170impl < T : Instance > Drop for RingBufferedAdc < ' _ , T > {
351171 fn drop ( & mut self ) {
352- self . teardown_adc ( ) ;
172+ Adc :: < T > :: teardown_adc ( ) ;
173+
174+ compiler_fence ( Ordering :: SeqCst ) ;
175+
176+ self . ring_buf . request_pause ( ) ;
353177 rcc:: disable :: < T > ( ) ;
354178 }
355179}
0 commit comments