Skip to content

Commit

Permalink
Add PeripheralClockControl argument to timg, wdt, sha, `usb-ser…
Browse files Browse the repository at this point in the history
…ial-jtag` and `uart` constructors (esp-rs#463)

* PeripheralClockControl timer

* Add PeripheralClockControl to timg, wdt, sha, usb-serial-jtag and uart

* ESP32 updated examples

* ESP32C2 updated examples

* ESP32C3 updated examples

* ESP32S2 updated examples

* ESP32S3 updated examples

* ESP32C6 updated examples

* cargo fmt
  • Loading branch information
JurajSadel authored and i404788 committed Jul 22, 2023
1 parent a4ed678 commit aec9636
Show file tree
Hide file tree
Showing 203 changed files with 1,828 additions and 456 deletions.
8 changes: 7 additions & 1 deletion esp-hal-common/src/sha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use core::convert::Infallible;
use crate::{
peripheral::{Peripheral, PeripheralRef},
peripherals::SHA,
system::PeripheralClockControl,
};

// All the hash algorithms introduced in FIPS PUB 180-4 Spec.
Expand Down Expand Up @@ -227,8 +228,13 @@ fn mode_as_bits(mode: ShaMode) -> u8 {
// This implementation might fail after u32::MAX/8 bytes, to increase please see
// ::finish() length/self.cursor usage
impl<'d> Sha<'d> {
pub fn new(sha: impl Peripheral<P = SHA> + 'd, mode: ShaMode) -> Self {
pub fn new(
sha: impl Peripheral<P = SHA> + 'd,
mode: ShaMode,
peripheral_clock_control: &mut PeripheralClockControl,
) -> Self {
crate::into_ref!(sha);
peripheral_clock_control.enable(crate::system::Peripheral::Sha);

// Setup SHA Mode
#[cfg(not(esp32))]
Expand Down
125 changes: 125 additions & 0 deletions esp-hal-common/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ pub enum Peripheral {
Twai0,
#[cfg(twai1)]
Twai1,
#[cfg(timg0)]
Timg0,
#[cfg(timg1)]
Timg1,
#[cfg(lp_wdt)]
Wdt,
Sha,
#[cfg(usb_device)]
UsbDevice,
Uart0,
Uart1,
#[cfg(uart2)]
Uart2,
}

/// Controls the enablement of peripheral clocks.
Expand Down Expand Up @@ -190,6 +203,60 @@ impl PeripheralClockControl {
perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().set_bit());
perip_rst_en1.modify(|_, w| w.crypto_aes_rst().clear_bit());
}
#[cfg(timg0)]
Peripheral::Timg0 => {
#[cfg(any(esp32c3, esp32s2, esp32s3))]
perip_clk_en0.modify(|_, w| w.timers_clk_en().set_bit());
perip_clk_en0.modify(|_, w| w.timergroup_clk_en().set_bit());

#[cfg(any(esp32c3, esp32s2, esp32s3))]
perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit());
perip_rst_en0.modify(|_, w| w.timergroup_rst().clear_bit());
}
#[cfg(timg1)]
Peripheral::Timg1 => {
#[cfg(any(esp32c3, esp32s2, esp32s3))]
perip_clk_en0.modify(|_, w| w.timers_clk_en().set_bit());
perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().set_bit());

#[cfg(any(esp32c3, esp32s2, esp32s3))]
perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit());
perip_rst_en0.modify(|_, w| w.timergroup1_rst().clear_bit());
}
Peripheral::Sha => {
#[cfg(not(esp32))]
perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().set_bit());
#[cfg(not(esp32))]
perip_rst_en1.modify(|_, w| w.crypto_sha_rst().clear_bit());
}
#[cfg(esp32c3)]
Peripheral::UsbDevice => {
perip_clk_en0.modify(|_, w| w.usb_device_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.usb_device_rst().clear_bit());
}
#[cfg(esp32s3)]
Peripheral::UsbDevice => {
perip_clk_en1.modify(|_, w| w.usb_device_clk_en().set_bit());
perip_rst_en1.modify(|_, w| w.usb_device_rst().clear_bit());
}
Peripheral::Uart0 => {
perip_clk_en0.modify(|_, w| w.uart_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.uart_rst().clear_bit());
}
Peripheral::Uart1 => {
perip_clk_en0.modify(|_, w| w.uart1_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.uart1_rst().clear_bit());
}
#[cfg(all(uart2, esp32s3))]
Peripheral::Uart2 => {
perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit());
perip_rst_en1.modify(|_, w| w.uart2_rst().clear_bit());
}
#[cfg(all(uart2, esp32))]
Peripheral::Uart2 => {
perip_clk_en0.modify(|_, w| w.uart2_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.uart2_rst().clear_bit());
}
}
}
}
Expand Down Expand Up @@ -273,6 +340,64 @@ impl PeripheralClockControl {
system.pcnt_conf.modify(|_, w| w.pcnt_clk_en().set_bit());
system.pcnt_conf.modify(|_, w| w.pcnt_rst_en().clear_bit());
}
#[cfg(timg0)]
Peripheral::Timg0 => {
system
.timergroup0_timer_clk_conf
.write(|w| w.tg0_timer_clk_en().set_bit());
system
.timergroup0_timer_clk_conf
.write(|w| unsafe { w.tg0_timer_clk_sel().bits(1) });
}
#[cfg(timg1)]
Peripheral::Timg1 => {
system
.timergroup1_timer_clk_conf
.write(|w| w.tg1_timer_clk_en().set_bit());
system
.timergroup1_timer_clk_conf
.write(|w| unsafe { w.tg1_timer_clk_sel().bits(1) });
}
#[cfg(lp_wdt)]
Peripheral::Wdt => {
system
.timergroup0_wdt_clk_conf
.write(|w| w.tg0_wdt_clk_en().set_bit());
system
.timergroup0_wdt_clk_conf
.write(|w| unsafe { w.tg0_wdt_clk_sel().bits(1) });

system
.timergroup1_timer_clk_conf
.write(|w| w.tg1_timer_clk_en().set_bit());
system
.timergroup1_timer_clk_conf
.write(|w| unsafe { w.tg1_timer_clk_sel().bits(1) });
}
Peripheral::Sha => {
system.sha_conf.modify(|_, w| w.sha_clk_en().set_bit());
system.sha_conf.modify(|_, w| w.sha_rst_en().clear_bit());
}
Peripheral::UsbDevice => {
system
.usb_device_conf
.modify(|_, w| w.usb_device_clk_en().set_bit());
system
.usb_device_conf
.modify(|_, w| w.usb_device_rst_en().clear_bit());
}
Peripheral::Uart0 => {
system.uart0_conf.modify(|_, w| w.uart0_clk_en().set_bit());
system
.uart0_conf
.modify(|_, w| w.uart0_rst_en().clear_bit());
}
Peripheral::Uart1 => {
system.uart1_conf.modify(|_, w| w.uart1_clk_en().set_bit());
system
.uart1_conf
.modify(|_, w| w.uart1_rst_en().clear_bit());
}
}
}
}
Expand Down
64 changes: 28 additions & 36 deletions esp-hal-common/src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
clock::Clocks,
peripheral::{Peripheral, PeripheralRef},
peripherals::{timg0::RegisterBlock, TIMG0},
system::PeripheralClockControl,
};

