diff options
| author | James Munns <[email protected]> | 2025-12-09 15:58:34 +0100 |
|---|---|---|
| committer | James Munns <[email protected]> | 2025-12-09 15:58:34 +0100 |
| commit | af768af11cf10e0376b34c0e5abfc4f0a56398fc (patch) | |
| tree | b27621c69cf5b1f0a55b9bdd9f7254b81e066164 /embassy-mcxa/src | |
| parent | e962f5568a9f6433dcd6ad3e41d3faabb8b7c552 (diff) | |
Make init private (suggestion from @felipebalbi)
Diffstat (limited to 'embassy-mcxa/src')
| -rw-r--r-- | embassy-mcxa/src/dma.rs | 61 |
1 files changed, 22 insertions, 39 deletions
diff --git a/embassy-mcxa/src/dma.rs b/embassy-mcxa/src/dma.rs index 1f604a340..7996a45bc 100644 --- a/embassy-mcxa/src/dma.rs +++ b/embassy-mcxa/src/dma.rs | |||
| @@ -104,7 +104,7 @@ use core::future::Future; | |||
| 104 | use core::marker::PhantomData; | 104 | use core::marker::PhantomData; |
| 105 | use core::pin::Pin; | 105 | use core::pin::Pin; |
| 106 | use core::ptr::NonNull; | 106 | use core::ptr::NonNull; |
| 107 | use core::sync::atomic::{fence, AtomicBool, AtomicUsize, Ordering}; | 107 | use core::sync::atomic::{fence, AtomicUsize, Ordering}; |
| 108 | use core::task::{Context, Poll}; | 108 | use core::task::{Context, Poll}; |
| 109 | 109 | ||
| 110 | use embassy_hal_internal::PeripheralType; | 110 | use embassy_hal_internal::PeripheralType; |
| @@ -115,49 +115,32 @@ use crate::pac; | |||
| 115 | use crate::pac::Interrupt; | 115 | use crate::pac::Interrupt; |
| 116 | use crate::peripherals::DMA0; | 116 | use crate::peripherals::DMA0; |
| 117 | 117 | ||
| 118 | /// Static flag to track whether DMA has been initialized. | ||
| 119 | static DMA_INITIALIZED: AtomicBool = AtomicBool::new(false); | ||
| 120 | |||
| 121 | /// Initialize DMA controller (clock enabled, reset released, controller configured). | 118 | /// Initialize DMA controller (clock enabled, reset released, controller configured). |
| 122 | /// | 119 | /// |
| 123 | /// This function is intended to be called during HAL initialization (`hal::init()`). | 120 | /// This function is intended to be called ONCE during HAL initialization (`hal::init()`). |
| 124 | /// It is idempotent - it will only initialize DMA once, even if called multiple times. | ||
| 125 | /// | 121 | /// |
| 126 | /// The function enables the DMA0 clock, releases reset, and configures the controller | 122 | /// The function enables the DMA0 clock, releases reset, and configures the controller |
| 127 | /// for normal operation with round-robin arbitration. | 123 | /// for normal operation with round-robin arbitration. |
| 128 | pub fn init() { | 124 | pub(crate) fn init() { |
| 129 | // Fast path: already initialized | 125 | unsafe { |
| 130 | if DMA_INITIALIZED.load(Ordering::Acquire) { | 126 | // Enable DMA0 clock and release reset |
| 131 | return; | 127 | DMA0::enable_clock(); |
| 132 | } | 128 | DMA0::release_reset(); |
| 133 | 129 | ||
| 134 | // Slow path: initialize DMA | 130 | // Configure DMA controller |
| 135 | // Use compare_exchange to ensure only one caller initializes | 131 | let dma = &(*pac::Dma0::ptr()); |
| 136 | if DMA_INITIALIZED | 132 | dma.mp_csr().modify(|_, w| { |
| 137 | .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire) | 133 | w.edbg() |
| 138 | .is_ok() | 134 | .enable() |
| 139 | { | 135 | .erca() |
| 140 | // We won the race - initialize DMA | 136 | .enable() |
| 141 | unsafe { | 137 | .halt() |
| 142 | // Enable DMA0 clock and release reset | 138 | .normal_operation() |
| 143 | DMA0::enable_clock(); | 139 | .gclc() |
| 144 | DMA0::release_reset(); | 140 | .available() |
| 145 | 141 | .gmrc() | |
| 146 | // Configure DMA controller | 142 | .available() |
| 147 | let dma = &(*pac::Dma0::ptr()); | 143 | }); |
| 148 | dma.mp_csr().modify(|_, w| { | ||
| 149 | w.edbg() | ||
| 150 | .enable() | ||
| 151 | .erca() | ||
| 152 | .enable() | ||
| 153 | .halt() | ||
| 154 | .normal_operation() | ||
| 155 | .gclc() | ||
| 156 | .available() | ||
| 157 | .gmrc() | ||
| 158 | .available() | ||
| 159 | }); | ||
| 160 | } | ||
| 161 | } | 144 | } |
| 162 | } | 145 | } |
| 163 | 146 | ||
