aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma/dma_bdma.rs38
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs26
2 files changed, 35 insertions, 29 deletions
diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs
index 1945c3587..8b4b454c0 100644
--- a/embassy-stm32/src/dma/dma_bdma.rs
+++ b/embassy-stm32/src/dma/dma_bdma.rs
@@ -340,7 +340,8 @@ impl AnyChannel {
340 mem_addr: *mut u32, 340 mem_addr: *mut u32,
341 mem_len: usize, 341 mem_len: usize,
342 incr_mem: bool, 342 incr_mem: bool,
343 data_size: WordSize, 343 mem_size: WordSize,
344 peripheral_size: WordSize,
344 options: TransferOptions, 345 options: TransferOptions,
345 ) { 346 ) {
346 let info = self.info(); 347 let info = self.info();
@@ -380,8 +381,8 @@ impl AnyChannel {
380 }); 381 });
381 ch.cr().write(|w| { 382 ch.cr().write(|w| {
382 w.set_dir(dir.into()); 383 w.set_dir(dir.into());
383 w.set_msize(data_size.into()); 384 w.set_msize(mem_size.into());
384 w.set_psize(data_size.into()); 385 w.set_psize(peripheral_size.into());
385 w.set_pl(options.priority.into()); 386 w.set_pl(options.priority.into());
386 w.set_minc(incr_mem); 387 w.set_minc(incr_mem);
387 w.set_pinc(false); 388 w.set_pinc(false);
@@ -414,8 +415,8 @@ impl AnyChannel {
414 ch.mar().write_value(mem_addr as u32); 415 ch.mar().write_value(mem_addr as u32);
415 ch.ndtr().write(|w| w.set_ndt(mem_len as u16)); 416 ch.ndtr().write(|w| w.set_ndt(mem_len as u16));
416 ch.cr().write(|w| { 417 ch.cr().write(|w| {
417 w.set_psize(data_size.into()); 418 w.set_psize(peripheral_size.into());
418 w.set_msize(data_size.into()); 419 w.set_msize(mem_size.into());
419 w.set_minc(incr_mem); 420 w.set_minc(incr_mem);
420 w.set_dir(dir.into()); 421 w.set_dir(dir.into());
421 w.set_teie(true); 422 w.set_teie(true);
@@ -602,27 +603,28 @@ impl<'a> Transfer<'a> {
602 buf.len(), 603 buf.len(),
603 true, 604 true,
604 W::size(), 605 W::size(),
606 W::size(),
605 options, 607 options,
606 ) 608 )
607 } 609 }
608 610
609 /// Create a new write DMA transfer (memory to peripheral). 611 /// Create a new write DMA transfer (memory to peripheral).
610 pub unsafe fn new_write<W: Word>( 612 pub unsafe fn new_write<MW: Word, PW: Word>(
611 channel: impl Peripheral<P = impl Channel> + 'a, 613 channel: impl Peripheral<P = impl Channel> + 'a,
612 request: Request, 614 request: Request,
613 buf: &'a [W], 615 buf: &'a [MW],
614 peri_addr: *mut W, 616 peri_addr: *mut PW,
615 options: TransferOptions, 617 options: TransferOptions,
616 ) -> Self { 618 ) -> Self {
617 Self::new_write_raw(channel, request, buf, peri_addr, options) 619 Self::new_write_raw(channel, request, buf, peri_addr, options)
618 } 620 }
619 621
620 /// Create a new write DMA transfer (memory to peripheral), using raw pointers. 622 /// Create a new write DMA transfer (memory to peripheral), using raw pointers.
621 pub unsafe fn new_write_raw<W: Word>( 623 pub unsafe fn new_write_raw<W: Word, PW: Word>(
622 channel: impl Peripheral<P = impl Channel> + 'a, 624 channel: impl Peripheral<P = impl Channel> + 'a,
623 request: Request, 625 request: Request,
624 buf: *const [W], 626 buf: *const [W],
625 peri_addr: *mut W, 627 peri_addr: *mut PW,
626 options: TransferOptions, 628 options: TransferOptions,
627 ) -> Self { 629 ) -> Self {
628 into_ref!(channel); 630 into_ref!(channel);
@@ -636,6 +638,7 @@ impl<'a> Transfer<'a> {
636 buf.len(), 638 buf.len(),
637 true, 639 true,
638 W::size(), 640 W::size(),
641 W::size(),
639 options, 642 options,
640 ) 643 )
641 } 644 }
@@ -660,6 +663,7 @@ impl<'a> Transfer<'a> {
660 count, 663 count,
661 false, 664 false,
662 W::size(), 665 W::size(),
666 W::size(),
663 options, 667 options,
664 ) 668 )
665 } 669 }
@@ -673,15 +677,23 @@ impl<'a> Transfer<'a> {
673 mem_len: usize, 677 mem_len: usize,
674 incr_mem: bool, 678 incr_mem: bool,
675 data_size: WordSize, 679 data_size: WordSize,
680 peripheral_size: WordSize,
676 options: TransferOptions, 681 options: TransferOptions,
677 ) -> Self { 682 ) -> Self {
678 assert!(mem_len > 0 && mem_len <= 0xFFFF); 683 assert!(mem_len > 0 && mem_len <= 0xFFFF);
679 684
680 channel.configure( 685 channel.configure(
681 _request, dir, peri_addr, mem_addr, mem_len, incr_mem, data_size, options, 686 _request,
687 dir,
688 peri_addr,
689 mem_addr,
690 mem_len,
691 incr_mem,
692 data_size,
693 peripheral_size,
694 options,
682 ); 695 );
683 channel.start(); 696 channel.start();
684
685 Self { channel } 697 Self { channel }
686 } 698 }
687 699
@@ -814,6 +826,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
814 len, 826 len,
815 true, 827 true,
816 data_size, 828 data_size,
829 data_size,
817 options, 830 options,
818 ); 831 );
819 832
@@ -966,6 +979,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
966 len, 979 len,
967 true, 980 true,
968 data_size, 981 data_size,
982 data_size,
969 options, 983 options,
970 ); 984 );
971 985
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index f36fa026c..8d3c9a131 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -334,7 +334,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
334 &mut dma, 334 &mut dma,
335 req, 335 req,
336 duty, 336 duty,
337 self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut _, 337 self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16,
338 dma_transfer_option, 338 dma_transfer_option,
339 ) 339 )
340 .await 340 .await
@@ -362,13 +362,7 @@ macro_rules! impl_waveform_chx {
362 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { 362 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
363 impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { 363 impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
364 /// Generate a sequence of PWM waveform 364 /// Generate a sequence of PWM waveform
365 /// 365 pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u16]) {
366 /// Note:
367 /// 1. you will need to provide corresponding TIMx_CHy DMA channel to use this method.
368 /// 2. Please make sure the duty data length is aligned to the timer data width(16-bit or 32-bit).
369 /// 3. Please notice the endianess of the duty data. STM32 use little endian,
370 /// for example, 0x12345678 as u32 will be stored as [0x78, 0x56, 0x34, 0x12] in memory.
371 pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u8]) {
372 use crate::pac::timer::vals::Ccds; 366 use crate::pac::timer::vals::Ccds;
373 367
374 into_ref!(dma); 368 into_ref!(dma);
@@ -411,32 +405,30 @@ macro_rules! impl_waveform_chx {
411 405
412 match self.inner.bits() { 406 match self.inner.bits() {
413 TimerBits::Bits16 => { 407 TimerBits::Bits16 => {
414 // the data must be aligned to double words
415 assert!(duty.len() % 2 == 0);
416 let duty = core::slice::from_raw_parts(duty.as_ptr() as *const u16, duty.len() / 2);
417 Transfer::new_write( 408 Transfer::new_write(
418 &mut dma, 409 &mut dma,
419 req, 410 req,
420 duty, 411 duty,
421 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _, 412 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16,
422 dma_transfer_option, 413 dma_transfer_option,
423 ) 414 )
424 .await 415 .await
425 } 416 }
426 #[cfg(not(stm32l0))] 417 #[cfg(not(any(stm32l0, bdma, gpdma)))]
427 TimerBits::Bits32 => { 418 TimerBits::Bits32 => {
428 // the data must be aligned to quad words
429 assert!(duty.len() % 4 == 0);
430 let duty = core::slice::from_raw_parts(duty.as_ptr() as *const u32, duty.len() / 4);
431 Transfer::new_write( 419 Transfer::new_write(
432 &mut dma, 420 &mut dma,
433 req, 421 req,
434 duty, 422 duty,
435 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _, 423 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32,
436 dma_transfer_option, 424 dma_transfer_option,
437 ) 425 )
438 .await 426 .await
439 } 427 }
428 #[cfg(any(stm32l0, bdma, gpdma))]
429 _ => {
430 panic!("unsupported timer bits")
431 }
440 }; 432 };
441 }; 433 };
442 434