bump AXI uart16550 crate
ci / Check build (macos-latest) (push) Has been cancelled
ci / Check build (ubuntu-latest) (push) Has been cancelled
ci / Check build (windows-latest) (push) Has been cancelled
ci / Check MSRV (push) Has been cancelled
ci / Check Cross-Compilation (armv7-unknown-linux-gnueabihf) (push) Has been cancelled
ci / Check Cross-Compilation (armv7a-none-eabi) (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (macos-latest) (pull_request) Has been cancelled
ci / Check build (ubuntu-latest) (pull_request) Has been cancelled
ci / Check build (windows-latest) (pull_request) Has been cancelled
ci / Check MSRV (pull_request) Has been cancelled
ci / Check Cross-Compilation (armv7-unknown-linux-gnueabihf) (pull_request) Has been cancelled
ci / Check Cross-Compilation (armv7a-none-eabi) (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled

This commit is contained in:
Robin Mueller
2026-06-08 21:15:01 +02:00
parent 86a96e956a
commit 151f5289da
5 changed files with 28 additions and 31 deletions
+4
View File
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
- TX futures borrow buffer for their lifetime now.
- Constructor is now `unsafe`.
- Async TX write method now returns a future.
# [v0.1.0] 2025-11-28
Initial release.
+5 -6
View File
@@ -1,8 +1,7 @@
[package]
name = "axi-uart16550"
version = "0.1.0"
version = "0.2.0"
description = "AXI UART16550 IP core driver"
author = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
rust-version = "1.85.1"
edition = "2024"
homepage = "https://egit.irs.uni-stuttgart.de/rust/axi-uart16550"
@@ -11,19 +10,19 @@ license = "MIT OR Apache-2.0"
[dependencies]
derive-mmio = "0.6"
bitbybit = "1.4"
bitbybit = "2"
arbitrary-int = "2"
nb = "1"
libm = "0.2"
critical-section = "1"
thiserror = { version = "2", default-features = false }
fugit = "0.3"
fugit = "0.4"
embedded-hal-async = "1"
embedded-hal-nb = "1"
embedded-io = "0.7"
embedded-io-async = "0.7"
embassy-sync = "0.7"
raw-slicee = "0.1"
embassy-sync = "0.8"
raw-buffer = "0.1"
[features]
default = ["1-waker"]
+1 -1
View File
@@ -13,7 +13,7 @@ check:
cargo check
embedded:
cargo build --target armv7a-none-eabi
cargo build --target armv7a-none-eabihf
test:
cargo nextest r
+2 -2
View File
@@ -61,7 +61,7 @@ pub fn calculate_error_rate_from_div(
if baudrate == 0 || div == 0 {
return Err(DivisorZeroError);
}
let actual = (clk_in.raw() as f32) / (16.0 * div as f32);
let actual = (clk_in.to_raw() as f32) / (16.0 * div as f32);
Ok(libm::fabsf(actual - baudrate as f32) / baudrate as f32)
}
@@ -140,7 +140,7 @@ impl ClockConfig {
return Err(DivisorZeroError);
}
// Rounding integer division, by adding half the divisor to the dividend.
Ok((clk_in.raw() + (8 * baudrate)) / (16 * baudrate))
Ok((clk_in.to_raw() + (8 * baudrate)) / (16 * baudrate))
}
}
+16 -22
View File
@@ -20,7 +20,7 @@ use core::{cell::RefCell, convert::Infallible, sync::atomic::AtomicBool};
use critical_section::Mutex;
use embassy_sync::waitqueue::AtomicWaker;
use embedded_hal_async::delay::DelayNs;
use raw_slice::RawBufSlice;
use raw_buffer::RawBufSlice;
use crate::{
FIFO_DEPTH, Tx,
@@ -130,23 +130,15 @@ impl TxContext {
}
/// TX future structure.
pub struct TxFuture {
pub struct TxFuture<'tx, 'buf> {
waker_idx: usize,
reg_block: registers::MmioRegisters<'static>,
phantom: core::marker::PhantomData<(&'tx (), &'buf ())>,
}
impl TxFuture {
impl<'tx, 'buf> TxFuture<'tx, 'buf> {
/// Create a new TX future which can be used for asynchronous TX operations.
///
/// # Safety
///
/// This function stores the raw pointer of the passed data slice. The user MUST ensure
/// that the slice outlives the data structure.
pub unsafe fn new(
tx: &mut Tx,
waker_idx: usize,
data: &[u8],
) -> Result<Self, InvalidWakerIndex> {
pub fn new(tx: &mut Tx, waker_idx: usize, data: &'buf [u8]) -> Result<Self, InvalidWakerIndex> {
TX_DONE[waker_idx].store(false, core::sync::atomic::Ordering::Relaxed);
tx.disable_interrupt();
tx.reset_fifo();
@@ -168,11 +160,12 @@ impl TxFuture {
Ok(Self {
waker_idx,
reg_block: unsafe { tx.regs.clone() },
phantom: core::marker::PhantomData,
})
}
}
impl Future for TxFuture {
impl Future for TxFuture<'_, '_> {
type Output = usize;
fn poll(
@@ -192,7 +185,7 @@ impl Future for TxFuture {
}
}
impl Drop for TxFuture {
impl Drop for TxFuture<'_, '_> {
fn drop(&mut self) {
let mut tx = Tx::new(unsafe { self.reg_block.clone() });
tx.disable_interrupt();
@@ -212,7 +205,12 @@ impl<D: DelayNs> TxAsync<D> {
/// The delay function is a [DelayNs] provider which is used to allow flushing the
/// device properly. This is because even when a write finished, the UART might still
/// be busy shifting the last byte out.
pub fn new(tx: Tx, waker_idx: usize, delay: D) -> Result<Self, InvalidWakerIndex> {
///
/// # Safety
///
/// The user MUST ensure that the `Drop` method of all futures generated with this driver
/// is called on transfer cancellation. By default, this does not require any special handling.
pub unsafe fn new(tx: Tx, waker_idx: usize, delay: D) -> Result<Self, InvalidWakerIndex> {
if waker_idx >= NUM_WAKERS {
return Err(InvalidWakerIndex(waker_idx));
}
@@ -227,12 +225,8 @@ impl<D: DelayNs> TxAsync<D> {
///
/// This implementation is not side effect free, and a started future might have already
/// written part of the passed buffer.
pub async fn write(&mut self, buf: &[u8]) -> usize {
if buf.is_empty() {
return 0;
}
let fut = unsafe { TxFuture::new(&mut self.tx, self.waker_idx, buf).unwrap() };
fut.await
pub fn write<'buf>(&mut self, buf: &'buf [u8]) -> TxFuture<'_, 'buf> {
TxFuture::new(&mut self.tx, self.waker_idx, buf).unwrap()
}
/// Flush this output stream, ensuring that all intermediately buffered contents reach their destination.