Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ESP32S2 #12

Merged
merged 2 commits into from
Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
chip: [esp32]
chip: [esp32, esp32s2]
steps:
- uses: actions/checkout@v2
- uses: esp-rs/xtensa-toolchain@afb2ca0c7eefb637832d240ae357b820a1edc2c7
Expand Down
6 changes: 3 additions & 3 deletions esp-hal-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ paste = "1.0"
riscv = { version = "0.7", optional = true }
void = { version = "1.0", default-features = false }
xtensa-lx = { version = "0.6.0", optional = true }
xtensa-lx-rt = { version = "0.8.0", features = ["esp32"], optional = true }
xtensa-lx-rt = { version = "0.9.0", optional = true }
procmacros = { path = "../esp-hal-procmacros", package = "esp-hal-procmacros" }
# IMPORTANT:
# Each supported device MUST have its PAC included below along with a
Expand All @@ -30,8 +30,8 @@ esp32s3_pac = { package = "esp32s3", git = "https://github.com/esp-rs/esp-pacs.g
[features]
esp32 = ["esp32_pac", "esp32_pac/rt", "xtensa-lx/esp32", "xtensa-lx-rt/esp32", "procmacros/rtc_slow", "dual_core"]
esp32c3 = ["esp32c3_pac", "esp32c3_pac/rt", "riscv", "single_core"]
esp32s2 = ["esp32s2_pac", "esp32s2_pac/rt", "xtensa-lx/esp32", "xtensa-lx-rt/esp32", "procmacros/rtc_slow", "single_core"] # FIXME
esp32s3 = ["esp32s3_pac", "esp32s3_pac/rt", "xtensa-lx/esp32", "xtensa-lx-rt/esp32", "procmacros/rtc_slow", "dual_core"] # FIXME
esp32s2 = ["esp32s2_pac", "esp32s2_pac/rt", "xtensa-lx/esp32", "xtensa-lx-rt/esp32s2", "procmacros/rtc_slow", "single_core"]
esp32s3 = ["esp32s3_pac", "esp32s3_pac/rt", "xtensa-lx/esp32", "xtensa-lx-rt/esp32s3", "procmacros/rtc_slow", "dual_core"]

single_core = []
dual_core = []
96 changes: 80 additions & 16 deletions esp-hal-common/src/interrupt/xtensa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ extern "C" {
}

/// Enumeration of available CPU interrupts
/// It's possible to create one handler per priority level. (e.g `level1_interrupt`)
/// It's possible to create one handler per priority level. (e.g
/// `level1_interrupt`)
#[allow(unused)]
pub enum CpuInterrupt {
Interrupt0LevelPriority1 = 0,
Expand All @@ -30,7 +31,7 @@ pub enum CpuInterrupt {
Interrupt13LevelPriority1,
Interrupt14NmiPriority7,
Interrupt15Timer1Priority3,
Interrupt16Timer2Priority3,
Interrupt16Timer2Priority5,
Interrupt17LevelPriority1,
Interrupt18LevelPriority1,
Interrupt19LevelPriority2,
Expand All @@ -53,13 +54,12 @@ pub fn enable(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
unsafe {
let interrupt_number = interrupt as isize;
let cpu_interrupt_number = which as isize;
let intr = &*crate::pac::DPORT::ptr();
let intr_map_base = match core {
Cpu::ProCpu => intr.pro_mac_intr_map.as_ptr(),
Cpu::ProCpu => (&*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(),
#[cfg(feature = "dual_core")]
Cpu::AppCpu => intr.app_mac_intr_map.as_ptr(),
Cpu::AppCpu => (&*core1_interrupt_peripheral()).app_mac_intr_map.as_ptr(),
#[cfg(feature = "single_core")]
Cpu::AppCpu => intr.pro_mac_intr_map.as_ptr(),
Cpu::AppCpu => (&*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(),
};
intr_map_base
.offset(interrupt_number)
Expand All @@ -71,13 +71,12 @@ pub fn enable(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
pub fn disable(core: Cpu, interrupt: Interrupt) {
unsafe {
let interrupt_number = interrupt as isize;
let intr = &*crate::pac::DPORT::ptr();
let intr_map_base = match core {
Cpu::ProCpu => intr.pro_mac_intr_map.as_ptr(),
Cpu::ProCpu => (&*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(),
#[cfg(feature = "dual_core")]
Cpu::AppCpu => intr.app_mac_intr_map.as_ptr(),
Cpu::AppCpu => (&*core1_interrupt_peripheral()).app_mac_intr_map.as_ptr(),
#[cfg(feature = "single_core")]
Cpu::AppCpu => intr.pro_mac_intr_map.as_ptr(),
Cpu::AppCpu => (&*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(),
};
intr_map_base.offset(interrupt_number).write_volatile(0);
}
Expand All @@ -95,19 +94,84 @@ pub fn get_status(core: Cpu) -> u128 {
unsafe {
match core {
Cpu::ProCpu => {
((*crate::pac::DPORT::ptr()).pro_intr_status_0.read().bits() as u128)
| ((*crate::pac::DPORT::ptr()).pro_intr_status_1.read().bits() as u128) << 32
| ((*crate::pac::DPORT::ptr()).pro_intr_status_2.read().bits() as u128) << 64
((&*core0_interrupt_peripheral())
.pro_intr_status_0
.read()
.bits() as u128)
| ((&*core0_interrupt_peripheral())
.pro_intr_status_1
.read()
.bits() as u128)
<< 32
| ((&*core0_interrupt_peripheral())
.pro_intr_status_2
.read()
.bits() as u128)
<< 64
}
#[cfg(feature = "dual_core")]
Cpu::AppCpu => {
((&*core1_interrupt_peripheral())
.app_intr_status_0
.read()
.bits() as u128)
| ((&*core1_interrupt_peripheral())
.app_intr_status_1
.read()
.bits() as u128)
<< 32
| ((&*core1_interrupt_peripheral())
.app_intr_status_2
.read()
.bits() as u128)
<< 64
}
#[cfg(feature = "single_core")]
Cpu::AppCpu => {
((*crate::pac::DPORT::ptr()).app_intr_status_0.read().bits() as u128)
| ((*crate::pac::DPORT::ptr()).app_intr_status_1.read().bits() as u128) << 32
| ((*crate::pac::DPORT::ptr()).app_intr_status_2.read().bits() as u128) << 64
((&*core0_interrupt_peripheral())
.pro_intr_status_0
.read()
.bits() as u128)
| ((&*core0_interrupt_peripheral())
.pro_intr_status_1
.read()
.bits() as u128)
<< 32
| ((&*core0_interrupt_peripheral())
.pro_intr_status_2
.read()
.bits() as u128)
<< 64
}
}
}
}

#[cfg(feature = "esp32")]
unsafe fn core0_interrupt_peripheral() -> *const crate::pac::dport::RegisterBlock {
crate::pac::DPORT::ptr()
}

#[cfg(feature = "esp32")]
unsafe fn core1_interrupt_peripheral() -> *const crate::pac::dport::RegisterBlock {
crate::pac::DPORT::ptr()
}

#[cfg(feature = "esp32s2")]
unsafe fn core0_interrupt_peripheral() -> *const crate::pac::interrupt::RegisterBlock {
crate::pac::INTERRUPT::ptr()
}

#[cfg(feature = "esp32s3")]
unsafe fn core0_interrupt_peripheral() -> *const crate::pac::interrupt_core0::RegisterBlock {
crate::pac::INTERRUPT_CORE0::ptr()
}

#[cfg(feature = "esp32s3")]
unsafe fn core1_interrupt_peripheral() -> *const crate::pac::interrupt_core1::RegisterBlock {
crate::pac::INTERRUPT_CORE1::ptr()
}

#[xtensa_lx_rt::interrupt(1)]
fn _level1_interrupt() {
unsafe { level1_interrupt() };
Expand Down
2 changes: 2 additions & 0 deletions esp-hal-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub use esp32s3_pac as pac;
pub mod delay;
pub mod gpio;
#[cfg_attr(feature = "esp32", path = "interrupt/xtensa.rs")]
#[cfg_attr(feature = "esp32s2", path = "interrupt/xtensa.rs")]
#[cfg_attr(feature = "esp32s3", path = "interrupt/xtensa.rs")]
#[cfg_attr(feature = "esp32c3", path = "interrupt/riscv.rs")]
pub mod interrupt;
pub mod prelude;
Expand Down
2 changes: 1 addition & 1 deletion esp32-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ embedded-hal = { version = "0.2", features = ["unproven"] }
nb = "1.0"
void = { version = "1.0", default-features = false }
xtensa-lx = { version = "0.6.0", features = ["esp32"] }
xtensa-lx-rt = { version = "0.8.0", features = ["esp32"], optional = true }
xtensa-lx-rt = { version = "0.9.0", features = ["esp32"], optional = true }

[dependencies.esp-hal-common]
path = "../esp-hal-common"
Expand Down
6 changes: 3 additions & 3 deletions esp32-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ pub unsafe extern "C" fn ESP32Reset() -> ! {
static mut _stack_end_cpu0: u32;
}

// set stack pointer to end of memory: no need to retain stack up to this point
xtensa_lx::set_stack_pointer(&mut _stack_end_cpu0);

// copying data from flash to various data segments is done by the bootloader
// initialization to zero needs to be done by the application

// Initialize RTC RAM
xtensa_lx_rt::zero_bss(&mut _rtc_fast_bss_start, &mut _rtc_fast_bss_end);
xtensa_lx_rt::zero_bss(&mut _rtc_slow_bss_start, &mut _rtc_slow_bss_end);

// set stack pointer to end of memory: no need to retain stack up to this point
xtensa_lx::set_stack_pointer(&mut _stack_end_cpu0);

// continue with default reset handler
xtensa_lx_rt::Reset();
}
Expand Down
2 changes: 1 addition & 1 deletion esp32s2-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ embedded-hal = { version = "0.2", features = ["unproven"] }
nb = "1.0"
void = { version = "1.0", default-features = false }
xtensa-lx = { version = "0.6.0", features = ["esp32"] } # FIXME
xtensa-lx-rt = { version = "0.8.0", features = ["esp32"], optional = true }
xtensa-lx-rt = { version = "0.9.0", features = ["esp32s2"], optional = true }

[dependencies.esp-hal-common]
path = "../esp-hal-common"
Expand Down
7 changes: 7 additions & 0 deletions esp32s2-hal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ fn main() {
.write_all(include_bytes!("rom.x"))
.unwrap();

File::create(out.join("hal-defaults.x"))
.unwrap()
.write_all(include_bytes!("hal-defaults.x"))
.unwrap();

println!("cargo:rustc-link-arg=-Thal-defaults.x");

println!("cargo:rustc-link-search={}", out.display());

// Only re-run the build script when memory.x is changed,
Expand Down
27 changes: 27 additions & 0 deletions esp32s2-hal/examples/hello_world.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![no_std]
#![no_main]

use core::fmt::Write;

use esp32s2_hal::{pac::Peripherals, prelude::*, Serial, Timer};
use nb::block;
use panic_halt as _;
use xtensa_lx_rt::entry;

#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();

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

// Disable watchdog timer
timer0.disable();

timer0.start(40_000_000u64);

loop {
writeln!(serial0, "Hello world!").unwrap();
block!(timer0.wait()).unwrap();
}
}
91 changes: 91 additions & 0 deletions esp32s2-hal/examples/ram.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#![no_std]
#![no_main]

use core::fmt::Write;

use esp32s2_hal::{
pac::{Peripherals, UART0},
prelude::*,
ram,
Serial,
Timer,
};
use nb::block;
use panic_halt as _;
use xtensa_lx_rt::entry;

#[ram(rtc_fast)]
static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb];

#[ram(rtc_fast, uninitialized)]
static mut SOME_UNINITED_DATA: [u8; 2] = [0; 2];

#[ram(rtc_fast, zeroed)]
static mut SOME_ZEROED_DATA: [u8; 8] = [0; 8];

#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();

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

// Disable watchdog timer
timer0.disable();

timer0.start(10_000_000u64);

writeln!(
serial0,
"IRAM function located at {:p}",
function_in_ram as *const ()
)
.unwrap();
unsafe {
writeln!(serial0, "SOME_INITED_DATA {:x?}", SOME_INITED_DATA).unwrap();
writeln!(serial0, "SOME_UNINITED_DATA {:x?}", SOME_UNINITED_DATA).unwrap();
writeln!(serial0, "SOME_ZEROED_DATA {:x?}", SOME_ZEROED_DATA).unwrap();

SOME_INITED_DATA[0] = 0xff;
SOME_ZEROED_DATA[0] = 0xff;

writeln!(serial0, "SOME_INITED_DATA {:x?}", SOME_INITED_DATA).unwrap();
writeln!(serial0, "SOME_UNINITED_DATA {:x?}", SOME_UNINITED_DATA).unwrap();
writeln!(serial0, "SOME_ZEROED_DATA {:x?}", SOME_ZEROED_DATA).unwrap();

if SOME_UNINITED_DATA[0] != 0 {
SOME_UNINITED_DATA[0] = 0;
SOME_UNINITED_DATA[1] = 0;
}

if SOME_UNINITED_DATA[1] == 0xff {
SOME_UNINITED_DATA[1] = 0;
}

writeln!(serial0, "Counter {}", SOME_UNINITED_DATA[1]).unwrap();
SOME_UNINITED_DATA[1] += 1;
}

writeln!(
serial0,
"RTC_FAST function located at {:p}",
function_in_rtc_ram as *const ()
)
.unwrap();
writeln!(serial0, "Result {}", function_in_rtc_ram()).unwrap();

loop {
function_in_ram(&mut serial0);
block!(timer0.wait()).unwrap();
}
}

#[ram]
fn function_in_ram(serial0: &mut Serial<UART0>) {
writeln!(serial0, "Hello world!").unwrap();
}

#[ram(rtc_fast)]
fn function_in_rtc_ram() -> u32 {
42
}
7 changes: 7 additions & 0 deletions esp32s2-hal/hal-defaults.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
PROVIDE(level1_interrupt = DefaultHandler);
PROVIDE(level2_interrupt = DefaultHandler);
PROVIDE(level3_interrupt = DefaultHandler);
PROVIDE(level4_interrupt = DefaultHandler);
PROVIDE(level5_interrupt = DefaultHandler);
PROVIDE(level6_interrupt = DefaultHandler);
PROVIDE(level7_interrupt = DefaultHandler);
Loading