commit
226877b16a
2 changed files with 65 additions and 2 deletions
|
@ -10,7 +10,7 @@ use core::marker::PhantomData;
|
||||||
use futures::{select_biased, FutureExt};
|
use futures::{select_biased, FutureExt};
|
||||||
|
|
||||||
use embassy::interrupt::Interrupt;
|
use embassy::interrupt::Interrupt;
|
||||||
use embassy::traits::uart::{Error, Uart};
|
use embassy::traits::uart::{Error, IdleUart, Uart};
|
||||||
use embassy::util::InterruptFuture;
|
use embassy::util::InterruptFuture;
|
||||||
|
|
||||||
use crate::hal::{
|
use crate::hal::{
|
||||||
|
@ -150,6 +150,56 @@ where
|
||||||
let rx_stream = self.rx_stream.take().unwrap();
|
let rx_stream = self.rx_stream.take().unwrap();
|
||||||
let usart = self.usart.take().unwrap();
|
let usart = self.usart.take().unwrap();
|
||||||
|
|
||||||
|
async move {
|
||||||
|
let mut rx_transfer = Transfer::init(
|
||||||
|
rx_stream,
|
||||||
|
usart,
|
||||||
|
static_buf,
|
||||||
|
None,
|
||||||
|
DmaConfig::default()
|
||||||
|
.transfer_complete_interrupt(true)
|
||||||
|
.memory_increment(true)
|
||||||
|
.double_buffer(false),
|
||||||
|
);
|
||||||
|
|
||||||
|
let fut = InterruptFuture::new(&mut self.rx_int);
|
||||||
|
rx_transfer.start(|_usart| {});
|
||||||
|
fut.await;
|
||||||
|
|
||||||
|
let (rx_stream, usart, _, _) = rx_transfer.free();
|
||||||
|
self.rx_stream.replace(rx_stream);
|
||||||
|
self.usart.replace(usart);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<USART, TSTREAM, RSTREAM, CHANNEL> IdleUart for Serial<USART, TSTREAM, RSTREAM, CHANNEL>
|
||||||
|
where
|
||||||
|
USART: serial::Instance
|
||||||
|
+ PeriAddress<MemSize = u8>
|
||||||
|
+ DMASet<TSTREAM, CHANNEL, MemoryToPeripheral>
|
||||||
|
+ DMASet<RSTREAM, CHANNEL, PeripheralToMemory>
|
||||||
|
+ WithInterrupt
|
||||||
|
+ 'static,
|
||||||
|
TSTREAM: Stream + WithInterrupt + 'static,
|
||||||
|
RSTREAM: Stream + WithInterrupt + 'static,
|
||||||
|
CHANNEL: Channel + 'static,
|
||||||
|
{
|
||||||
|
type ReceiveFuture<'a> = impl Future<Output = Result<usize, Error>> + 'a;
|
||||||
|
|
||||||
|
/// Receives serial data.
|
||||||
|
///
|
||||||
|
/// The future is pending until either the buffer is completely full, or the RX line falls idle after receiving some data.
|
||||||
|
///
|
||||||
|
/// Returns the number of bytes read.
|
||||||
|
fn receive_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a> {
|
||||||
|
let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
|
||||||
|
|
||||||
|
let rx_stream = self.rx_stream.take().unwrap();
|
||||||
|
let usart = self.usart.take().unwrap();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
unsafe {
|
unsafe {
|
||||||
/* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */
|
/* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */
|
||||||
|
@ -171,6 +221,8 @@ where
|
||||||
.double_buffer(false),
|
.double_buffer(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let total_bytes = RSTREAM::get_number_of_transfers() as usize;
|
||||||
|
|
||||||
let fut = InterruptFuture::new(&mut self.rx_int);
|
let fut = InterruptFuture::new(&mut self.rx_int);
|
||||||
let fut_idle = InterruptFuture::new(&mut self.usart_int);
|
let fut_idle = InterruptFuture::new(&mut self.usart_int);
|
||||||
|
|
||||||
|
@ -183,13 +235,15 @@ where
|
||||||
|
|
||||||
let (rx_stream, usart, _, _) = rx_transfer.free();
|
let (rx_stream, usart, _, _) = rx_transfer.free();
|
||||||
|
|
||||||
|
let remaining_bytes = RSTREAM::get_number_of_transfers() as usize;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
|
(*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
|
||||||
}
|
}
|
||||||
self.rx_stream.replace(rx_stream);
|
self.rx_stream.replace(rx_stream);
|
||||||
self.usart.replace(usart);
|
self.usart.replace(usart);
|
||||||
|
|
||||||
Ok(())
|
Ok(total_bytes - remaining_bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,15 @@ pub enum Error {
|
||||||
pub trait Uart {
|
pub trait Uart {
|
||||||
type ReceiveFuture<'a>: Future<Output = Result<(), Error>>;
|
type ReceiveFuture<'a>: Future<Output = Result<(), Error>>;
|
||||||
type SendFuture<'a>: Future<Output = Result<(), Error>>;
|
type SendFuture<'a>: Future<Output = Result<(), Error>>;
|
||||||
|
/// Receive into the buffer until the buffer is full
|
||||||
fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a>;
|
fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a>;
|
||||||
|
/// Send the specified buffer, and return when the transmission has completed
|
||||||
fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a>;
|
fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IdleUart {
|
||||||
|
type ReceiveFuture<'a>: Future<Output = Result<usize, Error>>;
|
||||||
|
/// Receive into the buffer until the buffer is full or the line is idle after some bytes are received
|
||||||
|
/// Return the number of bytes received
|
||||||
|
fn receive_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a>;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue