Skip to content

Commit

Permalink
Add support for radio peripheral clock control
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoernQ committed Mar 27, 2023
1 parent 91ded64 commit 67a07b6
Show file tree
Hide file tree
Showing 20 changed files with 762 additions and 2 deletions.
3 changes: 3 additions & 0 deletions esp-hal-common/devices/esp32.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,7 @@ peripherals = [
"dac",
"pdma",
"radio",
"phy",
"bt",
"wifi",
]
3 changes: 3 additions & 0 deletions esp-hal-common/devices/esp32c2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ peripherals = [
"adc",
"gdma",
"radio",
"phy",
"bt",
"wifi",
]
3 changes: 3 additions & 0 deletions esp-hal-common/devices/esp32c3.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ peripherals = [
"adc",
"gdma",
"radio",
"phy",
"bt",
"wifi",
]
4 changes: 4 additions & 0 deletions esp-hal-common/devices/esp32c6.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,8 @@ peripherals = [
"large_intr_status",
"plic",
"radio",
"phy",
"bt",
"wifi",
"ieee802154",
]
2 changes: 2 additions & 0 deletions esp-hal-common/devices/esp32s2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,6 @@ peripherals = [
"dac",
"pdma",
"radio",
"phy",
"wifi",
]
3 changes: 3 additions & 0 deletions esp-hal-common/devices/esp32s3.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ peripherals = [
"adc",
"gdma",
"radio",
"phy",
"bt",
"wifi",
]
3 changes: 1 addition & 2 deletions esp-hal-common/ld/sections/rodata.x
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ SECTIONS {
_rodata_end = ABSOLUTE(.);
} > RODATA

.rodata.wifi :
.rodata.wifi : ALIGN(4)
{
. = ALIGN(4);
*( .rodata_wlog_*.* )
} > RODATA
}
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod cpu_control;
pub mod efuse;
pub mod gpio;
pub mod peripherals;
pub mod radio_clocks;
84 changes: 84 additions & 0 deletions esp-hal-common/src/soc/esp32/radio_clocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use crate::system::{RadioClockContoller, RadioClockControl, RadioPeripherals};

const SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x000003c9;
const SYSTEM_WIFI_CLK_EN: u32 = 0xFFFFFFFF;

impl RadioClockContoller for RadioClockControl {
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() {
let system = unsafe { &*esp32::DPORT::PTR };
system
.wifi_clk_en
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn disable_phy() {
let system = unsafe { &*esp32::DPORT::PTR };
system
.wifi_clk_en
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn common_wifi_bt_clock_enable() {
let system = unsafe { &*esp32::DPORT::PTR };
system
.perip_clk_en
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_EN) });
}

fn common_wifi_bt_clock_disable() {
let system = unsafe { &*esp32::DPORT::PTR };
system
.perip_clk_en
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_EN) });
}

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

fn init_clocks() {
let syscon = unsafe { &*esp32::DPORT::PTR };
syscon
.wifi_clk_en
.modify(|_, w| unsafe { w.bits(0xffffffff) });
}
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32c2/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod efuse;
pub mod gpio;
pub mod peripherals;
pub mod radio_clocks;

pub(crate) mod registers {
pub const INTERRUPT_MAP_BASE: u32 = 0x600c2000;
Expand Down
127 changes: 127 additions & 0 deletions esp-hal-common/src/soc/esp32c2/radio_clocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use crate::system::{RadioClockContoller, RadioClockControl, RadioPeripherals};

// 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
// from experiments `0x00FB9FCF` is not enough for esp-wifi to work
const SYSTEM_WIFI_CLK_EN: u32 = 0xFFFFFFFF;

impl RadioClockContoller for RadioClockControl {
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() {
let system = unsafe { &*esp32c2::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn disable_phy() {
let system = unsafe { &*esp32c2::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn common_wifi_bt_clock_enable() {
let system = unsafe { &*esp32c2::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_EN) });
}

fn common_wifi_bt_clock_disable() {
let system = unsafe { &*esp32c2::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_EN) });
}

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

fn init_clocks() {
let syscon = unsafe { &*esp32c2::APB_CTRL::PTR };
syscon
.wifi_clk_en
.modify(|_, w| unsafe { w.bits(0xffffffff) });
}

fn ble_rtc_clk_init() {
let modem_clkrst = unsafe { &*esp32c2::MODEM_CLKRST::PTR };
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| w.lp_timer_clk_div_num().variant(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;
let syscon = unsafe { &*esp32c2::APB_CTRL::PTR };
syscon
.wifi_rst_en
.modify(|r, w| unsafe { w.bits(r.bits() | BLE_RPA_REST_BIT) });
syscon
.wifi_rst_en
.modify(|r, w| unsafe { w.bits(r.bits() & !BLE_RPA_REST_BIT) });
}
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32c3/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod efuse;
pub mod gpio;
pub mod peripherals;
pub mod radio_clocks;

pub(crate) mod registers {
pub const INTERRUPT_MAP_BASE: u32 = 0x600c2000;
Expand Down
88 changes: 88 additions & 0 deletions esp-hal-common/src/soc/esp32c3/radio_clocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::system::{RadioClockContoller, RadioClockControl, RadioPeripherals};

// 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
// from experiments `0x00FB9FCF` is not enough for esp-wifi to work
const SYSTEM_WIFI_CLK_EN: u32 = 0xFFFFFFFF;

impl RadioClockContoller for RadioClockControl {
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() {
let system = unsafe { &*esp32c3::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn disable_phy() {
let system = unsafe { &*esp32c3::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M) });
}

fn common_wifi_bt_clock_enable() {
let system = unsafe { &*esp32c3::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() | SYSTEM_WIFI_CLK_EN) });
}

fn common_wifi_bt_clock_disable() {
let system = unsafe { &*esp32c3::SYSTEM::PTR };
system
.perip_clk_en1
.modify(|r, w| unsafe { w.bits(r.bits() & !SYSTEM_WIFI_CLK_EN) });
}

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

fn init_clocks() {
let syscon = unsafe { &*esp32c3::APB_CTRL::PTR };
syscon
.wifi_clk_en
.modify(|_, w| unsafe { w.bits(0xffffffff) });
}
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32c6/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod efuse;
pub mod gpio;
pub mod peripherals;
pub mod radio_clocks;

pub(crate) mod registers {
pub const INTERRUPT_MAP_BASE: u32 = 0x60010000;
Expand Down
Loading

0 comments on commit 67a07b6

Please sign in to comment.