/// Custom timer error type
Expand Down Expand Up @@ -64,14 +65,19 @@ impl<'d, T> TimerGroup<'d, T>
where
T: TimerGroupInstance,
{
pub fn new(timer_group: impl Peripheral<P = T> + 'd, clocks: &Clocks) -> Self {
pub fn new(
timer_group: impl Peripheral<P = T> + 'd,
clocks: &Clocks,
peripheral_clock_control: &mut PeripheralClockControl,
) -> Self {
crate::into_ref!(timer_group);

let timer0 = Timer::new(
Timer0 {
phantom: PhantomData::default(),
},
clocks.apb_clock,
peripheral_clock_control,
);

#[cfg(not(any(esp32c2, esp32c3, esp32c6)))]
Expand All @@ -80,9 +86,10 @@ where
phantom: PhantomData::default(),
},
clocks.apb_clock,
peripheral_clock_control,
);

let wdt = Wdt::new();
let wdt = Wdt::new(peripheral_clock_control);

Self {
_timer_group: timer_group,
Expand All @@ -106,32 +113,21 @@ where
T: Instance,
{
/// Create a new timer instance
pub fn new(timg: T, apb_clk_freq: HertzU32) -> Self {
pub fn new(
timg: T,
apb_clk_freq: HertzU32,
peripheral_clock_control: &mut PeripheralClockControl,
) -> Self {
// TODO: this currently assumes APB_CLK is being used, as we don't yet have a
// way to select the XTAL_CLK.
#[cfg(esp32c6)]
Self::enable_clock();
timg.enable_peripheral(peripheral_clock_control);
Self { timg, apb_clk_freq }
}

/// Return the raw interface to the underlying timer instance
pub fn free(self) -> T {
self.timg
}

#[cfg(esp32c6)]
fn enable_clock() {
let pcr = unsafe { &*crate::peripherals::PCR::ptr() };
pcr.timergroup0_timer_clk_conf
.write(|w| w.tg0_timer_clk_en().set_bit());
pcr.timergroup0_timer_clk_conf
.write(|w| unsafe { w.tg0_timer_clk_sel().bits(1) });

pcr.timergroup1_timer_clk_conf
.write(|w| w.tg1_timer_clk_en().set_bit());
pcr.timergroup1_timer_clk_conf
.write(|w| unsafe { w.tg1_timer_clk_sel().bits(1) });
}
}

impl<T> Deref for Timer<T>
Expand Down Expand Up @@ -185,6 +181,8 @@ pub trait Instance {
fn set_divider(&mut self, divider: u16);

fn is_interrupt_set(&self) -> bool;

fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl);
}

pub struct Timer0<TG> {
Expand Down Expand Up @@ -328,6 +326,10 @@ where
.t0config
.modify(|_, w| unsafe { w.divider().bits(divider) })
}

fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(crate::system::Peripheral::Timg0);
}
}

