fn set_frequency(&self, clock_config: &Config) -> Result<(), ConfigError> {
        let timeout = clock_config.timeout;

        let clocks = Clocks::get();
        let source_clk = clocks.apb_clock.as_hz();
        let bus_freq = clock_config.frequency.as_hz();

        let half_cycle: u32 = source_clk / bus_freq / 2;
        // SCL
        let scl_low = half_cycle;
        // default, scl_wait_high < scl_high
        let scl_high = half_cycle / 2 + 2;
        let scl_wait_high = half_cycle - scl_high;
        let sda_hold = half_cycle / 2;
        // scl_wait_high < sda_sample <= scl_high
        let sda_sample = half_cycle / 2 - 1;
        let setup = half_cycle;
        let hold = half_cycle;

        // scl period
        let scl_low_period = scl_low - 1;
        let scl_high_period = scl_high;
        let scl_wait_high_period = scl_wait_high;
        // sda sample
        let sda_hold_time = sda_hold;
        let sda_sample_time = sda_sample;
        // setup
        let scl_rstart_setup_time = setup;
        let scl_stop_setup_time = setup;
        // hold
        let scl_start_hold_time = hold - 1;
        let scl_stop_hold_time = hold;

        configure_clock(
            self.regs(),
            0,
            scl_low_period,
            scl_high_period,
            scl_wait_high_period,
            sda_hold_time,
            sda_sample_time,
            scl_rstart_setup_time,
            scl_stop_setup_time,
            scl_start_hold_time,
            scl_stop_hold_time,
            timeout.apb_cycles(half_cycle)?,
        )?;

        Ok(())
    }
Sets the frequency of the I2C interface by calculating and applying the
associated timings - corresponds to i2c_ll_cal_bus_clk and
i2c_ll_set_bus_timing in ESP-IDF
esp-hal/src/i2c/master/mod.rs