feat: Add 32-bit timer support for waveform function

This commit is contained in:
Liu Hancheng 2025-01-01 17:05:48 +08:00
parent 667dfa34b5
commit cbc7a9fe5b
2 changed files with 34 additions and 9 deletions

View File

@ -235,6 +235,10 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
self.regs_core().cnt().write(|r| r.set_cnt(0)); self.regs_core().cnt().write(|r| r.set_cnt(0));
} }
pub fn get_bits(&self) -> TimerBits {
T::BITS
}
/// Set the frequency of how many times per second the timer counts up to the max value or down to 0. /// Set the frequency of how many times per second the timer counts up to the max value or down to 0.
/// ///
/// This means that in the default edge-aligned mode, /// This means that in the default edge-aligned mode,

View File

@ -6,6 +6,7 @@ use core::mem::ManuallyDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
use super::TimerBits;
use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel}; use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel};
use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::gpio::{AfType, AnyPin, OutputType, Speed};
use crate::time::Hertz; use crate::time::Hertz;
@ -365,7 +366,7 @@ macro_rules! impl_waveform_chx {
/// ///
/// Note: /// Note:
/// you will need to provide corresponding TIMx_CHy DMA channel to use this method. /// you will need to provide corresponding TIMx_CHy DMA channel to use this method.
pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u16]) { pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u8]) {
use crate::pac::timer::vals::Ccds; use crate::pac::timer::vals::Ccds;
into_ref!(dma); into_ref!(dma);
@ -406,14 +407,34 @@ macro_rules! impl_waveform_chx {
..Default::default() ..Default::default()
}; };
Transfer::new_write( match self.inner.get_bits() {
&mut dma, TimerBits::Bits16 => {
req, // the data must be aligned to double words
duty, assert!(duty.len() % 2 == 0);
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _, let duty = core::slice::from_raw_parts(duty.as_ptr() as *const u16, duty.len() / 2);
dma_transfer_option, Transfer::new_write(
) &mut dma,
.await req,
duty,
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _,
dma_transfer_option,
)
.await
}
TimerBits::Bits32 => {
// the data must be aligned to quad words
assert!(duty.len() % 4 == 0);
let duty = core::slice::from_raw_parts(duty.as_ptr() as *const u32, duty.len() / 4);
Transfer::new_write(
&mut dma,
req,
duty,
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _,
dma_transfer_option,
)
.await
}
};
}; };
// restore output compare state // restore output compare state