From 43ec8916b49023558db7fb286519f34130af85a5 Mon Sep 17 00:00:00 2001 From: Claas Date: Mon, 4 Nov 2024 22:26:15 +0100 Subject: [PATCH] Try out buffered UART to allow variable length for modbus responses this is useful because temperature sensor response has different length than the set set point response --- fan-controller/src/fan.rs | 16 +++++++++++----- fan-controller/src/main.rs | 25 +++++++++++++++++++++---- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/fan-controller/src/fan.rs b/fan-controller/src/fan.rs index a4f4704..949cc11 100644 --- a/fan-controller/src/fan.rs +++ b/fan-controller/src/fan.rs @@ -7,9 +7,13 @@ use defmt::{error, info, Format}; use embassy_rp::dma::Channel; use embassy_rp::gpio::{Level, Output, Pin}; use embassy_rp::interrupt::typelevel::Binding; -use embassy_rp::uart::{Async, DataBits, InterruptHandler, Parity, RxPin, StopBits, TxPin, Uart}; +use embassy_rp::uart::{ + Async, BufferedInterruptHandler, BufferedUart, DataBits, InterruptHandler, Parity, RxPin, + StopBits, TxPin, Uart, +}; use embassy_rp::{uart, Peripheral}; use embassy_time::{block_for, with_timeout, Duration, TimeoutError, Timer}; +use embedded_io_async::{Read, Write}; pub(crate) const BAUD_RATE: u32 = 19_200; pub(crate) fn get_configuration() -> uart::Config { @@ -79,7 +83,7 @@ pub(crate) enum Fan { /// Modbus messages are sent through UART to MAX845 to control fans. /// The pin is used to enable the DE pin to switch between reading and writing pub(crate) struct Client<'a, UART: uart::Instance, PIN: Pin> { - uart: Uart<'a, UART, Async>, + uart: BufferedUart<'a, UART>, driver_enable: Output<'a, PIN>, } @@ -88,12 +92,14 @@ impl<'a, UART: uart::Instance, PIN: Pin> Client<'a, UART, PIN> { uart: impl Peripheral

+ 'a, tx: impl Peripheral

> + 'a, rx: impl Peripheral

> + 'a, - irq: impl Binding>, + irq: impl Binding>, tx_dma: impl Peripheral

+ 'a, rx_dma: impl Peripheral

+ 'a, driver_enable: impl Peripheral

+ 'a, + tx_buffer: &'a mut [u8], + rx_buffer: &'a mut [u8], ) -> Self { - let uart = Uart::new(uart, tx, rx, irq, tx_dma, rx_dma, get_configuration()); + let uart = BufferedUart::new(uart, irq, tx, rx, tx_buffer, rx_buffer, get_configuration()); let driver_enable = Output::new(driver_enable, Level::Low); Self { @@ -110,7 +116,7 @@ impl<'a, UART: uart::Instance, PIN: Pin> Client<'a, UART, PIN> { // As ref because &[u8; 8] is not the same as &[u8] let result = with_timeout( configuration::FAN_TIMEOUT, - self.uart.write(message.as_ref()), + self.uart.write_all(message.as_ref()), ) .await?; // let result = self.uart.blocking_write(message.as_ref()); diff --git a/fan-controller/src/main.rs b/fan-controller/src/main.rs index 9b6aefd..0dca458 100644 --- a/fan-controller/src/main.rs +++ b/fan-controller/src/main.rs @@ -28,7 +28,7 @@ use embassy_rp::peripherals::{ DMA_CH0, PIN_12, PIN_13, PIN_18, PIN_23, PIN_24, PIN_25, PIN_29, PIN_4, PIO0, UART0, }; use embassy_rp::pio::{InterruptHandler as PioInterruptHandler, Pio, PioPin}; -use embassy_rp::uart::{InterruptHandler as UartInterruptHandler, Uart}; +use embassy_rp::uart::{BufferedInterruptHandler, InterruptHandler as UartInterruptHandler, Uart}; use embassy_rp::{bind_interrupts, dma, pio, uart, Peripheral, Peripherals}; use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; use embassy_sync::channel; @@ -74,7 +74,7 @@ mod mqtt; bind_interrupts!(struct Irqs { PIO0_IRQ_0 => PioInterruptHandler; - UART0_IRQ => UartInterruptHandler; + UART0_IRQ => BufferedInterruptHandler; }); #[embassy_executor::task] @@ -1013,7 +1013,15 @@ async fn mqtt_task( } //TODO cancel all tasks when client loses connection - join5(listen, talk, keep_alive, set_up, update_homeassistant()).await; + join5( + listen, + talk, + keep_alive, + set_up, + // Join because there is only a join with max 5 arguments 😬 + join(update_homeassistant(), poll_sensors()), + ) + .await; } /// This task handles inputs from physical buttons to change the fan speed @@ -1166,7 +1174,16 @@ async fn main(spawner: Spawner) { // UART - let client = fan::Client::new(uart0, pin_12, pin_13, Irqs, dma_ch1, dma_ch2, pin_4); + /// Transmit buffer for UART + static TX_BUFFER: StaticCell<[u8; 16]> = StaticCell::new(); + let tx_buffer = &mut TX_BUFFER.init([0; 16])[..]; + /// Receive buffer for UART + static RX_BUFFER: StaticCell<[u8; 16]> = StaticCell::new(); + let rx_buffer = &mut RX_BUFFER.init([0; 16])[..]; + + let client = fan::Client::new( + uart0, pin_12, pin_13, Irqs, dma_ch1, dma_ch2, pin_4, tx_buffer, rx_buffer, + ); //TODO load fan setting from fan // Inner scope to drop the guard after assigning { -- 2.51.2