bump dependencies
Some checks failed
ci / Check build (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 (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
Some checks failed
ci / Check build (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 (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:
@@ -12,10 +12,10 @@ cortex-m = { version = "0.7" }
|
|||||||
cfg-if = "1"
|
cfg-if = "1"
|
||||||
derive-mmio = { git = "https://github.com/knurling-rs/derive-mmio.git", version = "0.6" }
|
derive-mmio = { git = "https://github.com/knurling-rs/derive-mmio.git", version = "0.6" }
|
||||||
bitbybit = "1.3"
|
bitbybit = "1.3"
|
||||||
arbitrary-int = "1.3"
|
arbitrary-int = "2"
|
||||||
static_assertions = "1.1"
|
static_assertions = "1.1"
|
||||||
nb = "1"
|
nb = "1"
|
||||||
heapless = "0.8"
|
heapless = "0.9"
|
||||||
critical-section = "1"
|
critical-section = "1"
|
||||||
embedded-hal = "1.0"
|
embedded-hal = "1.0"
|
||||||
embedded-hal-async = "1"
|
embedded-hal-async = "1"
|
||||||
@@ -31,7 +31,7 @@ va108xx = { version = "0.5", default-features = false, optional = true }
|
|||||||
va416xx = { version = "0.4", default-features = false, optional = true }
|
va416xx = { version = "0.4", default-features = false, optional = true }
|
||||||
embassy-sync = "0.7"
|
embassy-sync = "0.7"
|
||||||
embassy-time-driver = "0.2"
|
embassy-time-driver = "0.2"
|
||||||
embassy-time-queue-utils = "0.1"
|
embassy-time-queue-utils = "0.3"
|
||||||
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
|
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
|
||||||
|
|
||||||
[target.thumbv6m-none-eabi.dependencies]
|
[target.thumbv6m-none-eabi.dependencies]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use arbitrary_int::{Number, u7};
|
use arbitrary_int::{prelude::*, u7};
|
||||||
|
|
||||||
#[cfg(feature = "vor1x")]
|
#[cfg(feature = "vor1x")]
|
||||||
const BASE_ADDR: usize = 0x4002_0000;
|
const BASE_ADDR: usize = 0x4002_0000;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub mod regs;
|
|||||||
#[cfg(feature = "vor1x")]
|
#[cfg(feature = "vor1x")]
|
||||||
use crate::InterruptConfig;
|
use crate::InterruptConfig;
|
||||||
use crate::{FunSel, gpio::IoPeriphPin, pins::PinMarker, sealed::Sealed};
|
use crate::{FunSel, gpio::IoPeriphPin, pins::PinMarker, sealed::Sealed};
|
||||||
use arbitrary_int::{Number, u6, u18};
|
use arbitrary_int::{prelude::*, u6, u18};
|
||||||
use fugit::RateExtU32;
|
use fugit::RateExtU32;
|
||||||
use regs::{ClkScale, Control, Data, Enable, FifoClear, InterruptClear, MmioUart};
|
use regs::{ClkScale, Control, Data, Enable, FifoClear, InterruptClear, MmioUart};
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
//! structure returned by the interrupt handlers.
|
//! structure returned by the interrupt handlers.
|
||||||
use core::{cell::RefCell, convert::Infallible, future::Future, sync::atomic::Ordering};
|
use core::{cell::RefCell, convert::Infallible, future::Future, sync::atomic::Ordering};
|
||||||
|
|
||||||
use arbitrary_int::Number;
|
use arbitrary_int::prelude::*;
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
use embedded_io::ErrorType;
|
use embedded_io::ErrorType;
|
||||||
@@ -120,18 +120,18 @@ fn on_interrupt_rx_common_post_processing(
|
|||||||
/// Should be called in the user interrupt handler to enable
|
/// Should be called in the user interrupt handler to enable
|
||||||
/// asynchronous reception. This variant will overwrite old data in the ring buffer in case
|
/// asynchronous reception. This variant will overwrite old data in the ring buffer in case
|
||||||
/// the ring buffer is full.
|
/// the ring buffer is full.
|
||||||
pub fn on_interrupt_rx_overwriting<const N: usize>(
|
pub fn on_interrupt_rx_overwriting(
|
||||||
bank: Bank,
|
bank: Bank,
|
||||||
prod: &mut heapless::spsc::Producer<u8, N>,
|
prod: &mut heapless::spsc::Producer<u8>,
|
||||||
shared_consumer: &Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8, N>>>>,
|
shared_consumer: &Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8>>>>,
|
||||||
) -> Result<(), AsyncUartErrors> {
|
) -> Result<(), AsyncUartErrors> {
|
||||||
on_interrupt_rx_async_heapless_queue_overwriting(bank, prod, shared_consumer)
|
on_interrupt_rx_async_heapless_queue_overwriting(bank, prod, shared_consumer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_interrupt_rx_async_heapless_queue_overwriting<const N: usize>(
|
pub fn on_interrupt_rx_async_heapless_queue_overwriting(
|
||||||
bank: Bank,
|
bank: Bank,
|
||||||
prod: &mut heapless::spsc::Producer<u8, N>,
|
prod: &mut heapless::spsc::Producer<u8>,
|
||||||
shared_consumer: &Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8, N>>>>,
|
shared_consumer: &Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8>>>>,
|
||||||
) -> Result<(), AsyncUartErrors> {
|
) -> Result<(), AsyncUartErrors> {
|
||||||
let uart_regs = unsafe { bank.steal_regs() };
|
let uart_regs = unsafe { bank.steal_regs() };
|
||||||
let irq_status = uart_regs.read_irq_status();
|
let irq_status = uart_regs.read_irq_status();
|
||||||
@@ -190,16 +190,16 @@ pub fn on_interrupt_rx_async_heapless_queue_overwriting<const N: usize>(
|
|||||||
/// Interrupt handler for asynchronous RX operations.
|
/// Interrupt handler for asynchronous RX operations.
|
||||||
///
|
///
|
||||||
/// Should be called in the user interrupt handler to enable asynchronous reception.
|
/// Should be called in the user interrupt handler to enable asynchronous reception.
|
||||||
pub fn on_interrupt_rx<const N: usize>(
|
pub fn on_interrupt_rx(
|
||||||
bank: Bank,
|
bank: Bank,
|
||||||
prod: &mut heapless::spsc::Producer<'_, u8, N>,
|
prod: &mut heapless::spsc::Producer<'_, u8>,
|
||||||
) -> Result<(), AsyncUartErrors> {
|
) -> Result<(), AsyncUartErrors> {
|
||||||
on_interrupt_rx_async_heapless_queue(bank, prod)
|
on_interrupt_rx_async_heapless_queue(bank, prod)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_interrupt_rx_async_heapless_queue<const N: usize>(
|
pub fn on_interrupt_rx_async_heapless_queue(
|
||||||
bank: Bank,
|
bank: Bank,
|
||||||
prod: &mut heapless::spsc::Producer<'_, u8, N>,
|
prod: &mut heapless::spsc::Producer<'_, u8>,
|
||||||
) -> Result<(), AsyncUartErrors> {
|
) -> Result<(), AsyncUartErrors> {
|
||||||
let uart_regs = unsafe { bank.steal_regs() };
|
let uart_regs = unsafe { bank.steal_regs() };
|
||||||
let irq_status = uart_regs.read_irq_status();
|
let irq_status = uart_regs.read_irq_status();
|
||||||
@@ -255,17 +255,17 @@ impl Drop for ActiveReadGuard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RxAsyncInner<const N: usize> {
|
struct RxAsyncInner {
|
||||||
rx: Rx,
|
rx: Rx,
|
||||||
pub queue: heapless::spsc::Consumer<'static, u8, N>,
|
pub queue: heapless::spsc::Consumer<'static, u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Core data structure to allow asynchronous UART reception.
|
/// Core data structure to allow asynchronous UART reception.
|
||||||
///
|
///
|
||||||
/// If the ring buffer becomes full, data will be lost.
|
/// If the ring buffer becomes full, data will be lost.
|
||||||
pub struct RxAsync<const N: usize>(Option<RxAsyncInner<N>>);
|
pub struct RxAsync(Option<RxAsyncInner>);
|
||||||
|
|
||||||
impl<const N: usize> ErrorType for RxAsync<N> {
|
impl ErrorType for RxAsync {
|
||||||
/// Error reporting is done using the result of the interrupt functions.
|
/// Error reporting is done using the result of the interrupt functions.
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
}
|
}
|
||||||
@@ -276,12 +276,12 @@ fn stop_async_rx(rx: &mut Rx) {
|
|||||||
rx.clear_fifo();
|
rx.clear_fifo();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> RxAsync<N> {
|
impl RxAsync {
|
||||||
/// Create a new asynchronous receiver.
|
/// Create a new asynchronous receiver.
|
||||||
///
|
///
|
||||||
/// The passed [heapless::spsc::Consumer] will be used to asynchronously receive data which
|
/// The passed [heapless::spsc::Consumer] will be used to asynchronously receive data which
|
||||||
/// is filled by the interrupt handler [on_interrupt_rx].
|
/// is filled by the interrupt handler [on_interrupt_rx].
|
||||||
pub fn new(mut rx: Rx, queue: heapless::spsc::Consumer<'static, u8, N>) -> Self {
|
pub fn new(mut rx: Rx, queue: heapless::spsc::Consumer<'static, u8>) -> Self {
|
||||||
rx.disable_interrupts();
|
rx.disable_interrupts();
|
||||||
rx.disable();
|
rx.disable();
|
||||||
rx.clear_fifo();
|
rx.clear_fifo();
|
||||||
@@ -300,29 +300,29 @@ impl<const N: usize> RxAsync<N> {
|
|||||||
stop_async_rx(&mut self.0.as_mut().unwrap().rx);
|
stop_async_rx(&mut self.0.as_mut().unwrap().rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn release(mut self) -> (Rx, heapless::spsc::Consumer<'static, u8, N>) {
|
pub fn release(mut self) -> (Rx, heapless::spsc::Consumer<'static, u8>) {
|
||||||
self.stop();
|
self.stop();
|
||||||
let inner = self.0.take().unwrap();
|
let inner = self.0.take().unwrap();
|
||||||
(inner.rx, inner.queue)
|
(inner.rx, inner.queue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> Drop for RxAsync<N> {
|
impl Drop for RxAsync {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.stop();
|
self.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> embedded_io_async::Read for RxAsync<N> {
|
impl embedded_io_async::Read for RxAsync {
|
||||||
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||||
let inner = self.0.as_ref().unwrap();
|
let inner = self.0.as_ref().unwrap();
|
||||||
// Need to wait for the IRQ to read data and set this flag. If the queue is not
|
// Need to wait for the IRQ to read data and set this flag. If the queue is not
|
||||||
// empty, we can read data immediately.
|
// empty, we can read data immediately.
|
||||||
if inner.queue.len() == 0 {
|
if inner.queue.is_empty() {
|
||||||
RX_HAS_DATA[inner.rx.id as usize].store(false, Ordering::Relaxed);
|
RX_HAS_DATA[inner.rx.id as usize].store(false, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
let _guard = ActiveReadGuard(inner.rx.id as usize);
|
let _guard = ActiveReadGuard(inner.rx.id as usize);
|
||||||
let mut handle_data_in_queue = |consumer: &mut heapless::spsc::Consumer<'static, u8, N>| {
|
let mut handle_data_in_queue = |consumer: &mut heapless::spsc::Consumer<'static, u8>| {
|
||||||
let data_to_read = consumer.len().min(buf.len());
|
let data_to_read = consumer.len().min(buf.len());
|
||||||
for byte in buf.iter_mut().take(data_to_read) {
|
for byte in buf.iter_mut().take(data_to_read) {
|
||||||
// We own the consumer and we checked that the amount of data is guaranteed to be available.
|
// We own the consumer and we checked that the amount of data is guaranteed to be available.
|
||||||
@@ -343,23 +343,23 @@ impl<const N: usize> embedded_io_async::Read for RxAsync<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RxAsyncOverwritingInner<const N: usize> {
|
struct RxAsyncOverwritingInner {
|
||||||
rx: Rx,
|
rx: Rx,
|
||||||
pub shared_consumer: &'static Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8, N>>>>,
|
pub shared_consumer: &'static Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Core data structure to allow asynchronous UART reception.
|
/// Core data structure to allow asynchronous UART reception.
|
||||||
///
|
///
|
||||||
/// If the ring buffer becomes full, the oldest data will be overwritten when using the
|
/// If the ring buffer becomes full, the oldest data will be overwritten when using the
|
||||||
/// [on_interrupt_rx_overwriting] interrupt handlers.
|
/// [on_interrupt_rx_overwriting] interrupt handlers.
|
||||||
pub struct RxAsyncOverwriting<const N: usize>(Option<RxAsyncOverwritingInner<N>>);
|
pub struct RxAsyncOverwriting(Option<RxAsyncOverwritingInner>);
|
||||||
|
|
||||||
impl<const N: usize> ErrorType for RxAsyncOverwriting<N> {
|
impl ErrorType for RxAsyncOverwriting {
|
||||||
/// Error reporting is done using the result of the interrupt functions.
|
/// Error reporting is done using the result of the interrupt functions.
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> RxAsyncOverwriting<N> {
|
impl RxAsyncOverwriting {
|
||||||
/// Create a new asynchronous receiver.
|
/// Create a new asynchronous receiver.
|
||||||
///
|
///
|
||||||
/// The passed shared [heapless::spsc::Consumer] will be used to asynchronously receive data
|
/// The passed shared [heapless::spsc::Consumer] will be used to asynchronously receive data
|
||||||
@@ -367,7 +367,7 @@ impl<const N: usize> RxAsyncOverwriting<N> {
|
|||||||
/// interrupt handler to overwrite old data.
|
/// interrupt handler to overwrite old data.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut rx: Rx,
|
mut rx: Rx,
|
||||||
shared_consumer: &'static Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8, N>>>>,
|
shared_consumer: &'static Mutex<RefCell<Option<heapless::spsc::Consumer<'static, u8>>>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
rx.disable_interrupts();
|
rx.disable_interrupts();
|
||||||
rx.disable();
|
rx.disable();
|
||||||
@@ -397,13 +397,13 @@ impl<const N: usize> RxAsyncOverwriting<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> Drop for RxAsyncOverwriting<N> {
|
impl Drop for RxAsyncOverwriting {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.stop();
|
self.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> embedded_io_async::Read for RxAsyncOverwriting<N> {
|
impl embedded_io_async::Read for RxAsyncOverwriting {
|
||||||
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||||
let inner = self.0.as_ref().unwrap();
|
let inner = self.0.as_ref().unwrap();
|
||||||
let id = inner.rx.id as usize;
|
let id = inner.rx.id as usize;
|
||||||
@@ -412,12 +412,12 @@ impl<const N: usize> embedded_io_async::Read for RxAsyncOverwriting<N> {
|
|||||||
|
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let queue = inner.shared_consumer.borrow(cs);
|
let queue = inner.shared_consumer.borrow(cs);
|
||||||
if queue.borrow().as_ref().unwrap().len() == 0 {
|
if queue.borrow().as_ref().unwrap().is_empty() {
|
||||||
RX_HAS_DATA[id].store(false, Ordering::Relaxed);
|
RX_HAS_DATA[id].store(false, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let _guard = ActiveReadGuard(id);
|
let _guard = ActiveReadGuard(id);
|
||||||
let mut handle_data_in_queue = |inner: &mut RxAsyncOverwritingInner<N>| {
|
let mut handle_data_in_queue = |inner: &mut RxAsyncOverwritingInner| {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let mut consumer_ref = inner.shared_consumer.borrow(cs).borrow_mut();
|
let mut consumer_ref = inner.shared_consumer.borrow(cs).borrow_mut();
|
||||||
let consumer = consumer_ref.as_mut().unwrap();
|
let consumer = consumer_ref.as_mut().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user