aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/timer/low_level.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/timer/low_level.rs')
-rw-r--r--embassy-stm32/src/timer/low_level.rs191
1 files changed, 71 insertions, 120 deletions
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs
index aba08081f..73a81bff1 100644
--- a/embassy-stm32/src/timer/low_level.rs
+++ b/embassy-stm32/src/timer/low_level.rs
@@ -268,6 +268,11 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
268 unsafe { crate::pac::timer::TimGp32::from_ptr(T::regs()) } 268 unsafe { crate::pac::timer::TimGp32::from_ptr(T::regs()) }
269 } 269 }
270 270
271 #[cfg(stm32l0)]
272 fn regs_gp32_unchecked(&self) -> crate::pac::timer::TimGp16 {
273 unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) }
274 }
275
271 /// Start the timer. 276 /// Start the timer.
272 pub fn start(&self) { 277 pub fn start(&self) {
273 self.regs_core().cr1().modify(|r| r.set_cen(true)); 278 self.regs_core().cr1().modify(|r| r.set_cen(true));
@@ -296,7 +301,12 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
296 301
297 /// get the capability of the timer 302 /// get the capability of the timer
298 pub fn bits(&self) -> TimerBits { 303 pub fn bits(&self) -> TimerBits {
299 T::BITS 304 match T::Word::bits() {
305 16 => TimerBits::Bits16,
306 #[cfg(not(stm32l0))]
307 32 => TimerBits::Bits32,
308 _ => unreachable!(),
309 }
300 } 310 }
301 311
302 /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. 312 /// Set the frequency of how many times per second the timer counts up to the max value or down to 0.
@@ -306,18 +316,10 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
306 /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved 316 /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved
307 /// because it needs to count up and down. 317 /// because it needs to count up and down.
308 pub fn set_frequency(&self, frequency: Hertz) { 318 pub fn set_frequency(&self, frequency: Hertz) {
309 match T::BITS { 319 self.set_frequency_internal(frequency, T::Word::bits());
310 TimerBits::Bits16 => {
311 self.set_frequency_internal(frequency, 16);
312 }
313 #[cfg(not(stm32l0))]
314 TimerBits::Bits32 => {
315 self.set_frequency_internal(frequency, 32);
316 }
317 }
318 } 320 }
319 321
320 pub(crate) fn set_frequency_internal(&self, frequency: Hertz, max_divide_by_bits: u8) { 322 pub(crate) fn set_frequency_internal(&self, frequency: Hertz, max_divide_by_bits: usize) {
321 let f = frequency.0; 323 let f = frequency.0;
322 assert!(f > 0); 324 assert!(f > 0);
323 let timer_f = T::frequency().0; 325 let timer_f = T::frequency().0;
@@ -326,25 +328,15 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
326 let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << max_divide_by_bits)).try_into()); 328 let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << max_divide_by_bits)).try_into());
327 let divide_by = pclk_ticks_per_timer_period / (u64::from(psc) + 1); 329 let divide_by = pclk_ticks_per_timer_period / (u64::from(psc) + 1);
328 330
329 match T::BITS { 331 // the timer counts `0..=arr`, we want it to count `0..divide_by`
330 TimerBits::Bits16 => { 332 let arr: T::Word = unwrap!(T::Word::try_from(divide_by - 1));
331 // the timer counts `0..=arr`, we want it to count `0..divide_by`
332 let arr = unwrap!(u16::try_from(divide_by - 1));
333
334 let regs = self.regs_core();
335 regs.psc().write_value(psc);
336 regs.arr().write(|r| r.set_arr(arr));
337 }
338 #[cfg(not(stm32l0))]
339 TimerBits::Bits32 => {
340 // the timer counts `0..=arr`, we want it to count `0..divide_by`
341 let arr: u32 = unwrap!(u32::try_from(divide_by - 1));
342 333
343 let regs = self.regs_gp32_unchecked(); 334 let regs = self.regs_gp32_unchecked();
344 regs.psc().write_value(psc); 335 regs.psc().write_value(psc);
345 regs.arr().write_value(arr); 336 #[cfg(stm32l0)]
346 } 337 regs.arr().write(|r| r.set_arr(unwrap!(arr.try_into())));
347 } 338 #[cfg(not(stm32l0))]
339 regs.arr().write_value(arr.into());
348 } 340 }
349 341
350 /// Set tick frequency. 342 /// Set tick frequency.
@@ -393,23 +385,14 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
393 pub fn get_frequency(&self) -> Hertz { 385 pub fn get_frequency(&self) -> Hertz {
394 let timer_f = T::frequency(); 386 let timer_f = T::frequency();
395 387
396 match T::BITS { 388 let regs = self.regs_gp32_unchecked();
397 TimerBits::Bits16 => { 389 #[cfg(not(stm32l0))]
398 let regs = self.regs_core(); 390 let arr = regs.arr().read();
399 let arr = regs.arr().read().arr(); 391 #[cfg(stm32l0)]
400 let psc = regs.psc().read(); 392 let arr = regs.arr().read().arr();
393 let psc = regs.psc().read();
401 394
402 timer_f / arr / (psc + 1) 395 timer_f / arr / (psc + 1)
403 }
404 #[cfg(not(stm32l0))]
405 TimerBits::Bits32 => {
406 let regs = self.regs_gp32_unchecked();
407 let arr = regs.arr().read();
408 let psc = regs.psc().read();
409
410 timer_f / arr / (psc + 1)
411 }
412 }
413 } 396 }
414 397
415 /// Get the clock frequency of the timer (before prescaler is applied). 398 /// Get the clock frequency of the timer (before prescaler is applied).
@@ -469,42 +452,29 @@ impl<'d, T: GeneralInstance1Channel> Timer<'d, T> {
469 } 452 }
470 453
471 /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. 454 /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC.
472 pub fn get_max_compare_value(&self) -> u32 { 455 pub fn get_max_compare_value(&self) -> T::Word {
473 match T::BITS { 456 #[cfg(not(stm32l0))]
474 TimerBits::Bits16 => self.regs_1ch().arr().read().arr() as u32, 457 return unwrap!(self.regs_gp32_unchecked().arr().read().try_into());
475 #[cfg(not(stm32l0))] 458 #[cfg(stm32l0)]
476 TimerBits::Bits32 => self.regs_gp32_unchecked().arr().read(), 459 return unwrap!(self.regs_gp32_unchecked().arr().read().arr().try_into());
477 }
478 } 460 }
479 461
480 /// Set the max compare value. 462 /// Set the max compare value.
481 /// 463 ///
482 /// An update event is generated to load the new value. The update event is 464 /// An update event is generated to load the new value. The update event is
483 /// generated such that it will not cause an interrupt or DMA request. 465 /// generated such that it will not cause an interrupt or DMA request.
484 pub fn set_max_compare_value(&self, ticks: u32) { 466 pub fn set_max_compare_value(&self, ticks: T::Word) {
485 match T::BITS { 467 let arr = ticks;
486 TimerBits::Bits16 => {
487 let arr = unwrap!(u16::try_from(ticks));
488 468
489 let regs = self.regs_1ch(); 469 let regs = self.regs_gp32_unchecked();
490 regs.arr().write(|r| r.set_arr(arr)); 470 #[cfg(not(stm32l0))]
471 regs.arr().write_value(arr.into());
472 #[cfg(stm32l0)]
473 regs.arr().write(|r| r.set_arr(unwrap!(arr.try_into())));
491 474
492 regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTER_ONLY)); 475 regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTER_ONLY));
493 regs.egr().write(|r| r.set_ug(true)); 476 regs.egr().write(|r| r.set_ug(true));
494 regs.cr1().modify(|r| r.set_urs(vals::Urs::ANY_EVENT)); 477 regs.cr1().modify(|r| r.set_urs(vals::Urs::ANY_EVENT));
495 }
496 #[cfg(not(stm32l0))]
497 TimerBits::Bits32 => {
498 let arr = ticks;
499
500 let regs = self.regs_gp32_unchecked();
501 regs.arr().write_value(arr);
502
503 regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTER_ONLY));
504 regs.egr().write(|r| r.set_ug(true));
505 regs.cr1().modify(|r| r.set_urs(vals::Urs::ANY_EVENT));
506 }
507 }
508 } 478 }
509} 479}
510 480
@@ -638,26 +608,23 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
638 } 608 }
639 609
640 /// Set compare value for a channel. 610 /// Set compare value for a channel.
641 pub fn set_compare_value(&self, channel: Channel, value: u32) { 611 pub fn set_compare_value(&self, channel: Channel, value: T::Word) {
642 match T::BITS { 612 #[cfg(not(stm32l0))]
643 TimerBits::Bits16 => { 613 self.regs_gp32_unchecked()
644 let value = unwrap!(u16::try_from(value)); 614 .ccr(channel.index())
645 self.regs_gp16().ccr(channel.index()).modify(|w| w.set_ccr(value)); 615 .write_value(value.into());
646 } 616 #[cfg(stm32l0)]
647 #[cfg(not(stm32l0))] 617 self.regs_gp16()
648 TimerBits::Bits32 => { 618 .ccr(channel.index())
649 self.regs_gp32_unchecked().ccr(channel.index()).write_value(value); 619 .modify(|w| w.set_ccr(unwrap!(value.try_into())));
650 }
651 }
652 } 620 }
653 621
654 /// Get compare value for a channel. 622 /// Get compare value for a channel.
655 pub fn get_compare_value(&self, channel: Channel) -> u32 { 623 pub fn get_compare_value(&self, channel: Channel) -> T::Word {
656 match T::BITS { 624 #[cfg(not(stm32l0))]
657 TimerBits::Bits16 => self.regs_gp16().ccr(channel.index()).read().ccr() as u32, 625 return unwrap!(self.regs_gp32_unchecked().ccr(channel.index()).read().try_into());
658 #[cfg(not(stm32l0))] 626 #[cfg(stm32l0)]
659 TimerBits::Bits32 => self.regs_gp32_unchecked().ccr(channel.index()).read(), 627 return unwrap!(self.regs_gp32_unchecked().ccr(channel.index()).read().ccr().try_into());
660 }
661 } 628 }
662 629
663 /// Setup a ring buffer for the channel 630 /// Setup a ring buffer for the channel
@@ -665,8 +632,8 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
665 &mut self, 632 &mut self,
666 dma: Peri<'a, impl super::UpDma<T>>, 633 dma: Peri<'a, impl super::UpDma<T>>,
667 channel: Channel, 634 channel: Channel,
668 dma_buf: &'a mut [u16], 635 dma_buf: &'a mut [T::Word],
669 ) -> WritableRingBuffer<'a, u16> { 636 ) -> WritableRingBuffer<'a, T::Word> {
670 #[allow(clippy::let_unit_value)] // eg. stm32f334 637 #[allow(clippy::let_unit_value)] // eg. stm32f334
671 let req = dma.request(); 638 let req = dma.request();
672 639
@@ -686,7 +653,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
686 WritableRingBuffer::new( 653 WritableRingBuffer::new(
687 dma, 654 dma,
688 req, 655 req,
689 self.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16, 656 self.regs_1ch().ccr(channel.index()).as_ptr() as *mut T::Word,
690 dma_buf, 657 dma_buf,
691 dma_transfer_option, 658 dma_transfer_option,
692 ) 659 )
@@ -701,7 +668,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
701 &mut self, 668 &mut self,
702 dma: Peri<'a, impl super::UpDma<T>>, 669 dma: Peri<'a, impl super::UpDma<T>>,
703 channel: Channel, 670 channel: Channel,
704 duty: &'a [u16], 671 duty: &'a [T::Word],
705 ) -> Transfer<'a> { 672 ) -> Transfer<'a> {
706 #[allow(clippy::let_unit_value)] // eg. stm32f334 673 #[allow(clippy::let_unit_value)] // eg. stm32f334
707 let req = dma.request(); 674 let req = dma.request();
@@ -719,29 +686,13 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
719 ..Default::default() 686 ..Default::default()
720 }; 687 };
721 688
722 match self.bits() { 689 Transfer::new_write(
723 TimerBits::Bits16 => Transfer::new_write( 690 dma,
724 dma, 691 req,
725 req, 692 duty,
726 duty, 693 self.regs_gp16().ccr(channel.index()).as_ptr() as *mut T::Word,
727 self.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16, 694 dma_transfer_option,
728 dma_transfer_option, 695 )
729 ),
730 #[cfg(not(any(stm32l0)))]
731 TimerBits::Bits32 => {
732 #[cfg(not(any(bdma, gpdma)))]
733 panic!("unsupported timer bits");
734
735 #[cfg(any(bdma, gpdma))]
736 Transfer::new_write(
737 dma,
738 req,
739 duty,
740 self.regs_1ch().ccr(channel.index()).as_ptr() as *mut u32,
741 dma_transfer_option,
742 )
743 }
744 }
745 } 696 }
746 } 697 }
747 698
@@ -779,7 +730,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
779 dma: Peri<'a, impl super::UpDma<T>>, 730 dma: Peri<'a, impl super::UpDma<T>>,
780 starting_channel: Channel, 731 starting_channel: Channel,
781 ending_channel: Channel, 732 ending_channel: Channel,
782 duty: &'a [u16], 733 duty: &'a [T::Word],
783 ) -> Transfer<'a> { 734 ) -> Transfer<'a> {
784 let cr1_addr = self.regs_gp16().cr1().as_ptr() as u32; 735 let cr1_addr = self.regs_gp16().cr1().as_ptr() as u32;
785 let start_ch_index = starting_channel.index(); 736 let start_ch_index = starting_channel.index();
@@ -815,14 +766,14 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
815 dma, 766 dma,
816 req, 767 req,
817 duty, 768 duty,
818 self.regs_gp16().dmar().as_ptr() as *mut u16, 769 self.regs_gp16().dmar().as_ptr() as *mut T::Word,
819 dma_transfer_option, 770 dma_transfer_option,
820 ) 771 )
821 } 772 }
822 } 773 }
823 774
824 /// Get capture value for a channel. 775 /// Get capture value for a channel.
825 pub fn get_capture_value(&self, channel: Channel) -> u32 { 776 pub fn get_capture_value(&self, channel: Channel) -> T::Word {
826 self.get_compare_value(channel) 777 self.get_compare_value(channel)
827 } 778 }
828 779