Merge pull request #3549 from aurelj/stm32_pwm_32bits_timer
stm32/timer: avoid max_compare_value >= u16::MAX
This commit is contained in:
		
						commit
						db9ad1c30c
					
				@ -116,7 +116,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            1u8
 | 
					            1u8
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        self.inner.set_frequency(freq * multiplier);
 | 
					        self.inner.set_frequency_internal(freq * multiplier, 16);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Get max duty value.
 | 
					    /// Get max duty value.
 | 
				
			||||||
 | 
				
			|||||||
@ -242,16 +242,28 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
 | 
				
			|||||||
    /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved
 | 
					    /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved
 | 
				
			||||||
    /// because it needs to count up and down.
 | 
					    /// because it needs to count up and down.
 | 
				
			||||||
    pub fn set_frequency(&self, frequency: Hertz) {
 | 
					    pub fn set_frequency(&self, frequency: Hertz) {
 | 
				
			||||||
 | 
					        match T::BITS {
 | 
				
			||||||
 | 
					            TimerBits::Bits16 => {
 | 
				
			||||||
 | 
					                self.set_frequency_internal(frequency, 16);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            #[cfg(not(stm32l0))]
 | 
				
			||||||
 | 
					            TimerBits::Bits32 => {
 | 
				
			||||||
 | 
					                self.set_frequency_internal(frequency, 32);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub(crate) fn set_frequency_internal(&self, frequency: Hertz, max_divide_by_bits: u8) {
 | 
				
			||||||
        let f = frequency.0;
 | 
					        let f = frequency.0;
 | 
				
			||||||
        assert!(f > 0);
 | 
					        assert!(f > 0);
 | 
				
			||||||
        let timer_f = T::frequency().0;
 | 
					        let timer_f = T::frequency().0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let pclk_ticks_per_timer_period = (timer_f / f) as u64;
 | 
				
			||||||
 | 
					        let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << max_divide_by_bits)).try_into());
 | 
				
			||||||
 | 
					        let divide_by = pclk_ticks_per_timer_period / (u64::from(psc) + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        match T::BITS {
 | 
					        match T::BITS {
 | 
				
			||||||
            TimerBits::Bits16 => {
 | 
					            TimerBits::Bits16 => {
 | 
				
			||||||
                let pclk_ticks_per_timer_period = timer_f / f;
 | 
					 | 
				
			||||||
                let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 16)).try_into());
 | 
					 | 
				
			||||||
                let divide_by = pclk_ticks_per_timer_period / (u32::from(psc) + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // the timer counts `0..=arr`, we want it to count `0..divide_by`
 | 
					                // the timer counts `0..=arr`, we want it to count `0..divide_by`
 | 
				
			||||||
                let arr = unwrap!(u16::try_from(divide_by - 1));
 | 
					                let arr = unwrap!(u16::try_from(divide_by - 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -265,10 +277,6 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            #[cfg(not(stm32l0))]
 | 
					            #[cfg(not(stm32l0))]
 | 
				
			||||||
            TimerBits::Bits32 => {
 | 
					            TimerBits::Bits32 => {
 | 
				
			||||||
                let pclk_ticks_per_timer_period = (timer_f / f) as u64;
 | 
					 | 
				
			||||||
                let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 32)).try_into());
 | 
					 | 
				
			||||||
                let divide_by = pclk_ticks_per_timer_period / (u64::from(psc) + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // the timer counts `0..=arr`, we want it to count `0..divide_by`
 | 
					                // the timer counts `0..=arr`, we want it to count `0..divide_by`
 | 
				
			||||||
                let arr: u32 = unwrap!(u32::try_from(divide_by - 1));
 | 
					                let arr: u32 = unwrap!(u32::try_from(divide_by - 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -278,7 +278,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            1u8
 | 
					            1u8
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        self.inner.set_frequency(freq * multiplier);
 | 
					        self.inner.set_frequency_internal(freq * multiplier, 16);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Get max duty value.
 | 
					    /// Get max duty value.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user