continue improvements

This commit is contained in:
Robin Müller 2024-09-23 11:27:06 +02:00
parent dc7918a696
commit 731fe7ca4f
Signed by: muellerr
GPG Key ID: A649FB78196E3849
2 changed files with 30 additions and 34 deletions

View File

@ -46,13 +46,13 @@ const BOOTLOADER_CRC_ADDR: u32 = BOOTLOADER_END_ADDR - 4;
const BOOTLOADER_END_ADDR: u32 = 0x4000; const BOOTLOADER_END_ADDR: u32 = 0x4000;
const APP_A_START_ADDR: u32 = BOOTLOADER_END_ADDR; // 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_SIZE_ADDR: u32 = APP_B_END_ADDR - 8; // 0x21FF8
const APP_A_CRC_ADDR: u32 = APP_B_END_ADDR - 4; // 0x21FFC 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; 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 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_SIZE_ADDR: u32 = APP_B_END_ADDR - 8; // 0x3FFF8
const APP_B_CRC_ADDR: u32 = APP_B_END_ADDR - 4; // 0x3FFFC const APP_B_CRC_ADDR: u32 = APP_B_END_ADDR - 4; // 0x3FFFC
pub const APP_B_END_ADDR: u32 = NVM_SIZE; // 0x40000 pub const APP_B_END_ADDR: u32 = NVM_SIZE; // 0x40000

View File

