mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 04:40:52 +00:00
critical_section
implementations & esp_backtrace (#151)
* CS impl * use CS Mutex in C3 examples * use CS Mutex in S2 examples * Update esp32 example * run fmt * Update S3 examples * Remove uses of unsafe where no longer required * use esp_backtrace in examples * fix import & fmt once more * Bump MSRV to 1.60.0 Co-authored-by: Jesse Braham <jesse@beta7.io>
This commit is contained in:
parent
b354a29bc4
commit
be184a552d
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -118,7 +118,7 @@ jobs:
|
||||
with:
|
||||
profile: minimal
|
||||
target: riscv32imc-unknown-none-elf
|
||||
toolchain: "1.59.0"
|
||||
toolchain: "1.60.0"
|
||||
default: true
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions-rs/cargo@v1
|
||||
@ -140,7 +140,7 @@ jobs:
|
||||
default: true
|
||||
ldproxy: false
|
||||
buildtargets: ${{ matrix.chip }}
|
||||
version: "1.59.0"
|
||||
version: "1.60.0"
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
|
@ -36,8 +36,8 @@ _\* via [atomic emulation]_
|
||||
|
||||
The **M**inimum **S**upported **R**ust **V**ersions are:
|
||||
|
||||
- `1.59.0` for RISC-V devices (**ESP32-C3**)
|
||||
- `1.59.0` for Xtensa devices (**ESP32**, **ESP32-S2**, **ESP32-S3**)
|
||||
- `1.60.0` for RISC-V devices (**ESP32-C3**)
|
||||
- `1.60.0` for Xtensa devices (**ESP32**, **ESP32-S2**, **ESP32-S3**)
|
||||
|
||||
Note that targeting the Xtensa ISA requires the use of the [esp-rs/rust] compiler fork, whereas RISC-V is officially supported by the official Rust compiler.
|
||||
|
||||
|
@ -34,6 +34,8 @@ ufmt-write = { version = "0.1", optional = true }
|
||||
# Smart-LED (e.g., WS2812/SK68XX) support
|
||||
smart-leds-trait = { version = "0.2.1", optional = true }
|
||||
|
||||
critical-section = "1.0.0"
|
||||
|
||||
# IMPORTANT:
|
||||
# Each supported device MUST have its PAC included below along with a
|
||||
# corresponding feature. We rename the PAC packages because we cannot
|
||||
@ -46,10 +48,10 @@ esp32s2_pac = { package = "esp32s2", version = "0.3.0", optional = true }
|
||||
esp32s3_pac = { package = "esp32s3", version = "0.3.0", optional = true }
|
||||
|
||||
[features]
|
||||
esp32 = ["esp32_pac/rt" , "procmacros/xtensa", "multi_core" , "xtensa-lx-rt/esp32", "xtensa-lx/esp32"]
|
||||
esp32c3 = ["esp32c3_pac/rt", "procmacros/riscv" , "single_core", "riscv", "riscv-atomic-emulation-trap"]
|
||||
esp32s2 = ["esp32s2_pac/rt", "procmacros/xtensa", "single_core", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2"]
|
||||
esp32s3 = ["esp32s3_pac/rt", "procmacros/xtensa", "multi_core" , "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3"]
|
||||
esp32 = ["esp32_pac/rt" , "procmacros/xtensa", "multi_core" , "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "critical-section/restore-state-u32"]
|
||||
esp32c3 = ["esp32c3_pac/rt", "procmacros/riscv" , "single_core", "riscv", "riscv-atomic-emulation-trap", "critical-section/restore-state-u8"]
|
||||
esp32s2 = ["esp32s2_pac/rt", "procmacros/xtensa", "single_core", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "critical-section/restore-state-u32"]
|
||||
esp32s3 = ["esp32s3_pac/rt", "procmacros/xtensa", "multi_core" , "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "critical-section/restore-state-u32"]
|
||||
|
||||
# Core Count (should not be enabled directly, but instead by a PAC's feature)
|
||||
single_core = []
|
||||
|
@ -1,8 +1,4 @@
|
||||
use crate::clock::{
|
||||
Clock,
|
||||
XtalClock,
|
||||
PllClock,
|
||||
};
|
||||
use crate::clock::{Clock, PllClock, XtalClock};
|
||||
|
||||
const REF_CLK_FREQ: u32 = 1000000;
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
use paste::paste;
|
||||
|
||||
use crate::clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock};
|
||||
|
||||
use crate::rom::{ets_update_cpu_frequency, regi2c_ctrl_write_reg, regi2c_ctrl_write_reg_mask};
|
||||
use crate::{regi2c_write, regi2c_write_mask};
|
||||
use crate::{
|
||||
clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
|
||||
regi2c_write,
|
||||
regi2c_write_mask,
|
||||
rom::{ets_update_cpu_frequency, regi2c_ctrl_write_reg, regi2c_ctrl_write_reg_mask},
|
||||
};
|
||||
|
||||
const I2C_BBPLL: u32 = 0x66;
|
||||
const I2C_BBPLL_HOSTID: u32 = 0;
|
||||
@ -188,7 +190,8 @@ pub(crate) fn esp32c3_rtc_update_to_xtal(freq: XtalClock, _div: u32) {
|
||||
|
||||
unsafe {
|
||||
ets_update_cpu_frequency(freq.mhz());
|
||||
// Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first.
|
||||
// Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0)
|
||||
// first.
|
||||
system_control.sysclk_conf.modify(|_, w| {
|
||||
w.pre_div_cnt()
|
||||
.bits(0)
|
||||
|
@ -142,8 +142,9 @@ pub trait InputPin: Pin {
|
||||
|
||||
/// Remove a connected `signal` from this input pin.
|
||||
///
|
||||
/// Clears the entry in the GPIO matrix / IO mux that associates this input pin with the given
|
||||
/// [input `signal`](`InputSignal`). Any other connected signals remain intact.
|
||||
/// Clears the entry in the GPIO matrix / IO mux that associates this input
|
||||
/// pin with the given [input `signal`](`InputSignal`). Any other
|
||||
/// connected signals remain intact.
|
||||
fn disconnect_input_from_peripheral(&mut self, signal: InputSignal) -> &mut Self;
|
||||
}
|
||||
|
||||
@ -181,9 +182,9 @@ pub trait OutputPin: Pin {
|
||||
|
||||
/// Remove this output pin from a connected [signal](`InputSignal`).
|
||||
///
|
||||
/// Clears the entry in the GPIO matrix / IO mux that associates this output pin with a
|
||||
/// previously connected [signal](`InputSignal`). Any other outputs connected to the signal
|
||||
/// remain intact.
|
||||
/// Clears the entry in the GPIO matrix / IO mux that associates this output
|
||||
/// pin with a previously connected [signal](`InputSignal`). Any other
|
||||
/// outputs connected to the signal remain intact.
|
||||
fn disconnect_peripheral_from_output(&mut self) -> &mut Self;
|
||||
|
||||
fn internal_pull_up(&mut self, on: bool) -> &mut Self;
|
||||
|
@ -161,7 +161,8 @@ where
|
||||
let mut divisor = ((src_freq as u64) << 8) / frequency as u64 / precision as u64;
|
||||
|
||||
if divisor > LEDC_TIMER_DIV_NUM_MAX {
|
||||
// APB_CLK results in divisor which too high. Try using REF_TICK as clock source.
|
||||
// APB_CLK results in divisor which too high. Try using REF_TICK as clock
|
||||
// source.
|
||||
self.use_ref_tick = true;
|
||||
divisor = ((1_000_000 as u64) << 8) / frequency as u64 / precision as u64;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
//! [esp32s3-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32s3-hal
|
||||
|
||||
#![no_std]
|
||||
#![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))]
|
||||
|
||||
#[cfg(feature = "esp32")]
|
||||
pub use esp32_pac as pac;
|
||||
@ -101,3 +102,120 @@ pub fn get_core() -> Cpu {
|
||||
#[cfg(feature = "single_core")]
|
||||
Cpu::ProCpu
|
||||
}
|
||||
|
||||
mod critical_section_impl {
|
||||
struct CriticalSection;
|
||||
|
||||
critical_section::set_impl!(CriticalSection);
|
||||
|
||||
#[cfg(target_arch = "xtensa")]
|
||||
mod xtensa {
|
||||
|
||||
unsafe impl critical_section::Impl for super::CriticalSection {
|
||||
unsafe fn acquire() -> critical_section::RawRestoreState {
|
||||
let tkn: critical_section::RawRestoreState;
|
||||
core::arch::asm!("rsil {0}, 15", out(reg) tkn);
|
||||
#[cfg(feature = "multicore")]
|
||||
{
|
||||
let guard = multicore::MULTICORE_LOCK.lock();
|
||||
core::mem::forget(guard); // forget it so drop doesn't run
|
||||
}
|
||||
tkn
|
||||
}
|
||||
|
||||
unsafe fn release(token: critical_section::RawRestoreState) {
|
||||
if token != 0 {
|
||||
#[cfg(feature = "multicore")]
|
||||
{
|
||||
debug_assert!(multicore::MULTICORE_LOCK.is_owned_by_current_thread());
|
||||
// safety: we logically own the mutex from acquire()
|
||||
multicore::MULTICORE_LOCK.force_unlock();
|
||||
}
|
||||
core::arch::asm!(
|
||||
"wsr.ps {0}",
|
||||
"rsync", in(reg) token)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
mod riscv {
|
||||
unsafe impl critical_section::Impl for super::CriticalSection {
|
||||
unsafe fn acquire() -> critical_section::RawRestoreState {
|
||||
let interrupts_active = riscv::register::mstatus::read().mie();
|
||||
riscv::interrupt::disable();
|
||||
|
||||
#[cfg(feature = "multicore")]
|
||||
{
|
||||
let guard = multicore::MULTICORE_LOCK.lock();
|
||||
core::mem::forget(guard); // forget it so drop doesn't run
|
||||
}
|
||||
|
||||
interrupts_active as _
|
||||
}
|
||||
|
||||
unsafe fn release(token: critical_section::RawRestoreState) {
|
||||
if token != 0 {
|
||||
#[cfg(feature = "multicore")]
|
||||
{
|
||||
debug_assert!(multicore::MULTICORE_LOCK.is_owned_by_current_thread());
|
||||
// safety: we logically own the mutex from acquire()
|
||||
multicore::MULTICORE_LOCK.force_unlock();
|
||||
}
|
||||
riscv::interrupt::enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "multicore")]
|
||||
mod multicore {
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use lock_api::{GetThreadId, GuardSend, RawMutex};
|
||||
|
||||
use crate::get_core;
|
||||
|
||||
/// Reentrant Mutex
|
||||
///
|
||||
/// Currently implemented using an atomic spin lock.
|
||||
/// In the future we can optimize this raw mutex to use some hardware
|
||||
/// features.
|
||||
pub(crate) static MULTICORE_LOCK: lock_api::ReentrantMutex<RawSpinlock, RawThreadId, ()> =
|
||||
lock_api::ReentrantMutex::const_new(RawSpinlock::INIT, RawThreadId::INIT, ());
|
||||
|
||||
pub(crate) struct RawThreadId;
|
||||
|
||||
unsafe impl lock_api::GetThreadId for RawThreadId {
|
||||
const INIT: Self = RawThreadId;
|
||||
|
||||
fn nonzero_thread_id(&self) -> core::num::NonZeroUsize {
|
||||
core::num::NonZeroUsize::new((get_core() as usize) + 1).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct RawSpinlock(AtomicBool);
|
||||
|
||||
unsafe impl lock_api::RawMutex for RawSpinlock {
|
||||
const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
|
||||
|
||||
// A spinlock guard can be sent to another thread and unlocked there
|
||||
type GuardMarker = GuardSend;
|
||||
|
||||
fn lock(&self) {
|
||||
while !self.try_lock() {}
|
||||
}
|
||||
|
||||
fn try_lock(&self) -> bool {
|
||||
self.0
|
||||
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
unsafe fn unlock(&self) {
|
||||
self.0.store(false, Ordering::Release);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
use crate::{clock::XtalClock, pac::RTC_CNTL};
|
||||
|
||||
use crate::rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock};
|
||||
use crate::{
|
||||
clock::XtalClock,
|
||||
pac::RTC_CNTL,
|
||||
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
|
||||
};
|
||||
|
||||
pub(crate) fn init() {}
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
use paste::paste;
|
||||
|
||||
use crate::{
|
||||
clock::XtalClock, pac::APB_CTRL, pac::EXTMEM, pac::RTC_CNTL, pac::SPI0, pac::SPI1, pac::SYSTEM,
|
||||
clock::XtalClock,
|
||||
pac::{APB_CTRL, EXTMEM, RTC_CNTL, SPI0, SPI1, SYSTEM},
|
||||
regi2c_write_mask,
|
||||
rom::regi2c_ctrl_write_reg_mask,
|
||||
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
|
||||
};
|
||||
|
||||
use crate::rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock};
|
||||
|
||||
use crate::regi2c_write_mask;
|
||||
use crate::rom::regi2c_ctrl_write_reg_mask;
|
||||
|
||||
const I2C_DIG_REG: u32 = 0x6d;
|
||||
const I2C_DIG_REG_HOSTID: u32 = 0;
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
use crate::{clock::XtalClock, pac::RTC_CNTL};
|
||||
|
||||
use crate::rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock};
|
||||
use crate::{
|
||||
clock::XtalClock,
|
||||
pac::RTC_CNTL,
|
||||
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
|
||||
};
|
||||
|
||||
pub(crate) fn init() {}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
use crate::{clock::XtalClock, pac::RTC_CNTL};
|
||||
|
||||
use crate::rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock};
|
||||
use crate::{
|
||||
clock::XtalClock,
|
||||
pac::RTC_CNTL,
|
||||
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
|
||||
};
|
||||
|
||||
pub(crate) fn init() {}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
use fugit::{HertzU32, MicrosDurationU64};
|
||||
|
||||
use embedded_hal::watchdog::{Watchdog, WatchdogDisable, WatchdogEnable};
|
||||
|
||||
use crate::{clock::Clock, clock::XtalClock, pac::RTC_CNTL, pac::TIMG0};
|
||||
use fugit::{HertzU32, MicrosDurationU64};
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
use crate::efuse::Efuse;
|
||||
|
||||
use crate::rom::esp_rom_delay_us;
|
||||
use crate::{
|
||||
clock::{Clock, XtalClock},
|
||||
pac::{RTC_CNTL, TIMG0},
|
||||
rom::esp_rom_delay_us,
|
||||
};
|
||||
|
||||
#[cfg_attr(feature = "esp32", path = "rtc/esp32.rs")]
|
||||
#[cfg_attr(feature = "esp32s2", path = "rtc/esp32s2.rs")]
|
||||
@ -22,7 +22,7 @@ pub(crate) enum RtcFastClock {
|
||||
/// Main XTAL, divided by 4
|
||||
RtcFastClockXtalD4 = 0,
|
||||
/// Internal fast RC oscillator
|
||||
RtcFastClock8m = 1,
|
||||
RtcFastClock8m = 1,
|
||||
}
|
||||
|
||||
impl Clock for RtcFastClock {
|
||||
@ -42,11 +42,11 @@ impl Clock for RtcFastClock {
|
||||
/// RTC SLOW_CLK frequency values
|
||||
pub(crate) enum RtcSlowClock {
|
||||
/// Internal slow RC oscillator
|
||||
RtcSlowClockRtc = 0,
|
||||
RtcSlowClockRtc = 0,
|
||||
/// External 32 KHz XTAL
|
||||
RtcSlowClock32kXtal = 1,
|
||||
/// Internal fast RC oscillator, divided by 256
|
||||
RtcSlowClock8mD256 = 2,
|
||||
RtcSlowClock8mD256 = 2,
|
||||
}
|
||||
|
||||
impl Clock for RtcSlowClock {
|
||||
@ -72,11 +72,11 @@ impl Clock for RtcSlowClock {
|
||||
/// Clock source to be calibrated using rtc_clk_cal function
|
||||
pub(crate) enum RtcCalSel {
|
||||
/// Currently selected RTC SLOW_CLK
|
||||
RtcCalRtcMux = 0,
|
||||
RtcCalRtcMux = 0,
|
||||
/// Internal 8 MHz RC oscillator, divided by 256
|
||||
RtcCal8mD256 = 1,
|
||||
RtcCal8mD256 = 1,
|
||||
/// External 32 KHz XTAL
|
||||
RtcCal32kXtal = 2,
|
||||
RtcCal32kXtal = 2,
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
/// Internal 150 KHz RC oscillator
|
||||
RtcCalInternalOsc = 3,
|
||||
@ -118,12 +118,13 @@ impl RtcClock {
|
||||
/// Output from 8 MHz internal oscillator is passed into a configurable
|
||||
/// divider, which by default divides the input clock frequency by 256.
|
||||
/// Output of the divider may be used as RTC_SLOW_CLK source.
|
||||
/// Output of the divider is referred to in register descriptions and code as
|
||||
/// 8md256 or simply d256. Divider values other than 256 may be configured, but
|
||||
/// this facility is not currently needed, so is not exposed in the code.
|
||||
/// Output of the divider is referred to in register descriptions and code
|
||||
/// as 8md256 or simply d256. Divider values other than 256 may be
|
||||
/// configured, but this facility is not currently needed, so is not
|
||||
/// exposed in the code.
|
||||
///
|
||||
/// When 8MHz/256 divided output is not needed, the divider should be disabled
|
||||
/// to reduce power consumption.
|
||||
/// When 8MHz/256 divided output is not needed, the divider should be
|
||||
/// disabled to reduce power consumption.
|
||||
fn enable_8m(clk_8m_en: bool, d256_en: bool) {
|
||||
let rtc_cntl = unsafe { &*RTC_CNTL::ptr() };
|
||||
|
||||
@ -150,8 +151,8 @@ impl RtcClock {
|
||||
}
|
||||
|
||||
/// Get main XTAL frequency
|
||||
/// This is the value stored in RTC register RTC_XTAL_FREQ_REG by the bootloader, as passed to
|
||||
/// rtc_clk_init function.
|
||||
/// This is the value stored in RTC register RTC_XTAL_FREQ_REG by the
|
||||
/// bootloader, as passed to rtc_clk_init function.
|
||||
fn get_xtal_freq() -> XtalClock {
|
||||
let rtc_cntl = unsafe { &*RTC_CNTL::ptr() };
|
||||
let xtal_freq_reg = rtc_cntl.store4.read().bits();
|
||||
@ -235,13 +236,13 @@ impl RtcClock {
|
||||
};
|
||||
}
|
||||
|
||||
/// Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||
/// This feature counts the number of XTAL clock cycles within a given number of
|
||||
/// RTC_SLOW_CLK cycles.
|
||||
/// Calibration of RTC_SLOW_CLK is performed using a special feature of
|
||||
/// TIMG0. This feature counts the number of XTAL clock cycles within a
|
||||
/// given number of RTC_SLOW_CLK cycles.
|
||||
fn calibrate_internal(cal_clk: RtcCalSel, slowclk_cycles: u32) -> u32 {
|
||||
// Except for ESP32, choosing RTC_CAL_RTC_MUX results in calibration of
|
||||
// the 150k RTC clock (90k on ESP32-S2) regardless of the currently selected SLOW_CLK.
|
||||
// On the ESP32, it uses the currently selected SLOW_CLK.
|
||||
// the 150k RTC clock (90k on ESP32-S2) regardless of the currently selected
|
||||
// SLOW_CLK. On the ESP32, it uses the currently selected SLOW_CLK.
|
||||
// The following code emulates ESP32 behavior for the other chips:
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
let cal_clk = match cal_clk {
|
||||
@ -281,7 +282,8 @@ impl RtcClock {
|
||||
.bit_is_set()
|
||||
{
|
||||
// Set a small timeout threshold to accelerate the generation of timeout.
|
||||
// The internal circuit will be reset when the timeout occurs and will not affect the next calibration.
|
||||
// The internal circuit will be reset when the timeout occurs and will not
|
||||
// affect the next calibration.
|
||||
timg0
|
||||
.rtccalicfg2
|
||||
.modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(1) });
|
||||
@ -391,10 +393,11 @@ impl RtcClock {
|
||||
|
||||
/// Measure RTC slow clock's period, based on main XTAL frequency
|
||||
///
|
||||
/// This function will time out and return 0 if the time for the given number
|
||||
/// of cycles to be counted exceeds the expected time twice. This may happen if
|
||||
/// 32k XTAL is being calibrated, but the oscillator has not started up (due to
|
||||
/// incorrect loading capacitance, board design issue, or lack of 32 XTAL on board).
|
||||
/// This function will time out and return 0 if the time for the given
|
||||
/// number of cycles to be counted exceeds the expected time twice. This
|
||||
/// may happen if 32k XTAL is being calibrated, but the oscillator has
|
||||
/// not started up (due to incorrect loading capacitance, board design
|
||||
/// issue, or lack of 32 XTAL on board).
|
||||
fn calibrate(cal_clk: RtcCalSel, slowclk_cycles: u32) -> u32 {
|
||||
let xtal_freq = RtcClock::get_xtal_freq();
|
||||
let xtal_cycles = RtcClock::calibrate_internal(cal_clk, slowclk_cycles) as u64;
|
||||
@ -448,11 +451,11 @@ impl RtcClock {
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum RwdtStageAction {
|
||||
RwdtStageActionOff = 0,
|
||||
RwdtStageActionInterrupt = 1,
|
||||
RwdtStageActionResetCpu = 2,
|
||||
RwdtStageActionOff = 0,
|
||||
RwdtStageActionInterrupt = 1,
|
||||
RwdtStageActionResetCpu = 2,
|
||||
RwdtStageActionResetSystem = 3,
|
||||
RwdtStageActionResetRtc = 4,
|
||||
RwdtStageActionResetRtc = 4,
|
||||
}
|
||||
|
||||
/// RTC Watchdog Timer
|
||||
@ -580,7 +583,9 @@ impl WatchdogDisable for Rwdt {
|
||||
|
||||
self.set_write_protection(false);
|
||||
|
||||
rtc_cntl.wdtconfig0.modify(|_, w| w.wdt_en().clear_bit().wdt_flashboot_mod_en().clear_bit());
|
||||
rtc_cntl
|
||||
.wdtconfig0
|
||||
.modify(|_, w| w.wdt_en().clear_bit().wdt_flashboot_mod_en().clear_bit());
|
||||
|
||||
self.set_write_protection(true);
|
||||
}
|
||||
|
@ -22,15 +22,18 @@
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
use core::convert::Infallible;
|
||||
|
||||
use fugit::HertzU32;
|
||||
|
||||
use crate::{
|
||||
clock::Clocks,
|
||||
pac::spi2::RegisterBlock,
|
||||
system::PeripheralClockControl,
|
||||
types::{InputSignal, OutputSignal},
|
||||
InputPin, OutputPin,
|
||||
InputPin,
|
||||
OutputPin,
|
||||
};
|
||||
use core::convert::Infallible;
|
||||
use fugit::HertzU32;
|
||||
|
||||
/// The size of the FIFO buffer for SPI
|
||||
#[cfg(not(feature = "esp32s2"))]
|
||||
@ -209,10 +212,12 @@ pub use ehal1::*;
|
||||
|
||||
#[cfg(feature = "eh1")]
|
||||
mod ehal1 {
|
||||
use super::*;
|
||||
use embedded_hal_1::spi::blocking::{SpiBus, SpiBusFlush, SpiBusRead, SpiBusWrite};
|
||||
use embedded_hal_1::spi::nb::FullDuplex;
|
||||
use embedded_hal_1::spi::{
|
||||
blocking::{SpiBus, SpiBusFlush, SpiBusRead, SpiBusWrite},
|
||||
nb::FullDuplex,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
impl<T> embedded_hal_1::spi::ErrorType for Spi<T> {
|
||||
type Error = Infallible;
|
||||
@ -257,9 +262,10 @@ mod ehal1 {
|
||||
{
|
||||
/// Write out data from `write`, read response into `read`.
|
||||
///
|
||||
/// `read` and `write` are allowed to have different lengths. If `write` is longer, all
|
||||
/// other bytes received are discarded. If `read` is longer, [`EMPTY_WRITE_PAD`] is written
|
||||
/// out as necessary until enough bytes have been read. Reading and writing happens
|
||||
/// `read` and `write` are allowed to have different lengths. If `write`
|
||||
/// is longer, all other bytes received are discarded. If `read`
|
||||
/// is longer, [`EMPTY_WRITE_PAD`] is written out as necessary
|
||||
/// until enough bytes have been read. Reading and writing happens
|
||||
/// simultaneously.
|
||||
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
|
||||
// Optimizations
|
||||
@ -296,7 +302,8 @@ mod ehal1 {
|
||||
SpiBusFlush::flush(self)?;
|
||||
|
||||
if read_inc > 0 {
|
||||
self.spi.read_bytes_from_fifo(&mut read[read_from..read_to])?;
|
||||
self.spi
|
||||
.read_bytes_from_fifo(&mut read[read_from..read_to])?;
|
||||
}
|
||||
|
||||
write_from = write_to;
|
||||
@ -307,8 +314,9 @@ mod ehal1 {
|
||||
|
||||
/// Transfer data in place.
|
||||
///
|
||||
/// Writes data from `words` out on the bus and stores the reply into `words`. A convenient
|
||||
/// wrapper around [`write`](SpiBusWrite::write), [`flush`](SpiBusFlush::flush) and
|
||||
/// Writes data from `words` out on the bus and stores the reply into
|
||||
/// `words`. A convenient wrapper around
|
||||
/// [`write`](SpiBusWrite::write), [`flush`](SpiBusFlush::flush) and
|
||||
/// [`read`](SpiBusRead::read).
|
||||
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
||||
// Since we have the traits so neatly implemented above, use them!
|
||||
@ -548,9 +556,10 @@ pub trait Instance {
|
||||
|
||||
/// Write bytes to SPI.
|
||||
///
|
||||
/// Copies the content of `words` in chunks of 64 bytes into the SPI transmission FIFO. If
|
||||
/// `words` is longer than 64 bytes, multiple sequential transfers are performed. This function
|
||||
/// will return before all bytes of the last chunk to transmit have been sent to the wire. If
|
||||
/// Copies the content of `words` in chunks of 64 bytes into the SPI
|
||||
/// transmission FIFO. If `words` is longer than 64 bytes, multiple
|
||||
/// sequential transfers are performed. This function will return before
|
||||
/// all bytes of the last chunk to transmit have been sent to the wire. If
|
||||
/// you must ensure that the whole messages was written correctly, use
|
||||
/// [`flush`].
|
||||
// FIXME: See below.
|
||||
@ -558,14 +567,15 @@ pub trait Instance {
|
||||
let reg_block = self.register_block();
|
||||
let num_chunks = words.len() / FIFO_SIZE;
|
||||
|
||||
// The fifo has a limited fixed size, so the data must be chunked and then transmitted
|
||||
// The fifo has a limited fixed size, so the data must be chunked and then
|
||||
// transmitted
|
||||
for (i, chunk) in words.chunks(FIFO_SIZE).enumerate() {
|
||||
self.configure_datalen(chunk.len() as u32 * 8);
|
||||
|
||||
let fifo_ptr = reg_block.w0.as_ptr();
|
||||
unsafe {
|
||||
// It seems that `copy_nonoverlapping` is significantly faster than regular `copy`,
|
||||
// by about 20%... ?
|
||||
// It seems that `copy_nonoverlapping` is significantly faster than regular
|
||||
// `copy`, by about 20%... ?
|
||||
core::ptr::copy_nonoverlapping::<u32>(
|
||||
chunk.as_ptr() as *const u32,
|
||||
fifo_ptr as *mut u32,
|
||||
@ -593,9 +603,9 @@ pub trait Instance {
|
||||
|
||||
/// Read bytes from SPI.
|
||||
///
|
||||
/// Sends out a stuffing byte for every byte to read. This function doesn't perform flushing.
|
||||
/// If you want to read the response to something you have written before, consider using
|
||||
/// [`transfer`] instead.
|
||||
/// Sends out a stuffing byte for every byte to read. This function doesn't
|
||||
/// perform flushing. If you want to read the response to something you
|
||||
/// have written before, consider using [`transfer`] instead.
|
||||
fn read_bytes(&mut self, words: &mut [u8]) -> Result<(), Infallible> {
|
||||
let empty_array = [EMPTY_WRITE_PAD; FIFO_SIZE];
|
||||
|
||||
@ -607,15 +617,15 @@ pub trait Instance {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
/// Read received bytes from SPI FIFO.
|
||||
///
|
||||
/// Copies the contents of the SPI receive FIFO into `words`. This function doesn't perform
|
||||
/// flushing. If you want to read the response to something you have written before, consider
|
||||
/// using [`transfer`] instead.
|
||||
// FIXME: Using something like `core::slice::from_raw_parts` and `copy_from_slice` on the
|
||||
// receive registers works only for the esp32 and esp32c3 varaints. The reason for this is
|
||||
// unknown.
|
||||
/// Copies the contents of the SPI receive FIFO into `words`. This function
|
||||
/// doesn't perform flushing. If you want to read the response to
|
||||
/// something you have written before, consider using [`transfer`]
|
||||
/// instead.
|
||||
// FIXME: Using something like `core::slice::from_raw_parts` and
|
||||
// `copy_from_slice` on the receive registers works only for the esp32 and
|
||||
// esp32c3 varaints. The reason for this is unknown.
|
||||
fn read_bytes_from_fifo(&mut self, words: &mut [u8]) -> Result<(), Infallible> {
|
||||
let reg_block = self.register_block();
|
||||
|
||||
|
@ -37,10 +37,11 @@ features = ["esp32"]
|
||||
|
||||
[dev-dependencies]
|
||||
embedded-graphics = "0.7"
|
||||
panic-halt = "0.2"
|
||||
ssd1306 = "0.7"
|
||||
smart-leds = "0.3"
|
||||
esp-println = { version = "0.2.0", features = ["esp32"] }
|
||||
esp-backtrace = { version = "0.2", features = ["esp32", "panic-handler", "exception-handler", "print-uart"] }
|
||||
critical-section = "1"
|
||||
|
||||
[features]
|
||||
default = ["rt", "vectored"]
|
||||
|
@ -15,8 +15,8 @@ use esp32_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -20,9 +20,9 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -14,7 +14,7 @@ use esp32_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -14,12 +15,10 @@ use esp32_hal::{
|
||||
prelude::*,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut RTC: CriticalSectionMutex<RefCell<Option<Rtc>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static RTC: Mutex<RefCell<Option<Rtc>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -43,27 +42,23 @@ fn main() -> ! {
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
unsafe {
|
||||
(&RTC).lock(|data| (*data).replace(Some(rtc)));
|
||||
}
|
||||
critical_section::with(|cs| RTC.borrow_ref_mut(cs).replace(rtc));
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
unsafe {
|
||||
(&RTC).lock(|data| {
|
||||
let mut rtc = data.borrow_mut();
|
||||
let rtc = rtc.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut rtc = RTC.borrow_ref_mut(cs);
|
||||
let rtc = rtc.as_mut().unwrap();
|
||||
|
||||
esp_println::println!(
|
||||
"{: <10} XTAL frequency: {} MHz",
|
||||
"[Monitor]",
|
||||
rtc.estimate_xtal_frequency()
|
||||
);
|
||||
esp_println::println!(
|
||||
"{: <10} XTAL frequency: {} MHz",
|
||||
"[Monitor]",
|
||||
rtc.estimate_xtal_frequency()
|
||||
);
|
||||
|
||||
rtc.rwdt.clear_interrupt();
|
||||
});
|
||||
}
|
||||
rtc.rwdt.clear_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use esp32_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -6,8 +6,9 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
use core::{borrow::BorrowMut, cell::RefCell};
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::{Gpio0, IO},
|
||||
@ -20,12 +21,10 @@ use esp32_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{Mutex, SpinLockMutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut BUTTON: SpinLockMutex<RefCell<Option<Gpio0<Input<PullDown>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static BUTTON: Mutex<RefCell<Option<Gpio0<Input<PullDown>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -48,9 +47,7 @@ fn main() -> ! {
|
||||
let mut button = io.pins.gpio0.into_pull_down_input();
|
||||
button.listen(Event::FallingEdge);
|
||||
|
||||
unsafe {
|
||||
(&BUTTON).lock(|data| (*data).replace(Some(button)));
|
||||
}
|
||||
critical_section::with(|cs| BUTTON.borrow_ref_mut(cs).replace(button));
|
||||
|
||||
interrupt::enable(pac::Interrupt::GPIO, interrupt::Priority::Priority2).unwrap();
|
||||
|
||||
@ -68,17 +65,18 @@ fn main() -> ! {
|
||||
|
||||
#[ram]
|
||||
#[interrupt]
|
||||
fn GPIO() {
|
||||
unsafe {
|
||||
esp_println::println!(
|
||||
"GPIO Interrupt with priority {}",
|
||||
xtensa_lx::interrupt::get_level()
|
||||
);
|
||||
unsafe fn GPIO() {
|
||||
esp_println::println!(
|
||||
"GPIO Interrupt with priority {}",
|
||||
xtensa_lx::interrupt::get_level()
|
||||
);
|
||||
|
||||
(&BUTTON).lock(|data| {
|
||||
let mut button = data.borrow_mut();
|
||||
let button = button.as_mut().unwrap();
|
||||
button.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
BUTTON
|
||||
.borrow_ref_mut(cs)
|
||||
.borrow_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use esp32_hal::{
|
||||
IO,
|
||||
};
|
||||
#[allow(unused_imports)]
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use smart_leds::{
|
||||
brightness,
|
||||
gamma,
|
||||
|
@ -14,8 +14,8 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -31,8 +31,8 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
|
@ -23,7 +23,7 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -5,8 +5,9 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::sync::atomic::{AtomicI32, Ordering};
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
pac::{Peripherals, TIMG1},
|
||||
@ -15,10 +16,9 @@ use esp32_hal::{
|
||||
CpuControl,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::Mutex;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
@ -45,7 +45,7 @@ fn main() -> ! {
|
||||
timer0.start(1u64.secs());
|
||||
timer1.start(500u64.millis());
|
||||
|
||||
let counter = xtensa_lx::mutex::SpinLockMutex::new(AtomicI32::new(0));
|
||||
let counter = Mutex::new(RefCell::new(0));
|
||||
|
||||
let mut cpu_control = CpuControl::new(system.cpu_control);
|
||||
let mut cpu1_fnctn = || {
|
||||
@ -56,24 +56,19 @@ fn main() -> ! {
|
||||
loop {
|
||||
block!(timer0.wait()).unwrap();
|
||||
|
||||
let count = (&counter).lock(|counter| counter.load(Ordering::Relaxed));
|
||||
let count = critical_section::with(|cs| *counter.borrow_ref(cs));
|
||||
println!("Hello World - Core 0! Counter is {}", count);
|
||||
}
|
||||
}
|
||||
|
||||
fn cpu1_task(
|
||||
timer: &mut Timer<Timer0<TIMG1>>,
|
||||
counter: &xtensa_lx::mutex::SpinLockMutex<AtomicI32>,
|
||||
counter: &critical_section::Mutex<RefCell<i32>>,
|
||||
) -> ! {
|
||||
println!("Hello World - Core 1!");
|
||||
loop {
|
||||
block!(timer.wait()).unwrap();
|
||||
|
||||
(&*counter).lock(|counter| {
|
||||
counter.store(
|
||||
counter.load(Ordering::Relaxed).wrapping_add(1),
|
||||
Ordering::Relaxed,
|
||||
);
|
||||
});
|
||||
critical_section::with(|cs| counter.borrow_ref_mut(cs).wrapping_add(1));
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use esp32_hal::{
|
||||
PulseControl,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -18,8 +18,8 @@ use esp32_hal::{
|
||||
timer::TimerGroup,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[ram(rtc_fast)]
|
||||
|
@ -15,7 +15,7 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -16,12 +17,10 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Rwdt,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut RWDT: CriticalSectionMutex<RefCell<Option<Rwdt>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static RWDT: Mutex<RefCell<Option<Rwdt>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -37,30 +36,23 @@ fn main() -> ! {
|
||||
rtc.rwdt.start(2000u64.millis());
|
||||
rtc.rwdt.listen();
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt));
|
||||
|
||||
unsafe {
|
||||
(&RWDT).lock(|data| (*data).replace(Some(rtc.rwdt)));
|
||||
}
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
unsafe {
|
||||
(&RWDT).lock(|data| {
|
||||
esp_println::println!("RWDT Interrupt");
|
||||
critical_section::with(|cs| {
|
||||
let mut rwdt = RWDT.borrow_ref_mut(cs);
|
||||
let rwdt = rwdt.as_mut().unwrap();
|
||||
rwdt.clear_interrupt();
|
||||
|
||||
let mut rwdt = data.borrow_mut();
|
||||
let rwdt = rwdt.as_mut().unwrap();
|
||||
esp_println::println!("Restarting in 5 seconds...");
|
||||
|
||||
rwdt.clear_interrupt();
|
||||
|
||||
esp_println::println!("Restarting in 5 seconds...");
|
||||
|
||||
rwdt.start(5000u64.millis());
|
||||
rwdt.unlisten();
|
||||
});
|
||||
}
|
||||
rwdt.start(5000u64.millis());
|
||||
rwdt.unlisten();
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -17,13 +18,11 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
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 SERIAL: Mutex<RefCell<Option<Serial<UART0>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -56,18 +55,14 @@ fn main() -> ! {
|
||||
|
||||
timer0.start(1u64.secs());
|
||||
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| (*data).replace(Some(serial0)));
|
||||
}
|
||||
critical_section::with(|cs| SERIAL.borrow_ref_mut(cs).replace(serial0));
|
||||
|
||||
loop {
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
let mut serial = SERIAL.borrow_ref_mut(cs);
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
});
|
||||
|
||||
block!(timer0.wait()).unwrap();
|
||||
}
|
||||
@ -75,27 +70,25 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn UART0() {
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut serial = SERIAL.borrow_ref_mut(cs);
|
||||
let serial = serial.as_mut().unwrap();
|
||||
|
||||
let mut cnt = 0;
|
||||
while let nb::Result::Ok(_c) = serial.read() {
|
||||
cnt += 1;
|
||||
}
|
||||
writeln!(serial, "Read {} bytes", cnt,).ok();
|
||||
let mut cnt = 0;
|
||||
while let nb::Result::Ok(_c) = serial.read() {
|
||||
cnt += 1;
|
||||
}
|
||||
writeln!(serial, "Read {} bytes", cnt,).ok();
|
||||
|
||||
writeln!(
|
||||
serial,
|
||||
"Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
|
||||
serial.at_cmd_interrupt_set(),
|
||||
serial.rx_fifo_full_interrupt_set(),
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
serial,
|
||||
"Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
|
||||
serial.at_cmd_interrupt_set(),
|
||||
serial.rx_fifo_full_interrupt_set(),
|
||||
)
|
||||
.ok();
|
||||
|
||||
serial.reset_at_cmd_interrupt();
|
||||
serial.reset_rx_fifo_full_interrupt();
|
||||
});
|
||||
}
|
||||
serial.reset_at_cmd_interrupt();
|
||||
serial.reset_rx_fifo_full_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use embedded_hal_1::spi::blocking::SpiBus;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::IO,
|
||||
@ -29,11 +30,9 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
use embedded_hal_1::spi::blocking::SpiBus;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
@ -82,18 +81,17 @@ fn main() -> ! {
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Asymmetric transfer (Read more than we write) ---
|
||||
write!(serial0, "Starting asymetric transfer (read > write)...").unwrap();
|
||||
let mut read: [u8; 4] = [0x00; 4];
|
||||
|
||||
SpiBus::transfer(&mut spi, &mut read[0..2], &write[..]).expect("Asymmetric transfer failed");
|
||||
SpiBus::transfer(&mut spi, &mut read[0..2], &write[..])
|
||||
.expect("Asymmetric transfer failed");
|
||||
assert_eq!(write[0], read[0]);
|
||||
assert_eq!(read[2], 0x00u8);
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Symmetric transfer with huge buffer ---
|
||||
// Only your RAM is the limit!
|
||||
write!(serial0, "Starting huge transfer...").unwrap();
|
||||
@ -108,8 +106,8 @@ fn main() -> ! {
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Symmetric transfer with huge buffer in-place (No additional allocation needed) ---
|
||||
// --- Symmetric transfer with huge buffer in-place (No additional allocation
|
||||
// needed) ---
|
||||
write!(serial0, "Starting huge transfer (in-place)...").unwrap();
|
||||
let mut write = [0x55u8; 4096];
|
||||
for byte in 0..write.len() {
|
||||
@ -124,4 +122,3 @@ fn main() -> ! {
|
||||
delay.delay_ms(250u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -5,32 +5,25 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
interrupt::Priority,
|
||||
pac::{self, Peripherals, TIMG0, TIMG1, UART0},
|
||||
pac::{self, Peripherals, TIMG0, TIMG1},
|
||||
prelude::*,
|
||||
timer::{Timer, Timer0, Timer1, TimerGroup},
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{Mutex, SpinLockMutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut SERIAL: SpinLockMutex<RefCell<Option<Serial<UART0>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER00: SpinLockMutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER01: SpinLockMutex<RefCell<Option<Timer<Timer1<TIMG0>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER10: SpinLockMutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER11: SpinLockMutex<RefCell<Option<Timer<Timer1<TIMG1>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static TIMER00: Mutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER01: Mutex<RefCell<Option<Timer<Timer1<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER10: Mutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER11: Mutex<RefCell<Option<Timer<Timer1<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -49,7 +42,6 @@ fn main() -> ! {
|
||||
let mut timer11 = timer_group1.timer1;
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
let serial0 = Serial::new(peripherals.UART0);
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
@ -70,97 +62,72 @@ fn main() -> ! {
|
||||
timer11.start(3u64.secs());
|
||||
timer11.listen();
|
||||
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| (*data).replace(Some(serial0)));
|
||||
(&TIMER00).lock(|data| (*data).replace(Some(timer00)));
|
||||
(&TIMER01).lock(|data| (*data).replace(Some(timer01)));
|
||||
(&TIMER10).lock(|data| (*data).replace(Some(timer10)));
|
||||
(&TIMER11).lock(|data| (*data).replace(Some(timer11)));
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
TIMER00.borrow_ref_mut(cs).replace(timer00);
|
||||
TIMER01.borrow_ref_mut(cs).replace(timer01);
|
||||
TIMER10.borrow_ref_mut(cs).replace(timer10);
|
||||
TIMER11.borrow_ref_mut(cs).replace(timer11);
|
||||
});
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG0_T0_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER00).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER00.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 2 - Timer0").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
esp_println::println!("Interrupt Level 2 - Timer0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG0_T1_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER01).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER01.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(2500u64.millis());
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(2500u64.millis());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 2 - Timer1").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
esp_println::println!("Interrupt Level 2 - Timer1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG1_T0_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER10).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER10.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(1u64.secs());
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(1u64.secs());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 3 - Timer0").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
esp_println::println!("Interrupt Level 3 - Timer0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG1_T1_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER11).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER10.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(3u64.secs());
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(3u64.secs());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 3 - Timer1").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
esp_println::println!("Interrupt Level 3 - Timer1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ use esp32_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -24,7 +24,6 @@ categories = [
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
bare-metal = "1.0"
|
||||
embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.8" }
|
||||
r0 = "1.0"
|
||||
@ -37,10 +36,11 @@ features = ["esp32c3"]
|
||||
|
||||
[dev-dependencies]
|
||||
embedded-graphics = "0.7"
|
||||
panic-halt = "0.2"
|
||||
ssd1306 = "0.7"
|
||||
smart-leds = "0.3"
|
||||
esp-println = { version = "0.2.0", features = ["esp32c3"] }
|
||||
esp-backtrace = { version = "0.2", features = ["esp32c3", "panic-handler", "exception-handler", "print-uart"] }
|
||||
critical-section = "1"
|
||||
|
||||
[features]
|
||||
default = ["rt", "vectored"]
|
||||
|
@ -17,8 +17,8 @@ use esp32c3_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -19,9 +19,9 @@ use esp32c3_hal::{
|
||||
Serial,
|
||||
IO,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -15,7 +15,7 @@ use esp32c3_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -1,14 +1,13 @@
|
||||
//! This demos a simple monitor for the XTAL frequency, by relying on a special feature of the
|
||||
//! TIMG0 (Timer Group 0). This feature counts the number of XTAL clock cycles within a given
|
||||
//! number of RTC_SLOW_CLK cycles.
|
||||
//! This demos a simple monitor for the XTAL frequency, by relying on a special
|
||||
//! feature of the TIMG0 (Timer Group 0). This feature counts the number of XTAL
|
||||
//! clock cycles within a given number of RTC_SLOW_CLK cycles.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use bare_metal::Mutex;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32c3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -16,10 +15,10 @@ use esp32c3_hal::{
|
||||
prelude::*,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
static mut RTC: Mutex<RefCell<Option<Rtc>>> = Mutex::new(RefCell::new(None));
|
||||
static RTC: Mutex<RefCell<Option<Rtc>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -44,8 +43,8 @@ fn main() -> ! {
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
riscv::interrupt::free(|_cs| unsafe {
|
||||
RTC.get_mut().replace(Some(rtc));
|
||||
critical_section::with(|cs| {
|
||||
RTC.borrow_ref_mut(cs).replace(rtc);
|
||||
});
|
||||
|
||||
unsafe {
|
||||
@ -57,8 +56,8 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
let mut rtc = RTC.borrow(*cs).borrow_mut();
|
||||
critical_section::with(|cs| {
|
||||
let mut rtc = RTC.borrow(cs).borrow_mut();
|
||||
let rtc = rtc.as_mut().unwrap();
|
||||
|
||||
esp_println::println!(
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use bare_metal::Mutex;
|
||||
use critical_section::Mutex;
|
||||
use esp32c3_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::{Gpio9, IO},
|
||||
@ -20,10 +20,10 @@ use esp32c3_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
static mut BUTTON: Mutex<RefCell<Option<Gpio9<Input<PullDown>>>>> = Mutex::new(RefCell::new(None));
|
||||
static BUTTON: Mutex<RefCell<Option<Gpio9<Input<PullDown>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -52,9 +52,7 @@ fn main() -> ! {
|
||||
let mut button = io.pins.gpio9.into_pull_down_input();
|
||||
button.listen(Event::FallingEdge);
|
||||
|
||||
riscv::interrupt::free(|_cs| unsafe {
|
||||
BUTTON.get_mut().replace(Some(button));
|
||||
});
|
||||
critical_section::with(|cs| BUTTON.borrow_ref_mut(cs).replace(button));
|
||||
|
||||
interrupt::enable(pac::Interrupt::GPIO, interrupt::Priority::Priority3).unwrap();
|
||||
|
||||
@ -71,10 +69,12 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn GPIO() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
let mut button = BUTTON.borrow(*cs).borrow_mut();
|
||||
let button = button.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
esp_println::println!("GPIO interrupt");
|
||||
button.clear_interrupt();
|
||||
BUTTON
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ use esp32c3_hal::{
|
||||
IO,
|
||||
};
|
||||
#[allow(unused_imports)]
|
||||
use panic_halt;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
use smart_leds::{
|
||||
brightness,
|
||||
|
@ -14,8 +14,8 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -28,8 +28,8 @@ use esp32c3_hal::{
|
||||
timer::TimerGroup,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
||||
|
||||
|
@ -21,8 +21,8 @@ use esp32c3_hal::{
|
||||
timer::TimerGroup,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -16,7 +16,7 @@ use esp32c3_hal::{
|
||||
PulseControl,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -18,8 +18,8 @@ use esp32c3_hal::{
|
||||
timer::TimerGroup,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[ram(rtc_fast)]
|
||||
|
@ -15,7 +15,7 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use bare_metal::Mutex;
|
||||
use critical_section::Mutex;
|
||||
use esp32c3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -17,10 +17,10 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
Rwdt,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
static mut RWDT: Mutex<RefCell<Option<Rwdt>>> = Mutex::new(RefCell::new(None));
|
||||
static RWDT: Mutex<RefCell<Option<Rwdt>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -39,9 +39,7 @@ fn main() -> ! {
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
riscv::interrupt::free(|_cs| unsafe {
|
||||
RWDT.get_mut().replace(Some(rtc.rwdt));
|
||||
});
|
||||
critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt));
|
||||
|
||||
unsafe {
|
||||
riscv::interrupt::enable();
|
||||
@ -52,10 +50,10 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
critical_section::with(|cs| {
|
||||
esp_println::println!("RWDT Interrupt");
|
||||
|
||||
let mut rwdt = RWDT.borrow(*cs).borrow_mut();
|
||||
let mut rwdt = RWDT.borrow_ref_mut(cs);
|
||||
let rwdt = rwdt.as_mut().unwrap();
|
||||
|
||||
rwdt.clear_interrupt();
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
|
||||
use bare_metal::Mutex;
|
||||
use critical_section::Mutex;
|
||||
use esp32c3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -19,11 +19,11 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
static mut SERIAL: Mutex<RefCell<Option<Serial<UART0>>>> = Mutex::new(RefCell::new(None));
|
||||
static SERIAL: Mutex<RefCell<Option<Serial<UART0>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -52,9 +52,7 @@ fn main() -> ! {
|
||||
|
||||
timer0.start(1u64.secs());
|
||||
|
||||
riscv::interrupt::free(|_cs| unsafe {
|
||||
SERIAL.get_mut().replace(Some(serial0));
|
||||
});
|
||||
critical_section::with(|cs| SERIAL.borrow_ref_mut(cs).replace(serial0));
|
||||
|
||||
interrupt::enable(pac::Interrupt::UART0, interrupt::Priority::Priority1).unwrap();
|
||||
interrupt::set_kind(
|
||||
@ -68,11 +66,8 @@ fn main() -> ! {
|
||||
}
|
||||
|
||||
loop {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
let mut serial = SERIAL.borrow(*cs).borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
|
||||
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
critical_section::with(|cs| {
|
||||
writeln!(SERIAL.borrow_ref_mut(cs).as_mut().unwrap(), "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
});
|
||||
|
||||
block!(timer0.wait()).unwrap();
|
||||
@ -81,8 +76,8 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn UART0() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
let mut serial = SERIAL.borrow(*cs).borrow_mut();
|
||||
critical_section::with(|cs| {
|
||||
let mut serial = SERIAL.borrow_ref_mut(cs);
|
||||
let serial = serial.as_mut().unwrap();
|
||||
|
||||
let mut cnt = 0;
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use embedded_hal_1::spi::blocking::SpiBus;
|
||||
use esp32c3_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::IO,
|
||||
@ -29,11 +30,9 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
use embedded_hal_1::spi::blocking::SpiBus;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
@ -87,18 +86,17 @@ fn main() -> ! {
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Asymmetric transfer (Read more than we write) ---
|
||||
write!(serial0, "Starting asymetric transfer (read > write)...").unwrap();
|
||||
let mut read: [u8; 4] = [0x00; 4];
|
||||
|
||||
SpiBus::transfer(&mut spi, &mut read[0..2], &write[..]).expect("Asymmetric transfer failed");
|
||||
SpiBus::transfer(&mut spi, &mut read[0..2], &write[..])
|
||||
.expect("Asymmetric transfer failed");
|
||||
assert_eq!(write[0], read[0]);
|
||||
assert_eq!(read[2], 0x00u8);
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Symmetric transfer with huge buffer ---
|
||||
// Only your RAM is the limit!
|
||||
write!(serial0, "Starting huge transfer...").unwrap();
|
||||
@ -113,8 +111,8 @@ fn main() -> ! {
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Symmetric transfer with huge buffer in-place (No additional allocation needed) ---
|
||||
// --- Symmetric transfer with huge buffer in-place (No additional allocation
|
||||
// needed) ---
|
||||
write!(serial0, "Starting huge transfer (in-place)...").unwrap();
|
||||
let mut write = [0x55u8; 4096];
|
||||
for byte in 0..write.len() {
|
||||
@ -129,4 +127,3 @@ fn main() -> ! {
|
||||
delay.delay_ms(250u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -6,23 +6,24 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use bare_metal::Mutex;
|
||||
use critical_section::Mutex;
|
||||
use esp32c3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
interrupt::Priority,
|
||||
pac::{self, Peripherals},
|
||||
prelude::*,
|
||||
systimer::{Alarm, SystemTimer, Target},
|
||||
timer::TimerGroup,
|
||||
Cpu,
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
static mut ALARM0: Mutex<RefCell<Option<Alarm<Target, 0>>>> = Mutex::new(RefCell::new(None));
|
||||
static mut ALARM1: Mutex<RefCell<Option<Alarm<Target, 1>>>> = Mutex::new(RefCell::new(None));
|
||||
static mut ALARM2: Mutex<RefCell<Option<Alarm<Target, 2>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM0: Mutex<RefCell<Option<Alarm<Target, 0>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM1: Mutex<RefCell<Option<Alarm<Target, 1>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM2: Mutex<RefCell<Option<Alarm<Target, 2>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -30,99 +31,79 @@ fn main() -> ! {
|
||||
let system = peripherals.SYSTEM.split();
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
// Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT,
|
||||
// the RTC WDT, and the TIMG WDTs.
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks);
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
let mut wdt = timer_group0.wdt;
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
rtc.swd.disable();
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
wdt.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
wdt1.disable();
|
||||
|
||||
let syst = SystemTimer::new(peripherals.SYSTIMER);
|
||||
|
||||
esp_println::println!("SYSTIMER Current value = {}", SystemTimer::now());
|
||||
|
||||
let alarm0 = syst.alarm0;
|
||||
alarm0.set_target(40_000_000);
|
||||
alarm0.set_target(40_000_0000);
|
||||
alarm0.enable_interrupt();
|
||||
|
||||
let alarm1 = syst.alarm1;
|
||||
alarm1.set_target(41_111_111);
|
||||
alarm1.set_target(41_111_1110);
|
||||
alarm1.enable_interrupt();
|
||||
|
||||
let alarm2 = syst.alarm2;
|
||||
alarm2.set_target(42_222_222 * 2);
|
||||
alarm2.set_target(42_222_2220 * 2);
|
||||
alarm2.enable_interrupt();
|
||||
|
||||
interrupt::enable(
|
||||
pac::Interrupt::SYSTIMER_TARGET0,
|
||||
interrupt::Priority::Priority1,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
pac::Interrupt::SYSTIMER_TARGET1,
|
||||
interrupt::Priority::Priority1,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
pac::Interrupt::SYSTIMER_TARGET2,
|
||||
interrupt::Priority::Priority1,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
riscv::interrupt::free(|_cs| unsafe {
|
||||
ALARM0.get_mut().replace(Some(alarm0));
|
||||
ALARM1.get_mut().replace(Some(alarm1));
|
||||
ALARM2.get_mut().replace(Some(alarm2));
|
||||
critical_section::with(|cs| {
|
||||
ALARM0.borrow_ref_mut(cs).replace(alarm0);
|
||||
ALARM1.borrow_ref_mut(cs).replace(alarm1);
|
||||
ALARM2.borrow_ref_mut(cs).replace(alarm2);
|
||||
});
|
||||
|
||||
unsafe {
|
||||
riscv::interrupt::enable();
|
||||
}
|
||||
interrupt::enable(pac::Interrupt::SYSTIMER_TARGET0, Priority::Priority1).unwrap();
|
||||
interrupt::enable(pac::Interrupt::SYSTIMER_TARGET1, Priority::Priority2).unwrap();
|
||||
interrupt::enable(pac::Interrupt::SYSTIMER_TARGET2, Priority::Priority2).unwrap();
|
||||
|
||||
loop {}
|
||||
// Initialize the Delay peripheral, and use it to toggle the LED state in a
|
||||
// loop.
|
||||
let mut delay = Delay::new(&clocks);
|
||||
|
||||
loop {
|
||||
delay.delay_ms(500u32);
|
||||
}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET0() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
esp_println::println!("Interrupt 1 = {}", SystemTimer::now());
|
||||
|
||||
let mut alarm = ALARM0.borrow(*cs).borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
|
||||
interrupt::clear(Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt1);
|
||||
alarm.clear_interrupt();
|
||||
esp_println::println!("Interrupt lvl1 (alarm0)");
|
||||
critical_section::with(|cs| {
|
||||
ALARM0
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET1() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
esp_println::println!("Interrupt 2 = {}", SystemTimer::now());
|
||||
|
||||
let mut alarm = ALARM1.borrow(*cs).borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
|
||||
interrupt::clear(Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt2);
|
||||
alarm.clear_interrupt();
|
||||
esp_println::println!("Interrupt lvl2 (alarm1)");
|
||||
critical_section::with(|cs| {
|
||||
ALARM1
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET2() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
esp_println::println!("Interrupt 3 = {}", SystemTimer::now());
|
||||
|
||||
let mut alarm = ALARM2.borrow(*cs).borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
|
||||
interrupt::clear(Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt3);
|
||||
alarm.clear_interrupt();
|
||||
esp_println::println!("Interrupt lvl2 (alarm2)");
|
||||
critical_section::with(|cs| {
|
||||
ALARM2
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use bare_metal::Mutex;
|
||||
use critical_section::Mutex;
|
||||
use esp32c3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -16,11 +16,11 @@ use esp32c3_hal::{
|
||||
timer::{Timer, Timer0, TimerGroup},
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
static mut TIMER0: Mutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static mut TIMER1: Mutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER0: Mutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER1: Mutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -51,9 +51,9 @@ fn main() -> ! {
|
||||
timer1.start(1u64.secs());
|
||||
timer1.listen();
|
||||
|
||||
riscv::interrupt::free(|_cs| unsafe {
|
||||
TIMER0.get_mut().replace(Some(timer0));
|
||||
TIMER1.get_mut().replace(Some(timer1));
|
||||
critical_section::with(|cs| {
|
||||
TIMER0.borrow_ref_mut(cs).replace(timer0);
|
||||
TIMER1.borrow_ref_mut(cs).replace(timer1);
|
||||
});
|
||||
|
||||
unsafe {
|
||||
@ -65,10 +65,10 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn TG0_T0_LEVEL() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
critical_section::with(|cs| {
|
||||
esp_println::println!("Interrupt 1");
|
||||
|
||||
let mut timer0 = TIMER0.borrow(*cs).borrow_mut();
|
||||
let mut timer0 = TIMER0.borrow_ref_mut(cs);
|
||||
let timer0 = timer0.as_mut().unwrap();
|
||||
|
||||
timer0.clear_interrupt();
|
||||
@ -78,10 +78,10 @@ fn TG0_T0_LEVEL() {
|
||||
|
||||
#[interrupt]
|
||||
fn TG1_T0_LEVEL() {
|
||||
riscv::interrupt::free(|cs| unsafe {
|
||||
critical_section::with(|cs| {
|
||||
esp_println::println!("Interrupt 11");
|
||||
|
||||
let mut timer1 = TIMER1.borrow(*cs).borrow_mut();
|
||||
let mut timer1 = TIMER1.borrow_ref_mut(cs);
|
||||
let timer1 = timer1.as_mut().unwrap();
|
||||
|
||||
timer1.clear_interrupt();
|
||||
|
@ -17,7 +17,7 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
UsbSerialJtag,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -15,8 +15,8 @@ use esp32c3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use riscv_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -24,7 +24,6 @@ categories = [
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
bare-metal = "1.0"
|
||||
embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.8" }
|
||||
xtensa-lx = { version = "0.7", features = ["esp32s2"] }
|
||||
@ -40,6 +39,8 @@ panic-halt = "0.2"
|
||||
ssd1306 = "0.7"
|
||||
smart-leds = "0.3"
|
||||
esp-println = { version = "0.2.0", features = ["esp32s2"] }
|
||||
esp-backtrace = { version = "0.2", features = ["esp32s2", "panic-handler", "exception-handler", "print-uart"] }
|
||||
critical-section = "1"
|
||||
|
||||
[features]
|
||||
default = ["rt", "vectored"]
|
||||
|
@ -15,8 +15,8 @@ use esp32s2_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -21,8 +21,8 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -14,7 +14,7 @@ use esp32s2_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -14,12 +15,10 @@ use esp32s2_hal::{
|
||||
prelude::*,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut RTC: CriticalSectionMutex<RefCell<Option<Rtc>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static RTC: Mutex<RefCell<Option<Rtc>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -43,27 +42,23 @@ fn main() -> ! {
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
unsafe {
|
||||
(&RTC).lock(|data| (*data).replace(Some(rtc)));
|
||||
}
|
||||
critical_section::with(|cs| RTC.borrow_ref_mut(cs).replace(rtc));
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
unsafe {
|
||||
(&RTC).lock(|data| {
|
||||
let mut rtc = data.borrow_mut();
|
||||
let rtc = rtc.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut rtc = RTC.borrow_ref_mut(cs);
|
||||
let rtc = rtc.as_mut().unwrap();
|
||||
|
||||
esp_println::println!(
|
||||
"{: <10} XTAL frequency: {} MHz",
|
||||
"[Monitor]",
|
||||
rtc.estimate_xtal_frequency()
|
||||
);
|
||||
esp_println::println!(
|
||||
"{: <10} XTAL frequency: {} MHz",
|
||||
"[Monitor]",
|
||||
rtc.estimate_xtal_frequency()
|
||||
);
|
||||
|
||||
rtc.rwdt.clear_interrupt();
|
||||
});
|
||||
}
|
||||
rtc.rwdt.clear_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use esp32s2_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::{Gpio0, IO},
|
||||
@ -20,12 +21,10 @@ use esp32s2_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut BUTTON: CriticalSectionMutex<RefCell<Option<Gpio0<Input<PullDown>>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static BUTTON: Mutex<RefCell<Option<Gpio0<Input<PullDown>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -48,9 +47,7 @@ fn main() -> ! {
|
||||
let mut button = io.pins.gpio0.into_pull_down_input();
|
||||
button.listen(Event::FallingEdge);
|
||||
|
||||
unsafe {
|
||||
(&BUTTON).lock(|data| (*data).replace(Some(button)));
|
||||
}
|
||||
critical_section::with(|cs| BUTTON.borrow_ref_mut(cs).replace(button));
|
||||
|
||||
interrupt::enable(pac::Interrupt::GPIO, interrupt::Priority::Priority2).unwrap();
|
||||
|
||||
@ -69,16 +66,15 @@ fn main() -> ! {
|
||||
#[ram]
|
||||
#[interrupt]
|
||||
fn GPIO() {
|
||||
unsafe {
|
||||
esp_println::println!(
|
||||
"GPIO Interrupt with priority {}",
|
||||
xtensa_lx::interrupt::get_level()
|
||||
);
|
||||
|
||||
(&BUTTON).lock(|data| {
|
||||
let mut button = data.borrow_mut();
|
||||
let button = button.as_mut().unwrap();
|
||||
button.clear_interrupt();
|
||||
});
|
||||
}
|
||||
esp_println::println!(
|
||||
"GPIO Interrupt with priority {}",
|
||||
xtensa_lx::interrupt::get_level()
|
||||
);
|
||||
critical_section::with(|cs| {
|
||||
BUTTON
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use esp32s2_hal::{
|
||||
IO,
|
||||
};
|
||||
#[allow(unused_imports)]
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use smart_leds::{
|
||||
brightness,
|
||||
gamma,
|
||||
|
@ -14,8 +14,8 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -31,8 +31,8 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
|
@ -22,8 +22,8 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -15,7 +15,7 @@ use esp32s2_hal::{
|
||||
PulseControl,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -18,8 +18,8 @@ use esp32s2_hal::{
|
||||
timer::TimerGroup,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[ram(rtc_fast)]
|
||||
|
@ -15,7 +15,7 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -16,12 +17,10 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Rwdt,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut RWDT: CriticalSectionMutex<RefCell<Option<Rwdt>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static RWDT: Mutex<RefCell<Option<Rwdt>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -37,30 +36,23 @@ fn main() -> ! {
|
||||
rtc.rwdt.start(2000u64.millis());
|
||||
rtc.rwdt.listen();
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt));
|
||||
|
||||
unsafe {
|
||||
(&RWDT).lock(|data| (*data).replace(Some(rtc.rwdt)));
|
||||
}
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
unsafe {
|
||||
(&RWDT).lock(|data| {
|
||||
esp_println::println!("RWDT Interrupt");
|
||||
critical_section::with(|cs| {
|
||||
let mut rwdt = RWDT.borrow_ref_mut(cs);
|
||||
let rwdt = rwdt.as_mut().unwrap();
|
||||
rwdt.clear_interrupt();
|
||||
|
||||
let mut rwdt = data.borrow_mut();
|
||||
let rwdt = rwdt.as_mut().unwrap();
|
||||
esp_println::println!("Restarting in 5 seconds...");
|
||||
|
||||
rwdt.clear_interrupt();
|
||||
|
||||
esp_println::println!("Restarting in 5 seconds...");
|
||||
|
||||
rwdt.start(5000u64.millis());
|
||||
rwdt.unlisten();
|
||||
});
|
||||
}
|
||||
rwdt.start(5000u64.millis());
|
||||
rwdt.unlisten();
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -17,13 +18,11 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut SERIAL: CriticalSectionMutex<RefCell<Option<Serial<UART0>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static SERIAL: Mutex<RefCell<Option<Serial<UART0>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -56,18 +55,14 @@ fn main() -> ! {
|
||||
|
||||
timer0.start(1u64.secs());
|
||||
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| (*data).replace(Some(serial0)));
|
||||
}
|
||||
critical_section::with(|cs| SERIAL.borrow_ref_mut(cs).replace(serial0));
|
||||
|
||||
loop {
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
let mut serial = SERIAL.borrow_ref_mut(cs);
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
});
|
||||
|
||||
block!(timer0.wait()).unwrap();
|
||||
}
|
||||
@ -75,27 +70,25 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn UART0() {
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut serial = SERIAL.borrow_ref_mut(cs);
|
||||
let serial = serial.as_mut().unwrap();
|
||||
|
||||
let mut cnt = 0;
|
||||
while let nb::Result::Ok(_c) = serial.read() {
|
||||
cnt += 1;
|
||||
}
|
||||
writeln!(serial, "Read {} bytes", cnt,).ok();
|
||||
let mut cnt = 0;
|
||||
while let nb::Result::Ok(_c) = serial.read() {
|
||||
cnt += 1;
|
||||
}
|
||||
writeln!(serial, "Read {} bytes", cnt,).ok();
|
||||
|
||||
writeln!(
|
||||
serial,
|
||||
"Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
|
||||
serial.at_cmd_interrupt_set(),
|
||||
serial.rx_fifo_full_interrupt_set(),
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
serial,
|
||||
"Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
|
||||
serial.at_cmd_interrupt_set(),
|
||||
serial.rx_fifo_full_interrupt_set(),
|
||||
)
|
||||
.ok();
|
||||
|
||||
serial.reset_at_cmd_interrupt();
|
||||
serial.reset_rx_fifo_full_interrupt();
|
||||
});
|
||||
}
|
||||
serial.reset_at_cmd_interrupt();
|
||||
serial.reset_rx_fifo_full_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -29,7 +29,7 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -17,16 +18,12 @@ use esp32s2_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut ALARM0: CriticalSectionMutex<RefCell<Option<Alarm<Target, 0>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static mut ALARM1: CriticalSectionMutex<RefCell<Option<Alarm<Target, 1>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static mut ALARM2: CriticalSectionMutex<RefCell<Option<Alarm<Target, 2>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static ALARM0: Mutex<RefCell<Option<Alarm<Target, 0>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM1: Mutex<RefCell<Option<Alarm<Target, 1>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM2: Mutex<RefCell<Option<Alarm<Target, 2>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -56,11 +53,11 @@ fn main() -> ! {
|
||||
alarm2.set_target(42_222_2220 * 2);
|
||||
alarm2.enable_interrupt();
|
||||
|
||||
unsafe {
|
||||
(&ALARM0).lock(|data| (*data).replace(Some(alarm0)));
|
||||
(&ALARM1).lock(|data| (*data).replace(Some(alarm1)));
|
||||
(&ALARM2).lock(|data| (*data).replace(Some(alarm2)));
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM0.borrow_ref_mut(cs).replace(alarm0);
|
||||
ALARM1.borrow_ref_mut(cs).replace(alarm1);
|
||||
ALARM2.borrow_ref_mut(cs).replace(alarm2);
|
||||
});
|
||||
|
||||
interrupt::enable(pac::Interrupt::SYSTIMER_TARGET0, Priority::Priority1).unwrap();
|
||||
interrupt::enable(pac::Interrupt::SYSTIMER_TARGET1, Priority::Priority2).unwrap();
|
||||
@ -78,38 +75,35 @@ fn main() -> ! {
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET0() {
|
||||
esp_println::println!("Interrupt lvl1 (alarm0)");
|
||||
|
||||
unsafe {
|
||||
(&ALARM0).lock(|data| {
|
||||
let mut alarm = data.borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
alarm.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM0
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET1() {
|
||||
esp_println::println!("Interrupt lvl2 (alarm1)");
|
||||
|
||||
unsafe {
|
||||
(&ALARM1).lock(|data| {
|
||||
let mut alarm = data.borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
alarm.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM1
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET2() {
|
||||
esp_println::println!("Interrupt lvl2 (alarm2)");
|
||||
|
||||
unsafe {
|
||||
(&ALARM2).lock(|data| {
|
||||
let mut alarm = data.borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
alarm.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM2
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
@ -5,32 +5,25 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
interrupt::Priority,
|
||||
pac::{self, Peripherals, TIMG0, TIMG1, UART0},
|
||||
pac::{self, Peripherals, TIMG0, TIMG1},
|
||||
prelude::*,
|
||||
timer::{Timer, Timer0, Timer1, TimerGroup},
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut SERIAL: CriticalSectionMutex<RefCell<Option<Serial<UART0>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static mut TIMER00: CriticalSectionMutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static mut TIMER01: CriticalSectionMutex<RefCell<Option<Timer<Timer1<TIMG0>>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static mut TIMER10: CriticalSectionMutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static mut TIMER11: CriticalSectionMutex<RefCell<Option<Timer<Timer1<TIMG1>>>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static TIMER00: Mutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER01: Mutex<RefCell<Option<Timer<Timer1<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER10: Mutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER11: Mutex<RefCell<Option<Timer<Timer1<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -49,7 +42,6 @@ fn main() -> ! {
|
||||
let mut timer11 = timer_group1.timer1;
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
let serial0 = Serial::new(peripherals.UART0);
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
@ -70,97 +62,68 @@ fn main() -> ! {
|
||||
timer11.start(3u64.secs());
|
||||
timer11.listen();
|
||||
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| (*data).replace(Some(serial0)));
|
||||
(&TIMER00).lock(|data| (*data).replace(Some(timer00)));
|
||||
(&TIMER01).lock(|data| (*data).replace(Some(timer01)));
|
||||
(&TIMER10).lock(|data| (*data).replace(Some(timer10)));
|
||||
(&TIMER11).lock(|data| (*data).replace(Some(timer11)));
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
TIMER00.borrow_ref_mut(cs).replace(timer00);
|
||||
TIMER01.borrow_ref_mut(cs).replace(timer01);
|
||||
TIMER10.borrow_ref_mut(cs).replace(timer10);
|
||||
TIMER11.borrow_ref_mut(cs).replace(timer11);
|
||||
});
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG0_T0_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER00).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER00.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 2 - Timer0").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 2 - Timer0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG0_T1_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER01).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER01.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(2500u64.millis());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 2 - Timer1").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 2 - Timer1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG1_T0_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER10).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER10.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(1u64.secs());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 3 - Timer0").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 3 - Timer0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG1_T1_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER11).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER11.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(3u64.secs());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 3 - Timer1").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 3 - Timer1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ use esp32s2_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -41,6 +41,8 @@ panic-halt = "0.2"
|
||||
ssd1306 = "0.7"
|
||||
smart-leds = "0.3"
|
||||
esp-println = { version = "0.2.0", features = ["esp32s3"] }
|
||||
esp-backtrace = { version = "0.2", features = ["esp32s3", "panic-handler", "exception-handler", "print-uart"] }
|
||||
critical-section = "1"
|
||||
|
||||
[features]
|
||||
default = ["rt", "vectored"]
|
||||
|
@ -21,8 +21,8 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -14,7 +14,7 @@ use esp32s3_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -14,12 +15,10 @@ use esp32s3_hal::{
|
||||
prelude::*,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut RTC: CriticalSectionMutex<RefCell<Option<Rtc>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static RTC: Mutex<RefCell<Option<Rtc>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -29,8 +28,7 @@ fn main() -> ! {
|
||||
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable watchdog timers
|
||||
rtc.swd.disable();
|
||||
// Disable watchdog timer
|
||||
rtc.rwdt.disable();
|
||||
|
||||
rtc.rwdt.start(2000u64.millis());
|
||||
@ -44,27 +42,23 @@ fn main() -> ! {
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
unsafe {
|
||||
(&RTC).lock(|data| (*data).replace(Some(rtc)));
|
||||
}
|
||||
critical_section::with(|cs| RTC.borrow_ref_mut(cs).replace(rtc));
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
unsafe {
|
||||
(&RTC).lock(|data| {
|
||||
let mut rtc = data.borrow_mut();
|
||||
let rtc = rtc.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut rtc = RTC.borrow_ref_mut(cs);
|
||||
let rtc = rtc.as_mut().unwrap();
|
||||
|
||||
esp_println::println!(
|
||||
"{: <10} XTAL frequency: {} MHz",
|
||||
"[Monitor]",
|
||||
rtc.estimate_xtal_frequency()
|
||||
);
|
||||
esp_println::println!(
|
||||
"{: <10} XTAL frequency: {} MHz",
|
||||
"[Monitor]",
|
||||
rtc.estimate_xtal_frequency()
|
||||
);
|
||||
|
||||
rtc.rwdt.clear_interrupt();
|
||||
});
|
||||
}
|
||||
rtc.rwdt.clear_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::{Gpio0, IO},
|
||||
@ -20,12 +21,10 @@ use esp32s3_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{Mutex, SpinLockMutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut BUTTON: SpinLockMutex<RefCell<Option<Gpio0<Input<PullDown>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static BUTTON: Mutex<RefCell<Option<Gpio0<Input<PullDown>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -48,9 +47,7 @@ fn main() -> ! {
|
||||
let mut button = io.pins.gpio0.into_pull_down_input();
|
||||
button.listen(Event::FallingEdge);
|
||||
|
||||
unsafe {
|
||||
(&BUTTON).lock(|data| (*data).replace(Some(button)));
|
||||
}
|
||||
critical_section::with(|cs| BUTTON.borrow_ref_mut(cs).replace(button));
|
||||
|
||||
interrupt::enable(pac::Interrupt::GPIO, interrupt::Priority::Priority2).unwrap();
|
||||
|
||||
@ -69,16 +66,16 @@ fn main() -> ! {
|
||||
#[ram]
|
||||
#[interrupt]
|
||||
fn GPIO() {
|
||||
unsafe {
|
||||
esp_println::println!(
|
||||
"GPIO Interrupt with priority {}",
|
||||
xtensa_lx::interrupt::get_level()
|
||||
);
|
||||
esp_println::println!(
|
||||
"GPIO Interrupt with priority {}",
|
||||
xtensa_lx::interrupt::get_level()
|
||||
);
|
||||
|
||||
(&BUTTON).lock(|data| {
|
||||
let mut button = data.borrow_mut();
|
||||
let button = button.as_mut().unwrap();
|
||||
button.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
BUTTON
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ use esp32s3_hal::{
|
||||
IO,
|
||||
};
|
||||
#[allow(unused_imports)]
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use smart_leds::{
|
||||
brightness,
|
||||
gamma,
|
||||
|
@ -14,8 +14,8 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -31,8 +31,8 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
|
@ -22,8 +22,8 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
@ -53,7 +53,7 @@ fn main() -> ! {
|
||||
|
||||
let mut lstimer0 = ledc.get_timer::<LowSpeed>(timer::Number::Timer0);
|
||||
|
||||
let res = lstimer0
|
||||
lstimer0
|
||||
.configure(timer::config::Config {
|
||||
duty: timer::config::Duty::Duty5Bit,
|
||||
clock_source: timer::LSClockSource::APBClk,
|
||||
|
@ -5,8 +5,9 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::sync::atomic::{AtomicI32, Ordering};
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
pac::{Peripherals, TIMG1},
|
||||
@ -15,10 +16,9 @@ use esp32s3_hal::{
|
||||
CpuControl,
|
||||
Rtc,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use esp_println::println;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::Mutex;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
@ -45,7 +45,7 @@ fn main() -> ! {
|
||||
timer0.start(1u64.secs());
|
||||
timer1.start(500u64.millis());
|
||||
|
||||
let counter = xtensa_lx::mutex::SpinLockMutex::new(AtomicI32::new(0));
|
||||
let counter = Mutex::new(RefCell::new(0));
|
||||
|
||||
let mut cpu_control = CpuControl::new(system.cpu_control);
|
||||
let mut cpu1_fnctn = || {
|
||||
@ -56,24 +56,19 @@ fn main() -> ! {
|
||||
loop {
|
||||
block!(timer0.wait()).unwrap();
|
||||
|
||||
let count = (&counter).lock(|counter| counter.load(Ordering::Relaxed));
|
||||
let count = critical_section::with(|cs| *counter.borrow_ref(cs));
|
||||
println!("Hello World - Core 0! Counter is {}", count);
|
||||
}
|
||||
}
|
||||
|
||||
fn cpu1_task(
|
||||
timer: &mut Timer<Timer0<TIMG1>>,
|
||||
counter: &xtensa_lx::mutex::SpinLockMutex<AtomicI32>,
|
||||
counter: &critical_section::Mutex<RefCell<i32>>,
|
||||
) -> ! {
|
||||
println!("Hello World - Core 1!");
|
||||
loop {
|
||||
block!(timer.wait()).unwrap();
|
||||
|
||||
(&*counter).lock(|counter| {
|
||||
counter.store(
|
||||
counter.load(Ordering::Relaxed).wrapping_add(1),
|
||||
Ordering::Relaxed,
|
||||
);
|
||||
});
|
||||
critical_section::with(|cs| counter.borrow_ref_mut(cs).wrapping_add(1));
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use esp32s3_hal::{
|
||||
PulseControl,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -18,8 +18,8 @@ use esp32s3_hal::{
|
||||
timer::TimerGroup,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[ram(rtc_fast)]
|
||||
|
@ -15,7 +15,7 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -16,12 +17,10 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Rwdt,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{CriticalSectionMutex, Mutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut RWDT: CriticalSectionMutex<RefCell<Option<Rwdt>>> =
|
||||
CriticalSectionMutex::new(RefCell::new(None));
|
||||
static RWDT: Mutex<RefCell<Option<Rwdt>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -31,37 +30,29 @@ fn main() -> ! {
|
||||
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable watchdog timers
|
||||
rtc.swd.disable();
|
||||
// Disable watchdog timer
|
||||
rtc.rwdt.disable();
|
||||
|
||||
rtc.rwdt.start(2000u64.millis());
|
||||
rtc.rwdt.listen();
|
||||
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt));
|
||||
|
||||
unsafe {
|
||||
(&RWDT).lock(|data| (*data).replace(Some(rtc.rwdt)));
|
||||
}
|
||||
interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn RTC_CORE() {
|
||||
unsafe {
|
||||
(&RWDT).lock(|data| {
|
||||
esp_println::println!("RWDT Interrupt");
|
||||
critical_section::with(|cs| {
|
||||
let mut rwdt = RWDT.borrow_ref_mut(cs);
|
||||
let rwdt = rwdt.as_mut().unwrap();
|
||||
rwdt.clear_interrupt();
|
||||
|
||||
let mut rwdt = data.borrow_mut();
|
||||
let rwdt = rwdt.as_mut().unwrap();
|
||||
esp_println::println!("Restarting in 5 seconds...");
|
||||
|
||||
rwdt.clear_interrupt();
|
||||
|
||||
esp_println::println!("Restarting in 5 seconds...");
|
||||
|
||||
rwdt.start(5000u64.millis());
|
||||
rwdt.unlisten();
|
||||
});
|
||||
}
|
||||
rwdt.start(5000u64.millis());
|
||||
rwdt.unlisten();
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -17,13 +18,11 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
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 SERIAL: Mutex<RefCell<Option<Serial<UART0>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -56,18 +55,14 @@ fn main() -> ! {
|
||||
|
||||
timer0.start(1u64.secs());
|
||||
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| (*data).replace(Some(serial0)));
|
||||
}
|
||||
critical_section::with(|cs| SERIAL.borrow_ref_mut(cs).replace(serial0));
|
||||
|
||||
loop {
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
let mut serial = SERIAL.borrow_ref_mut(cs);
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
|
||||
});
|
||||
|
||||
block!(timer0.wait()).unwrap();
|
||||
}
|
||||
@ -75,27 +70,25 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn UART0() {
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut serial = SERIAL.borrow_ref_mut(cs);
|
||||
let serial = serial.as_mut().unwrap();
|
||||
|
||||
let mut cnt = 0;
|
||||
while let nb::Result::Ok(_c) = serial.read() {
|
||||
cnt += 1;
|
||||
}
|
||||
writeln!(serial, "Read {} bytes", cnt,).ok();
|
||||
let mut cnt = 0;
|
||||
while let nb::Result::Ok(_c) = serial.read() {
|
||||
cnt += 1;
|
||||
}
|
||||
writeln!(serial, "Read {} bytes", cnt,).ok();
|
||||
|
||||
writeln!(
|
||||
serial,
|
||||
"Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
|
||||
serial.at_cmd_interrupt_set(),
|
||||
serial.rx_fifo_full_interrupt_set(),
|
||||
)
|
||||
.ok();
|
||||
writeln!(
|
||||
serial,
|
||||
"Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
|
||||
serial.at_cmd_interrupt_set(),
|
||||
serial.rx_fifo_full_interrupt_set(),
|
||||
)
|
||||
.ok();
|
||||
|
||||
serial.reset_at_cmd_interrupt();
|
||||
serial.reset_rx_fifo_full_interrupt();
|
||||
});
|
||||
}
|
||||
serial.reset_at_cmd_interrupt();
|
||||
serial.reset_rx_fifo_full_interrupt();
|
||||
});
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use embedded_hal_1::spi::blocking::SpiBus;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::IO,
|
||||
@ -29,11 +30,9 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
use embedded_hal_1::spi::blocking::SpiBus;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
@ -82,18 +81,17 @@ fn main() -> ! {
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Asymmetric transfer (Read more than we write) ---
|
||||
write!(serial0, "Starting asymetric transfer (read > write)...").unwrap();
|
||||
let mut read: [u8; 4] = [0x00; 4];
|
||||
|
||||
SpiBus::transfer(&mut spi, &mut read[0..2], &write[..]).expect("Asymmetric transfer failed");
|
||||
SpiBus::transfer(&mut spi, &mut read[0..2], &write[..])
|
||||
.expect("Asymmetric transfer failed");
|
||||
assert_eq!(write[0], read[0]);
|
||||
assert_eq!(read[2], 0x00u8);
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Symmetric transfer with huge buffer ---
|
||||
// Only your RAM is the limit!
|
||||
write!(serial0, "Starting huge transfer...").unwrap();
|
||||
@ -108,8 +106,8 @@ fn main() -> ! {
|
||||
writeln!(serial0, " SUCCESS").unwrap();
|
||||
delay.delay_ms(250u32);
|
||||
|
||||
|
||||
// --- Symmetric transfer with huge buffer in-place (No additional allocation needed) ---
|
||||
// --- Symmetric transfer with huge buffer in-place (No additional allocation
|
||||
// needed) ---
|
||||
write!(serial0, "Starting huge transfer (in-place)...").unwrap();
|
||||
let mut write = [0x55u8; 4096];
|
||||
for byte in 0..write.len() {
|
||||
@ -124,4 +122,3 @@ fn main() -> ! {
|
||||
delay.delay_ms(250u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
@ -17,16 +18,12 @@ use esp32s3_hal::{
|
||||
Delay,
|
||||
Rtc,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{Mutex, SpinLockMutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
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));
|
||||
static ALARM0: Mutex<RefCell<Option<Alarm<Target, 0>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM1: Mutex<RefCell<Option<Alarm<Target, 1>>>> = Mutex::new(RefCell::new(None));
|
||||
static ALARM2: Mutex<RefCell<Option<Alarm<Target, 2>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -45,22 +42,22 @@ fn main() -> ! {
|
||||
let syst = SystemTimer::new(peripherals.SYSTIMER);
|
||||
|
||||
let alarm0 = syst.alarm0;
|
||||
alarm0.set_target(40_000_000);
|
||||
alarm0.set_target(40_000_0000);
|
||||
alarm0.enable_interrupt();
|
||||
|
||||
let alarm1 = syst.alarm1;
|
||||
alarm1.set_target(41_111_111);
|
||||
alarm1.set_target(41_111_1110);
|
||||
alarm1.enable_interrupt();
|
||||
|
||||
let alarm2 = syst.alarm2;
|
||||
alarm2.set_target(42_222_222 * 2);
|
||||
alarm2.set_target(42_222_2220 * 2);
|
||||
alarm2.enable_interrupt();
|
||||
|
||||
unsafe {
|
||||
(&ALARM0).lock(|data| (*data).replace(Some(alarm0)));
|
||||
(&ALARM1).lock(|data| (*data).replace(Some(alarm1)));
|
||||
(&ALARM2).lock(|data| (*data).replace(Some(alarm2)));
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM0.borrow_ref_mut(cs).replace(alarm0);
|
||||
ALARM1.borrow_ref_mut(cs).replace(alarm1);
|
||||
ALARM2.borrow_ref_mut(cs).replace(alarm2);
|
||||
});
|
||||
|
||||
interrupt::enable(pac::Interrupt::SYSTIMER_TARGET0, Priority::Priority1).unwrap();
|
||||
interrupt::enable(pac::Interrupt::SYSTIMER_TARGET1, Priority::Priority2).unwrap();
|
||||
@ -78,38 +75,35 @@ fn main() -> ! {
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET0() {
|
||||
esp_println::println!("Interrupt lvl1 (alarm0)");
|
||||
|
||||
unsafe {
|
||||
(&ALARM0).lock(|data| {
|
||||
let mut alarm = data.borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
alarm.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM0
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET1() {
|
||||
esp_println::println!("Interrupt lvl2 (alarm1)");
|
||||
|
||||
unsafe {
|
||||
(&ALARM1).lock(|data| {
|
||||
let mut alarm = data.borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
alarm.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM1
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn SYSTIMER_TARGET2() {
|
||||
esp_println::println!("Interrupt lvl2 (alarm2)");
|
||||
|
||||
unsafe {
|
||||
(&ALARM2).lock(|data| {
|
||||
let mut alarm = data.borrow_mut();
|
||||
let alarm = alarm.as_mut().unwrap();
|
||||
alarm.clear_interrupt();
|
||||
});
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
ALARM2
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.clear_interrupt()
|
||||
});
|
||||
}
|
||||
|
@ -5,32 +5,25 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::{cell::RefCell, fmt::Write};
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt,
|
||||
interrupt::Priority,
|
||||
pac::{self, Peripherals, TIMG0, TIMG1, UART0},
|
||||
pac::{self, Peripherals, TIMG0, TIMG1},
|
||||
prelude::*,
|
||||
timer::{Timer, Timer0, Timer1, TimerGroup},
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use xtensa_lx::mutex::{Mutex, SpinLockMutex};
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut SERIAL: SpinLockMutex<RefCell<Option<Serial<UART0>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER00: SpinLockMutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER01: SpinLockMutex<RefCell<Option<Timer<Timer1<TIMG0>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER10: SpinLockMutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static mut TIMER11: SpinLockMutex<RefCell<Option<Timer<Timer1<TIMG1>>>>> =
|
||||
SpinLockMutex::new(RefCell::new(None));
|
||||
static TIMER00: Mutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER01: Mutex<RefCell<Option<Timer<Timer1<TIMG0>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER10: Mutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
static TIMER11: Mutex<RefCell<Option<Timer<Timer1<TIMG1>>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@ -49,7 +42,6 @@ fn main() -> ! {
|
||||
let mut timer11 = timer_group1.timer1;
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
let serial0 = Serial::new(peripherals.UART0);
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
@ -70,97 +62,68 @@ fn main() -> ! {
|
||||
timer11.start(3u64.secs());
|
||||
timer11.listen();
|
||||
|
||||
unsafe {
|
||||
(&SERIAL).lock(|data| (*data).replace(Some(serial0)));
|
||||
(&TIMER00).lock(|data| (*data).replace(Some(timer00)));
|
||||
(&TIMER01).lock(|data| (*data).replace(Some(timer01)));
|
||||
(&TIMER10).lock(|data| (*data).replace(Some(timer10)));
|
||||
(&TIMER11).lock(|data| (*data).replace(Some(timer11)));
|
||||
}
|
||||
critical_section::with(|cs| {
|
||||
TIMER00.borrow_ref_mut(cs).replace(timer00);
|
||||
TIMER01.borrow_ref_mut(cs).replace(timer01);
|
||||
TIMER10.borrow_ref_mut(cs).replace(timer10);
|
||||
TIMER11.borrow_ref_mut(cs).replace(timer11);
|
||||
});
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG0_T0_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER00).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER00.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 2 - Timer0").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 2 - Timer0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG0_T1_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER01).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER01.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(2500u64.millis());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 2 - Timer1").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 2 - Timer1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG1_T0_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER10).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER10.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(1u64.secs());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 3 - Timer0").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 3 - Timer0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn TG1_T1_LEVEL() {
|
||||
unsafe {
|
||||
(&TIMER11).lock(|data| {
|
||||
let mut timer = data.borrow_mut();
|
||||
let timer = timer.as_mut().unwrap();
|
||||
critical_section::with(|cs| {
|
||||
let mut timer = TIMER11.borrow_ref_mut(cs);
|
||||
let timer = timer.as_mut().unwrap();
|
||||
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(3u64.secs());
|
||||
|
||||
(&SERIAL).lock(|data| {
|
||||
let mut serial = data.borrow_mut();
|
||||
let serial = serial.as_mut().unwrap();
|
||||
writeln!(serial, "Interrupt Level 3 - Timer1").ok();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if timer.is_interrupt_set() {
|
||||
timer.clear_interrupt();
|
||||
timer.start(500u64.millis());
|
||||
esp_println::println!("Interrupt Level 3 - Timer1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
UsbSerialJtag,
|
||||
};
|
||||
use panic_halt as _;
|
||||
use esp_backtrace as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
@ -15,8 +15,8 @@ use esp32s3_hal::{
|
||||
Rtc,
|
||||
Serial,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use nb::block;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
|
Loading…
x
Reference in New Issue
Block a user