@@ -6,6 +6,8 @@ use crate::gpio::Analog;
6
6
use crate :: gpio:: { gpioa, gpiob, gpioc} ;
7
7
use crate :: rcc:: APB2 ;
8
8
use crate :: time:: Hertz ;
9
+ use crate :: dma:: { Receive , TransferPayload , dma1:: C1 , CircBuffer , Transfer , W , RxDma } ;
10
+ use core:: sync:: atomic:: { self , Ordering } ;
9
11
10
12
use crate :: stm32:: ADC1 ;
11
13
#[ cfg( any(
@@ -490,3 +492,118 @@ adc_hal! {
490
492
adc2rst
491
493
) ,
492
494
}
495
+
496
+ pub struct AdcPayload < PIN : Channel < ADC1 > > {
497
+ adc : Adc < ADC1 > ,
498
+ pin : PIN ,
499
+ }
500
+
501
+ pub type AdcDma < PIN > = RxDma < AdcPayload < PIN > , C1 > ;
502
+
503
+ impl < PIN > Receive for AdcDma < PIN > where PIN : Channel < ADC1 > {
504
+ type RxChannel = C1 ;
505
+ type TransmittedWord = u16 ;
506
+ }
507
+
508
+ impl < PIN > TransferPayload for AdcDma < PIN > where PIN : Channel < ADC1 > {
509
+ fn start ( & mut self ) {
510
+ self . channel . start ( ) ;
511
+ self . payload . adc . rb . cr2 . modify ( |_, w| w. cont ( ) . set_bit ( ) ) ;
512
+ self . payload . adc . rb . cr2 . modify ( |_, w| w. adon ( ) . set_bit ( ) ) ;
513
+ }
514
+ fn stop ( & mut self ) {
515
+ self . channel . stop ( ) ;
516
+ self . payload . adc . rb . cr2 . modify ( |_, w| w. cont ( ) . clear_bit ( ) ) ;
517
+ }
518
+ }
519
+
520
+ impl Adc < ADC1 > {
521
+ pub fn with_dma < PIN > ( mut self , pin : PIN , dma_ch : C1 ) -> AdcDma < PIN >
522
+ where
523
+ PIN : Channel < ADC1 , ID = u8 > ,
524
+ {
525
+ self . rb . cr1 . modify ( |_, w| w. discen ( ) . clear_bit ( ) ) ;
526
+ self . rb . cr2 . modify ( |_, w| w. align ( ) . bit ( self . align . into ( ) ) ) ;
527
+ self . set_chan_smps ( PIN :: channel ( ) ) ;
528
+ self . rb . sqr3 . modify ( |_, w| unsafe { w. sq1 ( ) . bits ( PIN :: channel ( ) ) } ) ;
529
+ self . rb . cr2 . modify ( |_, w| w. dma ( ) . set_bit ( ) ) ;
530
+
531
+ let payload = AdcPayload {
532
+ adc : self ,
533
+ pin,
534
+ } ;
535
+ RxDma {
536
+ payload,
537
+ channel : dma_ch,
538
+ }
539
+ }
540
+ }
541
+
542
+ impl < PIN > AdcDma < PIN > where PIN : Channel < ADC1 > {
543
+ pub fn split ( mut self ) -> ( Adc < ADC1 > , PIN , C1 ) {
544
+ self . stop ( ) ;
545
+
546
+ let AdcDma { payload, channel} = self ;
547
+ payload. adc . rb . cr2 . modify ( |_, w| w. dma ( ) . clear_bit ( ) ) ;
548
+ payload. adc . rb . cr1 . modify ( |_, w| w. discen ( ) . set_bit ( ) ) ;
549
+
550
+ ( payload. adc , payload. pin , channel)
551
+ }
552
+ }
553
+
554
+ impl < B , PIN > crate :: dma:: CircReadDma < B , u16 > for AdcDma < PIN >
555
+ where
556
+ B : AsMut < [ u16 ] > ,
557
+ PIN : Channel < ADC1 > ,
558
+ {
559
+ fn circ_read ( mut self , buffer : & ' static mut [ B ; 2 ] ) -> CircBuffer < B , Self > {
560
+ {
561
+ let buffer = buffer[ 0 ] . as_mut ( ) ;
562
+ self . channel . set_peripheral_address ( unsafe { & ( * ADC1 :: ptr ( ) ) . dr as * const _ as u32 } , false ) ;
563
+ self . channel . set_memory_address ( buffer. as_ptr ( ) as u32 , true ) ;
564
+ self . channel . set_transfer_length ( buffer. len ( ) * 2 ) ;
565
+
566
+ atomic:: compiler_fence ( Ordering :: Release ) ;
567
+
568
+ self . channel . ch ( ) . cr . modify ( |_, w| { w
569
+ . mem2mem ( ) . clear_bit ( )
570
+ . pl ( ) . medium ( )
571
+ . msize ( ) . bit16 ( )
572
+ . psize ( ) . bit16 ( )
573
+ . circ ( ) . set_bit ( )
574
+ . dir ( ) . clear_bit ( )
575
+ } ) ;
576
+ }
577
+
578
+ self . start ( ) ;
579
+
580
+ CircBuffer :: new ( buffer, self )
581
+ }
582
+ }
583
+
584
+ impl < B , PIN > crate :: dma:: ReadDma < B , u16 > for AdcDma < PIN >
585
+ where
586
+ B : AsMut < [ u16 ] > ,
587
+ PIN : Channel < ADC1 > ,
588
+ {
589
+ fn read ( mut self , buffer : & ' static mut B ) -> Transfer < W , & ' static mut B , Self > {
590
+ {
591
+ let buffer = buffer. as_mut ( ) ;
592
+ self . channel . set_peripheral_address ( unsafe { & ( * ADC1 :: ptr ( ) ) . dr as * const _ as u32 } , false ) ;
593
+ self . channel . set_memory_address ( buffer. as_ptr ( ) as u32 , true ) ;
594
+ self . channel . set_transfer_length ( buffer. len ( ) ) ;
595
+ }
596
+ atomic:: compiler_fence ( Ordering :: Release ) ;
597
+ self . channel . ch ( ) . cr . modify ( |_, w| { w
598
+ . mem2mem ( ) . clear_bit ( )
599
+ . pl ( ) . medium ( )
600
+ . msize ( ) . bit16 ( )
601
+ . psize ( ) . bit16 ( )
602
+ . circ ( ) . clear_bit ( )
603
+ . dir ( ) . clear_bit ( )
604
+ } ) ;
605
+ self . start ( ) ;
606
+
607
+ Transfer :: w ( buffer, self )
608
+ }
609
+ }
0 commit comments