Skip to content

Commit

Permalink
Move RadioClockController impls to clock
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Feb 5, 2025
1 parent 8c69e8c commit 9d51284
Show file tree
Hide file tree
Showing 21 changed files with 816 additions and 925 deletions.
122 changes: 122 additions & 0 deletions esp-hal/src/clock/clocks_ll/esp32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,125 @@ fn esp32_update_cpu_freq(mhz: u32) {
(G_TICKS_PER_US_PRO as *mut u32).write_volatile(mhz);
}
}

use crate::{
peripherals::DPORT,
system::{RadioClockController, RadioPeripherals},
};

const DPORT_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x000003c9;
const DPORT_WIFI_CLK_WIFI_EN_M: u32 = 0x00000406;
const DPORT_WIFI_CLK_BT_EN_M: u32 = 0x00030800;

impl RadioClockController for crate::peripherals::RADIO_CLK {
fn enable(&mut self, peripheral: RadioPeripherals) {
match peripheral {
RadioPeripherals::Phy => enable_phy(),
RadioPeripherals::Bt => bt_clock_enable(),
RadioPeripherals::Wifi => wifi_clock_enable(),
}
}

fn disable(&mut self, peripheral: RadioPeripherals) {
match peripheral {
RadioPeripherals::Phy => disable_phy(),
RadioPeripherals::Bt => bt_clock_disable(),
RadioPeripherals::Wifi => wifi_clock_disable(),
}
}

fn reset_mac(&mut self) {
reset_mac();
}

fn init_clocks(&mut self) {
init_clocks();
}

fn ble_rtc_clk_init(&mut self) {
// nothing for this target
}

fn reset_rpa(&mut self) {
// nothing for this target
}
}

fn enable_phy() {
// `periph_ll_wifi_bt_module_enable_clk_clear_rst`
DPORT::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() | DPORT_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn disable_phy() {
// `periph_ll_wifi_bt_module_disable_clk_set_rst`
DPORT::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !DPORT_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn bt_clock_enable() {
DPORT::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() | DPORT_WIFI_CLK_BT_EN_M) });
}

fn bt_clock_disable() {
DPORT::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !DPORT_WIFI_CLK_BT_EN_M) });
}

fn wifi_clock_enable() {
// `periph_ll_wifi_module_enable_clk_clear_rst`
DPORT::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() | DPORT_WIFI_CLK_WIFI_EN_M) });
}

fn wifi_clock_disable() {
// `periph_ll_wifi_module_disable_clk_set_rst`
DPORT::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !DPORT_WIFI_CLK_WIFI_EN_M) });
}

fn reset_mac() {
const SYSTEM_MAC_RST: u8 = 1 << 2;
DPORT::regs()
.core_rst_en()
.modify(|r, w| unsafe { w.core_rst().bits(r.core_rst().bits() | SYSTEM_MAC_RST) });
DPORT::regs()
.core_rst_en()
.modify(|r, w| unsafe { w.core_rst().bits(r.core_rst().bits() & !SYSTEM_MAC_RST) });
}

fn init_clocks() {
// esp-idf assumes all clocks are enabled by default, and disables the following
// bits:
//
// ```
// const DPORT_WIFI_CLK_SDIOSLAVE_EN: u32 = 1 << 4;
// const DPORT_WIFI_CLK_UNUSED_BIT5: u32 = 1 << 5;
// const DPORT_WIFI_CLK_UNUSED_BIT12: u32 = 1 << 12;
// const DPORT_WIFI_CLK_SDIO_HOST_EN: u32 = 1 << 13;
// const DPORT_WIFI_CLK_EMAC_EN: u32 = 1 << 14;
//
// const WIFI_BT_SDIO_CLK: u32 = DPORT_WIFI_CLK_WIFI_EN_M
// | DPORT_WIFI_CLK_BT_EN_M
// | DPORT_WIFI_CLK_UNUSED_BIT5
// | DPORT_WIFI_CLK_UNUSED_BIT12
// | DPORT_WIFI_CLK_SDIOSLAVE_EN
// | DPORT_WIFI_CLK_SDIO_HOST_EN
// | DPORT_WIFI_CLK_EMAC_EN;
// ```
//
// However, we can't do this because somehow our initialization process is
// different, and disabling some bits, or not enabling them makes the BT
// stack crash.

DPORT::regs()
.wifi_clk_en()
.write(|w| unsafe { w.bits(u32::MAX) });
}
123 changes: 123 additions & 0 deletions esp-hal/src/clock/clocks_ll/esp32c2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
peripherals::{APB_CTRL, MODEM_CLKRST},
rom::{regi2c_write, regi2c_write_mask},
system::{RadioClockController, RadioPeripherals},
};

