mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 04:40:52 +00:00
Support ESP32S3
This commit is contained in:
parent
0039996e8e
commit
545f997b07
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
chip: [esp32, esp32s2]
|
||||
chip: [esp32, esp32s2, esp32s3]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: esp-rs/xtensa-toolchain@afb2ca0c7eefb637832d240ae357b820a1edc2c7
|
||||
|
@ -172,37 +172,44 @@ unsafe fn core1_interrupt_peripheral() -> *const crate::pac::interrupt_core1::Re
|
||||
crate::pac::INTERRUPT_CORE1::ptr()
|
||||
}
|
||||
|
||||
#[xtensa_lx_rt::interrupt(1)]
|
||||
fn _level1_interrupt() {
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
fn __level1_interrupt() {
|
||||
unsafe { level1_interrupt() };
|
||||
}
|
||||
|
||||
#[xtensa_lx_rt::interrupt(2)]
|
||||
fn _level2_interrupt() {
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
fn __level2_interrupt() {
|
||||
unsafe { level2_interrupt() };
|
||||
}
|
||||
|
||||
#[xtensa_lx_rt::interrupt(3)]
|
||||
fn _level3_interrupt() {
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
fn __level3_interrupt() {
|
||||
unsafe { level3_interrupt() };
|
||||
}
|
||||
|
||||
#[xtensa_lx_rt::interrupt(4)]
|
||||
fn _level4_interrupt() {
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
fn __level4_interrupt() {
|
||||
unsafe { level4_interrupt() };
|
||||
}
|
||||
|
||||
#[xtensa_lx_rt::interrupt(5)]
|
||||
fn _level5_interrupt() {
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
fn __level5_interrupt() {
|
||||
unsafe { level5_interrupt() };
|
||||
}
|
||||
|
||||
#[xtensa_lx_rt::interrupt(6)]
|
||||
fn _level6_interrupt() {
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
fn __level6_interrupt() {
|
||||
unsafe { level6_interrupt() };
|
||||
}
|
||||
|
||||
#[xtensa_lx_rt::interrupt(7)]
|
||||
fn _level7_interrupt() {
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
fn __level7_interrupt() {
|
||||
unsafe { level7_interrupt() };
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ runner = "xtensa-esp32s3-elf-gdb -q -x xtensa.gdb"
|
||||
[build]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
"-C", "link-arg=-Wl,-Tlink.x",
|
||||
"-C", "link-arg=-Wl,-Tesp32s3.x",
|
||||
]
|
||||
target = "xtensa-esp32s3-none-elf"
|
||||
|
||||
|
@ -13,6 +13,18 @@ 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();
|
||||
|
||||
File::create(out.join("esp32s3.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("esp32s3.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,
|
||||
|
110
esp32s3-hal/esp32s3.x
Normal file
110
esp32s3-hal/esp32s3.x
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
/* before memory.x to allow override */
|
||||
ENTRY(Reset)
|
||||
|
||||
INCLUDE memory.x
|
||||
|
||||
/* after memory.x to allow override */
|
||||
PROVIDE(__pre_init = DefaultPreInit);
|
||||
PROVIDE(__zero_bss = default_mem_hook);
|
||||
PROVIDE(__init_data = default_mem_hook);
|
||||
|
||||
INCLUDE exception.x
|
||||
|
||||
SECTIONS {
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
_stext = .;
|
||||
. = ALIGN (4);
|
||||
_text_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
*(.literal .text .literal.* .text.*)
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} > ROTEXT
|
||||
|
||||
.rodata_dummy (NOLOAD) :
|
||||
{
|
||||
/* This dummy section represents the .flash.text section but in RODATA.
|
||||
* Thus, it must have its alignment and (at least) its size.
|
||||
*/
|
||||
|
||||
/* Start at the same alignment constraint than .flash.text */
|
||||
|
||||
. = ALIGN(ALIGNOF(.text));
|
||||
|
||||
/* Create an empty gap as big as .text section */
|
||||
|
||||
. = SIZEOF(.text);
|
||||
|
||||
/* Prepare the alignment of the section above. Few bytes (0x20) must be
|
||||
* added for the mapping header.
|
||||
*/
|
||||
|
||||
. = ALIGN(0x10000) + 0x20;
|
||||
_rodata_reserved_start = .;
|
||||
} > RODATA
|
||||
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
*(.rodata .rodata.*)
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
} > RODATA
|
||||
|
||||
|
||||
.rwtext : ALIGN(4)
|
||||
{
|
||||
. = ALIGN (4);
|
||||
*(.rwtext.literal .rwtext .rwtext.literal.* .rwtext.*)
|
||||
} > RWTEXT
|
||||
|
||||
.rwdata_dummy (NOLOAD) :
|
||||
{
|
||||
/* This dummy section represents the .rwtext section but in RWDATA.
|
||||
* Thus, it must have its alignment and (at least) its size.
|
||||
*/
|
||||
|
||||
/* Start at the same alignment constraint than .flash.text */
|
||||
|
||||
. = ALIGN(ALIGNOF(.rwtext));
|
||||
|
||||
/* Create an empty gap as big as .text section */
|
||||
|
||||
. = SIZEOF(.rwtext);
|
||||
|
||||
/* Prepare the alignment of the section above. Few bytes (0x20) must be
|
||||
* added for the mapping header.
|
||||
*/
|
||||
|
||||
. = ALIGN(0x10000) + 0x20;
|
||||
_rwdata_reserved_start = .;
|
||||
} > RWDATA
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
*(.data .data.*)
|
||||
_data_end = ABSOLUTE(.);
|
||||
} > RWDATA AT > RODATA
|
||||
|
||||
/* LMA of .data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
.bss (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
_bss_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
*(.bss .bss.* COMMON)
|
||||
_bss_end = ABSOLUTE(.);
|
||||
} > RWDATA
|
||||
|
||||
.noinit (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.noinit .noinit.*)
|
||||
} > RWDATA
|
||||
|
||||
}
|
27
esp32s3-hal/examples/hello_world.rs
Normal file
27
esp32s3-hal/examples/hello_world.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use esp32s3_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
esp32s3-hal/examples/ram.rs
Normal file
91
esp32s3-hal/examples/ram.rs
Normal file
@ -0,0 +1,91 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use esp32s3_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
esp32s3-hal/hal-defaults.x
Normal file
7
esp32s3-hal/hal-defaults.x
Normal file
@ -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);
|
@ -0,0 +1,163 @@
|
||||
/* override entry point */
|
||||
ENTRY(ESP32Reset)
|
||||
|
||||
/* reserved at the start of DRAM */
|
||||
RESERVE_DRAM = 0x8000;
|
||||
|
||||
/* reserved at the start of the RTC memories for use by the ULP processor */
|
||||
RESERVE_RTC_FAST = 0;
|
||||
RESERVE_RTC_SLOW = 0;
|
||||
|
||||
/* define stack size for both cores */
|
||||
STACK_SIZE = 8k;
|
||||
|
||||
/* Specify main memory areas */
|
||||
MEMORY
|
||||
{
|
||||
vectors_seg ( RX ) : ORIGIN = 0x40370000 + RESERVE_DRAM, len = 1k
|
||||
iram_seg ( RX ) : ORIGIN = 0x40370400 + RESERVE_DRAM, len = 328k - 0x400
|
||||
|
||||
dram_seg ( RW ) : ORIGIN = 0x3FC80000 + RESERVE_DRAM, len = 328k - RESERVE_DRAM
|
||||
reserved_for_boot_seg : ORIGIN = 0x3FFDC200, len = 144k /* ???? SRAM1; reserved for static ROM usage; can be used for heap */
|
||||
|
||||
/* external flash
|
||||
The 0x20 offset is a convenience for the app binary image generation.
|
||||
Flash cache has 64KB pages. The .bin file which is flashed to the chip
|
||||
has a 0x18 byte file header, and each segment has a 0x08 byte segment
|
||||
header. Setting this offset makes it simple to meet the flash cache MMU's
|
||||
constraint that (paddr % 64KB == vaddr % 64KB).)
|
||||
*/
|
||||
irom_seg ( RX ) : ORIGIN = 0x42000020, len = 4M - 0x20
|
||||
drom_seg ( R ) : ORIGIN = 0x3C000020, len = 4M - 0x20
|
||||
|
||||
|
||||
/* RTC fast memory (executable). Persists over deep sleep. Only for core 0 (PRO_CPU) */
|
||||
rtc_fast_iram_seg(RWX) : ORIGIN = 0x600fe000, len = 8k
|
||||
|
||||
/* RTC fast memory (same block as above), viewed from data bus. Only for core 0 (PRO_CPU) */
|
||||
rtc_fast_dram_seg(RW) : ORIGIN = 0x600fe000 + RESERVE_RTC_FAST, len = 8k - RESERVE_RTC_FAST
|
||||
|
||||
/* RTC slow memory (data accessible). Persists over deep sleep. */
|
||||
rtc_slow_seg(RW) : ORIGIN = 0x50000000 + RESERVE_RTC_SLOW, len = 8k - RESERVE_RTC_SLOW
|
||||
|
||||
/* external memory, including data and text */
|
||||
psram_seg(RWX) : ORIGIN = 0x3F500000, len = 0xA80000 /* ??? */
|
||||
}
|
||||
|
||||
/* map generic regions to output sections */
|
||||
INCLUDE "alias.x"
|
||||
|
||||
/* esp32 specific regions */
|
||||
SECTIONS {
|
||||
.rtc_fast.text : {
|
||||
. = ALIGN(4);
|
||||
*(.rtc_fast.literal .rtc_fast.text .rtc_fast.literal.* .rtc_fast.text.*)
|
||||
} > rtc_fast_iram_seg AT > RODATA
|
||||
|
||||
/*
|
||||
This section is required to skip rtc.text area because rtc_iram_seg and
|
||||
rtc_data_seg are reflect the same address space on different buses.
|
||||
*/
|
||||
.rtc_fast.dummy (NOLOAD) :
|
||||
{
|
||||
_rtc_dummy_start = ABSOLUTE(.); /* needed to make section proper size */
|
||||
. = SIZEOF(.rtc_fast.text);
|
||||
_rtc_dummy_end = ABSOLUTE(.); /* needed to make section proper size */
|
||||
} > rtc_fast_dram_seg
|
||||
|
||||
|
||||
.rtc_fast.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_data_start = ABSOLUTE(.);
|
||||
*(.rtc_fast.data .rtc_fast.data.*)
|
||||
_rtc_fast_data_end = ABSOLUTE(.);
|
||||
} > rtc_fast_dram_seg AT > RODATA
|
||||
|
||||
.rtc_fast.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_bss_start = ABSOLUTE(.);
|
||||
*(.rtc_fast.bss .rtc_fast.bss.*)
|
||||
_rtc_fast_bss_end = ABSOLUTE(.);
|
||||
} > rtc_fast_dram_seg
|
||||
|
||||
.rtc_fast.noinit (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc_fast.noinit .rtc_fast.noinit.*)
|
||||
} > rtc_fast_dram_seg
|
||||
|
||||
|
||||
.rtc_slow.text : {
|
||||
. = ALIGN(4);
|
||||
*(.rtc_slow.literal .rtc_slow.text .rtc_slow.literal.* .rtc_slow.text.*)
|
||||
} > rtc_slow_seg AT > RODATA
|
||||
|
||||
.rtc_slow.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_slow_data_start = ABSOLUTE(.);
|
||||
*(.rtc_slow.data .rtc_slow.data.*)
|
||||
_rtc_slow_data_end = ABSOLUTE(.);
|
||||
} > rtc_slow_seg AT > RODATA
|
||||
|
||||
.rtc_slow.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_slow_bss_start = ABSOLUTE(.);
|
||||
*(.rtc_slow.bss .rtc_slow.bss.*)
|
||||
_rtc_slow_bss_end = ABSOLUTE(.);
|
||||
} > rtc_slow_seg
|
||||
|
||||
.rtc_slow.noinit (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc_slow.noinit .rtc_slow.noinit.*)
|
||||
} > rtc_slow_seg
|
||||
|
||||
.external.data :
|
||||
{
|
||||
_external_data_start = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
*(.external.data .external.data.*)
|
||||
_external_data_end = ABSOLUTE(.);
|
||||
} > psram_seg AT > RODATA
|
||||
|
||||
.external.bss (NOLOAD) :
|
||||
{
|
||||
_external_bss_start = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
*(.external.bss .external.bss.*)
|
||||
_external_bss_end = ABSOLUTE(.);
|
||||
} > psram_seg
|
||||
|
||||
.external.noinit (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.external.noinit .external.noinit.*)
|
||||
} > psram_seg
|
||||
|
||||
/* must be last segment using psram_seg */
|
||||
.external_heap_start (NOLOAD) :
|
||||
{
|
||||
. = ALIGN (4);
|
||||
_external_heap_start = ABSOLUTE(.);
|
||||
} > psram_seg
|
||||
}
|
||||
|
||||
_external_ram_start = ABSOLUTE(ORIGIN(psram_seg));
|
||||
_external_ram_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg));
|
||||
|
||||
_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg)+LENGTH(reserved_for_boot_seg) - 2*STACK_SIZE;
|
||||
_text_heap_end = ABSOLUTE(ORIGIN(iram_seg)+LENGTH(iram_seg));
|
||||
_external_heap_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg));
|
||||
|
||||
_stack_start_cpu1 = _heap_end;
|
||||
_stack_end_cpu1 = _stack_start_cpu1 + STACK_SIZE;
|
||||
_stack_start_cpu0 = _stack_end_cpu1;
|
||||
_stack_end_cpu0 = _stack_start_cpu0 + STACK_SIZE;
|
||||
|
||||
EXTERN(DefaultHandler);
|
||||
|
||||
INCLUDE "device.x"
|
@ -2,3 +2,5 @@ REGION_ALIAS("ROTEXT", irom_seg);
|
||||
REGION_ALIAS("RWTEXT", iram_seg);
|
||||
REGION_ALIAS("RODATA", drom_seg);
|
||||
REGION_ALIAS("RWDATA", dram_seg);
|
||||
|
||||
PROVIDE( rom_config_instruction_cache_mode = 0x40001a1c );
|
||||
|
@ -1,4 +1,90 @@
|
||||
#![no_std]
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp_hal_common::{pac, prelude, Delay, Serial, Timer};
|
||||
pub use esp_hal_common::{pac, prelude, ram, Delay, Serial, Timer};
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {}
|
||||
|
||||
#[cfg(feature = "rt")]
|
||||
#[doc(hidden)]
|
||||
#[link_section = ".rwtext"]
|
||||
pub unsafe fn configure_cpu_caches() {
|
||||
// this is just the bare minimum we need to run code from flash
|
||||
// consider implementing more advanced configurations
|
||||
// see https://github.com/apache/incubator-nuttx/blob/master/arch/xtensa/src/esp32s3/esp32s3_start.c
|
||||
|
||||
extern "C" {
|
||||
fn rom_config_instruction_cache_mode(
|
||||
cfg_cache_size: u32,
|
||||
cfg_cache_ways: u8,
|
||||
cfg_cache_line_size: u8,
|
||||
);
|
||||
}
|
||||
|
||||
// ideally these should be configurable
|
||||
const CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE: u32 = 0x4000; // ESP32S3_INSTRUCTION_CACHE_16KB
|
||||
const CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS: u8 = 8; // ESP32S3_INSTRUCTION_CACHE_8WAYS
|
||||
const CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE: u8 = 32; // ESP32S3_INSTRUCTION_CACHE_LINE_32B
|
||||
|
||||
// Configure the mode of instruction cache: cache size, cache line size.
|
||||
rom_config_instruction_cache_mode(
|
||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE,
|
||||
CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS,
|
||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE,
|
||||
);
|
||||
}
|
||||
|
||||
/// Function initializes ESP32S3 specific memories (RTC slow and fast) and
|
||||
/// then calls original Reset function
|
||||
///
|
||||
/// ENTRY point is defined in memory.x
|
||||
/// *Note: the pre_init function is called in the original reset handler
|
||||
/// after the initializations done in this function*
|
||||
#[cfg(feature = "rt")]
|
||||
#[doc(hidden)]
|
||||
#[no_mangle]
|
||||
#[link_section = ".rwtext"]
|
||||
pub unsafe extern "C" fn ESP32Reset() -> ! {
|
||||
configure_cpu_caches();
|
||||
|
||||
// These symbols come from `memory.x`
|
||||
extern "C" {
|
||||
static mut _rtc_fast_bss_start: u32;
|
||||
static mut _rtc_fast_bss_end: u32;
|
||||
|
||||
static mut _rtc_slow_bss_start: u32;
|
||||
static mut _rtc_slow_bss_end: u32;
|
||||
|
||||
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);
|
||||
|
||||
// continue with default reset handler
|
||||
xtensa_lx_rt::Reset();
|
||||
}
|
||||
|
||||
/// The ESP32 has a first stage bootloader that handles loading program data
|
||||
/// into the right place therefore we skip loading it again.
|
||||
#[doc(hidden)]
|
||||
#[no_mangle]
|
||||
#[rustfmt::skip]
|
||||
pub extern "Rust" fn __init_data() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn _gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8 {
|
||||
int_enable as u8
|
||||
| ((nmi_enable as u8) << 1)
|
||||
| (int_enable as u8) << 2
|
||||
| ((nmi_enable as u8) << 3)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user