@@ -21,6 +21,22 @@ pub struct Continuous;
2121/// Single conversion mode
2222pub struct Single ;
2323
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+
2440/// ADC configuration
2541pub struct Adc < ADC > {
2642 rb : ADC ,
@@ -344,6 +360,11 @@ macro_rules! adc_hal {
344360 self . rb. sqr1. modify( |_, w| w. l( ) . bits( ( len-1 ) as u8 ) ) ;
345361 }
346362
363+ #[ allow( unused) ]
364+ fn sequence_len( & self ) -> usize {
365+ self . rb. sqr1. read( ) . l( ) . bits( ) as usize + 1
366+ }
367+
347368 /**
348369 Performs an ADC conversion
349370
@@ -709,15 +730,29 @@ impl<B, PINS, MODE> crate::dma::ReadDma<B, u16> for AdcDma<PINS, MODE>
709730where
710731 Self : TransferPayload ,
711732 B : as_slice:: AsMutSlice < Element = u16 > ,
733+ MODE : ConversionMode ,
712734{
713735 fn read ( mut self , buffer : & ' static mut B ) -> Transfer < W , & ' static mut B , Self > {
714736 {
715737 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+
716751 self . channel
717752 . set_peripheral_address ( unsafe { & ( * ADC1 :: ptr ( ) ) . dr as * const _ as u32 } , false ) ;
718753 self . channel
719754 . 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 ) ;
721756 }
722757 atomic:: compiler_fence ( Ordering :: Release ) ;
723758 self . channel . ch ( ) . cr . modify ( |_, w| {
0 commit comments