aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2021-03-23 21:05:01 -0500
committerGitHub <[email protected]>2021-03-23 21:05:01 -0500
commit226877b16af848dbe8553eb8789d82c301b5e584 (patch)
treec8a869edac81b4423ae40085d387a8d10f11c47a
parent639059ba33e2440027924155df5c8a2efb7f4f6d (diff)
parent095ba23ad30d0d019d3e47be59b2354133367212 (diff)
Merge pull request #104 from xoviat/idle-trait
traits: add idle trait
-rw-r--r--embassy-stm32f4/src/serial.rs58
-rw-r--r--embassy-traits/src/uart.rs9
2 files changed, 65 insertions, 2 deletions
diff --git a/embassy-stm32f4/src/serial.rs b/embassy-stm32f4/src/serial.rs
index bed89288e..c8dc0598a 100644
--- a/embassy-stm32f4/src/serial.rs
+++ b/embassy-stm32f4/src/serial.rs
@@ -10,7 +10,7 @@ use core::marker::PhantomData;
10use futures::{select_biased, FutureExt}; 10use futures::{select_biased, FutureExt};
11 11
12use embassy::interrupt::Interrupt; 12use embassy::interrupt::Interrupt;
13use embassy::traits::uart::{Error, Uart}; 13use embassy::traits::uart::{Error, IdleUart, Uart};
14use embassy::util::InterruptFuture; 14use embassy::util::InterruptFuture;
15 15
16use crate::hal::{ 16use crate::hal::{
@@ -151,6 +151,56 @@ where
151 let usart = self.usart.take().unwrap(); 151 let usart = self.usart.take().unwrap();
152 152
153 async move { 153 async move {
154 let mut rx_transfer = Transfer::init(
155 rx_stream,
156 usart,
157 static_buf,
158 None,
159 DmaConfig::default()
160 .transfer_complete_interrupt(true)
161 .memory_increment(true)
162 .double_buffer(false),
163 );
164
165 let fut = InterruptFuture::new(&mut self.rx_int);
166 rx_transfer.start(|_usart| {});
167 fut.await;
168
169 let (rx_stream, usart, _, _) = rx_transfer.free();
170 self.rx_stream.replace(rx_stream);
171 self.usart.replace(usart);
172
173 Ok(())
174 }
175 }
176}
177
178impl<USART, TSTREAM, RSTREAM, CHANNEL> IdleUart for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
179where
180 USART: serial::Instance
181 + PeriAddress<MemSize = u8>
182 + DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
183 + DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
184 + WithInterrupt
185 + 'static,
186 TSTREAM: Stream + WithInterrupt + 'static,
187 RSTREAM: Stream + WithInterrupt + 'static,
188 CHANNEL: Channel + 'static,
189{
190 type ReceiveFuture<'a> = impl Future<Output = Result<usize, Error>> + 'a;
191
192 /// Receives serial data.
193 ///
194 /// The future is pending until either the buffer is completely full, or the RX line falls idle after receiving some data.
195 ///
196 /// Returns the number of bytes read.
197 fn receive_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a> {
198 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
199
200 let rx_stream = self.rx_stream.take().unwrap();
201 let usart = self.usart.take().unwrap();
202
203 async move {
154 unsafe { 204 unsafe {
155 /* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */ 205 /* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */
156 (*USART::ptr()).cr1.modify(|_, w| w.idleie().set_bit()); 206 (*USART::ptr()).cr1.modify(|_, w| w.idleie().set_bit());
@@ -171,6 +221,8 @@ where
171 .double_buffer(false), 221 .double_buffer(false),
172 ); 222 );
173 223
224 let total_bytes = RSTREAM::get_number_of_transfers() as usize;
225
174 let fut = InterruptFuture::new(&mut self.rx_int); 226 let fut = InterruptFuture::new(&mut self.rx_int);
175 let fut_idle = InterruptFuture::new(&mut self.usart_int); 227 let fut_idle = InterruptFuture::new(&mut self.usart_int);
176 228
@@ -183,13 +235,15 @@ where
183 235
184 let (rx_stream, usart, _, _) = rx_transfer.free(); 236 let (rx_stream, usart, _, _) = rx_transfer.free();
185 237
238 let remaining_bytes = RSTREAM::get_number_of_transfers() as usize;
239
186 unsafe { 240 unsafe {
187 (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit()); 241 (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
188 } 242 }
189 self.rx_stream.replace(rx_stream); 243 self.rx_stream.replace(rx_stream);
190 self.usart.replace(usart); 244 self.usart.replace(usart);
191 245
192 Ok(()) 246 Ok(total_bytes - remaining_bytes)
193 } 247 }
194 } 248 }
195} 249}
diff --git a/embassy-traits/src/uart.rs b/embassy-traits/src/uart.rs
index b40b9e9bd..441747181 100644
--- a/embassy-traits/src/uart.rs
+++ b/embassy-traits/src/uart.rs
@@ -10,6 +10,15 @@ pub enum Error {
10pub trait Uart { 10pub trait Uart {
11 type ReceiveFuture<'a>: Future<Output = Result<(), Error>>; 11 type ReceiveFuture<'a>: Future<Output = Result<(), Error>>;
12 type SendFuture<'a>: Future<Output = Result<(), Error>>; 12 type SendFuture<'a>: Future<Output = Result<(), Error>>;
13 /// Receive into the buffer until the buffer is full
13 fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a>; 14 fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a>;
15 /// Send the specified buffer, and return when the transmission has completed
14 fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a>; 16 fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a>;
15} 17}
18
19pub trait IdleUart {
20 type ReceiveFuture<'a>: Future<Output = Result<usize, Error>>;
21 /// Receive into the buffer until the buffer is full or the line is idle after some bytes are received
22 /// Return the number of bytes received
23 fn receive_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a>;
24}