From 81da6f12fef54e9f6e0a8c97f38b59ab4b2b6b16 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Wed, 9 Nov 2022 15:34:44 +0000 Subject: [PATCH 1/2] Allow setting clock divisors on running state machines The documentation of CLKDIV_RESTART contains the following sentence: "Note also that CLKDIV_RESTART can be written to whilst the state machine is running, and this is useful to resynchronise clock dividers after the divisors (SMx_CLKDIV) have been changed on-the-fly." This implies that it's allowed to change the value of CLKDIV on a running state machine. --- rp2040-hal/src/pio.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/rp2040-hal/src/pio.rs b/rp2040-hal/src/pio.rs index 486af5d..942122d 100644 --- a/rp2040-hal/src/pio.rs +++ b/rp2040-hal/src/pio.rs @@ -636,6 +636,20 @@ impl StateMachine { } } } + + /// Change the clock divider of a state machine. + pub fn set_clock_divisor(&mut self, divisor: f32) { + // sm frequency = clock freq / (CLKDIV_INT + CLKDIV_FRAC / 256) + let int = divisor as u16; + let frac = ((divisor - int as f32) * 256.0) as u8; + + self.sm.set_clock_divisor(int, frac); + } + + /// Change the clock divider of a state machine using a 16.8 fixed point value. + pub fn clock_divisor_fixed_point(&mut self, int: u16, frac: u8) { + self.sm.set_clock_divisor(int, frac); + } } // Safety: All shared register accesses are atomic. @@ -656,20 +670,6 @@ impl StateMachine { } } - /// Change the clock divider of a stopped state machine. - pub fn set_clock_divisor(&mut self, divisor: f32) { - // sm frequency = clock freq / (CLKDIV_INT + CLKDIV_FRAC / 256) - let int = divisor as u16; - let frac = ((divisor - int as f32) * 256.0) as u8; - - self.sm.set_clock_divisor(int, frac); - } - - /// Change the clock divider of a stopped state machine using a 16.8 fixed point value. - pub fn clock_divisor_fixed_point(&mut self, int: u16, frac: u8) { - self.sm.set_clock_divisor(int, frac); - } - /// Sets the pin state for the specified pins. /// /// The user has to make sure that they do not select any pins that are in use by any From 2f077a434baa448c3b84cba32e8d51f7e384497f Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Thu, 10 Nov 2022 21:17:48 +0000 Subject: [PATCH 2/2] Update doc comment of set_clock_divisor, clock_divisor_fixed_point --- rp2040-hal/src/pio.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rp2040-hal/src/pio.rs b/rp2040-hal/src/pio.rs index 942122d..2b9e435 100644 --- a/rp2040-hal/src/pio.rs +++ b/rp2040-hal/src/pio.rs @@ -638,6 +638,10 @@ impl StateMachine { } /// Change the clock divider of a state machine. + /// + /// Changing the clock divider of a running state machine is allowed + /// and guaranteed to not cause any glitches, but the exact timing of + /// clock pulses during the change is not specified. pub fn set_clock_divisor(&mut self, divisor: f32) { // sm frequency = clock freq / (CLKDIV_INT + CLKDIV_FRAC / 256) let int = divisor as u16; @@ -647,6 +651,10 @@ impl StateMachine { } /// Change the clock divider of a state machine using a 16.8 fixed point value. + /// + /// Changing the clock divider of a running state machine is allowed + /// and guaranteed to not cause any glitches, but the exact timing of + /// clock pulses during the change is not specified. pub fn clock_divisor_fixed_point(&mut self, int: u16, frac: u8) { self.sm.set_clock_divisor(int, frac); }