diff options
| author | Bjorn Beishline <[email protected]> | 2025-11-25 12:05:52 -0700 |
|---|---|---|
| committer | Bjorn Beishline <[email protected]> | 2025-11-25 12:05:52 -0700 |
| commit | edd8878f8cbd15a56a6c845a2a8772a016e24d4b (patch) | |
| tree | 52afa798b0a8c6b56e7a8ff9f384e8fba94bb4bc /embassy-rp/src | |
| parent | f8ec795741663f559295327911a51559c526ba8f (diff) | |
Use two AtomicU32 instead
Diffstat (limited to 'embassy-rp/src')
| -rw-r--r-- | embassy-rp/src/pio/mod.rs | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs index fd0b4c072..1c370fdfc 100644 --- a/embassy-rp/src/pio/mod.rs +++ b/embassy-rp/src/pio/mod.rs | |||
| @@ -1,9 +1,8 @@ | |||
| 1 | //! PIO driver. | 1 | //! PIO driver. |
| 2 | use core::cell::Cell; | ||
| 3 | use core::future::Future; | 2 | use core::future::Future; |
| 4 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 5 | use core::pin::Pin as FuturePin; | 4 | use core::pin::Pin as FuturePin; |
| 6 | use core::sync::atomic::{AtomicU8, Ordering, compiler_fence}; | 5 | use core::sync::atomic::{AtomicU8, AtomicU32, Ordering, compiler_fence}; |
| 7 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 8 | 7 | ||
| 9 | use embassy_hal_internal::{Peri, PeripheralType}; | 8 | use embassy_hal_internal::{Peri, PeripheralType}; |
| @@ -1233,9 +1232,12 @@ impl<'d, PIO: Instance> Common<'d, PIO> { | |||
| 1233 | }); | 1232 | }); |
| 1234 | // we can be relaxed about this because we're &mut here and nothing is cached | 1233 | // we can be relaxed about this because we're &mut here and nothing is cached |
| 1235 | critical_section::with(|_| { | 1234 | critical_section::with(|_| { |
| 1236 | let val = PIO::state().used_pins.get(); | 1235 | let val = PIO::state().used_pins.load(Ordering::Relaxed); |
| 1237 | PIO::state().used_pins.set(val | 1 << pin.pin_bank()); | 1236 | PIO::state() |
| 1237 | .used_pins | ||
| 1238 | .store(val | 1 << pin.pin_bank(), Ordering::Relaxed); | ||
| 1238 | }); | 1239 | }); |
| 1240 | |||
| 1239 | Pin { | 1241 | Pin { |
| 1240 | pin: pin.into(), | 1242 | pin: pin.into(), |
| 1241 | pio: PhantomData::default(), | 1243 | pio: PhantomData::default(), |
| @@ -1372,7 +1374,7 @@ impl<'d, PIO: Instance> Pio<'d, PIO> { | |||
| 1372 | /// Create a new instance of a PIO peripheral. | 1374 | /// Create a new instance of a PIO peripheral. |
| 1373 | pub fn new(_pio: Peri<'d, PIO>, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self { | 1375 | pub fn new(_pio: Peri<'d, PIO>, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self { |
| 1374 | PIO::state().users.store(5, Ordering::Release); | 1376 | PIO::state().users.store(5, Ordering::Release); |
| 1375 | critical_section::with(|_| PIO::state().used_pins.set(0)); | 1377 | PIO::state().used_pins.store(0, Ordering::Release); |
| 1376 | PIO::Interrupt::unpend(); | 1378 | PIO::Interrupt::unpend(); |
| 1377 | 1379 | ||
| 1378 | unsafe { PIO::Interrupt::enable() }; | 1380 | unsafe { PIO::Interrupt::enable() }; |
| @@ -1407,6 +1409,42 @@ impl<'d, PIO: Instance> Pio<'d, PIO> { | |||
| 1407 | } | 1409 | } |
| 1408 | } | 1410 | } |
| 1409 | 1411 | ||
| 1412 | struct AtomicU64 { | ||
| 1413 | upper_32: AtomicU32, | ||
| 1414 | lower_32: AtomicU32, | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | impl AtomicU64 { | ||
| 1418 | const fn new(val: u64) -> Self { | ||
| 1419 | let upper_32 = (val >> 32) as u32; | ||
| 1420 | let lower_32 = val as u32; | ||
| 1421 | |||
| 1422 | Self { | ||
| 1423 | upper_32: AtomicU32::new(upper_32), | ||
| 1424 | lower_32: AtomicU32::new(lower_32), | ||
| 1425 | } | ||
| 1426 | } | ||
| 1427 | |||
| 1428 | fn load(&self, order: Ordering) -> u64 { | ||
| 1429 | let (upper, lower) = critical_section::with(|_| (self.upper_32.load(order), self.lower_32.load(order))); | ||
| 1430 | |||
| 1431 | let upper = (upper as u64) << 32; | ||
| 1432 | let lower = lower as u64; | ||
| 1433 | |||
| 1434 | upper | lower | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | fn store(&self, val: u64, order: Ordering) { | ||
| 1438 | let upper_32 = (val >> 32) as u32; | ||
| 1439 | let lower_32 = val as u32; | ||
| 1440 | |||
| 1441 | critical_section::with(|_| { | ||
| 1442 | self.upper_32.store(upper_32, order); | ||
| 1443 | self.lower_32.store(lower_32, order); | ||
| 1444 | }); | ||
| 1445 | } | ||
| 1446 | } | ||
| 1447 | |||
| 1410 | /// Representation of the PIO state keeping a record of which pins are assigned to | 1448 | /// Representation of the PIO state keeping a record of which pins are assigned to |
| 1411 | /// each PIO. | 1449 | /// each PIO. |
| 1412 | // make_pio_pin notionally takes ownership of the pin it is given, but the wrapped pin | 1450 | // make_pio_pin notionally takes ownership of the pin it is given, but the wrapped pin |
| @@ -1416,11 +1454,9 @@ impl<'d, PIO: Instance> Pio<'d, PIO> { | |||
| 1416 | // other way. | 1454 | // other way. |
| 1417 | pub struct State { | 1455 | pub struct State { |
| 1418 | users: AtomicU8, | 1456 | users: AtomicU8, |
| 1419 | used_pins: Cell<u64>, | 1457 | used_pins: AtomicU64, |
| 1420 | } | 1458 | } |
| 1421 | 1459 | ||
| 1422 | unsafe impl Sync for State {} | ||
| 1423 | |||
| 1424 | fn on_pio_drop<PIO: Instance>() { | 1460 | fn on_pio_drop<PIO: Instance>() { |
| 1425 | let state = PIO::state(); | 1461 | let state = PIO::state(); |
| 1426 | let users_state = critical_section::with(|_| { | 1462 | let users_state = critical_section::with(|_| { |
| @@ -1429,7 +1465,7 @@ fn on_pio_drop<PIO: Instance>() { | |||
| 1429 | val | 1465 | val |
| 1430 | }); | 1466 | }); |
| 1431 | if users_state == 1 { | 1467 | if users_state == 1 { |
| 1432 | let used_pins = critical_section::with(|_| state.used_pins.get()); | 1468 | let used_pins = state.used_pins.load(Ordering::Relaxed); |
| 1433 | let null = pac::io::vals::Gpio0ctrlFuncsel::NULL as _; | 1469 | let null = pac::io::vals::Gpio0ctrlFuncsel::NULL as _; |
| 1434 | for i in 0..crate::gpio::BANK0_PIN_COUNT { | 1470 | for i in 0..crate::gpio::BANK0_PIN_COUNT { |
| 1435 | if used_pins & (1 << i) != 0 { | 1471 | if used_pins & (1 << i) != 0 { |
| @@ -1454,7 +1490,7 @@ trait SealedInstance { | |||
| 1454 | fn state() -> &'static State { | 1490 | fn state() -> &'static State { |
| 1455 | static STATE: State = State { | 1491 | static STATE: State = State { |
| 1456 | users: AtomicU8::new(0), | 1492 | users: AtomicU8::new(0), |
| 1457 | used_pins: Cell::new(0), | 1493 | used_pins: AtomicU64::new(0), |
| 1458 | }; | 1494 | }; |
| 1459 | 1495 | ||
| 1460 | &STATE | 1496 | &STATE |
