Skip to content

Commit eda5167

Browse files
authored
Merge pull request #3704 from CNLHC/pwm_support_gp32
feat: Add 32-bit timer support for waveform function
2 parents 5bba87e + 4ad3b66 commit eda5167

File tree

6 files changed

+96
-50
lines changed

6 files changed

+96
-50
lines changed

embassy-stm32/src/cryp/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,9 +1785,9 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
17851785
assert_eq!(blocks.len() % block_size, 0);
17861786
// Configure DMA to transfer input to crypto core.
17871787
let dma_request = dma.request();
1788-
let dst_ptr = T::regs().din().as_ptr();
1788+
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
17891789
let num_words = blocks.len() / 4;
1790-
let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
1790+
let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
17911791
let options = TransferOptions {
17921792
#[cfg(not(gpdma))]
17931793
priority: crate::dma::Priority::High,
@@ -1825,9 +1825,9 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
18251825
assert_eq!((blocks.len() * 4) % block_size, 0);
18261826
// Configure DMA to transfer input to crypto core.
18271827
let dma_request = dma.request();
1828-
let dst_ptr = T::regs().din().as_ptr();
1828+
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
18291829
let num_words = blocks.len();
1830-
let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
1830+
let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
18311831
let options = TransferOptions {
18321832
#[cfg(not(gpdma))]
18331833
priority: crate::dma::Priority::High,

embassy-stm32/src/dma/dma_bdma.rs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ impl AnyChannel {
340340
mem_addr: *mut u32,
341341
mem_len: usize,
342342
incr_mem: bool,
343-
data_size: WordSize,
343+
mem_size: WordSize,
344+
peripheral_size: WordSize,
344345
options: TransferOptions,
345346
) {
346347
let info = self.info();
@@ -380,8 +381,8 @@ impl AnyChannel {
380381
});
381382
ch.cr().write(|w| {
382383
w.set_dir(dir.into());
383-
w.set_msize(data_size.into());
384-
w.set_psize(data_size.into());
384+
w.set_msize(mem_size.into());
385+
w.set_psize(peripheral_size.into());
385386
w.set_pl(options.priority.into());
386387
w.set_minc(incr_mem);
387388
w.set_pinc(false);
@@ -414,8 +415,8 @@ impl AnyChannel {
414415
ch.mar().write_value(mem_addr as u32);
415416
ch.ndtr().write(|w| w.set_ndt(mem_len as u16));
416417
ch.cr().write(|w| {
417-
w.set_psize(data_size.into());
418-
w.set_msize(data_size.into());
418+
w.set_psize(peripheral_size.into());
419+
w.set_msize(mem_size.into());
419420
w.set_minc(incr_mem);
420421
w.set_dir(dir.into());
421422
w.set_teie(true);
@@ -602,27 +603,28 @@ impl<'a> Transfer<'a> {
602603
buf.len(),
603604
true,
604605
W::size(),
606+
W::size(),
605607
options,
606608
)
607609
}
608610

609611
/// 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>(
611613
channel: impl Peripheral<P = impl Channel> + 'a,
612614
request: Request,
613-
buf: &'a [W],
614-
peri_addr: *mut W,
615+
buf: &'a [MW],
616+
peri_addr: *mut PW,
615617
options: TransferOptions,
616618
) -> Self {
617619
Self::new_write_raw(channel, request, buf, peri_addr, options)
618620
}
619621

620622
/// 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<MW: Word, PW: Word>(
622624
channel: impl Peripheral<P = impl Channel> + 'a,
623625
request: Request,
624-
buf: *const [W],
625-
peri_addr: *mut W,
626+
buf: *const [MW],
627+
peri_addr: *mut PW,
626628
options: TransferOptions,
627629
) -> Self {
628630
into_ref!(channel);
@@ -632,10 +634,11 @@ impl<'a> Transfer<'a> {
632634
request,
633635
Dir::MemoryToPeripheral,
634636
peri_addr as *const u32,
635-
buf as *const W as *mut u32,
637+
buf as *const MW as *mut u32,
636638
buf.len(),
637639
true,
638-
W::size(),
640+
MW::size(),
641+
PW::size(),
639642
options,
640643
)
641644
}
@@ -660,6 +663,7 @@ impl<'a> Transfer<'a> {
660663
count,
661664
false,
662665
W::size(),
666+
W::size(),
663667
options,
664668
)
665669
}
@@ -673,15 +677,23 @@ impl<'a> Transfer<'a> {
673677
mem_len: usize,
674678
incr_mem: bool,
675679
data_size: WordSize,
680+
peripheral_size: WordSize,
676681
options: TransferOptions,
677682
) -> Self {
678683
assert!(mem_len > 0 && mem_len <= 0xFFFF);
679684

680685
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,
682695
);
683696
channel.start();
684-
685697
Self { channel }
686698
}
687699

@@ -814,6 +826,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
814826
len,
815827
true,
816828
data_size,
829+
data_size,
817830
options,
818831
);
819832

@@ -966,6 +979,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
966979
len,
967980
true,
968981
data_size,
982+
data_size,
969983
options,
970984
);
971985