@ -308,12 +308,6 @@ pub struct Uart<UartInstance, Pins> {
/// Serial receiver /// Serial receiver
pub struct Rx<Uart>(Uart); pub struct Rx<Uart>(Uart);
// Serial receiver, using interrupts to offload reading to the hardware.
pub struct RxWithIrq<Uart> {
inner: Rx<Uart>,
// irq_info: IrqContextTimeoutOrMaxSize,
}
/// Serial transmitter /// Serial transmitter
pub struct Tx<Uart>(Uart); pub struct Tx<Uart>(Uart);
@ -588,7 +582,7 @@ impl<TxPinInst: TxPin<UartInstance>, RxPinInst: RxPin<UartInstance>, UartInstanc
) { ) {
let (inner, pins) = self.downgrade_internal(); let (inner, pins) = self.downgrade_internal();
let (tx, rx) = inner.split(); let (tx, rx) = inner.split();
(tx, RxWithIrq { inner: rx }, pins) (tx, RxWithIrq(rx), pins)
} }
delegate::delegate! { delegate::delegate! {
@ -715,15 +709,23 @@ pub enum IrqError {
Uart(IrqUartError), Uart(IrqUartError),
} }
// Serial receiver, using interrupts to offload reading to the hardware.
pub struct RxWithIrq<Uart>(Rx<Uart>);
impl<Uart: Instance> RxWithIrq<Uart> { impl<Uart: Instance> RxWithIrq<Uart> {
/// This function should be called once at initialization time if the regular /// 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. /// [Self::irq_handler] is used to read the UART receiver to enable and start the receiver.
pub fn start(&mut self) { pub fn start(&mut self) {
self.inner.enable(); self.0.enable();
self.enable_rx_irq_sources(true); self.enable_rx_irq_sources(true);
unsafe { enable_interrupt(Uart::IRQ_RX) }; 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] /// 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 /// function to read packets with a maximum size or variable sized packets by using the
/// receive timeout of the hardware. /// receive timeout of the hardware.
@ -747,7 +749,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
#[inline] #[inline]
fn enable_rx_irq_sources(&mut self, timeout: bool) { fn enable_rx_irq_sources(&mut self, timeout: bool) {
self.inner.0.irq_enb().modify(|_, w| { self.uart().irq_enb().modify(|_, w| {
if timeout { if timeout {
w.irq_rx_to().set_bit(); w.irq_rx_to().set_bit();
} }
@ -758,7 +760,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
#[inline] #[inline]
fn disable_rx_irq_sources(&mut self) { 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_to().clear_bit();
w.irq_rx_status().clear_bit(); w.irq_rx_status().clear_bit();
w.irq_rx().clear_bit() w.irq_rx().clear_bit()
@ -767,11 +769,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
pub fn cancel_transfer(&mut self) { pub fn cancel_transfer(&mut self) {
self.disable_rx_irq_sources(); self.disable_rx_irq_sources();
self.inner.clear_fifo(); self.0.clear_fifo();
}
pub fn uart(&self) -> &Uart {
&self.inner.0
} }
/// This function should be called in the user provided UART interrupt handler. /// This function should be called in the user provided UART interrupt handler.
@ -785,8 +783,8 @@ impl<Uart: Instance> RxWithIrq<Uart> {
let mut result = IrqResult::default(); let mut result = IrqResult::default();
let mut current_idx = 0; let mut current_idx = 0;
let irq_end = self.inner.0.irq_end().read(); let irq_end = self.uart().irq_end().read();
let enb_status = self.inner.0.enable().read(); let enb_status = self.uart().enable().read();
let rx_enabled = enb_status.rxenable().bit_is_set(); let rx_enabled = enb_status.rxenable().bit_is_set();
// Half-Full interrupt. We have a guaranteed amount of data we can read. // Half-Full interrupt. We have a guaranteed amount of data we can read.
@ -795,19 +793,19 @@ impl<Uart: Instance> RxWithIrq<Uart> {
// We use this trick/hack because the timeout feature of the peripheral relies on data // 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. // 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. // 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. // If this interrupt bit is set, the trigger level is available at the very least.
// Read everything as fast as possible // Read everything as fast as possible
for _ in 0..available_bytes { 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; current_idx += 1;
} }
} }
// Timeout, empty the FIFO completely. // Timeout, empty the FIFO completely.
if irq_end.irq_rx_to().bit_is_set() { 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 there is data in the FIFO, write it into the reception buffer
while let Some(byte) = self.read_handler(&mut result.errors, &read_result) { while let Some(byte) = self.read_handler(&mut result.errors, &read_result) {
buf[current_idx] = byte; buf[current_idx] = byte;
@ -821,8 +819,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
} }
// Clear the interrupt status bits // Clear the interrupt status bits
self.inner self.uart()
.0
.irq_clr() .irq_clr()
.write(|w| unsafe { w.bits(irq_end.bits()) }); .write(|w| unsafe { w.bits(irq_end.bits()) });
Ok(result) Ok(result)
@ -852,8 +849,8 @@ impl<Uart: Instance> RxWithIrq<Uart> {
} }
let mut result = IrqResultMaxSizeTimeout::default(); let mut result = IrqResultMaxSizeTimeout::default();
let irq_end = self.inner.0.irq_end().read(); let irq_end = self.uart().irq_end().read();
let enb_status = self.inner.0.enable().read(); let enb_status = self.uart().enable().read();
let rx_enabled = enb_status.rxenable().bit_is_set(); let rx_enabled = enb_status.rxenable().bit_is_set();
// Half-Full interrupt. We have a guaranteed amount of data we can read. // Half-Full interrupt. We have a guaranteed amount of data we can read.
@ -862,7 +859,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
// We use this trick/hack because the timeout feature of the peripheral relies on data // 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. // 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. // 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( let bytes_to_read = core::cmp::min(
available_bytes.saturating_sub(1), available_bytes.saturating_sub(1),
@ -872,7 +869,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
// If this interrupt bit is set, the trigger level is available at the very least. // If this interrupt bit is set, the trigger level is available at the very least.
// Read everything as fast as possible // Read everything as fast as possible
for _ in 0..bytes_to_read { 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; context.rx_idx += 1;
} }
@ -888,7 +885,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
if context.rx_idx == context.max_len { if context.rx_idx == context.max_len {
break; 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) { if let Some(byte) = self.read_handler(&mut result.errors, &read_result) {
buf[context.rx_idx] = byte; buf[context.rx_idx] = byte;
context.rx_idx += 1; context.rx_idx += 1;
@ -906,8 +903,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
} }
// Clear the interrupt status bits // Clear the interrupt status bits
self.inner self.uart()
.0
.irq_clr() .irq_clr()
.write(|w| unsafe { w.bits(irq_end.bits()) }); .write(|w| unsafe { w.bits(irq_end.bits()) });
Ok(result) Ok(result)
@ -943,7 +939,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
fn check_for_errors(&self, errors: &mut IrqUartError) { fn check_for_errors(&self, errors: &mut IrqUartError) {
// Read status register again, might have changed since reading received data // 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() { if rx_status.rxovr().bit_is_set() {
errors.overflow = true; errors.overflow = true;
} }
@ -961,7 +957,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
context: &mut IrqContextTimeoutOrMaxSize, context: &mut IrqContextTimeoutOrMaxSize,
) { ) {
self.disable_rx_irq_sources(); self.disable_rx_irq_sources();
self.inner.disable(); self.0.disable();
res.bytes_read = context.rx_idx; res.bytes_read = context.rx_idx;
res.complete = true; res.complete = true;
context.mode = IrqReceptionMode::Idle; context.mode = IrqReceptionMode::Idle;
@ -969,7 +965,7 @@ impl<Uart: Instance> RxWithIrq<Uart> {
} }
pub fn release(self) -> Uart { pub fn release(self) -> Uart {
self.inner.release() self.0.release()
} }
} }