aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-12-08 03:30:07 +0100
committerDario Nieuwenhuis <[email protected]>2021-12-08 03:30:07 +0100
commit022c4cb7397e690080edc06e2b7d4dc8e19ccb0b (patch)
tree98ae67910c9565478883f044446625f95c8302ed
parentb316d2620c73f7e2a5cd3c46dbc20c24b7a1c57f (diff)
stm32/dma: simplify impls a bit.
-rw-r--r--embassy-stm32/src/dma/bdma.rs19
-rw-r--r--embassy-stm32/src/dma/dma.rs56
2 files changed, 36 insertions, 39 deletions
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index 29c9fd592..b4c77757e 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -59,7 +59,7 @@ unsafe fn on_irq() {
59 let isr = pac::$dma.isr().read(); 59 let isr = pac::$dma.isr().read();
60 let dman = dma_num!($dma); 60 let dman = dma_num!($dma);
61 61
62 for chn in 0..crate::pac::dma_channels_count!($dma) { 62 for chn in 0..pac::dma_channels_count!($dma) {
63 let cr = pac::$dma.ch(chn).cr(); 63 let cr = pac::$dma.ch(chn).cr();
64 if isr.tcif(chn) && cr.read().tcie() { 64 if isr.tcif(chn) && cr.read().tcie() {
65 cr.write(|_| ()); // Disable channel interrupts with the default value. 65 cr.write(|_| ()); // Disable channel interrupts with the default value.
@@ -90,9 +90,8 @@ pac::dma_channels! {
90 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { 90 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
91 91
92 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) { 92 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
93 low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
94 low_level_api::start_transfer( 93 low_level_api::start_transfer(
95 crate::pac::$dma_peri, 94 pac::$dma_peri,
96 $channel_num, 95 $channel_num,
97 #[cfg(any(bdma_v2, dmamux))] 96 #[cfg(any(bdma_v2, dmamux))]
98 request, 97 request,
@@ -112,9 +111,8 @@ pac::dma_channels! {
112 111
113 unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) { 112 unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
114 let buf = [repeated]; 113 let buf = [repeated];
115 low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
116 low_level_api::start_transfer( 114 low_level_api::start_transfer(
117 crate::pac::$dma_peri, 115 pac::$dma_peri,
118 $channel_num, 116 $channel_num,
119 #[cfg(any(bdma_v2, dmamux))] 117 #[cfg(any(bdma_v2, dmamux))]
120 request, 118 request,
@@ -132,9 +130,8 @@ pac::dma_channels! {
132 } 130 }
133 131
134 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) { 132 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
135 low_level_api::reset_status(crate::pac::$dma_peri, $channel_num);
136 low_level_api::start_transfer( 133 low_level_api::start_transfer(
137 crate::pac::$dma_peri, 134 pac::$dma_peri,
138 $channel_num, 135 $channel_num,
139 #[cfg(any(bdma_v2, dmamux))] 136 #[cfg(any(bdma_v2, dmamux))]
140 request, 137 request,
@@ -152,14 +149,14 @@ pac::dma_channels! {
152 } 149 }
153 150
154 fn request_stop(&mut self){ 151 fn request_stop(&mut self){
155 unsafe {low_level_api::request_stop(crate::pac::$dma_peri, $channel_num);} 152 unsafe {low_level_api::request_stop(pac::$dma_peri, $channel_num);}
156 } 153 }
157 154
158 fn is_running(&self) -> bool { 155 fn is_running(&self) -> bool {
159 unsafe {low_level_api::is_running(crate::pac::$dma_peri, $channel_num)} 156 unsafe {low_level_api::is_running(pac::$dma_peri, $channel_num)}
160 } 157 }
161 fn remaining_transfers(&mut self) -> u16 { 158 fn remaining_transfers(&mut self) -> u16 {
162 unsafe {low_level_api::get_remaining_transfers(crate::pac::$dma_peri, $channel_num)} 159 unsafe {low_level_api::get_remaining_transfers(pac::$dma_peri, $channel_num)}
163 } 160 }
164 161
165 fn set_waker(&mut self, waker: &Waker) { 162 fn set_waker(&mut self, waker: &Waker) {
@@ -198,6 +195,8 @@ mod low_level_api {
198 ) { 195 ) {
199 let ch = dma.ch(channel_number as _); 196 let ch = dma.ch(channel_number as _);
200 197
198 reset_status(dma, channel_number);
199
201 #[cfg(dmamux)] 200 #[cfg(dmamux)]
202 super::super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request); 201 super::super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request);
203 202
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index 05d62ef8f..efe4d1d9d 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -85,17 +85,15 @@ pac::dma_channels! {
85 ($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => { 85 ($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
86 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { 86 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
87 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) { 87 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) {
88 let isrn = $channel_num as usize / 4;
89 let isrbit = $channel_num as usize % 4;
90 low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
91 low_level_api::start_transfer( 88 low_level_api::start_transfer(
89 pac::$dma_peri,
90 $channel_num,
92 request, 91 request,
93 vals::Dir::MEMORYTOPERIPHERAL, 92 vals::Dir::MEMORYTOPERIPHERAL,
94 reg_addr as *const u32, 93 reg_addr as *const u32,
95 buf.as_ptr() as *mut u32, 94 buf.as_ptr() as *mut u32,
96 buf.len(), 95 buf.len(),
97 true, 96 true,
98 crate::pac::$dma_peri.st($channel_num as _),
99 vals::Size::from(W::bits()), 97 vals::Size::from(W::bits()),
100 #[cfg(dmamux)] 98 #[cfg(dmamux)]
101 <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, 99 <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
@@ -106,17 +104,15 @@ pac::dma_channels! {
106 104
107 unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) { 105 unsafe fn start_write_repeated<W: Word>(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W) {
108 let buf = [repeated]; 106 let buf = [repeated];
109 let isrn = $channel_num as usize / 4;
110 let isrbit = $channel_num as usize % 4;
111 low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
112 low_level_api::start_transfer( 107 low_level_api::start_transfer(
108 pac::$dma_peri,
109 $channel_num,
113 request, 110 request,
114 vals::Dir::MEMORYTOPERIPHERAL, 111 vals::Dir::MEMORYTOPERIPHERAL,
115 reg_addr as *const u32, 112 reg_addr as *const u32,
116 buf.as_ptr() as *mut u32, 113 buf.as_ptr() as *mut u32,
117 count, 114 count,
118 false, 115 false,
119 crate::pac::$dma_peri.st($channel_num as _),
120 vals::Size::from(W::bits()), 116 vals::Size::from(W::bits()),
121 #[cfg(dmamux)] 117 #[cfg(dmamux)]
122 <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, 118 <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
@@ -126,17 +122,15 @@ pac::dma_channels! {
126 } 122 }
127 123
128 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) { 124 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) {
129 let isrn = $channel_num as usize / 4;
130 let isrbit = $channel_num as usize % 4;
131 low_level_api::reset_status(&crate::pac::$dma_peri, isrn, isrbit);
132 low_level_api::start_transfer( 125 low_level_api::start_transfer(
126 pac::$dma_peri,
127 $channel_num,
133 request, 128 request,
134 vals::Dir::PERIPHERALTOMEMORY, 129 vals::Dir::PERIPHERALTOMEMORY,
135 reg_addr as *const u32, 130 reg_addr as *const u32,
136 buf.as_ptr() as *mut u32, 131 buf.as_ptr() as *mut u32,
137 buf.len(), 132 buf.len(),
138 true, 133 true,
139 crate::pac::$dma_peri.st($channel_num as _),
140 vals::Size::from(W::bits()), 134 vals::Size::from(W::bits()),
141 #[cfg(dmamux)] 135 #[cfg(dmamux)]
142 <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, 136 <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS,
@@ -146,15 +140,15 @@ pac::dma_channels! {
146 } 140 }
147 141
148 fn request_stop(&mut self) { 142 fn request_stop(&mut self) {
149 unsafe {low_level_api::request_stop(&crate::pac::$dma_peri, $channel_num);} 143 unsafe {low_level_api::request_stop(pac::$dma_peri, $channel_num);}
150 } 144 }
151 145
152 fn is_running(&self) -> bool { 146 fn is_running(&self) -> bool {
153 unsafe {low_level_api::is_running(&crate::pac::$dma_peri, $channel_num)} 147 unsafe {low_level_api::is_running(pac::$dma_peri, $channel_num)}
154 } 148 }
155 149
156 fn remaining_transfers(&mut self) -> u16 { 150 fn remaining_transfers(&mut self) -> u16 {
157 unsafe {low_level_api::get_remaining_transfers(&crate::pac::$dma_peri, $channel_num)} 151 unsafe {low_level_api::get_remaining_transfers(pac::$dma_peri, $channel_num)}
158 } 152 }
159 153
160 fn set_waker(&mut self, waker: &Waker) { 154 fn set_waker(&mut self, waker: &Waker) {
@@ -179,13 +173,14 @@ mod low_level_api {
179 use super::*; 173 use super::*;
180 174
181 pub unsafe fn start_transfer( 175 pub unsafe fn start_transfer(
176 dma: pac::dma::Dma,
177 channel_number: u8,
182 request: Request, 178 request: Request,
183 dir: vals::Dir, 179 dir: vals::Dir,
184 peri_addr: *const u32, 180 peri_addr: *const u32,
185 mem_addr: *mut u32, 181 mem_addr: *mut u32,
186 mem_len: usize, 182 mem_len: usize,
187 incr_mem: bool, 183 incr_mem: bool,
188 ch: crate::pac::dma::St,
189 data_size: vals::Size, 184 data_size: vals::Size,
190 #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, 185 #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
191 #[cfg(dmamux)] dmamux_ch_num: u8, 186 #[cfg(dmamux)] dmamux_ch_num: u8,
@@ -196,6 +191,9 @@ mod low_level_api {
196 // "Preceding reads and writes cannot be moved past subsequent writes." 191 // "Preceding reads and writes cannot be moved past subsequent writes."
197 fence(Ordering::SeqCst); 192 fence(Ordering::SeqCst);
198 193
194 reset_status(dma, channel_number);
195
196 let ch = dma.st(channel_number as _);
199 ch.par().write_value(peri_addr as u32); 197 ch.par().write_value(peri_addr as u32);
200 ch.m0ar().write_value(mem_addr as u32); 198 ch.m0ar().write_value(mem_addr as u32);
201 ch.ndtr().write_value(regs::Ndtr(mem_len as _)); 199 ch.ndtr().write_value(regs::Ndtr(mem_len as _));
@@ -223,34 +221,31 @@ mod low_level_api {
223 } 221 }
224 222
225 /// Stops the DMA channel. 223 /// Stops the DMA channel.
226 pub unsafe fn request_stop(dma: &pac::dma::Dma, channel_number: u8) { 224 pub unsafe fn request_stop(dma: pac::dma::Dma, channel_number: u8) {
227 // Reset status
228 let isrn = channel_number as usize / 4;
229 let isrbit = channel_number as usize % 4;
230 reset_status(dma, isrn, isrbit);
231
232 // get a handle on the channel itself 225 // get a handle on the channel itself
233 let ch = dma.st(channel_number as _); 226 let ch = dma.st(channel_number as _);
234 227
235 // Disable the channel and interrupts with the default value. 228 // Disable the channel. Keep the IEs enabled so the irqs still fire.
236 ch.cr().write(|_| ()); 229 ch.cr().write(|w| {
230 w.set_teie(true);
231 w.set_tcie(true);
232 });
237 233
238 // "Subsequent reads and writes cannot be moved ahead of preceding reads." 234 // "Subsequent reads and writes cannot be moved ahead of preceding reads."
239 fence(Ordering::SeqCst); 235 fence(Ordering::SeqCst);
240 } 236 }
241 237
242 /// Gets the running status of the channel 238 /// Gets the running status of the channel
243 pub unsafe fn is_running(dma: &pac::dma::Dma, ch: u8) -> bool { 239 pub unsafe fn is_running(dma: pac::dma::Dma, ch: u8) -> bool {
244 // get a handle on the channel itself 240 // get a handle on the channel itself
245 let ch = dma.st(ch as _); 241 let ch = dma.st(ch as _);
246 242 // Get whether it's enabled (running)
247 // Wait for the transfer to complete when it was ongoing.
248 ch.cr().read().en() 243 ch.cr().read().en()
249 } 244 }
250 245
251 /// Gets the total remaining transfers for the channel 246 /// Gets the total remaining transfers for the channel
252 /// Note: this will be zero for transfers that completed without cancellation. 247 /// Note: this will be zero for transfers that completed without cancellation.
253 pub unsafe fn get_remaining_transfers(dma: &pac::dma::Dma, ch: u8) -> u16 { 248 pub unsafe fn get_remaining_transfers(dma: pac::dma::Dma, ch: u8) -> u16 {
254 // get a handle on the channel itself 249 // get a handle on the channel itself
255 let ch = dma.st(ch as _); 250 let ch = dma.st(ch as _);
256 // read the remaining transfer count. If this is zero, the transfer completed fully. 251 // read the remaining transfer count. If this is zero, the transfer completed fully.
@@ -262,7 +257,10 @@ mod low_level_api {
262 STATE.ch_wakers[state_number].register(waker); 257 STATE.ch_wakers[state_number].register(waker);
263 } 258 }
264 259
265 pub unsafe fn reset_status(dma: &crate::pac::dma::Dma, isrn: usize, isrbit: usize) { 260 pub unsafe fn reset_status(dma: pac::dma::Dma, channel_number: u8) {
261 let isrn = channel_number as usize / 4;
262 let isrbit = channel_number as usize % 4;
263
266 dma.ifcr(isrn).write(|w| { 264 dma.ifcr(isrn).write(|w| {
267 w.set_tcif(isrbit, true); 265 w.set_tcif(isrbit, true);
268 w.set_teif(isrbit, true); 266 w.set_teif(isrbit, true);