continue improvements
All checks were successful
Rust/va416xx-rs/pipeline/pr-main This commit looks good
All checks were successful
Rust/va416xx-rs/pipeline/pr-main This commit looks good
This commit is contained in:
parent
3c3270f722
commit
9f50bee415
@ -128,17 +128,14 @@ async fn blinky(mut led: Pin<PG5, OutputReadablePushPull>) {
|
|||||||
fn UART0_RX() {
|
fn UART0_RX() {
|
||||||
let mut buf: [u8; 16] = [0; 16];
|
let mut buf: [u8; 16] = [0; 16];
|
||||||
let mut read_len: usize = 0;
|
let mut read_len: usize = 0;
|
||||||
let mut irq_error = None;
|
let mut errors = None;
|
||||||
RX.lock(|static_rx| {
|
RX.lock(|static_rx| {
|
||||||
let mut rx_borrow = static_rx.borrow_mut();
|
let mut rx_borrow = static_rx.borrow_mut();
|
||||||
let rx_mut_ref = rx_borrow.as_mut().unwrap();
|
let rx_mut_ref = rx_borrow.as_mut().unwrap();
|
||||||
match rx_mut_ref.irq_handler(&mut buf) {
|
let result = rx_mut_ref.irq_handler(&mut buf);
|
||||||
Ok(result) => {
|
read_len = result.bytes_read;
|
||||||
read_len = result.bytes_read;
|
if result.errors.is_some() {
|
||||||
}
|
errors = result.errors;
|
||||||
Err(e) => {
|
|
||||||
irq_error = Some(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let mut ringbuf_full = false;
|
let mut ringbuf_full = false;
|
||||||
@ -155,8 +152,8 @@ fn UART0_RX() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if irq_error.is_some() {
|
if errors.is_some() {
|
||||||
rprintln!("error in IRQ handler: {:?}", irq_error);
|
rprintln!("UART error: {:?}", errors);
|
||||||
}
|
}
|
||||||
if ringbuf_full {
|
if ringbuf_full {
|
||||||
rprintln!("ringbuffer is full, deleted oldest data");
|
rprintln!("ringbuffer is full, deleted oldest data");
|
||||||
|
@ -293,8 +293,8 @@ mod app {
|
|||||||
.read_fixed_len_or_timeout_based_using_irq(cx.local.rx_context)
|
.read_fixed_len_or_timeout_based_using_irq(cx.local.rx_context)
|
||||||
.expect("read operation failed");
|
.expect("read operation failed");
|
||||||
}
|
}
|
||||||
if result.error() {
|
if result.has_errors() {
|
||||||
log::warn!("UART error: {:?}", result.error());
|
log::warn!("UART error: {:?}", result.errors.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -113,14 +113,6 @@ pub(super) unsafe trait RegisterInterface {
|
|||||||
/// this type.
|
/// this type.
|
||||||
fn id(&self) -> DynPinId;
|
fn id(&self) -> DynPinId;
|
||||||
|
|
||||||
const PORTA: *const PortRegisterBlock = Porta::ptr();
|
|
||||||
const PORTB: *const PortRegisterBlock = Portb::ptr();
|
|
||||||
const PORTC: *const PortRegisterBlock = Portc::ptr();
|
|
||||||
const PORTD: *const PortRegisterBlock = Portd::ptr();
|
|
||||||
const PORTE: *const PortRegisterBlock = Porte::ptr();
|
|
||||||
const PORTF: *const PortRegisterBlock = Portf::ptr();
|
|
||||||
const PORTG: *const PortRegisterBlock = Portg::ptr();
|
|
||||||
|
|
||||||
/// Change the pin mode
|
/// Change the pin mode
|
||||||
#[inline]
|
#[inline]
|
||||||
fn change_mode(&mut self, mode: DynPinMode) {
|
fn change_mode(&mut self, mode: DynPinMode) {
|
||||||
@ -155,13 +147,13 @@ pub(super) unsafe trait RegisterInterface {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn port_reg(&self) -> &PortRegisterBlock {
|
fn port_reg(&self) -> &PortRegisterBlock {
|
||||||
match self.id().group {
|
match self.id().group {
|
||||||
DynGroup::A => unsafe { &(*Self::PORTA) },
|
DynGroup::A => unsafe { &(*Porta::ptr()) },
|
||||||
DynGroup::B => unsafe { &(*Self::PORTB) },
|
DynGroup::B => unsafe { &(*Portb::ptr()) },
|
||||||
DynGroup::C => unsafe { &(*Self::PORTC) },
|
DynGroup::C => unsafe { &(*Portc::ptr()) },
|
||||||
DynGroup::D => unsafe { &(*Self::PORTD) },
|
DynGroup::D => unsafe { &(*Portd::ptr()) },
|
||||||
DynGroup::E => unsafe { &(*Self::PORTE) },
|
DynGroup::E => unsafe { &(*Porte::ptr()) },
|
||||||
DynGroup::F => unsafe { &(*Self::PORTF) },
|
DynGroup::F => unsafe { &(*Portf::ptr()) },
|
||||||
DynGroup::G => unsafe { &(*Self::PORTG) },
|
DynGroup::G => unsafe { &(*Portg::ptr()) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,10 @@ impl RxPin<Uart2> for Pin<PF9, AltFunc1> {}
|
|||||||
// Regular Definitions
|
// Regular Definitions
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub struct TransferPendingError;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum RxError {
|
pub enum RxError {
|
||||||
@ -82,8 +86,6 @@ pub enum RxError {
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
Rx(RxError),
|
Rx(RxError),
|
||||||
BreakCondition,
|
BreakCondition,
|
||||||
TransferPending,
|
|
||||||
BufferTooShort,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RxError> for Error {
|
impl From<RxError> for Error {
|
||||||
@ -243,50 +245,47 @@ impl IrqContextTimeoutOrMaxSize {
|
|||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct IrqResult {
|
pub struct IrqResult {
|
||||||
pub bytes_read: usize,
|
pub bytes_read: usize,
|
||||||
pub errors: IrqUartError,
|
pub errors: Option<IrqUartError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This struct is used to return the default IRQ handler result to the user
|
/// This struct is used to return the default IRQ handler result to the user
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct IrqResultMaxSizeTimeout {
|
pub struct IrqResultMaxSizeOrTimeout {
|
||||||
complete: bool,
|
complete: bool,
|
||||||
timeout: bool,
|
timeout: bool,
|
||||||
pub errors: IrqUartError,
|
pub errors: Option<IrqUartError>,
|
||||||
pub bytes_read: usize,
|
pub bytes_read: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IrqResultMaxSizeTimeout {
|
impl IrqResultMaxSizeOrTimeout {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
IrqResultMaxSizeTimeout {
|
IrqResultMaxSizeOrTimeout {
|
||||||
complete: false,
|
complete: false,
|
||||||
timeout: false,
|
timeout: false,
|
||||||
errors: IrqUartError::default(),
|
errors: None,
|
||||||
bytes_read: 0,
|
bytes_read: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl IrqResultMaxSizeTimeout {
|
impl IrqResultMaxSizeOrTimeout {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn error(&self) -> bool {
|
pub fn has_errors(&self) -> bool {
|
||||||
if self.errors.overflow || self.errors.parity || self.errors.framing {
|
self.errors.is_some()
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn overflow_error(&self) -> bool {
|
pub fn overflow_error(&self) -> bool {
|
||||||
self.errors.overflow
|
self.errors.map_or(false, |e| e.overflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn framing_error(&self) -> bool {
|
pub fn framing_error(&self) -> bool {
|
||||||
self.errors.framing
|
self.errors.map_or(false, |e| e.framing)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn parity_error(&self) -> bool {
|
pub fn parity_error(&self) -> bool {
|
||||||
self.errors.parity
|
self.errors.map_or(false, |e| e.parity)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -747,7 +746,7 @@ impl<Uart: Instance> Tx<Uart> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug, Copy, Clone)]
|
||||||
pub struct IrqUartError {
|
pub struct IrqUartError {
|
||||||
overflow: bool,
|
overflow: bool,
|
||||||
framing: bool,
|
framing: bool,
|
||||||
@ -784,10 +783,11 @@ impl IrqUartError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum IrqError {
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
BufferTooShort { found: usize, expected: usize },
|
pub struct BufferTooShortError {
|
||||||
Uart(IrqUartError),
|
found: usize,
|
||||||
|
expected: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serial receiver, using interrupts to offload reading to the hardware.
|
/// Serial receiver, using interrupts to offload reading to the hardware.
|
||||||
@ -833,9 +833,9 @@ impl<Uart: Instance> RxWithIrq<Uart> {
|
|||||||
pub fn read_fixed_len_or_timeout_based_using_irq(
|
pub fn read_fixed_len_or_timeout_based_using_irq(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut IrqContextTimeoutOrMaxSize,
|
context: &mut IrqContextTimeoutOrMaxSize,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), TransferPendingError> {
|
||||||
if context.mode != IrqReceptionMode::Idle {
|
if context.mode != IrqReceptionMode::Idle {
|
||||||
return Err(Error::TransferPending);
|
return Err(TransferPendingError);
|
||||||
}
|
}
|
||||||
context.mode = IrqReceptionMode::Pending;
|
context.mode = IrqReceptionMode::Pending;
|
||||||
context.rx_idx = 0;
|
context.rx_idx = 0;
|
||||||
@ -874,8 +874,9 @@ impl<Uart: Instance> RxWithIrq<Uart> {
|
|||||||
/// result of the operation.
|
/// result of the operation.
|
||||||
///
|
///
|
||||||
/// This function will not disable the RX interrupts, so you don't need to call any other
|
/// This function will not disable the RX interrupts, so you don't need to call any other
|
||||||
/// API after calling this function to continue emptying the FIFO.
|
/// API after calling this function to continue emptying the FIFO. RX errors are handled
|
||||||
pub fn irq_handler(&mut self, buf: &mut [u8; 16]) -> Result<IrqResult, IrqUartError> {
|
/// as partial errors and are returned as part of the [IrqResult].
|
||||||
|
pub fn irq_handler(&mut self, buf: &mut [u8; 16]) -> IrqResult {
|
||||||
let mut result = IrqResult::default();
|
let mut result = IrqResult::default();
|
||||||
|
|
||||||
let irq_end = self.uart().irq_end().read();
|
let irq_end = self.uart().irq_end().read();
|
||||||
@ -917,7 +918,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
|
|||||||
self.uart()
|
self.uart()
|
||||||
.irq_clr()
|
.irq_clr()
|
||||||
.write(|w| unsafe { w.bits(irq_end.bits()) });
|
.write(|w| unsafe { w.bits(irq_end.bits()) });
|
||||||
Ok(result)
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function should be called in the user provided UART interrupt handler.
|
/// This function should be called in the user provided UART interrupt handler.
|
||||||
@ -930,19 +931,20 @@ impl<Uart: Instance> RxWithIrq<Uart> {
|
|||||||
/// [IrqContextTimeoutOrMaxSize] structure.
|
/// [IrqContextTimeoutOrMaxSize] structure.
|
||||||
///
|
///
|
||||||
/// If passed buffer is equal to or larger than the specified maximum length, an
|
/// If passed buffer is equal to or larger than the specified maximum length, an
|
||||||
/// [`Error::BufferTooShort`] will be returned
|
/// [BufferTooShortError] will be returned. Other RX errors are treated as partial errors
|
||||||
|
/// and returned inside the [IrqResultMaxSizeOrTimeout] structure.
|
||||||
pub fn irq_handler_max_size_or_timeout_based(
|
pub fn irq_handler_max_size_or_timeout_based(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut IrqContextTimeoutOrMaxSize,
|
context: &mut IrqContextTimeoutOrMaxSize,
|
||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
) -> Result<IrqResultMaxSizeTimeout, IrqError> {
|
) -> Result<IrqResultMaxSizeOrTimeout, BufferTooShortError> {
|
||||||
if buf.len() < context.max_len {
|
if buf.len() < context.max_len {
|
||||||
return Err(IrqError::BufferTooShort {
|
return Err(BufferTooShortError {
|
||||||
found: buf.len(),
|
found: buf.len(),
|
||||||
expected: context.max_len,
|
expected: context.max_len,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let mut result = IrqResultMaxSizeTimeout::default();
|
let mut result = IrqResultMaxSizeOrTimeout::default();
|
||||||
|
|
||||||
let irq_end = self.uart().irq_end().read();
|
let irq_end = self.uart().irq_end().read();
|
||||||
let enb_status = self.uart().enable().read();
|
let enb_status = self.uart().enable().read();
|
||||||
@ -1006,46 +1008,51 @@ impl<Uart: Instance> RxWithIrq<Uart> {
|
|||||||
|
|
||||||
fn read_handler(
|
fn read_handler(
|
||||||
&self,
|
&self,
|
||||||
errors: &mut IrqUartError,
|
errors: &mut Option<IrqUartError>,
|
||||||
read_res: &nb::Result<u8, RxError>,
|
read_res: &nb::Result<u8, RxError>,
|
||||||
) -> Option<u8> {
|
) -> Option<u8> {
|
||||||
match read_res {
|
match read_res {
|
||||||
Ok(byte) => Some(*byte),
|
Ok(byte) => Some(*byte),
|
||||||
Err(nb::Error::WouldBlock) => None,
|
Err(nb::Error::WouldBlock) => None,
|
||||||
Err(nb::Error::Other(e)) => {
|
Err(nb::Error::Other(e)) => {
|
||||||
|
// Ensure `errors` is Some(IrqUartError), initializing if it's None
|
||||||
|
let err = errors.get_or_insert(IrqUartError::default());
|
||||||
|
|
||||||
|
// Now we can safely modify fields inside `err`
|
||||||
match e {
|
match e {
|
||||||
RxError::Overrun => {
|
RxError::Overrun => err.overflow = true,
|
||||||
errors.overflow = true;
|
RxError::Framing => err.framing = true,
|
||||||
}
|
RxError::Parity => err.parity = true,
|
||||||
RxError::Framing => {
|
|
||||||
errors.framing = true;
|
|
||||||
}
|
|
||||||
RxError::Parity => {
|
|
||||||
errors.parity = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_errors(&self, errors: &mut IrqUartError) {
|
fn check_for_errors(&self, errors: &mut Option<IrqUartError>) {
|
||||||
// Read status register again, might have changed since reading received data
|
|
||||||
let rx_status = self.uart().rxstatus().read();
|
let rx_status = self.uart().rxstatus().read();
|
||||||
if rx_status.rxovr().bit_is_set() {
|
|
||||||
errors.overflow = true;
|
if rx_status.rxovr().bit_is_set()
|
||||||
}
|
|| rx_status.rxfrm().bit_is_set()
|
||||||
if rx_status.rxfrm().bit_is_set() {
|
|| rx_status.rxpar().bit_is_set()
|
||||||
errors.framing = true;
|
{
|
||||||
}
|
let err = errors.get_or_insert(IrqUartError::default());
|
||||||
if rx_status.rxpar().bit_is_set() {
|
|
||||||
errors.parity = true;
|
if rx_status.rxovr().bit_is_set() {
|
||||||
|
err.overflow = true;
|
||||||
|
}
|
||||||
|
if rx_status.rxfrm().bit_is_set() {
|
||||||
|
err.framing = true;
|
||||||
|
}
|
||||||
|
if rx_status.rxpar().bit_is_set() {
|
||||||
|
err.parity = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn irq_completion_handler_max_size_timeout(
|
fn irq_completion_handler_max_size_timeout(
|
||||||
&mut self,
|
&mut self,
|
||||||
res: &mut IrqResultMaxSizeTimeout,
|
res: &mut IrqResultMaxSizeOrTimeout,
|
||||||
context: &mut IrqContextTimeoutOrMaxSize,
|
context: &mut IrqContextTimeoutOrMaxSize,
|
||||||
) {
|
) {
|
||||||
self.disable_rx_irq_sources();
|
self.disable_rx_irq_sources();
|
||||||
|
Loading…
Reference in New Issue
Block a user