From ea2e5fee569365525ee1e26e2dfbdeb060ae02de Mon Sep 17 00:00:00 2001 From: Benjamin Koch <bbbsnowball@gmail.com> Date: Wed, 28 Jun 2023 03:47:35 +0200 Subject: [PATCH] avoid race condition --- firmware/rust1/src/modbus_server.rs | 2 +- firmware/rust1/src/rs485.rs | 30 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/firmware/rust1/src/modbus_server.rs b/firmware/rust1/src/modbus_server.rs index aa6d6bf..ea79739 100644 --- a/firmware/rust1/src/modbus_server.rs +++ b/firmware/rust1/src/modbus_server.rs @@ -477,7 +477,7 @@ impl<REGS: ModbusRegisters> RS485Handler for ModbusServer<REGS> { let calculated_crc = CRC.checksum(rx_data); const CORRECT_CRC: u16 = 0; // because we include the CRC bytes in our calculation if calculated_crc != CORRECT_CRC { - info!("CRC: {:04x} (should be zero)", calculated_crc); + warn!("CRC: {:04x} (should be zero)", calculated_crc); } if calculated_crc == CORRECT_CRC { diff --git a/firmware/rust1/src/rs485.rs b/firmware/rust1/src/rs485.rs index 771255e..8fe8ef3 100644 --- a/firmware/rust1/src/rs485.rs +++ b/firmware/rust1/src/rs485.rs @@ -482,6 +482,13 @@ 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() } { + // wait for IRQ to handle this + x5 += 1; + } 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 @@ -493,7 +500,20 @@ impl<H: RS485Handler> RS485<H> { 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); - Ok(&self.rx_buffer[0..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. + match select(self.rx.read(&mut self.rx_buffer[len+len2..]), core::future::ready(())).await { + Either::First(Ok(len3)) => { + info!("DEBUG: We needed three calls to self.rx.read(): {} + {} + {}", len, len2, len3); + Ok(&self.rx_buffer[0..len+len2+len3]) + }, + Either::First(Err(err)) => Err(err), // oops, we are ignoring the previous data + Either::Second(()) => Ok(&self.rx_buffer[0..len+len2]), + } + } else { + Ok(&self.rx_buffer[0..len+len2]) + } }, Either::First(Err(err)) => Err(err), // oops, we are ignoring the previous data Either::Second(()) => Ok(&self.rx_buffer[0..len]), @@ -504,6 +524,14 @@ 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); + } + + //let addr = unsafe { embassy_rp::pac::PIO0.sm(0).addr().read().addr() }; + //info!("DEBUG: pio {}", addr); if tx_in_progress { // use a dummy closure to fix the type of the option because I don't know a better way... -- GitLab