#[cfg(not(any(esp32c2, esp32c3, esp32c6)))]
Expand Down Expand Up @@ -473,6 +475,10 @@ where
.t1config
.modify(|_, w| unsafe { w.divider().bits(divider) })
}

fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(crate::system::Peripheral::Timg1);
}
}

fn timeout_to_ticks<T, F>(timeout: T, clock: F, divider: u32) -> u64
Expand Down Expand Up @@ -565,28 +571,14 @@ where
TG: TimerGroupInstance,
{
/// Create a new watchdog timer instance
pub fn new() -> Self {
#[cfg(esp32c6)]
Self::enable_clock();
pub fn new(_peripheral_clock_control: &mut PeripheralClockControl) -> Self {
#[cfg(lp_wdt)]
_peripheral_clock_control.enable(crate::system::Peripheral::Wdt);
Self {
phantom: PhantomData::default(),
}
}

#[cfg(esp32c6)]
fn enable_clock() {
let pcr = unsafe { &*crate::peripherals::PCR::ptr() };
pcr.timergroup0_wdt_clk_conf
.write(|w| w.tg0_wdt_clk_en().set_bit());
pcr.timergroup0_wdt_clk_conf
.write(|w| unsafe { w.tg0_wdt_clk_sel().bits(1) });

pcr.timergroup1_timer_clk_conf
.write(|w| w.tg1_timer_clk_en().set_bit());
pcr.timergroup1_timer_clk_conf
.write(|w| unsafe { w.tg1_timer_clk_sel().bits(1) });
}

fn set_wdt_enabled(&mut self, enabled: bool) {
let reg_block = unsafe { &*TG::register_block() };

Expand Down
23 changes: 22 additions & 1 deletion esp-hal-common/src/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
UART0,
UART1,
},
system::PeripheralClockControl,
};

const UART_FIFO_SIZE: u16 = 128;
Expand Down Expand Up @@ -256,11 +257,13 @@ where
config: Option<Config>,
mut pins: Option<P>,
clocks: &Clocks,
peripheral_clock_control: &mut PeripheralClockControl,
) -> Self
where
P: UartPins,
{
crate::into_ref!(uart);
uart.enable_peripheral(peripheral_clock_control);
let mut serial = Uart { uart };
serial.uart.disable_rx_interrupts();
serial.uart.disable_tx_interrupts();
Expand All @@ -285,8 +288,12 @@ where
}

/// Create a new UART instance with defaults
pub fn new(uart: impl Peripheral<P = T> + 'd) -> Self {
pub fn new(
uart: impl Peripheral<P = T> + 'd,
peripheral_clock_control: &mut PeripheralClockControl,
) -> Self {
crate::into_ref!(uart);
uart.enable_peripheral(peripheral_clock_control);
let mut serial = Uart { uart };
serial.uart.disable_rx_interrupts();
serial.uart.disable_tx_interrupts();
Expand Down Expand Up @@ -787,6 +794,8 @@ pub trait Instance {
fn cts_signal(&self) -> InputSignal;

fn rts_signal(&self) -> OutputSignal;

fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl);
}

impl Instance for UART0 {
Expand Down Expand Up @@ -815,6 +824,10 @@ impl Instance for UART0 {
fn rts_signal(&self) -> OutputSignal {
OutputSignal::U0RTS
}

fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(crate::system::Peripheral::Uart0);
}
}

impl Instance for UART1 {
Expand Down Expand Up @@ -843,6 +856,10 @@ impl Instance for UART1 {
fn rts_signal(&self) -> OutputSignal {
OutputSignal::U1RTS
}

fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(crate::system::Peripheral::Uart1);
}
}

#[cfg(uart2)]
Expand Down Expand Up @@ -872,6 +889,10 @@ impl Instance for UART2 {
fn rts_signal(&self) -> OutputSignal {
OutputSignal::U2RTS
}

fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) {
peripheral_clock_control.enable(crate::system::Peripheral::Uart2);
}
}

#[cfg(feature = "ufmt")]
Expand Down
Loading

0 comments on commit aec9636

Please sign in to comment.