@@ -21,6 +21,22 @@ pub struct Continuous;
21
21
/// Single conversion mode
22
22
pub struct Single ;
23
23
24
+ pub trait ConversionMode {
25
+ fn is_continuous ( ) -> bool ;
26
+ }
27
+
28
+ impl ConversionMode for Continuous {
29
+ fn is_continuous ( ) -> bool {
30
+ true
31
+ }
32
+ }
33
+
34
+ impl ConversionMode for Single {
35
+ fn is_continuous ( ) -> bool {
36
+ false
37
+ }
38
+ }
39
+
24
40
/// ADC configuration
25
41
pub struct Adc < ADC > {
26
42
rb : ADC ,
@@ -344,6 +360,11 @@ macro_rules! adc_hal {
344
360
self . rb. sqr1. modify( |_, w| w. l( ) . bits( ( len-1 ) as u8 ) ) ;
345
361
}
346
362
363
+ #[ allow( unused) ]
364
+ fn sequence_len( & self ) -> usize {
365
+ self . rb. sqr1. read( ) . l( ) . bits( ) as usize + 1
366
+ }
367
+
347
368
/**
348
369
Performs an ADC conversion
349
370
@@ -709,15 +730,29 @@ impl<B, PINS, MODE> crate::dma::ReadDma<B, u16> for AdcDma<PINS, MODE>
709
730
where
710
731
Self : TransferPayload ,
711
732
B : as_slice:: AsMutSlice < Element = u16 > ,
733
+ MODE : ConversionMode ,
712
734
{
713
735
fn read ( mut self , buffer : & ' static mut B ) -> Transfer < W , & ' static mut B , Self > {
714
736
{
715
737
let buffer = buffer. as_mut_slice ( ) ;
738
+
739
+ let conversion_len = if MODE :: is_continuous ( ) {
740
+ buffer. len ( )
741
+ } else {
742
+ // for non-continous conversion, conversion sequence length should match with DMA
743
+ // transfer length, to prevent DMA from waiting for a conversion indefinitely
744
+ let sequence_len = self . payload . adc . sequence_len ( ) ;
745
+ if buffer. len ( ) < sequence_len {
746
+ panic ! ( "short buffer on ADC conversion: buffer.len()={:?}, adc.seqeuence_len()={:?}" , buffer. len( ) , sequence_len) ;
747
+ }
748
+ sequence_len
749
+ } ;
750
+
716
751
self . channel
717
752
. set_peripheral_address ( unsafe { & ( * ADC1 :: ptr ( ) ) . dr as * const _ as u32 } , false ) ;
718
753
self . channel
719
754
. set_memory_address ( buffer. as_ptr ( ) as u32 , true ) ;
720
- self . channel . set_transfer_length ( buffer . len ( ) ) ;
755
+ self . channel . set_transfer_length ( conversion_len ) ;
721
756
}
722
757
atomic:: compiler_fence ( Ordering :: Release ) ;
723
758
self . channel . ch ( ) . cr . modify ( |_, w| {
0 commit comments