aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/dma
diff options
context:
space:
mode:
authorAlexandros Liarokapis <[email protected]>2024-09-23 02:01:44 +0300
committerAlexandros Liarokapis <[email protected]>2024-10-15 12:29:12 +0300
commitf4ec0cb4d4d16bd4e1c242864c5ca828745704c0 (patch)
tree32bb4f73cb56afe77ee0a163276d65cfa7dfeb58 /embassy-stm32/src/dma
parent2b10caafd488987b6cf9a2cd69820c81d0a0826e (diff)
simplify and rename ringbuffer methods, make len available
Diffstat (limited to 'embassy-stm32/src/dma')
-rw-r--r--embassy-stm32/src/dma/ringbuffer/mod.rs92
1 files changed, 43 insertions, 49 deletions
diff --git a/embassy-stm32/src/dma/ringbuffer/mod.rs b/embassy-stm32/src/dma/ringbuffer/mod.rs
index 10a9ff975..d4d119a69 100644
--- a/embassy-stm32/src/dma/ringbuffer/mod.rs
+++ b/embassy-stm32/src/dma/ringbuffer/mod.rs
@@ -27,10 +27,6 @@ struct DmaIndex {
27 pos: usize, 27 pos: usize,
28} 28}
29 29
30fn pos(cap: usize, dma: &impl DmaCtrl) -> usize {
31 cap - dma.get_remaining_transfers()
32}
33
34impl DmaIndex { 30impl DmaIndex {
35 fn reset(&mut self) { 31 fn reset(&mut self) {
36 self.pos = 0; 32 self.pos = 0;
@@ -42,9 +38,9 @@ impl DmaIndex {
42 } 38 }
43 39
44 fn dma_sync(&mut self, cap: usize, dma: &mut impl DmaCtrl) { 40 fn dma_sync(&mut self, cap: usize, dma: &mut impl DmaCtrl) {
45 let fst_pos = pos(cap, dma); 41 let fst_pos = cap - dma.get_remaining_transfers();
46 let fst_count = dma.reset_complete_count(); 42 let fst_count = dma.reset_complete_count();
47 let pos = pos(cap, dma); 43 let pos = cap - dma.get_remaining_transfers();
48 44
49 let wrap_count = if pos >= fst_pos { 45 let wrap_count = if pos >= fst_pos {
50 fst_count 46 fst_count
@@ -68,8 +64,7 @@ impl DmaIndex {
68 rhs.completion_count -= min_count; 64 rhs.completion_count -= min_count;
69 } 65 }
70 66
71 fn diff(&mut self, cap: usize, rhs: &mut DmaIndex) -> isize { 67 fn diff(&self, cap: usize, rhs: &DmaIndex) -> isize {
72 Self::normalize(self, rhs);
73 (self.completion_count * cap + self.pos) as isize - (rhs.completion_count * cap + rhs.pos) as isize 68 (self.completion_count * cap + self.pos) as isize - (rhs.completion_count * cap + rhs.pos) as isize
74 } 69 }
75} 70}
@@ -94,26 +89,39 @@ impl<'a, W: Word> ReadableDmaRingBuffer<'a, W> {
94 pub fn clear(&mut self, dma: &mut impl DmaCtrl) { 89 pub fn clear(&mut self, dma: &mut impl DmaCtrl) {
95 dma.reset_complete_count(); 90 dma.reset_complete_count();
96 self.write_index.reset(); 91 self.write_index.reset();
97 self.update_dma_index(dma); 92 self.write_index.dma_sync(self.cap(), dma);
98 self.read_index = self.write_index; 93 self.read_index = self.write_index;
99 } 94 }
100 95
101 /// The capacity of the ringbuffer 96 /// Get the full ringbuffer capacity.
102 pub const fn cap(&self) -> usize { 97 pub const fn cap(&self) -> usize {
103 self.dma_buf.len() 98 self.dma_buf.len()
104 } 99 }
105 100
101 /// Get the available readable dma samples.
102 pub fn len(&self) -> Result<usize, OverrunError> {
103 let diff: usize = self.write_index.diff(self.cap(), &self.read_index).try_into().unwrap();
104
105 if diff > self.cap() {
106 Err(OverrunError)
107 } else {
108 Ok(diff)
109 }
110 }
111
106 /// Read elements from the ring buffer 112 /// Read elements from the ring buffer
107 /// Return a tuple of the length read and the length remaining in the buffer 113 /// Return a tuple of the length read and the length remaining in the buffer
108 /// If not all of the elements were read, then there will be some elements in the buffer remaining 114 /// If not all of the elements were read, then there will be some elements in the buffer remaining
109 /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read 115 /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
110 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. 116 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
111 pub fn read(&mut self, dma: &mut impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { 117 pub fn read(&mut self, dma: &mut impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
112 let readable = self.margin(dma)?.min(buf.len()); 118 self.sync_write_index(dma);
119 let readable = self.len()?.min(buf.len());
113 for i in 0..readable { 120 for i in 0..readable {
114 buf[i] = self.read_buf(i); 121 buf[i] = self.read_buf(i);
115 } 122 }
116 let available = self.margin(dma)?; 123 self.sync_write_index(dma);
124 let available = self.len()?;
117 self.read_index.advance(self.cap(), readable); 125 self.read_index.advance(self.cap(), readable);
118 Ok((readable, available - readable)) 126 Ok((readable, available - readable))
119 } 127 }
@@ -151,10 +159,6 @@ impl<'a, W: Word> ReadableDmaRingBuffer<'a, W> {
151 .await 159 .await
152 } 160 }
153 161
154 fn update_dma_index(&mut self, dma: &mut impl DmaCtrl) {
155 self.write_index.dma_sync(self.cap(), dma)
156 }
157
158 fn read_buf(&self, offset: usize) -> W { 162 fn read_buf(&self, offset: usize) -> W {
159 unsafe { 163 unsafe {
160 core::ptr::read_volatile( 164 core::ptr::read_volatile(
@@ -165,21 +169,9 @@ impl<'a, W: Word> ReadableDmaRingBuffer<'a, W> {
165 } 169 }
166 } 170 }
167 171
168 /// Returns available dma samples 172 fn sync_write_index(&mut self, dma: &mut impl DmaCtrl) {
169 fn margin(&mut self, dma: &mut impl DmaCtrl) -> Result<usize, OverrunError> { 173 self.write_index.dma_sync(self.cap(), dma);
170 self.update_dma_index(dma); 174 DmaIndex::normalize(&mut self.write_index, &mut self.read_index);
171
172 let diff: usize = self
173 .write_index
174 .diff(self.cap(), &mut self.read_index)
175 .try_into()
176 .unwrap();
177
178 if diff > self.cap() {
179 Err(OverrunError)
180 } else {
181 Ok(diff)
182 }
183 } 175 }
184} 176}
185 177
@@ -207,12 +199,23 @@ impl<'a, W: Word> WritableDmaRingBuffer<'a, W> {
207 pub fn clear(&mut self, dma: &mut impl DmaCtrl) { 199 pub fn clear(&mut self, dma: &mut impl DmaCtrl) {
208 dma.reset_complete_count(); 200 dma.reset_complete_count();
209 self.read_index.reset(); 201 self.read_index.reset();
210 self.update_dma_index(dma); 202 self.read_index.dma_sync(self.cap(), dma);
211 self.write_index = self.read_index; 203 self.write_index = self.read_index;
212 self.write_index.advance(self.cap(), self.cap()); 204 self.write_index.advance(self.cap(), self.cap());
213 } 205 }
214 206
215 /// Get the capacity of the ringbuffer. 207 /// Get the remaining writable dma samples.
208 pub fn len(&self) -> Result<usize, OverrunError> {
209 let diff = self.write_index.diff(self.cap(), &self.read_index);
210
211 if diff < 0 {
212 Err(OverrunError)
213 } else {
214 Ok(self.cap().saturating_sub(diff as usize))
215 }
216 }
217
218 /// Get the full ringbuffer capacity.
216 pub const fn cap(&self) -> usize { 219 pub const fn cap(&self) -> usize {
217 self.dma_buf.len() 220 self.dma_buf.len()
218 } 221 }
@@ -220,11 +223,13 @@ impl<'a, W: Word> WritableDmaRingBuffer<'a, W> {
220 /// Append data to the ring buffer. 223 /// Append data to the ring buffer.
221 /// Returns a tuple of the data written and the remaining write capacity in the buffer. 224 /// Returns a tuple of the data written and the remaining write capacity in the buffer.
222 pub fn write(&mut self, dma: &mut impl DmaCtrl, buf: &[W]) -> Result<(usize, usize), OverrunError> { 225 pub fn write(&mut self, dma: &mut impl DmaCtrl, buf: &[W]) -> Result<(usize, usize), OverrunError> {
223 let writable = self.margin(dma)?.min(buf.len()); 226 self.sync_read_index(dma);
227 let writable = self.len()?.min(buf.len());
224 for i in 0..writable { 228 for i in 0..writable {
225 self.write_buf(i, buf[i]); 229 self.write_buf(i, buf[i]);
226 } 230 }
227 let available = self.margin(dma)?; 231 self.sync_read_index(dma);
232 let available = self.len()?;
228 self.write_index.advance(self.cap(), writable); 233 self.write_index.advance(self.cap(), writable);
229 Ok((writable, available - writable)) 234 Ok((writable, available - writable))
230 } 235 }
@@ -261,10 +266,6 @@ impl<'a, W: Word> WritableDmaRingBuffer<'a, W> {
261 .await 266 .await
262 } 267 }
263 268
264 fn update_dma_index(&mut self, dma: &mut impl DmaCtrl) {
265 self.read_index.dma_sync(self.cap(), dma);
266 }
267
268 fn write_buf(&mut self, offset: usize, value: W) { 269 fn write_buf(&mut self, offset: usize, value: W) {
269 unsafe { 270 unsafe {
270 core::ptr::write_volatile( 271 core::ptr::write_volatile(
@@ -276,16 +277,9 @@ impl<'a, W: Word> WritableDmaRingBuffer<'a, W> {
276 } 277 }
277 } 278 }
278 279
279 fn margin(&mut self, dma: &mut impl DmaCtrl) -> Result<usize, OverrunError> { 280 fn sync_read_index(&mut self, dma: &mut impl DmaCtrl) {
280 self.update_dma_index(dma); 281 self.read_index.dma_sync(self.cap(), dma);
281 282 DmaIndex::normalize(&mut self.read_index, &mut self.write_index);
282 let diff = self.write_index.diff(self.cap(), &mut self.read_index);
283
284 if diff < 0 {
285 Err(OverrunError)
286 } else {
287 Ok(self.cap().saturating_sub(diff as usize))
288 }
289 } 283 }
290} 284}
291 285