@@ -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
@@ -1300,9 +1318,6 @@ where
13001318
13011319 // Call update_genctrl() on object that has the correct source type
13021320 gclk. update_genctrl (
1303- |w| {
1304- w. src ( ) . variant ( N :: DYN . into ( ) ) ;
1305- } ,
13061321 // This method is always called on Gclk0, which is always enabled
13071322 true ,
13081323 ) ;
@@ -1361,9 +1376,6 @@ where
13611376 pub fn output_off_value ( mut self , high : bool ) -> Self {
13621377 self . settings . output_off_value = high;
13631378 self . update_genctrl (
1364- |w| {
1365- w. oov ( ) . bit ( high) ;
1366- } ,
13671379 // This method is only accessible via disabled GCLKs
13681380 false ,
13691381 ) ;
@@ -1373,44 +1385,22 @@ where
13731385
13741386 /// Enable the [`Gclk`], so that it can be used as a clock [`Source`]
13751387 ///
1376- /// As mentioned in the [`Gclk`] documentation, no hardware registers are
1377- /// actually modified until this call. Rather, the desired configuration is
1378- /// stored internally, and the [`Gclk`] is initialized and configured here
1379- /// according to the datasheet.
1380- ///
13811388 /// The returned value is an [`EnabledGclk`] that can be used as a clock
13821389 /// [`Source`] for other clocks.
13831390 #[ inline]
13841391 #[ hal_macro_helper]
13851392 pub fn enable ( self ) -> EnabledGclk < G , I > {
1386- let ( divsel, div) = self . settings . div . divsel_div ( ) ;
1387-
13881393 #[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
13891394 {
1395+ let ( _divsel, div) = self . settings . div . divsel_div ( ) ;
13901396 self . token . gendiv ( ) . write ( |w| unsafe {
13911397 w. id ( ) . bits ( G :: NUM as u8 ) ;
13921398 w. div ( ) . bits ( div)
13931399 } ) ;
13941400 self . token . wait_syncbusy ( ) ;
13951401 }
13961402
1397- self . token . genctrl ( ) . write ( |w| {
1398- // Safety: The `DIVSEL` and `DIV` values are derived from the
1399- // `GclkDivider` type, so they are guaranteed to be valid.
1400- unsafe {
1401- #[ hal_cfg( "clock-d5x" ) ]
1402- w. div ( ) . bits ( div) ;
1403- #[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
1404- w. id ( ) . bits ( G :: NUM as u8 ) ;
1405- } ;
1406- w. divsel ( ) . bit ( divsel) ;
1407- w. src ( ) . variant ( I :: DYN . into ( ) ) ;
1408- w. idc ( ) . bit ( self . settings . improve_duty_cycle ) ;
1409- w. oe ( ) . bit ( self . settings . output_enable ) ;
1410- w. oov ( ) . bit ( self . settings . output_off_value ) ;
1411- w. genen ( ) . set_bit ( )
1412- } ) ;
1413- self . token . wait_syncbusy ( ) ;
1403+ self . update_genctrl ( true ) ;
14141404
14151405 Enabled :: new ( self )
14161406 }
@@ -1427,12 +1417,7 @@ where
14271417 /// only be disabled when no other clocks consume this [`Gclk`].
14281418 #[ inline]
14291419 pub fn disable ( self ) -> Gclk < G , I > {
1430- self . 0 . update_genctrl (
1431- |w| {
1432- w. genen ( ) . clear_bit ( ) ;
1433- } ,
1434- false ,
1435- ) ;
1420+ self . 0 . update_genctrl ( false ) ;
14361421 self . 0
14371422 }
14381423}
@@ -1540,42 +1525,27 @@ impl<I: GclkSourceId> EnabledGclk0<I, U1> {
15401525 pub fn div ( & mut self , divider : GclkDiv8 ) {
15411526 self . 0 . settings . div = divider;
15421527
1543- let ( divsel, div) = divider. divsel_div ( ) ;
1544-
15451528 // D5x div is in the GENCTRL register, smaller chips keep it separate
15461529 #[ hal_cfg( any( "clock-d11" , "clock-d21" ) ) ]
15471530 {
1531+ let ( _divsel, div) = divider. divsel_div ( ) ;
1532+ // Safety: The `DIVSEL` and `DIV` values are derived from the
1533+ // `GclkDivider` type, so they are guaranteed to be valid.
15481534 self . 0 . token . gendiv ( ) . write ( |w| unsafe {
15491535 w. id ( ) . bits ( 0 ) ;
15501536 w. div ( ) . bits ( div)
15511537 } ) ;
15521538 self . 0 . token . wait_syncbusy ( ) ;
15531539 }
15541540
1555- self . 0 . update_genctrl (
1556- |w| {
1557- // Safety: The `DIVSEL` and `DIV` values are derived from the
1558- // `GclkDivider` type, so they are guaranteed to be valid.
1559- #[ hal_cfg( "clock-d5x" ) ]
1560- unsafe {
1561- w. div ( ) . bits ( div) ;
1562- }
1563- w. divsel ( ) . bit ( divsel) ;
1564- } ,
1565- true ,
1566- ) ;
1541+ self . 0 . update_genctrl ( true ) ;
15671542 }
15681543
15691544 /// Output a 50-50 duty cycle clock when using an odd [`GclkDivider`]
15701545 #[ inline]
15711546 pub fn improve_duty_cycle ( & mut self , flag : bool ) {
15721547 self . 0 . settings . improve_duty_cycle = flag;
1573- self . 0 . update_genctrl (
1574- |w| {
1575- w. idc ( ) . bit ( flag) ;
1576- } ,
1577- true ,
1578- ) ;
1548+ self . 0 . update_genctrl ( true ) ;
15791549 }
15801550
15811551 /// Return the [`Gclk0`] frequency
@@ -1592,12 +1562,7 @@ impl<I: GclkSourceId> EnabledGclk0<I, U1> {
15921562 #[ inline]
15931563 pub fn output_off_value ( & mut self , high : bool ) {
15941564 self . 0 . settings . output_off_value = high;
1595- self . 0 . update_genctrl (
1596- |w| {
1597- w. oov ( ) . bit ( high) ;
1598- } ,
1599- true ,
1600- ) ;
1565+ self . 0 . update_genctrl ( true ) ;
16011566 }
16021567}
16031568
@@ -1734,12 +1699,7 @@ where
17341699 {
17351700 let pin = pin. into ( ) . into_mode ( ) ;
17361701 self . 0 . settings . output_enable = true ;
1737- self . 0 . update_genctrl (
1738- |w| {
1739- w. oe ( ) . set_bit ( ) ;
1740- } ,
1741- true ,
1742- ) ;
1702+ self . 0 . update_genctrl ( true ) ;
17431703
17441704 let gclk_out = GclkOut {
17451705 pin,
@@ -1764,12 +1724,7 @@ where
17641724 I : GclkIo < GclkId = G > ,
17651725 {
17661726 self . 0 . settings . output_enable = false ;
1767- self . 0 . update_genctrl (
1768- |w| {
1769- w. oe ( ) . clear_bit ( ) ;
1770- } ,
1771- true ,
1772- ) ;
1727+ self . 0 . update_genctrl ( true ) ;
17731728
17741729 ( self . dec ( ) , gclk_out. pin )
17751730 }
0 commit comments