diff --git a/CHANGELOG.md b/CHANGELOG.md index f08504b7b6c..2bb07561ed8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Implement enabling/disabling BLE clock on ESP32-C6 (#784) + ### Changed ### Fixed diff --git a/esp-hal-common/src/soc/esp32c6/radio_clocks.rs b/esp-hal-common/src/soc/esp32c6/radio_clocks.rs index bfeaf77aac5..8b14c5b419e 100644 --- a/esp-hal-common/src/soc/esp32c6/radio_clocks.rs +++ b/esp-hal-common/src/soc/esp32c6/radio_clocks.rs @@ -18,7 +18,7 @@ impl RadioClockController for RadioClockControl { match peripheral { RadioPeripherals::Phy => enable_phy(), RadioPeripherals::Wifi => wifi_clock_enable(), - RadioPeripherals::Bt => todo!("BLE not yet supported"), + RadioPeripherals::Bt => ble_clock_enable(), RadioPeripherals::Ieee802154 => ieee802154_clock_enable(), } } @@ -27,7 +27,7 @@ impl RadioClockController for RadioClockControl { match peripheral { RadioPeripherals::Phy => disable_phy(), RadioPeripherals::Wifi => wifi_clock_disable(), - RadioPeripherals::Bt => todo!("BLE not yet supported"), + RadioPeripherals::Bt => ble_clock_disable(), RadioPeripherals::Ieee802154 => ieee802154_clock_disable(), } } @@ -245,6 +245,88 @@ fn ieee802154_clock_disable() { .modify(|_, w| w.clk_coex_en().clear_bit()); } +fn ble_clock_enable() { + let modem_syscon = unsafe { &*esp32c6::MODEM_SYSCON::PTR }; + let modem_lpcon = unsafe { &*esp32c6::MODEM_LPCON::PTR }; + + modem_syscon.clk_conf.modify(|_, w| { + w.clk_etm_en() + .set_bit() + .clk_modem_sec_en() + .set_bit() + .clk_modem_sec_ecb_en() + .set_bit() + .clk_modem_sec_ccm_en() + .set_bit() + .clk_modem_sec_bah_en() + .set_bit() + .clk_modem_sec_apb_en() + .set_bit() + .clk_ble_timer_en() + .set_bit() + }); + + modem_syscon.clk_conf1.modify(|_, w| { + w.clk_fe_apb_en() + .set_bit() + .clk_fe_cal_160m_en() + .set_bit() + .clk_fe_160m_en() + .set_bit() + .clk_fe_80m_en() + .set_bit() + .clk_bt_apb_en() + .set_bit() + .clk_bt_en() + .set_bit() + }); + + modem_lpcon + .clk_conf + .modify(|_, w| w.clk_coex_en().set_bit()); +} + +fn ble_clock_disable() { + let modem_syscon = unsafe { &*esp32c6::MODEM_SYSCON::PTR }; + let modem_lpcon = unsafe { &*esp32c6::MODEM_LPCON::PTR }; + + modem_syscon.clk_conf.modify(|_, w| { + w.clk_etm_en() + .clear_bit() + .clk_modem_sec_en() + .clear_bit() + .clk_modem_sec_ecb_en() + .clear_bit() + .clk_modem_sec_ccm_en() + .clear_bit() + .clk_modem_sec_bah_en() + .clear_bit() + .clk_modem_sec_apb_en() + .clear_bit() + .clk_ble_timer_en() + .clear_bit() + }); + + modem_syscon.clk_conf1.modify(|_, w| { + w.clk_fe_apb_en() + .clear_bit() + .clk_fe_cal_160m_en() + .clear_bit() + .clk_fe_160m_en() + .clear_bit() + .clk_fe_80m_en() + .clear_bit() + .clk_bt_apb_en() + .clear_bit() + .clk_bt_en() + .clear_bit() + }); + + modem_lpcon + .clk_conf + .modify(|_, w| w.clk_coex_en().set_bit()); +} + fn reset_mac() { // empty }