const I2C_BBPLL: u32 = 0x66;
Expand Down Expand Up @@ -168,3 +170,124 @@ pub(crate) fn esp32c2_rtc_apb_freq_update(apb_freq: ApbClock) {
.store5()
.modify(|_, w| unsafe { w.scratch5().bits(value) });
}

// Mask for clock bits used by both WIFI and Bluetooth, 0, 1, 2, 3, 7, 8, 9, 10,
// 19, 20, 21, 22, 23
const SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x78078F;
// SYSTEM_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030
const SYSTEM_WIFI_CLK_EN: u32 = 0x00FB9FCF;

impl RadioClockController for crate::peripherals::RADIO_CLK {
fn enable(&mut self, peripheral: RadioPeripherals) {
match peripheral {
RadioPeripherals::Phy => enable_phy(),
RadioPeripherals::Bt => common_wifi_bt_clock_enable(),
RadioPeripherals::Wifi => common_wifi_bt_clock_enable(),
}
}

fn disable(&mut self, peripheral: RadioPeripherals) {
match peripheral {
RadioPeripherals::Phy => disable_phy(),
RadioPeripherals::Bt => common_wifi_bt_clock_disable(),
RadioPeripherals::Wifi => common_wifi_bt_clock_disable(),
}
}

fn reset_mac(&mut self) {
reset_mac();
}

fn init_clocks(&mut self) {
init_clocks();
}

fn ble_rtc_clk_init(&mut self) {
ble_rtc_clk_init();
}

fn reset_rpa(&mut self) {
reset_rpa();
}
}

fn enable_phy() {
// `periph_ll_wifi_bt_module_enable_clk_clear_rst`
APB_CTRL::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn disable_phy() {
// `periph_ll_wifi_bt_module_disable_clk_set_rst`
APB_CTRL::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn common_wifi_bt_clock_enable() {
// `periph_ll_wifi_module_enable_clk_clear_rst`, no-op
}

fn common_wifi_bt_clock_disable() {
// `periph_ll_wifi_module_disable_clk_clear_rst`, no-op
}

fn reset_mac() {
const SYSTEM_MAC_RST: u32 = 1 << 2;
APB_CTRL::regs()
.wifi_rst_en()
.modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() | SYSTEM_MAC_RST) });
APB_CTRL::regs()
.wifi_rst_en()
.modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() & !SYSTEM_MAC_RST) });
}

fn init_clocks() {
// from `esp_perip_clk_init`
const SYSTEM_WIFI_CLK_UNUSED_BIT5: u32 = 1 << 5;
const SYSTEM_WIFI_CLK_UNUSED_BIT12: u32 = 1 << 12;
const WIFI_BT_SDIO_CLK: u32 = SYSTEM_WIFI_CLK_UNUSED_BIT5 | SYSTEM_WIFI_CLK_UNUSED_BIT12;

APB_CTRL::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !WIFI_BT_SDIO_CLK | SYSTEM_WIFI_CLK_EN) });
}

fn ble_rtc_clk_init() {
let modem_clkrst = MODEM_CLKRST::regs();
modem_clkrst
.modem_lp_timer_conf()
.modify(|_, w| w.lp_timer_sel_xtal32k().clear_bit());
modem_clkrst
.modem_lp_timer_conf()
.modify(|_, w| w.lp_timer_sel_xtal().set_bit());
modem_clkrst
.modem_lp_timer_conf()
.modify(|_, w| w.lp_timer_sel_8m().clear_bit());
modem_clkrst
.modem_lp_timer_conf()
.modify(|_, w| w.lp_timer_sel_rtc_slow().clear_bit());

// assume 40MHz xtal
modem_clkrst
.modem_lp_timer_conf()
.modify(|_, w| unsafe { w.lp_timer_clk_div_num().bits(249) });

modem_clkrst
.etm_clk_conf()
.modify(|_, w| w.etm_clk_active().set_bit());
modem_clkrst
.etm_clk_conf()
.modify(|_, w| w.etm_clk_sel().clear_bit());
}

