From d4c46632bf71b966781c21c986223da2b7fd7e3c Mon Sep 17 00:00:00 2001 From: Benjamin Koch <bbbsnowball@gmail.com> Date: Wed, 28 Jun 2023 04:02:09 +0200 Subject: [PATCH] clean up --- firmware/rust1/src/rs485.rs | 28 ++++++++++++++-------------- firmware/rust1/src/uf2updater.rs | 4 ++++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/firmware/rust1/src/rs485.rs b/firmware/rust1/src/rs485.rs index 8fe8ef3..044c5c0 100644 --- a/firmware/rust1/src/rs485.rs +++ b/firmware/rust1/src/rs485.rs @@ -1,5 +1,6 @@ use defmt::*; use embassy_futures::select::*; +use embassy_futures::yield_now; use embassy_rp::gpio; use embassy_rp::pac; use embassy_rp::interrupt::UART0_IRQ; @@ -482,24 +483,25 @@ impl<H: RS485Handler> RS485<H> { */ }, Either4::Fourth(Either3::Third(())) => { - let x = unsafe { embassy_rp::pac::UART0.uartfr().read().rxfe() }; - let x2 = unsafe { embassy_rp::pac::UART0.uartfr().read().0 }; - let mut x5 = 0; - while ! unsafe { embassy_rp::pac::UART0.uartfr().read().rxfe() } { + // We were sometimes missing the last two chars so wait for the IRQ to copy them to the buffer. + let mut wait_for_rx_irq_cnt = 0; + while ! unsafe { embassy_rp::pac::UART0.uartfr().read().rxfe() } && wait_for_rx_irq_cnt < 500 { // wait for IRQ to handle this - x5 += 1; + wait_for_rx_irq_cnt += 1; + if false { + Timer::after(Duration::from_micros(1)).await; + } else { + yield_now().await; + } } + let rx_data = match select(self.rx.read(&mut self.rx_buffer), core::future::ready(())).await { Either::First(Ok(len)) => { // The UART uses a ringbuffer and it only pops data once so we need to ask a second // time if the frame wraps around the end of the ringbuffer and we want all data. - //FIXME There is a race condition: If the ringbuffer was full, it will exactly fill our buffer. - // However, we could be receiving another character right now, which will probably cause a panic in read(). - // -> Actually, pop() has a sane API so I think this cannot happen: The closure returns how - // much bytes have been processed and I think embassy-rp does that correctly. match select(self.rx.read(&mut self.rx_buffer[len..]), core::future::ready(())).await { Either::First(Ok(len2)) => { - info!("DEBUG: We needed two calls to self.rx.read(): {} + {}", len, len2); + //info!("DEBUG: We needed two calls to self.rx.read(): {} + {}", len, len2); if false { // ... and a third time's the charm because we may have received the last char right now. // -> Actually, it isn't. That's still not enough so we have the loop with rxfe above. @@ -524,10 +526,8 @@ impl<H: RS485Handler> RS485<H> { Ok(&self.rx_buffer[0..0]) }, }; - let x3 = unsafe { embassy_rp::pac::UART0.uartfr().read().rxfe() }; - let x4 = unsafe { embassy_rp::pac::UART0.uartfr().read().0 }; - if !x || !x3 { - info!("DEBUG: RX: {} bytes, {}, {}, {}, {}, x5={}", rx_data.map(|x| x.len()), x, x2, x3, x4, x5); + if wait_for_rx_irq_cnt > 0 { + info!("DEBUG: RX: {} bytes, waited for {} cycles", rx_data.map(|x| x.len()), wait_for_rx_irq_cnt); } //let addr = unsafe { embassy_rp::pac::PIO0.sm(0).addr().read().addr() }; diff --git a/firmware/rust1/src/uf2updater.rs b/firmware/rust1/src/uf2updater.rs index da0c002..344b780 100644 --- a/firmware/rust1/src/uf2updater.rs +++ b/firmware/rust1/src/uf2updater.rs @@ -90,6 +90,7 @@ impl<const FLASH_SIZE: usize> UF2UpdateHandler<FLASH_SIZE> { } pub fn write(self: &mut Self, pos: u32, data: &[u8]) -> Result<(), ModbusErrorCode> { + //info!("UF2Updater::write: {}, len={}", pos, data.len()); if data.len() > 256 { // We could handle these cases but we are limited by Modbus frames anyway. info!("Too much data in one call to UF2UpdateHandler::write()"); @@ -144,6 +145,9 @@ impl<const FLASH_SIZE: usize> UF2UpdateHandler<FLASH_SIZE> { let uf2_block = &self.buf.0[0..512]; + //info!("process_sector: {}", uf2_block); + //info!("process_sector: len={}", uf2_block.len()); + let uf2_header = Uf2BlockHeader::read_from_prefix(uf2_block).unwrap(); let uf2_footer = Uf2BlockFooter::read_from_suffix(uf2_block).unwrap(); if uf2_header.magic_start0 != UF2_MAGIC_START0 || uf2_header.magic_start1 != UF2_MAGIC_START1 || uf2_footer.magic_end != UF2_MAGIC_END { -- GitLab