From 731fe7ca4faeb7a6a1c17a412852a5edf612eed9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 23 Sep 2024 11:27:06 +0200 Subject: [PATCH] continue improvements --- bootloader/src/main.rs | 4 +-- va416xx-hal/src/uart.rs | 60 +++++++++++++++++++---------------------- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/bootloader/src/main.rs b/bootloader/src/main.rs index 40dbdf5..73d8788 100644 --- a/bootloader/src/main.rs +++ b/bootloader/src/main.rs @@ -46,13 +46,13 @@ const BOOTLOADER_CRC_ADDR: u32 = BOOTLOADER_END_ADDR - 4; const BOOTLOADER_END_ADDR: u32 = 0x4000; const APP_A_START_ADDR: u32 = BOOTLOADER_END_ADDR; // 0x4000 -// The actual size of the image which is relevant for CRC calculation. + // The actual size of the image which is relevant for CRC calculation. const APP_A_SIZE_ADDR: u32 = APP_B_END_ADDR - 8; // 0x21FF8 const APP_A_CRC_ADDR: u32 = APP_B_END_ADDR - 4; // 0x21FFC pub const APP_A_END_ADDR: u32 = APP_B_END_ADDR - BOOTLOADER_END_ADDR / 2; const APP_B_START_ADDR: u32 = APP_A_END_ADDR; // 0x22000 -// The actual size of the image which is relevant for CRC calculation. + // The actual size of the image which is relevant for CRC calculation. const APP_B_SIZE_ADDR: u32 = APP_B_END_ADDR - 8; // 0x3FFF8 const APP_B_CRC_ADDR: u32 = APP_B_END_ADDR - 4; // 0x3FFFC pub const APP_B_END_ADDR: u32 = NVM_SIZE; // 0x40000 diff --git a/va416xx-hal/src/uart.rs b/va416xx-hal/src/uart.rs index 9204a78..31c4f1d 100644 --- a/va416xx-hal/src/uart.rs +++ b/va416xx-hal/src/uart.rs @@ -308,12 +308,6 @@ pub struct Uart { /// Serial receiver pub struct Rx(Uart); -// Serial receiver, using interrupts to offload reading to the hardware. -pub struct RxWithIrq { - inner: Rx, - // irq_info: IrqContextTimeoutOrMaxSize, -} - /// Serial transmitter pub struct Tx(Uart); @@ -588,7 +582,7 @@ impl, RxPinInst: RxPin, UartInstanc ) { let (inner, pins) = self.downgrade_internal(); let (tx, rx) = inner.split(); - (tx, RxWithIrq { inner: rx }, pins) + (tx, RxWithIrq(rx), pins) } delegate::delegate! { @@ -715,15 +709,23 @@ pub enum IrqError { Uart(IrqUartError), } +// Serial receiver, using interrupts to offload reading to the hardware. +pub struct RxWithIrq(Rx); + impl RxWithIrq { /// This function should be called once at initialization time if the regular /// [Self::irq_handler] is used to read the UART receiver to enable and start the receiver. pub fn start(&mut self) { - self.inner.enable(); + self.0.enable(); self.enable_rx_irq_sources(true); unsafe { enable_interrupt(Uart::IRQ_RX) }; } + #[inline(always)] + pub fn uart(&self) -> &Uart { + &self.0 .0 + } + /// This function is used together with the [Self::irq_handler_max_size_or_timeout_based] /// function to read packets with a maximum size or variable sized packets by using the /// receive timeout of the hardware. @@ -747,7 +749,7 @@ impl RxWithIrq { #[inline] fn enable_rx_irq_sources(&mut self, timeout: bool) { - self.inner.0.irq_enb().modify(|_, w| { + self.uart().irq_enb().modify(|_, w| { if timeout { w.irq_rx_to().set_bit(); } @@ -758,7 +760,7 @@ impl RxWithIrq { #[inline] fn disable_rx_irq_sources(&mut self) { - self.inner.0.irq_enb().modify(|_, w| { + self.uart().irq_enb().modify(|_, w| { w.irq_rx_to().clear_bit(); w.irq_rx_status().clear_bit(); w.irq_rx().clear_bit() @@ -767,11 +769,7 @@ impl RxWithIrq { pub fn cancel_transfer(&mut self) { self.disable_rx_irq_sources(); - self.inner.clear_fifo(); - } - - pub fn uart(&self) -> &Uart { - &self.inner.0 + self.0.clear_fifo(); } /// This function should be called in the user provided UART interrupt handler. @@ -785,8 +783,8 @@ impl RxWithIrq { let mut result = IrqResult::default(); let mut current_idx = 0; - let irq_end = self.inner.0.irq_end().read(); - let enb_status = self.inner.0.enable().read(); + let irq_end = self.uart().irq_end().read(); + let enb_status = self.uart().enable().read(); let rx_enabled = enb_status.rxenable().bit_is_set(); // Half-Full interrupt. We have a guaranteed amount of data we can read. @@ -795,19 +793,19 @@ impl RxWithIrq { // We use this trick/hack because the timeout feature of the peripheral relies on data // being in the RX FIFO. If data continues arriving, another half-full IRQ will fire. // If not, the last byte(s) is/are emptied by the timeout interrupt. - let available_bytes = self.inner.0.rxfifoirqtrg().read().bits() as usize; + let available_bytes = self.uart().rxfifoirqtrg().read().bits() as usize; // If this interrupt bit is set, the trigger level is available at the very least. // Read everything as fast as possible for _ in 0..available_bytes { - buf[current_idx] = (self.inner.0.data().read().bits() & 0xff) as u8; + buf[current_idx] = (self.uart().data().read().bits() & 0xff) as u8; current_idx += 1; } } // Timeout, empty the FIFO completely. if irq_end.irq_rx_to().bit_is_set() { - let read_result = self.inner.read(); + let read_result = self.0.read(); // While there is data in the FIFO, write it into the reception buffer while let Some(byte) = self.read_handler(&mut result.errors, &read_result) { buf[current_idx] = byte; @@ -821,8 +819,7 @@ impl RxWithIrq { } // Clear the interrupt status bits - self.inner - .0 + self.uart() .irq_clr() .write(|w| unsafe { w.bits(irq_end.bits()) }); Ok(result) @@ -852,8 +849,8 @@ impl RxWithIrq { } let mut result = IrqResultMaxSizeTimeout::default(); - let irq_end = self.inner.0.irq_end().read(); - let enb_status = self.inner.0.enable().read(); + let irq_end = self.uart().irq_end().read(); + let enb_status = self.uart().enable().read(); let rx_enabled = enb_status.rxenable().bit_is_set(); // Half-Full interrupt. We have a guaranteed amount of data we can read. @@ -862,7 +859,7 @@ impl RxWithIrq { // We use this trick/hack because the timeout feature of the peripheral relies on data // being in the RX FIFO. If data continues arriving, another half-full IRQ will fire. // If not, the last byte(s) is/are emptied by the timeout interrupt. - let available_bytes = self.inner.0.rxfifoirqtrg().read().bits() as usize; + let available_bytes = self.uart().rxfifoirqtrg().read().bits() as usize; let bytes_to_read = core::cmp::min( available_bytes.saturating_sub(1), @@ -872,7 +869,7 @@ impl RxWithIrq { // If this interrupt bit is set, the trigger level is available at the very least. // Read everything as fast as possible for _ in 0..bytes_to_read { - buf[context.rx_idx] = (self.inner.0.data().read().bits() & 0xff) as u8; + buf[context.rx_idx] = (self.uart().data().read().bits() & 0xff) as u8; context.rx_idx += 1; } @@ -888,7 +885,7 @@ impl RxWithIrq { if context.rx_idx == context.max_len { break; } - let read_result = self.inner.read(); + let read_result = self.0.read(); if let Some(byte) = self.read_handler(&mut result.errors, &read_result) { buf[context.rx_idx] = byte; context.rx_idx += 1; @@ -906,8 +903,7 @@ impl RxWithIrq { } // Clear the interrupt status bits - self.inner - .0 + self.uart() .irq_clr() .write(|w| unsafe { w.bits(irq_end.bits()) }); Ok(result) @@ -943,7 +939,7 @@ impl RxWithIrq { fn check_for_errors(&self, errors: &mut IrqUartError) { // Read status register again, might have changed since reading received data - let rx_status = self.inner.0.rxstatus().read(); + let rx_status = self.uart().rxstatus().read(); if rx_status.rxovr().bit_is_set() { errors.overflow = true; } @@ -961,7 +957,7 @@ impl RxWithIrq { context: &mut IrqContextTimeoutOrMaxSize, ) { self.disable_rx_irq_sources(); - self.inner.disable(); + self.0.disable(); res.bytes_read = context.rx_idx; res.complete = true; context.mode = IrqReceptionMode::Idle; @@ -969,7 +965,7 @@ impl RxWithIrq { } pub fn release(self) -> Uart { - self.inner.release() + self.0.release() } }