use transmute for now

This commit is contained in:
xoviat 2021-01-06 14:12:33 -06:00
parent 27cfcbacb8
commit 1c3b7541cb

View File

@ -10,7 +10,7 @@ use core::sync::atomic::{self, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy::interrupt::OwnedInterrupt; use embassy::interrupt::OwnedInterrupt;
use embassy::uart::Uart; use embassy::uart::{Error, Uart};
use embassy::util::Signal; use embassy::util::Signal;
use embedded_dma::StaticWriteBuffer; use embedded_dma::StaticWriteBuffer;
@ -139,39 +139,49 @@ impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
} }
impl Uart for Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> { impl Uart for Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
type SendFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
type ReceiveFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
/// Sends serial data. /// Sends serial data.
/// ///
/// `tx_buffer` is marked as static as per `embedded-dma` requirements. /// `tx_buffer` is marked as static as per `embedded-dma` requirements.
/// It it safe to use a buffer with a non static lifetime if memory is not /// It it safe to use a buffer with a non static lifetime if memory is not
/// reused until the future has finished. /// reused until the future has finished.
fn send<'a>(&'a mut self, buf: &'a mut [u8]) -> dyn Future<Output = Result<(), Error>> { #[allow(mutable_transmutes)]
fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a> {
unsafe { INSTANCE = self }; unsafe { INSTANCE = self };
let tx_stream = self.tx_stream.take().unwrap(); unsafe {
let usart = self.usart.take().unwrap(); let static_buf = core::mem::transmute::<&'a [u8], &'static mut [u8]>(buf);
STATE.tx_int.reset();
async move { let tx_stream = self.tx_stream.take().unwrap();
let mut tx_transfer = Transfer::init( let usart = self.usart.take().unwrap();
tx_stream, STATE.tx_int.reset();
usart,
buf,
None,
DmaConfig::default()
.transfer_complete_interrupt(true)
.memory_increment(true)
.double_buffer(false),
);
self.tx_int.unpend(); async move {
self.tx_int.enable(); let mut tx_transfer = Transfer::init(
tx_transfer.start(|_usart| {}); tx_stream,
usart,
static_buf,
None,
DmaConfig::default()
.transfer_complete_interrupt(true)
.memory_increment(true)
.double_buffer(false),
);
STATE.tx_int.wait().await; self.tx_int.unpend();
self.tx_int.enable();
tx_transfer.start(|_usart| {});
let (tx_stream, usart, _buf, _) = tx_transfer.free(); STATE.tx_int.wait().await;
self.tx_stream.replace(tx_stream);
self.usart.replace(usart); let (tx_stream, usart, _buf, _) = tx_transfer.free();
self.tx_stream.replace(tx_stream);
self.usart.replace(usart);
Ok(())
}
} }
} }
@ -185,35 +195,34 @@ impl Uart for Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
/// `rx_buffer` is marked as static as per `embedded-dma` requirements. /// `rx_buffer` is marked as static as per `embedded-dma` requirements.
/// It it safe to use a buffer with a non static lifetime if memory is not /// It it safe to use a buffer with a non static lifetime if memory is not
/// reused until the future has finished. /// reused until the future has finished.
fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> dyn Future<Output = Result<(), Error>> { fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a> {
unsafe { INSTANCE = self }; unsafe { INSTANCE = self };
let rx_stream = self.rx_stream.take().unwrap(); unsafe {
let usart = self.usart.take().unwrap(); let static_buf = core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf);
STATE.rx_int.reset(); let rx_stream = self.rx_stream.take().unwrap();
let usart = self.usart.take().unwrap();
async move { STATE.rx_int.reset();
let mut rx_transfer = Transfer::init( async move {
rx_stream, let mut rx_transfer = Transfer::init(
usart, rx_stream,
buf.static_write_buffer(), usart,
None, static_buf,
DmaConfig::default() None,
.transfer_complete_interrupt(true) DmaConfig::default()
.memory_increment(true) .transfer_complete_interrupt(true)
.double_buffer(false), .memory_increment(true)
); .double_buffer(false),
);
self.rx_int.unpend(); self.rx_int.unpend();
self.rx_int.enable(); self.rx_int.enable();
rx_transfer.start(|_usart| {});
rx_transfer.start(|_usart| {}); STATE.rx_int.wait().await;
let (rx_stream, usart, buf, _) = rx_transfer.free();
STATE.rx_int.wait().await; self.rx_stream.replace(rx_stream);
self.usart.replace(usart);
let (rx_stream, usart, buf, _) = rx_transfer.free(); Ok(())
self.rx_stream.replace(rx_stream); }
self.usart.replace(usart);
} }
} }
} }