fn reset_rpa() {
const BLE_RPA_REST_BIT: u32 = 1 << 27;
APB_CTRL::regs()
.wifi_rst_en()
.modify(|r, w| unsafe { w.bits(r.bits() | BLE_RPA_REST_BIT) });
APB_CTRL::regs()
.wifi_rst_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !BLE_RPA_REST_BIT) });
}
94 changes: 94 additions & 0 deletions esp-hal/src/clock/clocks_ll/esp32c3.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
peripherals::{APB_CTRL, LPWR},
rom::{regi2c_write, regi2c_write_mask},
system::{RadioClockController, RadioPeripherals},
};

const I2C_BBPLL: u32 = 0x66;
Expand Down Expand Up @@ -228,3 +230,95 @@ pub(crate) fn esp32c3_rtc_apb_freq_update(apb_freq: ApbClock) {
.store5()
.modify(|_, w| unsafe { w.scratch5().bits(value) });
}

// Mask for clock bits used by both WIFI and Bluetooth, 0, 1, 2, 3, 7, 8, 9, 10,
// 19, 20, 21, 22, 23
const SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x78078F;
// SYSTEM_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030
const SYSTEM_WIFI_CLK_EN: u32 = 0x00FB9FCF;

impl RadioClockController for crate::peripherals::RADIO_CLK {
fn enable(&mut self, peripheral: RadioPeripherals) {
match peripheral {
RadioPeripherals::Phy => enable_phy(),
RadioPeripherals::Bt => common_wifi_bt_clock_enable(),
RadioPeripherals::Wifi => common_wifi_bt_clock_enable(),
}
}

fn disable(&mut self, peripheral: RadioPeripherals) {
match peripheral {
RadioPeripherals::Phy => disable_phy(),
RadioPeripherals::Bt => common_wifi_bt_clock_disable(),
RadioPeripherals::Wifi => common_wifi_bt_clock_disable(),
}
}

fn reset_mac(&mut self) {
reset_mac();
}

fn init_clocks(&mut self) {
init_clocks();
}

fn ble_rtc_clk_init(&mut self) {
// nothing for this target
}

fn reset_rpa(&mut self) {
// nothing for this target
}
}

fn enable_phy() {
// `periph_ll_wifi_bt_module_enable_clk_clear_rst`
APB_CTRL::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn disable_phy() {
// `periph_ll_wifi_bt_module_disable_clk_set_rst`
APB_CTRL::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn common_wifi_bt_clock_enable() {
// `periph_ll_wifi_module_enable_clk_clear_rst`, no-op
}

fn common_wifi_bt_clock_disable() {
// `periph_ll_wifi_module__clk_clear_rst`, no-op
}

fn reset_mac() {
const SYSTEM_MAC_RST: u32 = 1 << 2;
APB_CTRL::regs()
.wifi_rst_en()
.modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() | SYSTEM_MAC_RST) });
APB_CTRL::regs()
.wifi_rst_en()
.modify(|r, w| unsafe { w.wifi_rst().bits(r.wifi_rst().bits() & !SYSTEM_MAC_RST) });
}

fn init_clocks() {
// undo the power down in base_settings (esp32c3_sleep)
LPWR::regs()
.dig_iso()
.modify(|_, w| w.wifi_force_iso().clear_bit().bt_force_iso().clear_bit());

LPWR::regs()
.dig_pwc()
.modify(|_, w| w.wifi_force_pd().clear_bit().bt_force_pd().clear_bit());

// from `esp_perip_clk_init`
const SYSTEM_WIFI_CLK_I2C_CLK_EN: u32 = 1 << 5;
const SYSTEM_WIFI_CLK_UNUSED_BIT12: u32 = 1 << 12;
const WIFI_BT_SDIO_CLK: u32 = SYSTEM_WIFI_CLK_I2C_CLK_EN | SYSTEM_WIFI_CLK_UNUSED_BIT12;

APB_CTRL::regs()
.wifi_clk_en()
.modify(|r, w| unsafe { w.bits(r.bits() & !WIFI_BT_SDIO_CLK | SYSTEM_WIFI_CLK_EN) });
}
Loading

0 comments on commit 9d51284

Please sign in to comment.