Confused about use of `embedded_time::rate`

I am attempting to write an I2C slave device for the RP2040 based on the existing master implementation and inspired by some similar code for the stm32. The function to initially set up the peripheral has a signature that looks like this (excerpted from the macro that creates one for each peripheral):

using embedded_time::rate::Hertz;


impl<SCLPIN: PinId + BankPinId, SDAPIN: PinId + BankPinId> I2CSlave<$I2Cx, (Pin<SCLPIN, FunctionI2C>, Pin<SDAPIN, FunctionI2C>)> {
    pub fn $i2cx<F, SystemF>(
        i2c: $I2Cx,
        sclpin: Pin<SCLPIN, FunctionI2C>,
        sdapin: Pin<SDAPIN, FunctionI2C>,
        freq: F,
        address: u8,
        resets: &mut RESETS,
        system_clock: SystemF) -> Self
    where
        F: Into<Hertz<u32>>,
        SCLPIN: i2c::SclPin<$I2Cx>,
        SDAPIN: i2c::SdaPin<$I2Cx>,
        SystemF: Into<Hertz<u32>>,
    {

And is called like this:

using embedded_time::rate::Extensions;

let mut i2cs = i2c_slave::I2CSlave::i2c1(
    c.device.I2C1,
    scl_pin,
    sda_pin,
    400.kHz(),
    0x20,
    &mut resets,
    _clocks.peripheral_clock,
);

This results in the error

error[E0277]: the trait bound `Hertz: From<Kilohertz>` is not satisfied
   --> src/main.rs:101:24
    |
101 |         let mut i2cs = i2c_slave::I2CSlave::i2c1(
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<Kilohertz>` is not implemented for `Hertz`
    |
    = help: the following implementations were found:
              <Hertz as From<pico::rp2040_hal::clocks::AdcClock>>
              <Hertz as From<pico::rp2040_hal::clocks::GpioOutput0Clock>>
              <Hertz as From<pico::rp2040_hal::clocks::GpioOutput1Clock>>
              <Hertz as From<pico::rp2040_hal::clocks::GpioOutput2Clock>>
            and 25 others
    = note: required because of the requirements on the impl of `Into<Hertz>` for `Kilohertz`
note: required by `I2CSlave::<I2C1, (pico::rp2040_hal::gpio::Pin<SCLPIN, pico::rp2040_hal::gpio::Function<pico::rp2040_hal::gpio::I2C>>, pico::rp2040_hal::gpio::
Pin<SDAPIN, pico::rp2040_hal::gpio::Function<pico::rp2040_hal::gpio::I2C>>)>::i2c1`
   --> src/i2c_slave.rs:89:17
    |
89  | /                 pub fn $i2cx<F, SystemF>(
90  | |                     i2c: $I2Cx,
91  | |                     sclpin: Pin<SCLPIN, FunctionI2C>,
92  | |                     sdapin: Pin<SDAPIN, FunctionI2C>,
...   |
100 | |                     SDAPIN: i2c::SdaPin<$I2Cx>,
101 | |                     SystemF: Into<Hertz<u32>>,
    | |______________________________________________^

Converting kHz to Hz seems to be one of the examples in the documentation of embedded_time, why doesn't it work in this case?

How can I see all 25 implementations mentioned in the help message that would work?

And for the bonus round, why does the code I linked at the top work at all? When I tried to compile something very similar, none of the math on rates worked because system_clock was a Hertz<u64> and freq was a Hertz<u32>.

Just in case anyone else has this problem, I did figure it out. The reason the linked code works is because there is an as u32 that I missed in the first few read-throughs. This turns out to be the solution to my problem as well, Hertz: From<Kilohertz> is only defined for Hertz<u64>, using Hertz<u32> does not work.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.