embassy-stm32/src/dma/gpdma.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -143,27 +143,28 @@ impl<'a> Transfer<'a> {
143143
buf.len(),
144144
true,
145145
W::size(),
146+
W::size(),
146147
options,
147148
)
148149
}
149150

150151
/// Create a new write DMA transfer (memory to peripheral).
151-
pub unsafe fn new_write<W: Word>(
152+
pub unsafe fn new_write<MW: Word, PW: Word>(
152153
channel: impl Peripheral<P = impl Channel> + 'a,
153154
request: Request,
154-
buf: &'a [W],
155-
peri_addr: *mut W,
155+
buf: &'a [MW],
156+
peri_addr: *mut PW,
156157
options: TransferOptions,
157158
) -> Self {
158159
Self::new_write_raw(channel, request, buf, peri_addr, options)
159160
}
160161

161162
/// Create a new write DMA transfer (memory to peripheral), using raw pointers.
162-
pub unsafe fn new_write_raw<W: Word>(
163+
pub unsafe fn new_write_raw<MW: Word, PW: Word>(
163164
channel: impl Peripheral<P = impl Channel> + 'a,
164165
request: Request,
165-
buf: *const [W],
166-
peri_addr: *mut W,
166+
buf: *const [MW],
167+
peri_addr: *mut PW,
167168
options: TransferOptions,
168169
) -> Self {
169170
into_ref!(channel);
@@ -173,21 +174,22 @@ impl<'a> Transfer<'a> {
173174
request,
174175
Dir::MemoryToPeripheral,
175176
peri_addr as *const u32,
176-
buf as *const W as *mut u32,
177+
buf as *const MW as *mut u32,
177178
buf.len(),
178179
true,
179-
W::size(),
180+
MW::size(),
181+
PW::size(),
180182
options,
181183
)
182184
}
183185

184186
/// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
185-
pub unsafe fn new_write_repeated<W: Word>(
187+
pub unsafe fn new_write_repeated<MW: Word, PW: Word>(
186188
channel: impl Peripheral<P = impl Channel> + 'a,
187189
request: Request,
188-
repeated: &'a W,
190+
repeated: &'a MW,
189191
count: usize,
190-
peri_addr: *mut W,
192+
peri_addr: *mut PW,
191193
options: TransferOptions,
192194
) -> Self {
193195
into_ref!(channel);
@@ -197,10 +199,11 @@ impl<'a> Transfer<'a> {
197199
request,
198200
Dir::MemoryToPeripheral,
199201
peri_addr as *const u32,
200-
repeated as *const W as *mut u32,
202+
repeated as *const MW as *mut u32,
201203
count,
202204
false,
203-
W::size(),
205+
MW::size(),
206+
PW::size(),
204207
options,
205208
)
206209
}
@@ -214,6 +217,7 @@ impl<'a> Transfer<'a> {
214217
mem_len: usize,
215218
incr_mem: bool,
216219
data_size: WordSize,
220+
dst_size: WordSize,
217221
_options: TransferOptions,
218222
) -> Self {
219223
// BNDT is specified as bytes, not as number of transfers.
@@ -234,7 +238,7 @@ impl<'a> Transfer<'a> {
234238
ch.llr().write(|_| {}); // no linked list
235239
ch.tr1().write(|w| {
236240
w.set_sdw(data_size.into());
237-
w.set_ddw(data_size.into());
241+
w.set_ddw(dst_size.into());
238242
w.set_sinc(dir == Dir::MemoryToPeripheral && incr_mem);
239243
w.set_dinc(dir == Dir::PeripheralToMemory && incr_mem);
240244
});

embassy-stm32/src/hash/mod.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,14 +515,21 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
515515

516516
// Configure DMA to transfer input to hash core.
517517
let dma_request = self.dma.request();
518-
let dst_ptr = T::regs().din().as_ptr();
518+
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
519519
let mut num_words = input.len() / 4;
520520
if input.len() % 4 > 0 {
521521
num_words += 1;
522522
}
523-
let src_ptr = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words);
524-
let dma_transfer =
525-
unsafe { Transfer::new_write_raw(&mut self.dma, dma_request, src_ptr, dst_ptr, Default::default()) };
523+
let src_ptr: *const [u8] = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words);
524+
let dma_transfer = unsafe {
525+
Transfer::new_write_raw(
526+
&mut self.dma,
527+
dma_request,
528+
src_ptr,
529+
dst_ptr as *mut u32,
530+
Default::default(),
531+
)
532+
};
526533
T::regs().cr().modify(|w| w.set_dmae(true));
527534

528535
// Wait for the transfer to complete.

embassy-stm32/src/timer/low_level.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
235235
self.regs_core().cnt().write(|r| r.set_cnt(0));
236236
}
237237

238+
/// get the capability of the timer
239+
pub fn bits(&self) -> TimerBits {
240+
T::BITS
241+
}
242+
238243
/// Set the frequency of how many times per second the timer counts up to the max value or down to 0.
239244
///
240245
/// This means that in the default edge-aligned mode,

embassy-stm32/src/timer/simple_pwm.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use core::mem::ManuallyDrop;
66
use embassy_hal_internal::{into_ref, PeripheralRef};
77

88
use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
9-
use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel};
9+
use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits};
1010
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
1111
use crate::time::Hertz;
1212
use crate::Peripheral;
@@ -334,7 +334,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
334334
&mut dma,
335335
req,
336336
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,
338338
dma_transfer_option,
339339
)
340340
.await
@@ -362,9 +362,6 @@ macro_rules! impl_waveform_chx {
362362
($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
363363
impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
364364
/// Generate a sequence of PWM waveform
365-
///
366-
/// Note:
367-
/// you will need to provide corresponding TIMx_CHy DMA channel to use this method.
368365
pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u16]) {
369366
use crate::pac::timer::vals::Ccds;
370367

@@ -406,14 +403,33 @@ macro_rules! impl_waveform_chx {
406403
..Default::default()
407404
};
408405

409-
Transfer::new_write(
410-
&mut dma,
411-
req,
412-
duty,
413-
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _,
414-
dma_transfer_option,
415-
)
416-
.await
406+
match self.inner.bits() {
407+
TimerBits::Bits16 => {
408+
Transfer::new_write(
409+
&mut dma,
410+
req,
411+
duty,
412+
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16,
413+
dma_transfer_option,
414+
)
415+
.await
416+
}
417+
#[cfg(not(any(stm32l0)))]
418+
TimerBits::Bits32 => {
419+
#[cfg(not(any(bdma, gpdma)))]
420+
panic!("unsupported timer bits");
421+
422+
#[cfg(any(bdma, gpdma))]
423+
Transfer::new_write(
424+
&mut dma,
425+
req,
426+
duty,
427+
self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32,
428+
dma_transfer_option,
429+
)
430+
.await
431+
}
432+
};
417433
};
418434

419435
// restore output compare state

0 commit comments

Comments
 (0)