aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-05-27 00:11:13 +0200
committerDario Nieuwenhuis <[email protected]>2024-05-27 00:14:44 +0200
commitd18a919ab9cfa1c07d339dd885d8268ab0abb7e6 (patch)
treeefa6e34cfbf8650080c4ed1d5e50125dd412afc1
parent33bdc9e85ff391da4ff4ff439abe86c2bae32986 (diff)
rp: wait until read matches for PSM accesses.
-rw-r--r--embassy-rp/src/lib.rs25
1 files changed, 21 insertions, 4 deletions
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 4602e66f4..507d42280 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -383,25 +383,29 @@ unsafe fn pre_init() {
383 // 383 //
384 // The PSM order is SIO -> PROC0 -> PROC1. 384 // The PSM order is SIO -> PROC0 -> PROC1.
385 // So, we have to force-on PROC0 to prevent it from getting reset when resetting SIO. 385 // So, we have to force-on PROC0 to prevent it from getting reset when resetting SIO.
386 pac::PSM.frce_on().write(|w| { 386 pac::PSM.frce_on().write_and_wait(|w| {
387 w.set_proc0(true); 387 w.set_proc0(true);
388 }); 388 });
389 // Then reset SIO and PROC1. 389 // Then reset SIO and PROC1.
390 pac::PSM.frce_off().write(|w| { 390 pac::PSM.frce_off().write_and_wait(|w| {
391 w.set_sio(true); 391 w.set_sio(true);
392 w.set_proc1(true); 392 w.set_proc1(true);
393 }); 393 });
394 // clear force_off first, force_on second. The other way around would reset PROC0. 394 // clear force_off first, force_on second. The other way around would reset PROC0.
395 pac::PSM.frce_off().write(|_| {}); 395 pac::PSM.frce_off().write_and_wait(|_| {});
396 pac::PSM.frce_on().write(|_| {}); 396 pac::PSM.frce_on().write_and_wait(|_| {});
397} 397}
398 398
399/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes. 399/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.
400#[allow(unused)]
400trait RegExt<T: Copy> { 401trait RegExt<T: Copy> {
401 #[allow(unused)] 402 #[allow(unused)]
402 fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; 403 fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
403 fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; 404 fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
404 fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; 405 fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
406 fn write_and_wait<R>(&self, f: impl FnOnce(&mut T) -> R) -> R
407 where
408 T: PartialEq;
405} 409}
406 410
407impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T, A> { 411impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T, A> {
@@ -434,4 +438,17 @@ impl<T: Default + Copy, A: pac::common::Write> RegExt<T> for pac::common::Reg<T,
434 } 438 }
435 res 439 res
436 } 440 }
441
442 fn write_and_wait<R>(&self, f: impl FnOnce(&mut T) -> R) -> R
443 where
444 T: PartialEq,
445 {
446 let mut val = Default::default();
447 let res = f(&mut val);
448 unsafe {
449 self.as_ptr().write_volatile(val);
450 while self.as_ptr().read_volatile() != val {}
451 }
452 res
453 }
437} 454}