mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-10-02 14:44:32 +00:00
Merge pull request #3704 from CNLHC/pwm_support_gp32
feat: Add 32-bit timer support for waveform function
This commit is contained in:
commit
eda51673f5
@ -1785,9 +1785,9 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
|
|||||||
assert_eq!(blocks.len() % block_size, 0);
|
assert_eq!(blocks.len() % block_size, 0);
|
||||||
// Configure DMA to transfer input to crypto core.
|
// Configure DMA to transfer input to crypto core.
|
||||||
let dma_request = dma.request();
|
let dma_request = dma.request();
|
||||||
let dst_ptr = T::regs().din().as_ptr();
|
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
|
||||||
let num_words = blocks.len() / 4;
|
let num_words = blocks.len() / 4;
|
||||||
let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
|
let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
|
||||||
let options = TransferOptions {
|
let options = TransferOptions {
|
||||||
#[cfg(not(gpdma))]
|
#[cfg(not(gpdma))]
|
||||||
priority: crate::dma::Priority::High,
|
priority: crate::dma::Priority::High,
|
||||||
@ -1825,9 +1825,9 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
|
|||||||
assert_eq!((blocks.len() * 4) % block_size, 0);
|
assert_eq!((blocks.len() * 4) % block_size, 0);
|
||||||
// Configure DMA to transfer input to crypto core.
|
// Configure DMA to transfer input to crypto core.
|
||||||
let dma_request = dma.request();
|
let dma_request = dma.request();
|
||||||
let dst_ptr = T::regs().din().as_ptr();
|
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
|
||||||
let num_words = blocks.len();
|
let num_words = blocks.len();
|
||||||
let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
|
let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
|
||||||
let options = TransferOptions {
|
let options = TransferOptions {
|
||||||
#[cfg(not(gpdma))]
|
#[cfg(not(gpdma))]
|
||||||
priority: crate::dma::Priority::High,
|
priority: crate::dma::Priority::High,
|
||||||
|
@ -340,7 +340,8 @@ impl AnyChannel {
|
|||||||
mem_addr: *mut u32,
|
mem_addr: *mut u32,
|
||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
incr_mem: bool,
|
incr_mem: bool,
|
||||||
data_size: WordSize,
|
mem_size: WordSize,
|
||||||
|
peripheral_size: WordSize,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) {
|
) {
|
||||||
let info = self.info();
|
let info = self.info();
|
||||||
@ -380,8 +381,8 @@ impl AnyChannel {
|
|||||||
});
|
});
|
||||||
ch.cr().write(|w| {
|
ch.cr().write(|w| {
|
||||||
w.set_dir(dir.into());
|
w.set_dir(dir.into());
|
||||||
w.set_msize(data_size.into());
|
w.set_msize(mem_size.into());
|
||||||
w.set_psize(data_size.into());
|
w.set_psize(peripheral_size.into());
|
||||||
w.set_pl(options.priority.into());
|
w.set_pl(options.priority.into());
|
||||||
w.set_minc(incr_mem);
|
w.set_minc(incr_mem);
|
||||||
w.set_pinc(false);
|
w.set_pinc(false);
|
||||||
@ -414,8 +415,8 @@ impl AnyChannel {
|
|||||||
ch.mar().write_value(mem_addr as u32);
|
ch.mar().write_value(mem_addr as u32);
|
||||||
ch.ndtr().write(|w| w.set_ndt(mem_len as u16));
|
ch.ndtr().write(|w| w.set_ndt(mem_len as u16));
|
||||||
ch.cr().write(|w| {
|
ch.cr().write(|w| {
|
||||||
w.set_psize(data_size.into());
|
w.set_psize(peripheral_size.into());
|
||||||
w.set_msize(data_size.into());
|
w.set_msize(mem_size.into());
|
||||||
w.set_minc(incr_mem);
|
w.set_minc(incr_mem);
|
||||||
w.set_dir(dir.into());
|
w.set_dir(dir.into());
|
||||||
w.set_teie(true);
|
w.set_teie(true);
|
||||||
@ -602,27 +603,28 @@ impl<'a> Transfer<'a> {
|
|||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
W::size(),
|
W::size(),
|
||||||
|
W::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new write DMA transfer (memory to peripheral).
|
/// Create a new write DMA transfer (memory to peripheral).
|
||||||
pub unsafe fn new_write<W: Word>(
|
pub unsafe fn new_write<MW: Word, PW: Word>(
|
||||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||||
request: Request,
|
request: Request,
|
||||||
buf: &'a [W],
|
buf: &'a [MW],
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_write_raw(channel, request, buf, peri_addr, options)
|
Self::new_write_raw(channel, request, buf, peri_addr, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new write DMA transfer (memory to peripheral), using raw pointers.
|
/// Create a new write DMA transfer (memory to peripheral), using raw pointers.
|
||||||
pub unsafe fn new_write_raw<W: Word>(
|
pub unsafe fn new_write_raw<MW: Word, PW: Word>(
|
||||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||||
request: Request,
|
request: Request,
|
||||||
buf: *const [W],
|
buf: *const [MW],
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(channel);
|
into_ref!(channel);
|
||||||
@ -632,10 +634,11 @@ impl<'a> Transfer<'a> {
|
|||||||
request,
|
request,
|
||||||
Dir::MemoryToPeripheral,
|
Dir::MemoryToPeripheral,
|
||||||
peri_addr as *const u32,
|
peri_addr as *const u32,
|
||||||
buf as *const W as *mut u32,
|
buf as *const MW as *mut u32,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
W::size(),
|
MW::size(),
|
||||||
|
PW::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -660,6 +663,7 @@ impl<'a> Transfer<'a> {
|
|||||||
count,
|
count,
|
||||||
false,
|
false,
|
||||||
W::size(),
|
W::size(),
|
||||||
|
W::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -673,15 +677,23 @@ impl<'a> Transfer<'a> {
|
|||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
incr_mem: bool,
|
incr_mem: bool,
|
||||||
data_size: WordSize,
|
data_size: WordSize,
|
||||||
|
peripheral_size: WordSize,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
||||||
|
|
||||||
channel.configure(
|
channel.configure(
|
||||||
_request, dir, peri_addr, mem_addr, mem_len, incr_mem, data_size, options,
|
_request,
|
||||||
|
dir,
|
||||||
|
peri_addr,
|
||||||
|
mem_addr,
|
||||||
|
mem_len,
|
||||||
|
incr_mem,
|
||||||
|
data_size,
|
||||||
|
peripheral_size,
|
||||||
|
options,
|
||||||
);
|
);
|
||||||
channel.start();
|
channel.start();
|
||||||
|
|
||||||
Self { channel }
|
Self { channel }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -814,6 +826,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
|
|||||||
len,
|
len,
|
||||||
true,
|
true,
|
||||||
data_size,
|
data_size,
|
||||||
|
data_size,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -966,6 +979,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
|
|||||||
len,
|
len,
|
||||||
true,
|
true,
|
||||||
data_size,
|
data_size,
|
||||||
|
data_size,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -143,27 +143,28 @@ impl<'a> Transfer<'a> {
|
|||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
W::size(),
|
W::size(),
|
||||||
|
W::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new write DMA transfer (memory to peripheral).
|
/// Create a new write DMA transfer (memory to peripheral).
|
||||||
pub unsafe fn new_write<W: Word>(
|
pub unsafe fn new_write<MW: Word, PW: Word>(
|
||||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||||
request: Request,
|
request: Request,
|
||||||
buf: &'a [W],
|
buf: &'a [MW],
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_write_raw(channel, request, buf, peri_addr, options)
|
Self::new_write_raw(channel, request, buf, peri_addr, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new write DMA transfer (memory to peripheral), using raw pointers.
|
/// Create a new write DMA transfer (memory to peripheral), using raw pointers.
|
||||||
pub unsafe fn new_write_raw<W: Word>(
|
pub unsafe fn new_write_raw<MW: Word, PW: Word>(
|
||||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||||
request: Request,
|
request: Request,
|
||||||
buf: *const [W],
|
buf: *const [MW],
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(channel);
|
into_ref!(channel);
|
||||||
@ -173,21 +174,22 @@ impl<'a> Transfer<'a> {
|
|||||||
request,
|
request,
|
||||||
Dir::MemoryToPeripheral,
|
Dir::MemoryToPeripheral,
|
||||||
peri_addr as *const u32,
|
peri_addr as *const u32,
|
||||||
buf as *const W as *mut u32,
|
buf as *const MW as *mut u32,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
W::size(),
|
MW::size(),
|
||||||
|
PW::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
|
/// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
|
||||||
pub unsafe fn new_write_repeated<W: Word>(
|
pub unsafe fn new_write_repeated<MW: Word, PW: Word>(
|
||||||
channel: impl Peripheral<P = impl Channel> + 'a,
|
channel: impl Peripheral<P = impl Channel> + 'a,
|
||||||
request: Request,
|
request: Request,
|
||||||
repeated: &'a W,
|
repeated: &'a MW,
|
||||||
count: usize,
|
count: usize,
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(channel);
|
into_ref!(channel);
|
||||||
@ -197,10 +199,11 @@ impl<'a> Transfer<'a> {
|
|||||||
request,
|
request,
|
||||||
Dir::MemoryToPeripheral,
|
Dir::MemoryToPeripheral,
|
||||||
peri_addr as *const u32,
|
peri_addr as *const u32,
|
||||||
repeated as *const W as *mut u32,
|
repeated as *const MW as *mut u32,
|
||||||
count,
|
count,
|
||||||
false,
|
false,
|
||||||
W::size(),
|
MW::size(),
|
||||||
|
PW::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -214,6 +217,7 @@ impl<'a> Transfer<'a> {
|
|||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
incr_mem: bool,
|
incr_mem: bool,
|
||||||
data_size: WordSize,
|
data_size: WordSize,
|
||||||
|
dst_size: WordSize,
|
||||||
_options: TransferOptions,
|
_options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// BNDT is specified as bytes, not as number of transfers.
|
// BNDT is specified as bytes, not as number of transfers.
|
||||||
@ -234,7 +238,7 @@ impl<'a> Transfer<'a> {
|
|||||||
ch.llr().write(|_| {}); // no linked list
|
ch.llr().write(|_| {}); // no linked list
|
||||||
ch.tr1().write(|w| {
|
ch.tr1().write(|w| {
|
||||||
w.set_sdw(data_size.into());
|
w.set_sdw(data_size.into());
|
||||||
w.set_ddw(data_size.into());
|
w.set_ddw(dst_size.into());
|
||||||
w.set_sinc(dir == Dir::MemoryToPeripheral && incr_mem);
|
w.set_sinc(dir == Dir::MemoryToPeripheral && incr_mem);
|
||||||
w.set_dinc(dir == Dir::PeripheralToMemory && incr_mem);
|
w.set_dinc(dir == Dir::PeripheralToMemory && incr_mem);
|
||||||
});
|
});
|
||||||
|
@ -515,14 +515,21 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
|
|||||||
|
|
||||||
// Configure DMA to transfer input to hash core.
|
// Configure DMA to transfer input to hash core.
|
||||||
let dma_request = self.dma.request();
|
let dma_request = self.dma.request();
|
||||||
let dst_ptr = T::regs().din().as_ptr();
|
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
|
||||||
let mut num_words = input.len() / 4;
|
let mut num_words = input.len() / 4;
|
||||||
if input.len() % 4 > 0 {
|
if input.len() % 4 > 0 {
|
||||||
num_words += 1;
|
num_words += 1;
|
||||||
}
|
}
|
||||||
let src_ptr = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words);
|
let src_ptr: *const [u8] = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words);
|
||||||
let dma_transfer =
|
let dma_transfer = unsafe {
|
||||||
unsafe { Transfer::new_write_raw(&mut self.dma, dma_request, src_ptr, dst_ptr, Default::default()) };
|
Transfer::new_write_raw(
|
||||||
|
&mut self.dma,
|
||||||
|
dma_request,
|
||||||
|
src_ptr,
|
||||||
|
dst_ptr as *mut u32,
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
};
|
||||||
T::regs().cr().modify(|w| w.set_dmae(true));
|
T::regs().cr().modify(|w| w.set_dmae(true));
|
||||||
|
|
||||||
// Wait for the transfer to complete.
|
// Wait for the transfer to complete.
|
||||||
|
@ -235,6 +235,11 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get the capability of the timer
|
||||||
|
pub fn 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,
|
||||||
|
@ -6,7 +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::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel};
|
use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits};
|
||||||
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
|
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
@ -334,7 +334,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
|
|||||||
&mut dma,
|
&mut dma,
|
||||||
req,
|
req,
|
||||||
duty,
|
duty,
|
||||||
self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut _,
|
self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16,
|
||||||
dma_transfer_option,
|
dma_transfer_option,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -362,9 +362,6 @@ macro_rules! impl_waveform_chx {
|
|||||||
($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
|
($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
|
||||||
impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
|
impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
|
||||||
/// Generate a sequence of PWM waveform
|
/// Generate a sequence of PWM waveform
|
||||||
///
|
|
||||||
/// Note:
|
|
||||||
/// 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: &[u16]) {
|
||||||
use crate::pac::timer::vals::Ccds;
|
use crate::pac::timer::vals::Ccds;
|
||||||
|
|
||||||
@ -406,14 +403,33 @@ macro_rules! impl_waveform_chx {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match self.inner.bits() {
|
||||||
|
TimerBits::Bits16 => {
|
||||||
Transfer::new_write(
|
Transfer::new_write(
|
||||||
&mut dma,
|
&mut dma,
|
||||||
req,
|
req,
|
||||||
duty,
|
duty,
|
||||||
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _,
|
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16,
|
||||||
dma_transfer_option,
|
dma_transfer_option,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
}
|
||||||
|
#[cfg(not(any(stm32l0)))]
|
||||||
|
TimerBits::Bits32 => {
|
||||||
|
#[cfg(not(any(bdma, gpdma)))]
|
||||||
|
panic!("unsupported timer bits");
|
||||||
|
|
||||||
|
#[cfg(any(bdma, gpdma))]
|
||||||
|
Transfer::new_write(
|
||||||
|
&mut dma,
|
||||||
|
req,
|
||||||
|
duty,
|
||||||
|
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32,
|
||||||
|
dma_transfer_option,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// restore output compare state
|
// restore output compare state
|
||||||
|
Loading…
x
Reference in New Issue
Block a user