@@ -213,6 +213,7 @@ use crate::{
213213 Async ,
214214 Blocking ,
215215 asynch:: AtomicWaker ,
216+ clock:: Clocks ,
216217 gpio:: {
217218 self ,
218219 InputConfig ,
@@ -788,7 +789,7 @@ impl<'d> Rmt<'d, Blocking> {
788789 /// Create a new RMT instance
789790 pub fn new ( peripheral : RMT < ' d > , frequency : Rate ) -> Result < Self , Error > {
790791 let this = Rmt :: create ( peripheral) ;
791- self :: chip_specific:: configure_clock ( frequency) ?;
792+ self :: chip_specific:: configure_clock ( ClockSource :: default ( ) , frequency) ?;
792793 Ok ( this)
793794 }
794795
@@ -1032,13 +1033,7 @@ where
10321033
10331034 let _guard = GenericPeripheralGuard :: new ( ) ;
10341035
1035- let threshold = if cfg ! ( any( esp32, esp32s2) ) {
1036- 0b111_1111_1111_1111
1037- } else {
1038- 0b11_1111_1111_1111
1039- } ;
1040-
1041- if config. idle_threshold > threshold {
1036+ if config. idle_threshold > property ! ( "rmt.max_idle_threshold" ) {
10421037 return Err ( Error :: InvalidArgument ) ;
10431038 }
10441039
@@ -1661,13 +1656,70 @@ impl DynChannelAccess<Rx> {
16611656 }
16621657}
16631658
1659+ for_each_rmt_clock_source ! (
1660+ ( all $( ( $name: ident, $bits: literal) ) , +) => {
1661+ #[ derive( Clone , Copy , Debug ) ]
1662+ #[ repr( u8 ) ]
1663+ enum ClockSource {
1664+ $(
1665+ #[ allow( unused) ]
1666+ $name = $bits,
1667+ ) +
1668+ }
1669+ } ;
1670+
1671+ ( is_boolean) => {
1672+ impl ClockSource {
1673+ fn bit( self ) -> bool {
1674+ match ( self as u8 ) {
1675+ 0 => false ,
1676+ 1 => true ,
1677+ _ => unreachable!( "should be removed by the compiler!" ) ,
1678+ }
1679+ }
1680+ }
1681+ } ;
1682+
1683+ ( default ( $name: ident) ) => {
1684+ impl ClockSource {
1685+ fn default ( ) -> Self {
1686+ Self :: $name
1687+ }
1688+
1689+ fn bits( self ) -> u8 {
1690+ self as u8
1691+ }
1692+
1693+ fn freq( self ) -> crate :: time:: Rate {
1694+ match self {
1695+ #[ cfg( rmt_supports_apb_clock) ]
1696+ ClockSource :: Apb => Clocks :: get( ) . apb_clock,
1697+
1698+ #[ cfg( rmt_supports_rcfast_clock) ]
1699+ ClockSource :: RcFast => todo!( ) ,
1700+
1701+ #[ cfg( rmt_supports_xtal_clock) ]
1702+ ClockSource :: Xtal => Clocks :: get( ) . xtal_clock,
1703+
1704+ #[ cfg( rmt_supports_pll80mhz_clock) ]
1705+ ClockSource :: Pll80MHz => Rate :: from_mhz( 80 ) ,
1706+
1707+ #[ cfg( rmt_supports_reftick_clock) ]
1708+ ClockSource :: RefTick => todo!( ) ,
1709+ }
1710+ }
1711+ }
1712+ } ;
1713+ ) ;
1714+
16641715#[ cfg( not( any( esp32, esp32s2) ) ) ]
16651716mod chip_specific {
16661717 use enumset:: EnumSet ;
16671718
16681719 use super :: {
16691720 CHANNEL_INDEX_COUNT ,
16701721 ChannelIndex ,
1722+ ClockSource ,
16711723 Direction ,
16721724 DynChannelAccess ,
16731725 Error ,
@@ -1680,8 +1732,8 @@ mod chip_specific {
16801732 } ;
16811733 use crate :: { peripherals:: RMT , time:: Rate } ;
16821734
1683- pub ( super ) fn configure_clock ( frequency : Rate ) -> Result < ( ) , Error > {
1684- let src_clock = crate :: soc :: constants :: RMT_CLOCK_SRC_FREQ ;
1735+ pub ( super ) fn configure_clock ( source : ClockSource , frequency : Rate ) -> Result < ( ) , Error > {
1736+ let src_clock = source . freq ( ) ;
16851737
16861738 if frequency > src_clock {
16871739 return Err ( Error :: UnreachableTargetFrequency ) ;
@@ -1695,7 +1747,7 @@ mod chip_specific {
16951747 {
16961748 RMT :: regs ( ) . sys_conf ( ) . modify ( |_, w| unsafe {
16971749 w. clk_en ( ) . clear_bit ( ) ;
1698- w. sclk_sel ( ) . bits ( crate :: soc :: constants :: RMT_CLOCK_SRC ) ;
1750+ w. sclk_sel ( ) . bits ( source . bits ( ) ) ;
16991751 w. sclk_div_num ( ) . bits ( div) ;
17001752 w. sclk_div_a ( ) . bits ( 0 ) ;
17011753 w. sclk_div_b ( ) . bits ( 0 ) ;
@@ -1715,11 +1767,11 @@ mod chip_specific {
17151767 #[ cfg( esp32c6) ]
17161768 PCR :: regs ( )
17171769 . rmt_sclk_conf ( )
1718- . modify ( |_, w| unsafe { w. sclk_sel ( ) . bits ( crate :: soc :: constants :: RMT_CLOCK_SRC ) } ) ;
1770+ . modify ( |_, w| unsafe { w. sclk_sel ( ) . bits ( source . bits ( ) ) } ) ;
17191771 #[ cfg( not( esp32c6) ) ]
17201772 PCR :: regs ( )
17211773 . rmt_sclk_conf ( )
1722- . modify ( |_, w| w. sclk_sel ( ) . bit ( crate :: soc :: constants :: RMT_CLOCK_SRC ) ) ;
1774+ . modify ( |_, w| w. sclk_sel ( ) . bit ( source . bit ( ) ) ) ;
17231775
17241776 RMT :: regs ( )
17251777 . sys_conf ( )
@@ -2097,6 +2149,7 @@ mod chip_specific {
20972149
20982150 use super :: {
20992151 ChannelIndex ,
2152+ ClockSource ,
21002153 Direction ,
21012154 DynChannelAccess ,
21022155 Error ,
@@ -2111,16 +2164,16 @@ mod chip_specific {
21112164 } ;
21122165 use crate :: { peripherals:: RMT , time:: Rate } ;
21132166
2114- pub ( super ) fn configure_clock ( frequency : Rate ) -> Result < ( ) , Error > {
2115- if frequency != Rate :: from_mhz ( 80 ) {
2167+ pub ( super ) fn configure_clock ( source : ClockSource , frequency : Rate ) -> Result < ( ) , Error > {
2168+ if frequency != source . freq ( ) {
21162169 return Err ( Error :: UnreachableTargetFrequency ) ;
21172170 }
21182171
21192172 let rmt = RMT :: regs ( ) ;
21202173
21212174 for ch_num in 0 ..NUM_CHANNELS {
21222175 rmt. chconf1 ( ch_num)
2123- . modify ( |_, w| w. ref_always_on ( ) . set_bit ( ) ) ;
2176+ . modify ( |_, w| w. ref_always_on ( ) . bit ( source . bit ( ) ) ) ;
21242177 }
21252178
21262179 rmt. apb_conf ( ) . modify ( |_, w| w. apb_fifo_mask ( ) . set_bit ( ) ) ;
@@ -2201,7 +2254,7 @@ mod chip_specific {
22012254 }
22022255
22032256 impl DynChannelAccess < Tx > {
2204- #[ cfg( not ( esp32 ) ) ]
2257+ #[ cfg( rmt_has_tx_loop_count ) ]
22052258 #[ inline]
22062259 pub fn set_generate_repeat_interrupt ( & self , loopcount : Option < LoopCount > ) {
22072260 let rmt = crate :: peripherals:: RMT :: regs ( ) ;
@@ -2215,7 +2268,7 @@ mod chip_specific {
22152268 . modify ( |_, w| unsafe { w. tx_loop_num ( ) . bits ( repeats) } ) ;
22162269 }
22172270
2218- #[ cfg( esp32 ) ]
2271+ #[ cfg( not ( rmt_has_tx_loop_count ) ) ]
22192272 #[ inline]
22202273 pub fn set_generate_repeat_interrupt ( & self , _loopcount : Option < LoopCount > ) {
22212274 // unsupported
@@ -2329,7 +2382,7 @@ mod chip_specific {
23292382 // Returns whether stopping was immediate, or needs to wait for tx end
23302383 // Due to inlining, the compiler should be able to eliminate code in the caller that
23312384 // depends on this.
2332- #[ cfg( esp32s2 ) ]
2385+ #[ cfg( rmt_has_tx_immediate_stop ) ]
23332386 #[ inline]
23342387 pub fn stop_tx ( & self ) -> bool {
23352388 let rmt = crate :: peripherals:: RMT :: regs ( ) ;
@@ -2338,7 +2391,7 @@ mod chip_specific {
23382391 true
23392392 }
23402393
2341- #[ cfg( esp32 ) ]
2394+ #[ cfg( not ( rmt_has_tx_immediate_stop ) ) ]
23422395 #[ inline]
23432396 pub fn stop_tx ( & self ) -> bool {
23442397 let ptr = self . channel_ram_start ( ) ;
0 commit comments