From 713d6291d569cf44ce3a53bc93ddd7d569fb93ed Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Sat, 26 Apr 2025 21:54:48 +0200 Subject: [PATCH] Scale clock dividers in HD44780, rotary encoder, and stepper driver based on system clock frequency --- embassy-rp/src/pio_programs/hd44780.rs | 15 +++++++++++++-- embassy-rp/src/pio_programs/rotary_encoder.rs | 8 +++++++- embassy-rp/src/pio_programs/stepper.rs | 5 +++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/embassy-rp/src/pio_programs/hd44780.rs b/embassy-rp/src/pio_programs/hd44780.rs index 5846a8027..3aa54495f 100644 --- a/embassy-rp/src/pio_programs/hd44780.rs +++ b/embassy-rp/src/pio_programs/hd44780.rs @@ -1,5 +1,6 @@ //! [HD44780 display driver](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) +use crate::clocks::clk_sys_freq; use crate::dma::{AnyChannel, Channel}; use crate::pio::{ Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, @@ -134,7 +135,12 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> { let mut cfg = Config::default(); cfg.use_program(&word_prg.prg, &[&e]); - cfg.clock_divider = 125u8.into(); + + // Scale the divider based on system clock frequency + // Original: 125 at 125 MHz (1 MHz PIO clock) + let word_divider = (clk_sys_freq() / 1_000_000) as u8; // Target 1 MHz PIO clock + cfg.clock_divider = word_divider.into(); + cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); cfg.shift_out = ShiftConfig { auto_fill: true, @@ -160,7 +166,12 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> { let mut cfg = Config::default(); cfg.use_program(&seq_prg.prg, &[&e]); - cfg.clock_divider = 8u8.into(); // ~64ns/insn + + // Original: 8 at 125 MHz (~15.6 MHz PIO clock) + // Comment says ~64ns/insn which is 1/(15.6 MHz) = ~64ns + let seq_divider = (clk_sys_freq() / 15_600_000) as u8; // Target ~15.6 MHz PIO clock (~64ns/insn) + cfg.clock_divider = seq_divider.into(); + cfg.set_jmp_pin(&db7); cfg.set_set_pins(&[&rs, &rw]); cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); diff --git a/embassy-rp/src/pio_programs/rotary_encoder.rs b/embassy-rp/src/pio_programs/rotary_encoder.rs index e520da8a3..7bd463bb8 100644 --- a/embassy-rp/src/pio_programs/rotary_encoder.rs +++ b/embassy-rp/src/pio_programs/rotary_encoder.rs @@ -2,6 +2,7 @@ use fixed::traits::ToFixed; +use crate::clocks::clk_sys_freq; use crate::gpio::Pull; use crate::pio::{ Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, @@ -48,7 +49,12 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> { cfg.set_in_pins(&[&pin_a, &pin_b]); cfg.fifo_join = FifoJoin::RxOnly; cfg.shift_in.direction = ShiftDirection::Left; - cfg.clock_divider = 10_000.to_fixed(); + + // Original: 10_000 at 125 MHz (12.5 KHz PIO clock) + // Scale divider to maintain same PIO clock frequency at different system clocks + let divider = (clk_sys_freq() as f32 / 12_500.0).to_fixed(); + cfg.clock_divider = divider; + cfg.use_program(&program.prg, &[]); sm.set_config(&cfg); sm.set_enable(true); diff --git a/embassy-rp/src/pio_programs/stepper.rs b/embassy-rp/src/pio_programs/stepper.rs index 495191659..6878c32f5 100644 --- a/embassy-rp/src/pio_programs/stepper.rs +++ b/embassy-rp/src/pio_programs/stepper.rs @@ -6,6 +6,7 @@ use fixed::traits::ToFixed; use fixed::types::extra::U8; use fixed::FixedU32; +use crate::clocks::clk_sys_freq; use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine}; use crate::Peri; @@ -64,7 +65,7 @@ impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> { sm.set_pin_dirs(Direction::Out, &[&pin0, &pin1, &pin2, &pin3]); let mut cfg = Config::default(); cfg.set_out_pins(&[&pin0, &pin1, &pin2, &pin3]); - cfg.clock_divider = (125_000_000 / (100 * 136)).to_fixed(); + cfg.clock_divider = (clk_sys_freq() / (100 * 136)).to_fixed(); cfg.use_program(&program.prg, &[]); sm.set_config(&cfg); sm.set_enable(true); @@ -73,7 +74,7 @@ impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> { /// Set pulse frequency pub fn set_frequency(&mut self, freq: u32) { - let clock_divider: FixedU32 = (125_000_000 / (freq * 136)).to_fixed(); + let clock_divider: FixedU32 = (clk_sys_freq() / (freq * 136)).to_fixed(); assert!(clock_divider <= 65536, "clkdiv must be <= 65536"); assert!(clock_divider >= 1, "clkdiv must be >= 1"); self.sm.set_clock_divider(clock_divider);