rp: Workaround "SIO spinlock stuck bug", reset PROC1 at boot.

Just like RP2040. The bug was "working as intended" on rp2040, so it is on rp235x.
This commit is contained in:
Dario Nieuwenhuis 2025-02-05 00:46:30 +01:00
parent a2014c961d
commit bb2d9ec7f8

View File

@ -598,7 +598,7 @@ pub fn init(config: config::Config) -> Peripherals {
peripherals
}
#[cfg(all(feature = "rt", feature = "rp2040"))]
#[cfg(feature = "rt")]
#[cortex_m_rt::pre_init]
unsafe fn pre_init() {
// SIO does not get reset when core0 is reset with either `scb::sys_reset()` or with SWD.
@ -629,17 +629,34 @@ unsafe fn pre_init() {
//
// The PSM order is SIO -> PROC0 -> PROC1.
// So, we have to force-on PROC0 to prevent it from getting reset when resetting SIO.
pac::PSM.frce_on().write_and_wait(|w| {
w.set_proc0(true);
});
// Then reset SIO and PROC1.
pac::PSM.frce_off().write_and_wait(|w| {
w.set_sio(true);
w.set_proc1(true);
});
// clear force_off first, force_on second. The other way around would reset PROC0.
pac::PSM.frce_off().write_and_wait(|_| {});
pac::PSM.frce_on().write_and_wait(|_| {});
#[cfg(feature = "rp2040")]
{
pac::PSM.frce_on().write_and_wait(|w| {
w.set_proc0(true);
});
// Then reset SIO and PROC1.
pac::PSM.frce_off().write_and_wait(|w| {
w.set_sio(true);
w.set_proc1(true);
});
// clear force_off first, force_on second. The other way around would reset PROC0.
pac::PSM.frce_off().write_and_wait(|_| {});
pac::PSM.frce_on().write_and_wait(|_| {});
}
#[cfg(feature = "_rp235x")]
{
// on RP235x, datasheet says "The FRCE_ON register is a development feature that does nothing in production devices."
// No idea why they removed it. Removing it means we can't use PSM to reset SIO, because it comes before
// PROC0, so we'd need FRCE_ON to prevent resetting ourselves.
//
// So we just unlock the spinlock manually.
pac::SIO.spinlock(31).write_value(1);
// We can still use PSM to reset PROC1 since it comes after PROC0 in the state machine.
pac::PSM.frce_off().write_and_wait(|w| w.set_proc1(true));
pac::PSM.frce_off().write_and_wait(|_| {});
}
}
/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.