From e8fd09ba5b93fcd5859bb76ab0c95fc0fdf26573 Mon Sep 17 00:00:00 2001 From: Benjamin Koch <bbbsnowball@gmail.com> Date: Fri, 9 Jun 2023 18:24:29 +0200 Subject: [PATCH] make baud rate configurable --- firmware/rust1/src/rs485.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/firmware/rust1/src/rs485.rs b/firmware/rust1/src/rs485.rs index 93165c6..4df0d0d 100644 --- a/firmware/rust1/src/rs485.rs +++ b/firmware/rust1/src/rs485.rs @@ -3,6 +3,7 @@ use embassy_futures::select::*; use embassy_rp::gpio; use embassy_rp::pac; use embassy_rp::interrupt::UART0_IRQ; +use embassy_rp::uart::Parity; use embassy_time::{Duration, Timer}; use embassy_embedded_hal::SetConfig; use embassy_rp::peripherals::{self, UART0}; @@ -12,6 +13,8 @@ use embassy_rp::relocate::RelocatedProgram; use embassy_rp::Peripheral; use {defmt_rtt as _, panic_probe as _}; use fixed::traits::ToFixed; +use fixed::types::U24F8; +use fixed::types::U56F8; use fixed_macro::types::U56F8; use futures::Future; @@ -37,6 +40,8 @@ pub struct RS485<H: RS485Handler> { dma_channel: peripherals::DMA_CH0, tx_dma_channel: peripherals::DMA_CH2, rx: UartRx<'static, UART0, uart::Async>, + uart_baud_rate: u32, + uart_parity: Parity, handler: H } @@ -90,7 +95,13 @@ impl<H: RS485Handler> RS485<H> { rx_dma_channel, uart_config, ); - RS485 { pio, rx_pin: rx_pin_for_autobaud, tx_pin, tx_en_pin, dma_channel, tx_dma_channel, rx: uart_rx, handler } + RS485 { + pio, rx_pin: rx_pin_for_autobaud, tx_pin, tx_en_pin, dma_channel, tx_dma_channel, + rx: uart_rx, + uart_baud_rate: uart_config.baudrate, + uart_parity: uart_config.parity, + handler, + } } pub async fn run_task(mut self: Self) { @@ -208,8 +219,9 @@ impl<H: RS485Handler> RS485<H> { let mut cfg = Config::default(); let loaded_program = common.load_program(&relocated); cfg.use_program(&loaded_program, &[]); + const CPU_CLK: u32 = 125_000_000; const SM_FREQ: u32 = 25_000_000; - cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(25_000_000 /* SM_FREQ */)).to_fixed(); + cfg.clock_divider = U24F8::from_num(CPU_CLK / SM_FREQ); cfg.shift_in = ShiftConfig { auto_fill: true, threshold: 32, @@ -230,7 +242,10 @@ impl<H: RS485Handler> RS485<H> { // Timeout: Modbus wants 3.5 char times between frames but we should detect the end of a frame // after 1.5 char times. This is 0.86 ms at 19200 baud (8e1, i.e. 11 baud times per char). // We need two clocks for each loop. - let timeout_start_value = (SM_FREQ as f32 * 0.86e-3 / 2.) as u32; + //let timeout_start_value = (SM_FREQ as f32 * 0.86e-3 / 2.) as u32; + let symbols_per_byte = if self.uart_parity == Parity::ParityNone { 10 } else { 11 }; + let timeout_seconds = 1.5 * symbols_per_byte as f32 * 1000. / self.uart_baud_rate as f32; + let timeout_start_value = (SM_FREQ as f32 * timeout_seconds / 2.) as u32; sm.tx().push(timeout_start_value); info!("timeout_start_value: {} = 0x{:08x}", timeout_start_value, timeout_start_value); @@ -264,8 +279,7 @@ impl<H: RS485Handler> RS485<H> { let tx_en_pin_pio = common.make_pio_pin(self.tx_en_pin); let loaded_program = common.load_program(&relocated); cfg.use_program(&loaded_program, &[&tx_en_pin_pio, &tx_pin_pio]); - const BAUD_RATE: u32 = 19200; - cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(76800 /* BAUD_RATE*4 */)).to_fixed(); + cfg.clock_divider = (U56F8::from_num(CPU_CLK) / U56F8::from_num(self.uart_baud_rate*4)).to_fixed(); cfg.shift_out = ShiftConfig { auto_fill: false, threshold: 32, -- GitLab