Skip to content

Commit

Permalink
Add extend systimer support to esp32s3 and add example
Browse files Browse the repository at this point in the history
  • Loading branch information
MabezDev committed Jun 9, 2022
1 parent bda4239 commit 986753f
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 4 deletions.
2 changes: 1 addition & 1 deletion esp-hal-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub use spi::Spi;
pub use timer::Timer;
#[cfg(any(feature = "esp32c3", feature = "esp32s3"))]
pub use usb_serial_jtag::UsbSerialJtag;
#[cfg(feature = "esp32c3")]
#[cfg(any(feature = "esp32c3", feature = "esp32s3", feature = "esp32s2"))]
pub mod systimer;

pub mod clock;
Expand Down
5 changes: 2 additions & 3 deletions esp-hal-common/src/systimer.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
use core::{intrinsics::transmute, marker::PhantomData};

use esp32c3_pac::{
use crate::pac::{
generic::Reg,
systimer::{
comp0_load::COMP0_LOAD_SPEC,
target0_conf::TARGET0_CONF_SPEC,
target0_hi::TARGET0_HI_SPEC,
target0_lo::TARGET0_LO_SPEC,
},
SYSTIMER,
};

use crate::pac::SYSTIMER;

// TODO this only handles unit0 of the systimer

#[derive(Debug)]
Expand Down
1 change: 1 addition & 0 deletions esp32c3-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub use esp_hal_common::{
ram,
spi,
system,
systimer,
utils,
Cpu,
Delay,
Expand Down
169 changes: 169 additions & 0 deletions esp32s3-hal/examples/systimer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#![no_std]
#![no_main]

use core::{cell::RefCell, fmt::Write};

use esp32s3_hal::{
clock::ClockControl,
pac::{self, Peripherals, UART0},
prelude::*,
Delay,
RtcCntl,
Serial,
Timer,
};
use esp_hal_common::{
interrupt,
Cpu,
systimer::{SystemTimer, Alarm, Target}
};
use panic_halt as _;
use xtensa_lx::mutex::{Mutex, SpinLockMutex};
use xtensa_lx_rt::entry;

static mut SERIAL: SpinLockMutex<RefCell<Option<Serial<UART0>>>> =
SpinLockMutex::new(RefCell::new(None));
static mut ALARM0: SpinLockMutex<RefCell<Option<Alarm<Target, 0>>>> =
SpinLockMutex::new(RefCell::new(None));
static mut ALARM1: SpinLockMutex<RefCell<Option<Alarm<Target, 1>>>> =
SpinLockMutex::new(RefCell::new(None));
static mut ALARM2: SpinLockMutex<RefCell<Option<Alarm<Target, 2>>>> =
SpinLockMutex::new(RefCell::new(None));

#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();

let mut timer0 = Timer::new(peripherals.TIMG0);
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
let serial0 = Serial::new(peripherals.UART0).unwrap();

// Disable MWDT and RWDT (Watchdog) flash boot protection
timer0.disable();
rtc_cntl.set_wdt_global_enable(false);

let syst = SystemTimer::new(peripherals.SYSTIMER);

let alarm0 = syst.alarm0;
alarm0.set_target(40_000_000);
alarm0.enable_interrupt();

let alarm1 = syst.alarm1;
alarm1.set_target(41_111_111);
alarm1.enable_interrupt();

let alarm2 = syst.alarm2;
alarm2.set_target(42_222_222 * 2);
alarm2.enable_interrupt();

unsafe {
(&SERIAL).lock(|data| (*data).replace(Some(serial0)));
(&ALARM0).lock(|data| (*data).replace(Some(alarm0)));
(&ALARM1).lock(|data| (*data).replace(Some(alarm1)));
(&ALARM2).lock(|data| (*data).replace(Some(alarm2)));
}

interrupt::enable(
Cpu::ProCpu,
pac::Interrupt::SYSTIMER_TARGET0,
interrupt::CpuInterrupt::Interrupt0LevelPriority1,
);

interrupt::enable(
Cpu::ProCpu,
pac::Interrupt::SYSTIMER_TARGET1,
interrupt::CpuInterrupt::Interrupt19LevelPriority2,
);

interrupt::enable(
Cpu::ProCpu,
pac::Interrupt::SYSTIMER_TARGET2,
interrupt::CpuInterrupt::Interrupt23LevelPriority3,
);

// Initialize the Delay peripheral, and use it to toggle the LED state in a
// loop.
let mut delay = Delay::new(&clocks);

unsafe {
xtensa_lx::interrupt::enable_mask(1 << 19 | 1 << 0 | 1 << 23 );
}

loop {
delay.delay_ms(500u32);
}
}

#[no_mangle]
pub fn level1_interrupt() {
unsafe {
(&SERIAL).lock(|data| {
let mut serial = data.borrow_mut();
let serial = serial.as_mut().unwrap();
writeln!(serial, "Interrupt lvl1 (alarm0)").ok();
});
}

interrupt::clear(
Cpu::ProCpu,
interrupt::CpuInterrupt::Interrupt0LevelPriority1,
);

unsafe {
(&ALARM0).lock(|data| {
let mut alarm = data.borrow_mut();
let alarm = alarm.as_mut().unwrap();
alarm.clear_interrupt();
});
}
}

#[no_mangle]
pub fn level2_interrupt() {
unsafe {
(&SERIAL).lock(|data| {
let mut serial = data.borrow_mut();
let serial = serial.as_mut().unwrap();
writeln!(serial, "Interrupt lvl2 (alarm1)").ok();
});
}

interrupt::clear(
Cpu::ProCpu,
interrupt::CpuInterrupt::Interrupt19LevelPriority2,
);

unsafe {
(&ALARM1).lock(|data| {
let mut alarm = data.borrow_mut();
let alarm = alarm.as_mut().unwrap();
alarm.clear_interrupt();
});
}
}

#[no_mangle]
pub fn level3_interrupt() {
unsafe {
(&SERIAL).lock(|data| {
let mut serial = data.borrow_mut();
let serial = serial.as_mut().unwrap();
writeln!(serial, "Interrupt lvl3 (alarm2)").ok();
});
}

interrupt::clear(
Cpu::ProCpu,
interrupt::CpuInterrupt::Interrupt23LevelPriority3,
);

unsafe {
(&ALARM2).lock(|data| {
let mut alarm = data.borrow_mut();
let alarm = alarm.as_mut().unwrap();
alarm.clear_interrupt();
});
}
}
1 change: 1 addition & 0 deletions esp32s3-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub use esp_hal_common::{
pulse_control,
ram,
spi,
systimer,
usb_serial_jtag,
utils,
Cpu,
Expand Down

0 comments on commit 986753f

Please sign in to comment.