Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fractional divider support for RMT hal #2127

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
34 changes: 27 additions & 7 deletions esp-hal/src/rmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,34 @@ where
return Err(Error::UnreachableTargetFrequency);
}

let div = (src_clock / frequency) - 1;
let quotient = src_clock / frequency;
let div = quotient - 1;

if div > u8::MAX as u32 {
return Err(Error::UnreachableTargetFrequency);
}

self::chip_specific::configure_clock(div);
// Calculate the greatest common divisor of a and b
fn gcd(mut a: u32, mut b: u32) -> u32 {
while b != 0 {
(a, b) = (b, (a % b))
}
a
}

let mut div_a = 0;
let mut div_b = 0;
let remainder = src_clock.raw() % frequency.raw();
if remainder > 0 {
let gcd = gcd(frequency.raw(), remainder);
let numerator = remainder / gcd;
let denominator = frequency.raw() / gcd;
if numerator < (1 << 5) && denominator < (1 << 5) {
div_a = denominator;
div_b = numerator;
}
}
self::chip_specific::configure_clock(div, div_a, div_b);
Tnze marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}
}
Expand Down Expand Up @@ -1604,7 +1624,7 @@ mod private {

#[cfg(not(any(esp32, esp32s2)))]
mod chip_specific {
pub fn configure_clock(div: u32) {
pub fn configure_clock(div: u32, div_a: u32, div_b: u32) {
#[cfg(not(pcr))]
{
let rmt = unsafe { &*crate::peripherals::RMT::PTR };
Expand All @@ -1616,9 +1636,9 @@ mod chip_specific {
.sclk_div_num()
.bits(div as u8)
.sclk_div_a()
.bits(0)
.bits(div_a as u8)
.sclk_div_b()
.bits(0)
.bits(div_b as u8)
.apb_fifo_mask()
.set_bit()
});
Expand All @@ -1631,9 +1651,9 @@ mod chip_specific {
w.sclk_div_num()
.bits(div as u8)
.sclk_div_a()
.bits(0)
.bits(div_a as u8)
.sclk_div_b()
.bits(0)
.bits(div_b as u8)
});

#[cfg(esp32c6)]
Expand Down
Loading