From c8c366c23dcc9a49af932e16b835282f09dfa166 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 30 Jan 2022 12:56:51 +0000 Subject: [PATCH 1/6] Use new spinlock API provide by PAC 0.3.0 --- rp2040-hal/Cargo.toml | 2 +- rp2040-hal/src/critical_section_impl.rs | 4 +- rp2040-hal/src/sio.rs | 70 ++++++++++++------------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/rp2040-hal/Cargo.toml b/rp2040-hal/Cargo.toml index 6c5305a..6d6b652 100644 --- a/rp2040-hal/Cargo.toml +++ b/rp2040-hal/Cargo.toml @@ -16,7 +16,7 @@ eh1_0_alpha = { version = "=1.0.0-alpha.6", package="embedded-hal", optional=tru embedded-time = "0.12.0" itertools = { version = "0.10.1", default-features = false } nb = "1.0" -rp2040-pac = "0.2.0" +rp2040-pac = "0.3.0" paste = "1.0" pio = "0.1.0" usb-device = "0.2.8" diff --git a/rp2040-hal/src/critical_section_impl.rs b/rp2040-hal/src/critical_section_impl.rs index e58eb0e..711d395 100644 --- a/rp2040-hal/src/critical_section_impl.rs +++ b/rp2040-hal/src/critical_section_impl.rs @@ -41,7 +41,7 @@ unsafe impl critical_section::Impl for RpSpinlockCs { // Ensure the compiler doesn't re-order accesses and violate safety here core::sync::atomic::compiler_fence(Ordering::SeqCst); // Read the spinlock reserved for `critical_section` - if (*pac::SIO::ptr()).spinlock31.read().bits() != 0 { + if (*pac::SIO::ptr()).spinlock[31].read().bits() != 0 { // We just acquired the lock. // Store which core we are so we can tell if we're called recursively LOCK_OWNER.store(core, Ordering::Relaxed); @@ -67,7 +67,7 @@ unsafe impl critical_section::Impl for RpSpinlockCs { // Ensure the compiler doesn't re-order accesses and violate safety here core::sync::atomic::compiler_fence(Ordering::SeqCst); // Release the spinlock to allow others to enter critical_section again - (*pac::SIO::ptr()).spinlock31.write_with_zero(|w| w.bits(1)); + (*pac::SIO::ptr()).spinlock[31].write_with_zero(|w| w.bits(1)); // Re-enable interrupts if they were enabled when we first called acquire() // We only do this on the outermost `critical_section` to ensure interrupts stay disabled // for the whole time that we have the lock diff --git a/rp2040-hal/src/sio.rs b/rp2040-hal/src/sio.rs index ff808ec..59b65f8 100644 --- a/rp2040-hal/src/sio.rs +++ b/rp2040-hal/src/sio.rs @@ -230,7 +230,7 @@ pub trait Spinlock: typelevel::Sealed + Sized { } } macro_rules! impl_spinlock { - ($($spinlock_name:ident => $register:ident,)*) => { + ($($spinlock_name:ident => $register:literal,)*) => { $( /// Hardware based spinlock. /// @@ -258,7 +258,7 @@ macro_rules! impl_spinlock { fn try_claim() -> Option<$spinlock_name> { // Safety: We're only reading from this register let sio = unsafe { &*pac::SIO::ptr() }; - let lock = sio.$register.read().bits(); + let lock = sio.spinlock[$register].read().bits(); if lock > 0 { Some(Self(core::marker::PhantomData)) } else { @@ -276,7 +276,7 @@ macro_rules! impl_spinlock { let sio = unsafe { &*pac::SIO::ptr() }; // Write (any value): release the lock - sio.$register.write(|b| unsafe { b.bits(1) }); + sio.spinlock[$register].write(|b| unsafe { b.bits(1) }); } } )* @@ -284,38 +284,38 @@ macro_rules! impl_spinlock { } impl_spinlock! { - Spinlock0 => spinlock0, - Spinlock1 => spinlock1, - Spinlock2 => spinlock2, - Spinlock3 => spinlock3, - Spinlock4 => spinlock4, - Spinlock5 => spinlock5, - Spinlock6 => spinlock6, - Spinlock7 => spinlock7, - Spinlock8 => spinlock8, - Spinlock9 => spinlock9, - Spinlock10 => spinlock10, - Spinlock11 => spinlock11, - Spinlock12 => spinlock12, - Spinlock13 => spinlock13, - Spinlock14 => spinlock14, - Spinlock15 => spinlock15, - Spinlock16 => spinlock16, - Spinlock17 => spinlock17, - Spinlock18 => spinlock18, - Spinlock19 => spinlock19, - Spinlock20 => spinlock20, - Spinlock21 => spinlock21, - Spinlock22 => spinlock22, - Spinlock23 => spinlock23, - Spinlock24 => spinlock24, - Spinlock25 => spinlock25, - Spinlock26 => spinlock26, - Spinlock27 => spinlock27, - Spinlock28 => spinlock28, - Spinlock29 => spinlock29, - Spinlock30 => spinlock30, - Spinlock31 => spinlock31, + Spinlock0 => 0, + Spinlock1 => 1, + Spinlock2 => 2, + Spinlock3 => 3, + Spinlock4 => 4, + Spinlock5 => 5, + Spinlock6 => 6, + Spinlock7 => 7, + Spinlock8 => 8, + Spinlock9 => 9, + Spinlock10 => 10, + Spinlock11 => 11, + Spinlock12 => 12, + Spinlock13 => 13, + Spinlock14 => 14, + Spinlock15 => 15, + Spinlock16 => 16, + Spinlock17 => 17, + Spinlock18 => 18, + Spinlock19 => 19, + Spinlock20 => 20, + Spinlock21 => 21, + Spinlock22 => 22, + Spinlock23 => 23, + Spinlock24 => 24, + Spinlock25 => 25, + Spinlock26 => 26, + Spinlock27 => 27, + Spinlock28 => 28, + Spinlock29 => 29, + Spinlock30 => 30, + Spinlock31 => 31, } /// Returns the current state of the spinlocks. Each index corresponds to the associated spinlock, e.g. if index `5` is set to `true`, it means that [`Spinlock5`] is currently locked. From 7e2f8d274cb2de434bc1730600f0fd49f581ac67 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 30 Jan 2022 15:56:23 +0000 Subject: [PATCH 2/6] Use const generics for spinlocks. The fewer code-generating macros we have, the better! --- rp2040-hal/src/sio.rs | 304 ++++++++++++++++++++++++++++++------------ 1 file changed, 216 insertions(+), 88 deletions(-) diff --git a/rp2040-hal/src/sio.rs b/rp2040-hal/src/sio.rs index 59b65f8..e8148a8 100644 --- a/rp2040-hal/src/sio.rs +++ b/rp2040-hal/src/sio.rs @@ -207,16 +207,58 @@ impl HwDivider { } } -/// Trait for all the spinlock. See the documentation of e.g. [`Spinlock0`] for more information -pub trait Spinlock: typelevel::Sealed + Sized { +/// This type is just used to limit us to Spinlocks `0..=31` +pub trait SpinlockValid {} + +/// Hardware based spinlock. +/// +/// You can claim this lock by calling either [`claim`], [`try_claim`] or +/// [`claim_async`]. These spin-locks are hardware backed, so if you lock +/// `Spinlock<6>` any other part of your program using `Spinlock<6>` will +/// suddenly find it to be locked. +/// +/// When the obtained spinlock goes out of scope, it is automatically unlocked. +/// +/// **warning**: These spinlocks are not re-entrant, meaning that the following code will cause a deadlock: +/// +/// ```no_run +/// use rp2040_hal::sio::Spinlock0; +/// let lock_1 = Spinlock0::claim(); +/// let lock_2 = Spinlock0::claim(); // deadlock here +/// ``` +/// +/// Use `try_claim` if you are not the only piece of code using any given +/// spin-lock. Note also that the `critical-section` implementation uses +/// Spinlock 31. +/// +/// [`claim`]: #method.claim +/// [`try_claim`]: #method.try_claim +/// [`claim_async`]: #method.claim_asyncs +pub struct Spinlock(core::marker::PhantomData<()>) +where + Spinlock: SpinlockValid; + +impl Spinlock +where + Spinlock: SpinlockValid, +{ /// Try to claim the spinlock. Will return `Some(Self)` if the lock is obtained, and `None` if the lock is /// already in use somewhere else. - fn try_claim() -> Option; + pub fn try_claim() -> Option { + // Safety: We're only reading from this register + let sio = unsafe { &*pac::SIO::ptr() }; + let lock = sio.spinlock[N].read().bits(); + if lock > 0 { + Some(Self(core::marker::PhantomData)) + } else { + None + } + } /// Claim the spinlock, will block the current thread until the lock is available. /// /// Note that calling this multiple times in a row will cause a deadlock - fn claim() -> Self { + pub fn claim() -> Self { loop { if let Some(result) = Self::try_claim() { break result; @@ -225,98 +267,184 @@ pub trait Spinlock: typelevel::Sealed + Sized { } /// Try to claim the spinlock. Will return `WouldBlock` until the spinlock is available. - fn claim_async() -> nb::Result { + pub fn claim_async() -> nb::Result { Self::try_claim().ok_or(nb::Error::WouldBlock) } } -macro_rules! impl_spinlock { - ($($spinlock_name:ident => $register:literal,)*) => { - $( - /// Hardware based spinlock. - /// - /// You can claim this lock by calling either [`claim`], [`try_claim`] or [`claim_async`]. - /// This will automatically lock ALL spinlocks of type ` - #[doc = stringify!($spinlock_name)] - /// `. - /// - /// When the obtained spinlock goes out of scope, it is automatically unlocked. - /// - /// **warning**: These spinlocks are not re-entrant, meaning that the following code will cause a deadlock: - /// - /// ```no_run - /// use rp2040_hal::sio::{Spinlock0, Spinlock}; - /// let lock_1 = Spinlock0::claim(); - /// let lock_2 = Spinlock0::claim(); // deadlock here - /// ``` - /// - /// [`claim`]: #method.claim - /// [`try_claim`]: #method.try_claim - /// [`claim_async`]: #method.claim_async - pub struct $spinlock_name(core::marker::PhantomData<()>); - impl Spinlock for $spinlock_name { - fn try_claim() -> Option<$spinlock_name> { - // Safety: We're only reading from this register - let sio = unsafe { &*pac::SIO::ptr() }; - let lock = sio.spinlock[$register].read().bits(); - if lock > 0 { - Some(Self(core::marker::PhantomData)) - } else { - None - } - } - } +impl Drop for Spinlock +where + Spinlock: SpinlockValid, +{ + fn drop(&mut self) { + // Safety: At this point we should be the only one accessing this spinlock register + // so writing to this address is fine + let sio = unsafe { &*pac::SIO::ptr() }; - impl typelevel::Sealed for $spinlock_name {} - - impl Drop for $spinlock_name { - fn drop(&mut self) { - // Safety: At this point we should be the only one accessing this spinlock register - // so writing to this address is fine - let sio = unsafe { &*pac::SIO::ptr() }; - - // Write (any value): release the lock - sio.spinlock[$register].write(|b| unsafe { b.bits(1) }); - } - } - )* + // Write (any value): release the lock + sio.spinlock[N].write(|b| unsafe { b.bits(1) }); } } -impl_spinlock! { - Spinlock0 => 0, - Spinlock1 => 1, - Spinlock2 => 2, - Spinlock3 => 3, - Spinlock4 => 4, - Spinlock5 => 5, - Spinlock6 => 6, - Spinlock7 => 7, - Spinlock8 => 8, - Spinlock9 => 9, - Spinlock10 => 10, - Spinlock11 => 11, - Spinlock12 => 12, - Spinlock13 => 13, - Spinlock14 => 14, - Spinlock15 => 15, - Spinlock16 => 16, - Spinlock17 => 17, - Spinlock18 => 18, - Spinlock19 => 19, - Spinlock20 => 20, - Spinlock21 => 21, - Spinlock22 => 22, - Spinlock23 => 23, - Spinlock24 => 24, - Spinlock25 => 25, - Spinlock26 => 26, - Spinlock27 => 27, - Spinlock28 => 28, - Spinlock29 => 29, - Spinlock30 => 30, - Spinlock31 => 31, -} +/// Spinlock number 0 +pub type Spinlock0 = Spinlock<0>; + +impl SpinlockValid for Spinlock<0> {} + +/// Spinlock number 1 +pub type Spinlock1 = Spinlock<1>; + +impl SpinlockValid for Spinlock<1> {} + +/// Spinlock number 2 +pub type Spinlock2 = Spinlock<2>; + +impl SpinlockValid for Spinlock<2> {} + +/// Spinlock number 3 +pub type Spinlock3 = Spinlock<3>; + +impl SpinlockValid for Spinlock<3> {} + +/// Spinlock number 4 +pub type Spinlock4 = Spinlock<4>; + +impl SpinlockValid for Spinlock<4> {} + +/// Spinlock number 5 +pub type Spinlock5 = Spinlock<5>; + +impl SpinlockValid for Spinlock<5> {} + +/// Spinlock number 6 +pub type Spinlock6 = Spinlock<6>; + +impl SpinlockValid for Spinlock<6> {} + +/// Spinlock number 7 +pub type Spinlock7 = Spinlock<7>; + +impl SpinlockValid for Spinlock<7> {} + +/// Spinlock number 8 +pub type Spinlock8 = Spinlock<8>; + +impl SpinlockValid for Spinlock<8> {} + +/// Spinlock number 9 +pub type Spinlock9 = Spinlock<9>; + +impl SpinlockValid for Spinlock<9> {} + +/// Spinlock number 10 +pub type Spinlock10 = Spinlock<10>; + +impl SpinlockValid for Spinlock<10> {} + +/// Spinlock number 11 +pub type Spinlock11 = Spinlock<11>; + +impl SpinlockValid for Spinlock<11> {} + +/// Spinlock number 12 +pub type Spinlock12 = Spinlock<12>; + +impl SpinlockValid for Spinlock<12> {} + +/// Spinlock number 13 +pub type Spinlock13 = Spinlock<13>; + +impl SpinlockValid for Spinlock<13> {} + +/// Spinlock number 14 +pub type Spinlock14 = Spinlock<14>; + +impl SpinlockValid for Spinlock<14> {} + +/// Spinlock number 15 +pub type Spinlock15 = Spinlock<15>; + +impl SpinlockValid for Spinlock<15> {} + +/// Spinlock number 16 +pub type Spinlock16 = Spinlock<16>; + +impl SpinlockValid for Spinlock<16> {} + +/// Spinlock number 17 +pub type Spinlock17 = Spinlock<17>; + +impl SpinlockValid for Spinlock<17> {} + +/// Spinlock number 18 +pub type Spinlock18 = Spinlock<18>; + +impl SpinlockValid for Spinlock<18> {} + +/// Spinlock number 19 +pub type Spinlock19 = Spinlock<19>; + +impl SpinlockValid for Spinlock<19> {} + +/// Spinlock number 20 +pub type Spinlock20 = Spinlock<20>; + +impl SpinlockValid for Spinlock<20> {} + +/// Spinlock number 21 +pub type Spinlock21 = Spinlock<21>; + +impl SpinlockValid for Spinlock<21> {} + +/// Spinlock number 22 +pub type Spinlock22 = Spinlock<22>; + +impl SpinlockValid for Spinlock<22> {} + +/// Spinlock number 23 +pub type Spinlock23 = Spinlock<23>; + +impl SpinlockValid for Spinlock<23> {} + +/// Spinlock number 24 +pub type Spinlock24 = Spinlock<24>; + +impl SpinlockValid for Spinlock<24> {} + +/// Spinlock number 25 +pub type Spinlock25 = Spinlock<25>; + +impl SpinlockValid for Spinlock<25> {} + +/// Spinlock number 26 +pub type Spinlock26 = Spinlock<26>; + +impl SpinlockValid for Spinlock<26> {} + +/// Spinlock number 27 +pub type Spinlock27 = Spinlock<27>; + +impl SpinlockValid for Spinlock<27> {} + +/// Spinlock number 28 +pub type Spinlock28 = Spinlock<28>; + +impl SpinlockValid for Spinlock<28> {} + +/// Spinlock number 29 +pub type Spinlock29 = Spinlock<29>; + +impl SpinlockValid for Spinlock<29> {} + +/// Spinlock number 30 +pub type Spinlock30 = Spinlock<30>; + +impl SpinlockValid for Spinlock<30> {} + +/// Spinlock number 31 +pub type Spinlock31 = Spinlock<31>; + +impl SpinlockValid for Spinlock<31> {} /// Returns the current state of the spinlocks. Each index corresponds to the associated spinlock, e.g. if index `5` is set to `true`, it means that [`Spinlock5`] is currently locked. /// From 35a10f2bc69384566ce72538f60ddb88174a60c3 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 30 Jan 2022 16:07:40 +0000 Subject: [PATCH 3/6] Clean up critical-section impl. Adds new `Sio::core()` function. --- rp2040-hal/src/critical_section_impl.rs | 10 ++++++---- rp2040-hal/src/sio.rs | 23 +++++++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/rp2040-hal/src/critical_section_impl.rs b/rp2040-hal/src/critical_section_impl.rs index 711d395..e26cfd9 100644 --- a/rp2040-hal/src/critical_section_impl.rs +++ b/rp2040-hal/src/critical_section_impl.rs @@ -26,7 +26,7 @@ unsafe impl critical_section::Impl for RpSpinlockCs { // Store the initial interrupt state and current core id in stack variables let interrupts_active = cortex_m::register::primask::read().is_active(); // We reserved 0 as our `LOCK_UNOWNED` value, so add 1 to core_id so we get 1 for core0, 2 for core1. - let core = (*pac::SIO::ptr()).cpuid.read().bits() as u8 + 1_u8; + let core = crate::Sio::core() + 1_u8; // Do we already own the spinlock? if LOCK_OWNER.load(Ordering::Acquire) == core { // We already own the lock, so we must have called acquire within a critical_section. @@ -41,9 +41,11 @@ unsafe impl critical_section::Impl for RpSpinlockCs { // Ensure the compiler doesn't re-order accesses and violate safety here core::sync::atomic::compiler_fence(Ordering::SeqCst); // Read the spinlock reserved for `critical_section` - if (*pac::SIO::ptr()).spinlock[31].read().bits() != 0 { + if let Some(lock) = crate::sio::Spinlock31::try_claim() { // We just acquired the lock. - // Store which core we are so we can tell if we're called recursively + // 1. Forget it, so we don't immediately unlock + core::mem::forget(lock); + // 2. Store which core we are so we can tell if we're called recursively LOCK_OWNER.store(core, Ordering::Relaxed); break; } @@ -67,7 +69,7 @@ unsafe impl critical_section::Impl for RpSpinlockCs { // Ensure the compiler doesn't re-order accesses and violate safety here core::sync::atomic::compiler_fence(Ordering::SeqCst); // Release the spinlock to allow others to enter critical_section again - (*pac::SIO::ptr()).spinlock[31].write_with_zero(|w| w.bits(1)); + crate::sio::Spinlock31::release(); // Re-enable interrupts if they were enabled when we first called acquire() // We only do this on the outermost `critical_section` to ensure interrupts stay disabled // for the whole time that we have the lock diff --git a/rp2040-hal/src/sio.rs b/rp2040-hal/src/sio.rs index e8148a8..6d12b0b 100644 --- a/rp2040-hal/src/sio.rs +++ b/rp2040-hal/src/sio.rs @@ -76,6 +76,12 @@ impl Sio { hwdivider: HwDivider { _private: () }, } } + + /// Returns whether we are running on Core 0 (`0`) or Core 1 (`1`). + pub fn core() -> u8 { + // Safety: it is always safe to read this read-only register + unsafe { (*pac::SIO::ptr()).cpuid.read().bits() as u8 } + } } impl SioFifo { @@ -270,6 +276,15 @@ where pub fn claim_async() -> nb::Result { Self::try_claim().ok_or(nb::Error::WouldBlock) } + + /// Clear a locked spin-lock. + /// + /// Safety: Only call this function if you hold the spin-lock. + pub unsafe fn release() { + let sio = &*pac::SIO::ptr(); + // Write (any value): release the lock + sio.spinlock[N].write_with_zero(|b| b.bits(1)); + } } impl Drop for Spinlock @@ -277,12 +292,8 @@ where Spinlock: SpinlockValid, { fn drop(&mut self) { - // Safety: At this point we should be the only one accessing this spinlock register - // so writing to this address is fine - let sio = unsafe { &*pac::SIO::ptr() }; - - // Write (any value): release the lock - sio.spinlock[N].write(|b| unsafe { b.bits(1) }); + // This is safe because we own the object, and hence hold the lock. + unsafe { Self::release() } } } From f44f5f0e09d8be39c929e9477f1cc56f8a795888 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 30 Jan 2022 16:12:43 +0000 Subject: [PATCH 4/6] Make clippy happy. --- rp2040-hal/src/sio.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rp2040-hal/src/sio.rs b/rp2040-hal/src/sio.rs index 6d12b0b..14d8642 100644 --- a/rp2040-hal/src/sio.rs +++ b/rp2040-hal/src/sio.rs @@ -279,7 +279,9 @@ where /// Clear a locked spin-lock. /// - /// Safety: Only call this function if you hold the spin-lock. + /// # Safety + /// + /// Only call this function if you hold the spin-lock. pub unsafe fn release() { let sio = &*pac::SIO::ptr(); // Write (any value): release the lock From efda22c9eac0ee14a3c4c48cc7e9fe0bcba24700 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 30 Jan 2022 16:43:53 +0000 Subject: [PATCH 5/6] Update spinlock docs. --- rp2040-hal/src/sio.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/rp2040-hal/src/sio.rs b/rp2040-hal/src/sio.rs index 14d8642..ff4d7ea 100644 --- a/rp2040-hal/src/sio.rs +++ b/rp2040-hal/src/sio.rs @@ -220,12 +220,31 @@ pub trait SpinlockValid {} /// /// You can claim this lock by calling either [`claim`], [`try_claim`] or /// [`claim_async`]. These spin-locks are hardware backed, so if you lock -/// `Spinlock<6>` any other part of your program using `Spinlock<6>` will -/// suddenly find it to be locked. +/// e.g. `Spinlock<6>`, then any other part of your application using +/// `Spinlock<6>` will contend for the same lock, without them needing to +/// share a reference or otherwise communicate with each other. /// /// When the obtained spinlock goes out of scope, it is automatically unlocked. /// -/// **warning**: These spinlocks are not re-entrant, meaning that the following code will cause a deadlock: +/// +/// ```no_run +/// use rp2040_hal::sio::Spinlock0; +/// static mut SOME_GLOBAL_VAR: u32 = 0; +/// +/// /// This function is safe to call from two different cores, but is not safe +/// /// to call from an interrupt routine! +/// fn update_global_var() { +/// // Do not say `let _ = ` here - it will immediately unlock! +/// let _lock = Spinlock0::claim(); +/// // Do your thing here that Core 0 and Core 1 might want to do at the +/// // same time, like update this global variable: +/// unsafe { SOME_GLOBAL_VAR += 1 }; +/// // The lock is dropped here. +/// } +/// ``` +/// +/// **Warning**: These spinlocks are not re-entrant, meaning that the +/// following code will cause a deadlock: /// /// ```no_run /// use rp2040_hal::sio::Spinlock0; @@ -233,9 +252,7 @@ pub trait SpinlockValid {} /// let lock_2 = Spinlock0::claim(); // deadlock here /// ``` /// -/// Use `try_claim` if you are not the only piece of code using any given -/// spin-lock. Note also that the `critical-section` implementation uses -/// Spinlock 31. +/// **Note:** The `critical-section` implementation uses Spinlock 31. /// /// [`claim`]: #method.claim /// [`try_claim`]: #method.try_claim From 4a540d041abf60c61ec93180946be995f2cfecac Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 30 Jan 2022 16:43:59 +0000 Subject: [PATCH 6/6] Hide spinlock 31. --- rp2040-hal/src/sio.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rp2040-hal/src/sio.rs b/rp2040-hal/src/sio.rs index ff4d7ea..b9a2a91 100644 --- a/rp2040-hal/src/sio.rs +++ b/rp2040-hal/src/sio.rs @@ -471,8 +471,8 @@ pub type Spinlock30 = Spinlock<30>; impl SpinlockValid for Spinlock<30> {} -/// Spinlock number 31 -pub type Spinlock31 = Spinlock<31>; +/// Spinlock number 31 - used by critical section implementation +pub(crate) type Spinlock31 = Spinlock<31>; impl SpinlockValid for Spinlock<31> {}