Skip to content

feat : Add async-io feature and embedded-io-async dependency #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ test-rsa = []
test-ecdsa = []
test-hmac = []
test-hash = []
async-io = ["embedded-io-async"]

[dependencies]
ast1060-pac = { git = "https://github.com/rusty1968/ast1060-pac.git", features = ["rt"] }
Expand All @@ -35,3 +36,7 @@ cortex-m = { version = "0.7.5" }
cortex-m-rt = { version = "0.6.5", features = ["device"] }
panic-halt = "1.0.0"

[dependencies.embedded-io-async]
version = "0.6"
optional = true

3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ pub mod rsa;
pub mod syscon;
pub mod tests;
pub mod uart;
#[cfg(feature = "async-io")]
pub mod uart_async;

pub mod watchdog;
27 changes: 26 additions & 1 deletion src/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,16 @@ impl UartController<'_> {
// Additional configurations can be added here
}

/// Returns true if the Transmitter Holding Register (THR) is empty.
#[must_use]
pub fn is_thr_empty(&self) -> bool {
self.uart.uartlsr().read().thre().bit_is_set()
}

/// Sends a byte using the FIFO.
pub fn send_byte_fifo(&mut self, data: u8) {
// Wait until the Transmitter Holding Register (THR) is empty
while self.uart.uartlsr().read().thre().bit_is_clear() {}
while !self.is_thr_empty() {}

// Write the byte to the Transmit Holding Register (THR)
self.uart
Expand All @@ -166,6 +172,25 @@ impl UartController<'_> {
}

impl<'a> UartController<'a> {
/// Reads a byte from the UART receiver buffer register (UARTRBR).
#[must_use]
pub fn read_rbr(&self) -> u8 {
self.uart.uartrbr().read().uartrbr().bits()
}

/// Returns true if data is available in the UART receiver buffer (DR bit is set).
#[must_use]
pub fn is_data_ready(&self) -> bool {
self.uart.uartlsr().read().dr().bit_is_set()
}

/// Writes a byte to the UART transmit holding register (THR).
pub fn write_thr(&mut self, byte: u8) {
self.uart
.uartthr()
.write(|w| unsafe { w.bits(u32::from(byte)) });
}

// Wait until the Transmitter Holding Register (THR) is empty
pub fn new(uart: Uart, delay: &'a mut dyn DelayNs) -> Self {
Self { uart, delay }
Expand Down
55 changes: 55 additions & 0 deletions src/uart_async.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Licensed under the Apache-2.0 license

use ast1060_pac::Uart;

use crate::uart::UartController;

use core::future::poll_fn;
use core::task::{Context, Poll};
use embedded_io_async::{Read, Write};

/// Async implementation of embedded_io_async::Read for UartController.
///
/// Reads bytes asynchronously from the UART receiver buffer.
/// Waits until data is available before reading each byte.
impl embedded_io_async::Read for UartController<'_> {
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
let mut count = 0;
for byte in buf.iter_mut() {
poll_fn(|cx| {
if self.is_data_ready() {
*byte = self.read_rbr();
Poll::Ready(Ok(()))
} else {
cx.waker().wake_by_ref();
Poll::Pending
}
})
.await?;
count += 1;
}
Ok(count)
}
}

/// Async implementation of embedded_io_async::Write for UartController.
///
/// Writes bytes asynchronously to the UART transmit holding register.
/// Waits until the transmitter is ready before sending each byte.
impl embedded_io_async::Write for UartController<'_> {
async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
for &byte in buf {
poll_fn(|cx| {
if self.is_thr_empty() {
self.write_thr(byte);
Poll::Ready(Ok(()))
} else {
cx.waker().wake_by_ref();
Poll::Pending
}
})
.await?;
}
Ok(buf.len())
}
}