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