@@ -348,7 +348,7 @@ use crate::gpio::{self, AlternateH, AnyPin, Pin, PinId};
348348use crate :: pac:: gclk:: Genctrl ;
349349#[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
350350use crate :: pac:: gclk:: Gendiv ;
351- use crate :: pac:: gclk:: genctrl:: { self , Srcselect } ;
351+ use crate :: pac:: gclk:: genctrl:: Srcselect ;
352352use crate :: time:: Hertz ;
353353use crate :: typelevel:: { Decrement , Increment , PrivateDecrement , PrivateIncrement , Sealed } ;
354354
@@ -1255,31 +1255,49 @@ where
12551255 G : GclkId ,
12561256 I : GclkSourceId ,
12571257{
1258+ /// Updates the GENCTRL register based on self.settings
1259+ ///
1260+ /// The thumbv7em chips use one GENCTRL per clock generator and are capable
1261+ /// of read-modify-write operations, but the thumbv6 chips share one GENCTRL
1262+ /// register among the clock generators so only support writes. To
1263+ /// accommodate both, this implementation maintains a [`Settings`] struct
1264+ /// containing the GENCTRL settings, and this method is called after
1265+ /// updating it to apply them.
12581266 #[ hal_macro_helper]
1259- fn update_genctrl < F : FnOnce ( & mut genctrl:: W ) > ( & self , writer : F , genen : bool ) {
1267+ fn update_genctrl ( & self , genen : bool ) {
1268+ let ( divsel, div) = self . settings . div . divsel_div ( ) ;
1269+
12601270 #[ hal_cfg( "clock-d5x" ) ]
12611271 self . token . genctrl ( ) . modify ( |_, w| {
1262- let _ = genen; // Suppress warning on d5x builds
1263- writer ( w) ;
1264- w
1272+ w. divsel ( ) . bit ( divsel) ;
1273+ // Safety: The `DIVSEL` and `DIV` values are derived from the
1274+ // `GclkDivider` type, so they are guaranteed to be valid.
1275+ unsafe {
1276+ w. div ( ) . bits ( div) ;
1277+ }
1278+ w. oe ( ) . bit ( self . settings . output_enable ) ;
1279+ w. oov ( ) . bit ( self . settings . output_off_value ) ;
1280+ w. idc ( ) . bit ( self . settings . improve_duty_cycle ) ;
1281+ w. genen ( ) . bit ( genen) ;
1282+ w. src ( ) . variant ( I :: DYN . into ( ) )
12651283 } ) ;
12661284
12671285 #[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
12681286 {
1269- let ( divsel, _div) = self . settings . div . divsel_div ( ) ;
1287+ // Suppress warning for thumbv7em builds
1288+ let _ = div;
12701289
12711290 self . token . genctrl ( ) . write ( |w| {
1272- unsafe { w. id ( ) . bits ( G :: NUM as u8 ) } ;
1273- w. src ( ) . variant ( I :: DYN . into ( ) ) ;
12741291 w. divsel ( ) . bit ( divsel) ;
12751292 w. oe ( ) . bit ( self . settings . output_enable ) ;
12761293 w. oov ( ) . bit ( self . settings . output_off_value ) ;
12771294 w. idc ( ) . bit ( self . settings . improve_duty_cycle ) ;
12781295 w. genen ( ) . bit ( genen) ;
1279- writer ( w ) ;
1280- w
1296+ w . src ( ) . variant ( I :: DYN . into ( ) ) ;
1297+ unsafe { w . id ( ) . bits ( G :: NUM as u8 ) }
12811298 } ) ;
12821299 }
1300+
12831301 self . token . wait_syncbusy ( ) ;
12841302 }
12851303
@@ -1292,9 +1310,6 @@ where
12921310 freq : Hertz ,
12931311 ) -> ( Gclk < G , N > , I :: Resource ) {
12941312 self . update_genctrl (
1295- |w| {
1296- w. src ( ) . variant ( N :: DYN . into ( ) ) ;
1297- } ,
12981313 // This method is always called on Gclk0, which is always enabled
12991314 true ,
13001315 ) ;
@@ -1360,9 +1375,6 @@ where
13601375 pub fn output_off_value ( mut self , high : bool ) -> Self {
13611376 self . settings . output_off_value = high;
13621377 self . update_genctrl (
1363- |w| {
1364- w. oov ( ) . bit ( high) ;
1365- } ,
13661378 // This method is only accessible via disabled GCLKs
13671379 false ,
13681380 ) ;
@@ -1372,44 +1384,22 @@ where
13721384
13731385 /// Enable the [`Gclk`], so that it can be used as a clock [`Source`]
13741386 ///
1375- /// As mentioned in the [`Gclk`] documentation, no hardware registers are
1376- /// actually modified until this call. Rather, the desired configuration is
1377- /// stored internally, and the [`Gclk`] is initialized and configured here
1378- /// according to the datasheet.
1379- ///
13801387 /// The returned value is an [`EnabledGclk`] that can be used as a clock
13811388 /// [`Source`] for other clocks.
13821389 #[ inline]
13831390 #[ hal_macro_helper]
13841391 pub fn enable ( self ) -> EnabledGclk < G , I > {
1385- let ( divsel, div) = self . settings . div . divsel_div ( ) ;
1386-
13871392 #[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
13881393 {
1394+ let ( _divsel, div) = self . settings . div . divsel_div ( ) ;
13891395 self . token . gendiv ( ) . write ( |w| unsafe {
13901396 w. id ( ) . bits ( G :: NUM as u8 ) ;
13911397 w. div ( ) . bits ( div)
13921398 } ) ;
13931399 self . token . wait_syncbusy ( ) ;
13941400 }
13951401
1396- self . token . genctrl ( ) . write ( |w| {
1397- // Safety: The `DIVSEL` and `DIV` values are derived from the
1398- // `GclkDivider` type, so they are guaranteed to be valid.
1399- unsafe {
1400- #[ hal_cfg( "clock-d5x" ) ]
1401- w. div ( ) . bits ( div) ;
1402- #[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
1403- w. id ( ) . bits ( G :: NUM as u8 ) ;
1404- } ;
1405- w. divsel ( ) . bit ( divsel) ;
1406- w. src ( ) . variant ( I :: DYN . into ( ) ) ;
1407- w. idc ( ) . bit ( self . settings . improve_duty_cycle ) ;
1408- w. oe ( ) . bit ( self . settings . output_enable ) ;
1409- w. oov ( ) . bit ( self . settings . output_off_value ) ;
1410- w. genen ( ) . set_bit ( )
1411- } ) ;
1412- self . token . wait_syncbusy ( ) ;
1402+ self . update_genctrl ( true ) ;
14131403
14141404 Enabled :: new ( self )
14151405 }
@@ -1426,12 +1416,7 @@ where
14261416 /// only be disabled when no other clocks consume this [`Gclk`].
14271417 #[ inline]
14281418 pub fn disable ( self ) -> Gclk < G , I > {
1429- self . 0 . update_genctrl (
1430- |w| {
1431- w. genen ( ) . clear_bit ( ) ;
1432- } ,
1433- false ,
1434- ) ;
1419+ self . 0 . update_genctrl ( false ) ;
14351420 self . 0
14361421 }
14371422}
@@ -1539,42 +1524,27 @@ impl<I: GclkSourceId> EnabledGclk0<I, U1> {
15391524 pub fn div ( & mut self , divider : GclkDiv8 ) {
15401525 self . 0 . settings . div = divider;
15411526
1542- let ( divsel, div) = divider. divsel_div ( ) ;
1543-
15441527 // D5x div is in the GENCTRL register, smaller chips keep it separate
15451528 #[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
15461529 {
1530+ let ( _divsel, div) = divider. divsel_div ( ) ;
1531+ // Safety: The `DIVSEL` and `DIV` values are derived from the
1532+ // `GclkDivider` type, so they are guaranteed to be valid.
15471533 self . 0 . token . gendiv ( ) . write ( |w| unsafe {
15481534 w. id ( ) . bits ( 0 ) ;
15491535 w. div ( ) . bits ( div)
15501536 } ) ;
15511537 self . 0 . token . wait_syncbusy ( ) ;
15521538 }
15531539
1554- self . 0 . update_genctrl (
1555- |w| {
1556- // Safety: The `DIVSEL` and `DIV` values are derived from the
1557- // `GclkDivider` type, so they are guaranteed to be valid.
1558- #[ hal_cfg( "clock-d5x" ) ]
1559- unsafe {
1560- w. div ( ) . bits ( div) ;
1561- }
1562- w. divsel ( ) . bit ( divsel) ;
1563- } ,
1564- true ,
1565- ) ;
1540+ self . 0 . update_genctrl ( true ) ;
15661541 }
15671542
15681543 /// Output a 50-50 duty cycle clock when using an odd [`GclkDivider`]
15691544 #[ inline]
15701545 pub fn improve_duty_cycle ( & mut self , flag : bool ) {
15711546 self . 0 . settings . improve_duty_cycle = flag;
1572- self . 0 . update_genctrl (
1573- |w| {
1574- w. idc ( ) . bit ( flag) ;
1575- } ,
1576- true ,
1577- ) ;
1547+ self . 0 . update_genctrl ( true ) ;
15781548 }
15791549
15801550 /// Return the [`Gclk0`] frequency
@@ -1591,12 +1561,7 @@ impl<I: GclkSourceId> EnabledGclk0<I, U1> {
15911561 #[ inline]
15921562 pub fn output_off_value ( & mut self , high : bool ) {
15931563 self . 0 . settings . output_off_value = high;
1594- self . 0 . update_genctrl (
1595- |w| {
1596- w. oov ( ) . bit ( high) ;
1597- } ,
1598- true ,
1599- ) ;
1564+ self . 0 . update_genctrl ( true ) ;
16001565 }
16011566}
16021567
@@ -1733,12 +1698,7 @@ where
17331698 {
17341699 let pin = pin. into ( ) . into_mode ( ) ;
17351700 self . 0 . settings . output_enable = true ;
1736- self . 0 . update_genctrl (
1737- |w| {
1738- w. oe ( ) . set_bit ( ) ;
1739- } ,
1740- true ,
1741- ) ;
1701+ self . 0 . update_genctrl ( true ) ;
17421702
17431703 let gclk_out = GclkOut {
17441704 pin,
@@ -1763,12 +1723,7 @@ where
17631723 I : GclkIo < GclkId = G > ,
17641724 {
17651725 self . 0 . settings . output_enable = false ;
1766- self . 0 . update_genctrl (
1767- |w| {
1768- w. oe ( ) . clear_bit ( ) ;
1769- } ,
1770- true ,
1771- ) ;
1726+ self . 0 . update_genctrl ( true ) ;
17721727
17731728 ( self . dec ( ) , gclk_out. pin )
17741729 }
0 commit comments