aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2020-12-29 12:33:50 -0600
committerxoviat <[email protected]>2020-12-29 12:33:50 -0600
commit74b5d4693c91c23d0c2b75f213323ba1fc4d8bce (patch)
tree4ffa1fb2589d2943ac4888e71727d193fc2e92cb
parent04944b6379814560a1d3732ed76b56751023f055 (diff)
implement prelim draft
-rw-r--r--embassy-stm32f4/Cargo.toml2
-rw-r--r--embassy-stm32f4/src/lib.rs1
-rw-r--r--embassy-stm32f4/src/uarte.rs200
3 files changed, 49 insertions, 154 deletions
diff --git a/embassy-stm32f4/Cargo.toml b/embassy-stm32f4/Cargo.toml
index 654ea69a6..1891a5596 100644
--- a/embassy-stm32f4/Cargo.toml
+++ b/embassy-stm32f4/Cargo.toml
@@ -40,4 +40,4 @@ cortex-m-rt = "0.6.13"
40cortex-m = { version = "0.6.4" } 40cortex-m = { version = "0.6.4" }
41embedded-hal = { version = "0.2.4" } 41embedded-hal = { version = "0.2.4" }
42embedded-dma = { version = "0.1.2" } 42embedded-dma = { version = "0.1.2" }
43stm32f4xx-hal = { version = "0.8.3", features = ["rt"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git" } 43stm32f4xx-hal = { version = "0.8.3", features = ["rt"], git = "https://github.com/xoviat/stm32f4xx-hal.git", branch = "dma-is-done"}
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs
index 40386085a..e6d523d21 100644
--- a/embassy-stm32f4/src/lib.rs
+++ b/embassy-stm32f4/src/lib.rs
@@ -2,6 +2,7 @@
2#![feature(generic_associated_types)] 2#![feature(generic_associated_types)]
3#![feature(asm)] 3#![feature(asm)]
4#![feature(type_alias_impl_trait)] 4#![feature(type_alias_impl_trait)]
5#![feature(let_chains)]
5 6
6#[cfg(not(any( 7#[cfg(not(any(
7 feature = "stm32f401", 8 feature = "stm32f401",
diff --git a/embassy-stm32f4/src/uarte.rs b/embassy-stm32f4/src/uarte.rs
index 9e253dd9f..273c384cb 100644
--- a/embassy-stm32f4/src/uarte.rs
+++ b/embassy-stm32f4/src/uarte.rs
@@ -16,11 +16,14 @@ use core::task::{Context, Poll};
16use cortex_m::singleton; 16use cortex_m::singleton;
17 17
18use embassy::util::Signal; 18use embassy::util::Signal;
19use embedded_dma::{StaticReadBuffer, StaticWriteBuffer}; 19use embedded_dma::{StaticReadBuffer, StaticWriteBuffer, WriteBuffer};
20 20
21use crate::fmt::assert; 21use crate::fmt::assert;
22use crate::hal::dma::config::DmaConfig; 22use crate::hal::dma::config::DmaConfig;
23use crate::hal::dma::{Channel4, PeripheralToMemory, Stream2, StreamsTuple, Transfer}; 23use crate::hal::dma::{
24 Channel4, Channel7, MemoryToPeripheral, PeripheralToMemory, Stream2, Stream7, StreamsTuple,
25 Transfer,
26};
24use crate::hal::gpio::gpioa::{PA10, PA9}; 27use crate::hal::gpio::gpioa::{PA10, PA9};
25use crate::hal::gpio::{Alternate, AF10, AF7, AF9}; 28use crate::hal::gpio::{Alternate, AF10, AF7, AF9};
26use crate::hal::gpio::{Floating, Input, Output, PushPull}; 29use crate::hal::gpio::{Floating, Input, Output, PushPull};
@@ -94,45 +97,15 @@ impl Uarte {
94 ) 97 )
95 .unwrap(); 98 .unwrap();
96 99
97 let isr = pins.dma.hisr;0 100 // let is_set = dma.hifcr.read().tcif7.bit_is_set();
98 101
99 Uarte { instance: serial, dma: pins.dma, usart: pins.usart } 102 Uarte {
103 instance: serial,
104 dma: pins.dma,
105 usart: pins.usart,
106 }
100 } 107 }
101 108
102 /// Sets the baudrate, parity and assigns the pins to the UARTE peripheral.
103 // TODO: Make it take the same `Pins` structs nrf-hal (with optional RTS/CTS).
104 // // TODO: #[cfg()] for smaller device variants without port register (nrf52810, ...).
105 // pub fn configure(
106 // &mut self,
107 // rxd: &Pin<Input<Floating>>,
108 // txd: &mut Pin<Output<PushPull>>,
109 // parity: Parity,
110 // baudrate: Baudrate,
111 // ) {
112 // let uarte = &self.instance;
113 // assert!(uarte.enable.read().enable().is_disabled());
114 //
115 // uarte.psel.rxd.write(|w| {
116 // let w = unsafe { w.pin().bits(rxd.pin()) };
117 // let w = w.port().bit(rxd.port().bit());
118 // w.connect().connected()
119 // });
120 //
121 // txd.set_high().unwrap();
122 // uarte.psel.txd.write(|w| {
123 // let w = unsafe { w.pin().bits(txd.pin()) };
124 // let w = w.port().bit(txd.port().bit());
125 // w.connect().connected()
126 // });
127 //
128 // uarte.baudrate.write(|w| w.baudrate().variant(baudrate));
129 // uarte.config.write(|w| w.parity().variant(parity));
130 // }
131
132 // fn enable(&mut self) {
133 // self.instance.enable.write(|w| w.enable().enabled());
134 // }
135
136 /// Sends serial data. 109 /// Sends serial data.
137 /// 110 ///
138 /// `tx_buffer` is marked as static as per `embedded-dma` requirements. 111 /// `tx_buffer` is marked as static as per `embedded-dma` requirements.
@@ -140,25 +113,15 @@ impl Uarte {
140 /// reused until the future has finished. 113 /// reused until the future has finished.
141 pub fn send<'a, B>(&'a mut self, tx_buffer: B) -> SendFuture<'a, B> 114 pub fn send<'a, B>(&'a mut self, tx_buffer: B) -> SendFuture<'a, B>
142 where 115 where
143 B: StaticReadBuffer<Word = u8>, 116 B: WriteBuffer<Word = u8> + 'static,
144 { 117 {
145 // Panic if TX is running which can happen if the user has called
146 // `mem::forget()` on a previous future after polling it once.
147 assert!(!self.tx_started());
148
149 self.enable();
150
151 SendFuture { 118 SendFuture {
152 uarte: self, 119 uarte: self,
153 buf: tx_buffer, 120 buf: tx_buffer,
121 transfer: None,
154 } 122 }
155 } 123 }
156 124
157 fn tx_started(&self) -> bool {
158 // self.instance.events_txstarted.read().bits() != 0
159 false
160 }
161
162 /// Receives serial data. 125 /// Receives serial data.
163 /// 126 ///
164 /// The future is pending until the buffer is completely filled. 127 /// The future is pending until the buffer is completely filled.
@@ -171,83 +134,45 @@ impl Uarte {
171 /// reused until the future has finished. 134 /// reused until the future has finished.
172 pub fn receive<'a, B>(&'a mut self, rx_buffer: B) -> ReceiveFuture<'a, B> 135 pub fn receive<'a, B>(&'a mut self, rx_buffer: B) -> ReceiveFuture<'a, B>
173 where 136 where
174 B: StaticWriteBuffer<Word = u8>, 137 B: WriteBuffer<Word = u8> + 'static,
175 { 138 {
176 // Panic if RX is running which can happen if the user has called
177 // `mem::forget()` on a previous future after polling it once.
178 assert!(!self.rx_started());
179
180 self.enable();
181
182 ReceiveFuture { 139 ReceiveFuture {
183 uarte: self, 140 uarte: self,
184 buf: Some(rx_buffer), 141 buf: rx_buffer,
142 transfer: None,
185 } 143 }
186 } 144 }
187
188 fn rx_started(&self) -> bool {
189 self.instance.events_rxstarted.read().bits() != 0
190 }
191} 145}
192 146
193/// Future for the [`LowPowerUarte::send()`] method. 147/// Future for the [`LowPowerUarte::send()`] method.
194pub struct SendFuture<'a, B> { 148pub struct SendFuture<'a, B: WriteBuffer<Word = u8> + 'static> {
195 uarte: &'a Uarte, 149 uarte: &'a Uarte,
150 transfer: Option<&'a Transfer<Stream7<DMA2>, Channel4, USART1, MemoryToPeripheral, B>>,
196 buf: B, 151 buf: B,
197} 152}
198 153
199impl<'a, B> Drop for SendFuture<'a, B> { 154impl<'a, B> Drop for SendFuture<'a, B>
155where
156 B: WriteBuffer<Word = u8> + 'static,
157{
200 fn drop(self: &mut Self) { 158 fn drop(self: &mut Self) {
201 if self.uarte.tx_started() { 159 drop(self.transfer);
202 trace!("stoptx");
203
204 // Stop the transmitter to minimize the current consumption.
205 self.uarte
206 .instance
207 .tasks_stoptx
208 .write(|w| unsafe { w.bits(1) });
209 self.uarte.instance.events_txstarted.reset();
210 }
211 } 160 }
212} 161}
213 162
214impl<'a, B> Future for SendFuture<'a, B> 163impl<'a, B> Future for SendFuture<'a, B>
215where 164where
216 B: StaticReadBuffer<Word = u8>, 165 B: WriteBuffer<Word = u8> + 'static,
217{ 166{
218 type Output = (); 167 type Output = ();
219 168
220 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { 169 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
221 if self.is_ready() { 170 if !self.transfer.is_none() && self.transfer.unwrap().is_done() {
222 Poll::Ready(()) 171 Poll::Ready(())
223 } else { 172 } else {
224 // Start DMA transaction 173 self.transfer = Some(&mut Transfer::init(
225 let uarte = &self.uarte.instance; 174 StreamsTuple::new(self.uarte.dma).7,
226 175 self.uarte.usart,
227 STATE.tx_done.reset();
228
229 let (ptr, len) = unsafe { self.buf.read_buffer() };
230 // assert!(len <= EASY_DMA_SIZE);
231 // TODO: panic if buffer is not in SRAM
232
233 compiler_fence(Ordering::SeqCst);
234 // uarte.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
235 // uarte
236 // .txd
237 // .maxcnt
238 // .write(|w| unsafe { w.maxcnt().bits(len as _) });
239
240 // Start the DMA transfer
241 // See https://github.com/mwkroening/async-stm32f1xx/blob/78c46d1bff124eae4ebc7a2f4d40e6ed74def8b5/src/serial.rs#L118-L129
242 // https://github.com/stm32-rs/stm32f1xx-hal/blob/68fd3d6f282173816fd3181e795988d314cb17d0/src/serial.rs#L649-L671
243
244 // let first_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
245 // let second_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
246 // let triple_buffer = Some(singleton!(: [u8; 128] = [0; 128]).unwrap());
247
248 let transfer = Transfer::init(
249 StreamsTuple::new(self.dma).2,
250 self.usart,
251 self.buf, 176 self.buf,
252 // Some(second_buffer), 177 // Some(second_buffer),
253 None, 178 None,
@@ -255,85 +180,54 @@ where
255 .transfer_complete_interrupt(true) 180 .transfer_complete_interrupt(true)
256 .memory_increment(true) 181 .memory_increment(true)
257 .double_buffer(false), 182 .double_buffer(false),
258 ); 183 ));
259 184
260 waker_interrupt!(DMA2_STREAM2, cx.waker().clone()); 185 waker_interrupt!(DMA2_STREAM7, cx.waker().clone());
261 Poll::Pending 186 Poll::Pending
262 } 187 }
263 } 188 }
264} 189}
265 190
266/// Future for the [`Uarte::receive()`] method. 191/// Future for the [`Uarte::receive()`] method.
267pub struct ReceiveFuture<'a, B> { 192pub struct ReceiveFuture<'a, B: WriteBuffer<Word = u8> + 'static> {
268 uarte: &'a Uarte, 193 uarte: &'a Uarte,
269 buf: Option<B>, 194 transfer: Option<&'a Transfer<Stream2<DMA2>, Channel4, USART1, PeripheralToMemory, B>>,
195 buf: B,
270} 196}
271 197
272impl<'a, B> Drop for ReceiveFuture<'a, B> { 198impl<'a, B> Drop for ReceiveFuture<'a, B>
199where
200 B: WriteBuffer<Word = u8> + 'static,
201{
273 fn drop(self: &mut Self) { 202 fn drop(self: &mut Self) {
274 if self.uarte.rx_started() { 203 drop(self.transfer);
275 trace!("stoprx");
276
277 self.uarte
278 .instance
279 .tasks_stoprx
280 .write(|w| unsafe { w.bits(1) });
281 self.uarte.instance.events_rxstarted.reset();
282 }
283 } 204 }
284} 205}
285 206
286impl<'a, B> Future for ReceiveFuture<'a, B> 207impl<'a, B> Future for ReceiveFuture<'a, B>
287where 208where
288 B: StaticWriteBuffer<Word = u8>, 209 B: WriteBuffer<Word = u8> + 'static,
289{ 210{
290 type Output = B; 211 type Output = B;
291 212
292 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<B> { 213 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<B> {
293 if self.is_ready() { 214 if !self.transfer.is_none() && self.transfer.unwrap().is_done() {
294 Poll::Ready(()) 215 Poll::Ready(self.buf.take());
295 } else { 216 } else {
296 // Start DMA transaction 217 self.transfer = Some(&mut Transfer::init(
297 compiler_fence(Ordering::SeqCst); 218 StreamsTuple::new(self.uarte.dma).2,
298 // uarte.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 219 self.uarte.usart,
299 // uarte
300 // .txd
301 // .maxcnt
302 // .write(|w| unsafe { w.maxcnt().bits(len as _) });
303
304 // Start the DMA transfer
305 // See https://github.com/mwkroening/async-stm32f1xx/blob/78c46d1bff124eae4ebc7a2f4d40e6ed74def8b5/src/serial.rs#L118-L129
306 // https://github.com/stm32-rs/stm32f1xx-hal/blob/68fd3d6f282173816fd3181e795988d314cb17d0/src/serial.rs#L649-L671
307
308 // let first_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
309 // let second_buffer = singleton!(: [u8; 128] = [0; 128]).unwrap();
310 // let triple_buffer = Some(singleton!(: [u8; 128] = [0; 128]).unwrap());
311
312 let transfer = Transfer::init(
313 StreamsTuple::new(self.dma).7,
314 self.usart,
315 self.buf, 220 self.buf,
316 // Some(second_buffer),
317 None, 221 None,
318 DmaConfig::default() 222 DmaConfig::default()
319 .transfer_complete_interrupt(true) 223 .transfer_complete_interrupt(true)
224 .half_transfer_interrupt(true)
320 .memory_increment(true) 225 .memory_increment(true)
321 .double_buffer(false), 226 .double_buffer(false),
322 ); 227 ));
323 228
324 waker_interrupt!(DMA2_STREAM7, cx.waker().clone()); 229 waker_interrupt!(DMA2_STREAM2, cx.waker().clone());
325 Poll::Pending 230 Poll::Pending
326 } 231 }
327 } 232 }
328} 233}
329
330/// Future for the [`receive()`] method.
331impl<'a, B> ReceiveFuture<'a, B> {
332 /// Stops the ongoing reception and returns the number of bytes received.
333 pub async fn stop(mut self) -> (B, usize) {
334 let buf = self.buf.take().unwrap();
335 drop(self);
336 let len = STATE.rx_done.wait().await;
337 (buf, len as _)
338 }
339}