@@ -80,13 +80,15 @@ use fugit::{Instant, MicrosDurationU32, MicrosDurationU64};
8080use super :: { Error , Timer as _} ;
8181use crate :: {
8282 interrupt:: { self , InterruptHandler } ,
83+ lock,
8384 peripheral:: Peripheral ,
8485 peripherals:: { Interrupt , SYSTIMER } ,
8586 system:: { Peripheral as PeripheralEnable , PeripheralClockControl } ,
8687 Async ,
8788 Blocking ,
8889 Cpu ,
8990 InterruptConfigurable ,
91+ LockState ,
9092 Mode ,
9193} ;
9294
@@ -240,7 +242,7 @@ pub trait Unit {
240242 let systimer = unsafe { & * SYSTIMER :: ptr ( ) } ;
241243 let conf = systimer. conf ( ) ;
242244
243- critical_section :: with ( |_ | {
245+ lock ( & CONF_LOCK , | | {
244246 conf. modify ( |_, w| match config {
245247 UnitConfig :: Disabled => match self . channel ( ) {
246248 0 => w. timer_unit0_work_en ( ) . clear_bit ( ) ,
@@ -418,20 +420,22 @@ pub trait Comparator {
418420 fn set_enable ( & self , enable : bool ) {
419421 let systimer = unsafe { & * SYSTIMER :: ptr ( ) } ;
420422
421- critical_section :: with ( |_ | {
423+ lock ( & CONF_LOCK , | | {
422424 #[ cfg( not( esp32s2) ) ]
423425 systimer. conf ( ) . modify ( |_, w| match self . channel ( ) {
424426 0 => w. target0_work_en ( ) . bit ( enable) ,
425427 1 => w. target1_work_en ( ) . bit ( enable) ,
426428 2 => w. target2_work_en ( ) . bit ( enable) ,
427429 _ => unreachable ! ( ) ,
428430 } ) ;
429-
430- #[ cfg( esp32s2) ]
431- systimer
432- . target_conf ( self . channel ( ) as usize )
433- . modify ( |_r, w| w. work_en ( ) . bit ( enable) ) ;
434431 } ) ;
432+
433+ // Note: The ESP32-S2 doesn't require a lock because each
434+ // comparator's enable bit in a different register.
435+ #[ cfg( esp32s2) ]
436+ systimer
437+ . target_conf ( self . channel ( ) as usize )
438+ . modify ( |_r, w| w. work_en ( ) . bit ( enable) ) ;
435439 }
436440
437441 /// Returns true if the comparator has been enabled. This means
@@ -964,9 +968,11 @@ where
964968 }
965969
966970 fn enable_interrupt ( & self , state : bool ) {
967- unsafe { & * SYSTIMER :: PTR }
968- . int_ena ( )
969- . modify ( |_, w| w. target ( self . comparator . channel ( ) ) . bit ( state) ) ;
971+ lock ( & INT_ENA_LOCK , || {
972+ unsafe { & * SYSTIMER :: PTR }
973+ . int_ena ( )
974+ . modify ( |_, w| w. target ( self . comparator . channel ( ) ) . bit ( state) ) ;
975+ } ) ;
970976 }
971977
972978 fn clear_interrupt ( & self ) {
@@ -1004,6 +1010,9 @@ where
10041010 }
10051011}
10061012
1013+ static CONF_LOCK : LockState = LockState :: new ( ) ;
1014+ static INT_ENA_LOCK : LockState = LockState :: new ( ) ;
1015+
10071016// Async functionality of the system timer.
10081017#[ cfg( feature = "async" ) ]
10091018mod asynch {
@@ -1090,27 +1099,33 @@ mod asynch {
10901099
10911100 #[ handler]
10921101 fn target0_handler ( ) {
1093- unsafe { & * crate :: peripherals:: SYSTIMER :: PTR }
1094- . int_ena ( )
1095- . modify ( |_, w| w. target0 ( ) . clear_bit ( ) ) ;
1102+ lock ( & INT_ENA_LOCK , || {
1103+ unsafe { & * crate :: peripherals:: SYSTIMER :: PTR }
1104+ . int_ena ( )
1105+ . modify ( |_, w| w. target0 ( ) . clear_bit ( ) ) ;
1106+ } ) ;
10961107
10971108 WAKERS [ 0 ] . wake ( ) ;
10981109 }
10991110
11001111 #[ handler]
11011112 fn target1_handler ( ) {
1102- unsafe { & * crate :: peripherals:: SYSTIMER :: PTR }
1103- . int_ena ( )
1104- . modify ( |_, w| w. target1 ( ) . clear_bit ( ) ) ;
1113+ lock ( & INT_ENA_LOCK , || {
1114+ unsafe { & * crate :: peripherals:: SYSTIMER :: PTR }
1115+ . int_ena ( )
1116+ . modify ( |_, w| w. target1 ( ) . clear_bit ( ) ) ;
1117+ } ) ;
11051118
11061119 WAKERS [ 1 ] . wake ( ) ;
11071120 }
11081121
11091122 #[ handler]
11101123 fn target2_handler ( ) {
1111- unsafe { & * crate :: peripherals:: SYSTIMER :: PTR }
1112- . int_ena ( )
1113- . modify ( |_, w| w. target2 ( ) . clear_bit ( ) ) ;
1124+ lock ( & INT_ENA_LOCK , || {
1125+ unsafe { & * crate :: peripherals:: SYSTIMER :: PTR }
1126+ . int_ena ( )
1127+ . modify ( |_, w| w. target2 ( ) . clear_bit ( ) ) ;
1128+ } ) ;
11141129
11151130 WAKERS [ 2 ] . wake ( ) ;
11161131 }
0 commit comments