diff options
| author | Eric Seppanen <[email protected]> | 2025-12-13 13:56:54 -0800 |
|---|---|---|
| committer | Eric Seppanen <[email protected]> | 2025-12-13 14:40:40 -0800 |
| commit | 215804facc43623fd8bb9170c05032e7f8540025 (patch) | |
| tree | 18c836791a3f7dc8248f9f8df2394336fe2b95fe | |
| parent | d2740f8fad566f30bed24df970f1297209005126 (diff) | |
add unit test for calculate_pio_clock_divider
The test will fail, because the current implementation doesn't calculate
the fractional part.
| -rw-r--r-- | embassy-rp/src/pio_programs/clock_divider.rs | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/embassy-rp/src/pio_programs/clock_divider.rs b/embassy-rp/src/pio_programs/clock_divider.rs index 02e353f53..687fd53ba 100644 --- a/embassy-rp/src/pio_programs/clock_divider.rs +++ b/embassy-rp/src/pio_programs/clock_divider.rs | |||
| @@ -16,10 +16,38 @@ use crate::clocks::clk_sys_freq; | |||
| 16 | /// A fixed-point divider value suitable for use in a PIO state machine configuration | 16 | /// A fixed-point divider value suitable for use in a PIO state machine configuration |
| 17 | #[inline] | 17 | #[inline] |
| 18 | pub fn calculate_pio_clock_divider(target_hz: u32) -> fixed::FixedU32<U8> { | 18 | pub fn calculate_pio_clock_divider(target_hz: u32) -> fixed::FixedU32<U8> { |
| 19 | calculate_pio_clock_divider_inner(clk_sys_freq(), target_hz) | ||
| 20 | } | ||
| 21 | |||
| 22 | #[inline] | ||
| 23 | fn calculate_pio_clock_divider_inner(sys_freq: u32, target_hz: u32) -> fixed::FixedU32<U8> { | ||
| 19 | // Requires a non-zero frequency | 24 | // Requires a non-zero frequency |
| 20 | assert!(target_hz > 0, "PIO clock frequency cannot be zero"); | 25 | assert!(target_hz > 0, "PIO clock frequency cannot be zero"); |
| 21 | 26 | ||
| 22 | // Calculate the divider | 27 | // Calculate the divider |
| 23 | let divider = (clk_sys_freq() + target_hz / 2) / target_hz; | 28 | let divider = (sys_freq + target_hz / 2) / target_hz; |
| 24 | divider.to_fixed() | 29 | divider.to_fixed() |
| 25 | } | 30 | } |
| 31 | |||
| 32 | #[cfg(test)] | ||
| 33 | mod tests { | ||
| 34 | use super::*; | ||
| 35 | |||
| 36 | #[test] | ||
| 37 | fn clock_divider_math() { | ||
| 38 | // A simple divider that must have a fractional part. | ||
| 39 | let divider = calculate_pio_clock_divider_inner(125_000_000, 40_000_000); | ||
| 40 | let expected: fixed::FixedU32<U8> = 3.125.to_fixed(); | ||
| 41 | assert_eq!(divider, expected); | ||
| 42 | |||
| 43 | // A system clk so high it would overflow a u32 if shifted left. | ||
| 44 | let divider = calculate_pio_clock_divider_inner(2_000_000_000, 40_000); | ||
| 45 | let expected: fixed::FixedU32<U8> = 50000.to_fixed(); | ||
| 46 | assert_eq!(divider, expected); | ||
| 47 | |||
| 48 | // A divider that requires all 8 fractional bits. | ||
| 49 | let divider = calculate_pio_clock_divider_inner(134_283_264, 16_777_216); | ||
| 50 | let expected: fixed::FixedU32<U8> = 8.00390625.to_fixed(); | ||
| 51 | assert_eq!(divider, expected); | ||
| 52 | } | ||
| 53 | } | ||
