esp_hal/soc/esp32s3/
mod.rs

1//! # SOC (System-on-Chip) module (ESP32-S3)
2//!
3//! ## Overview
4//!
5//! The `SOC` module provides access, functions and structures that are useful
6//! for interacting with various system-related peripherals on `ESP32-S3` chip.
7//!
8//! Also few constants are defined in this module for `ESP32-S3` chip:
9//!    * I2S_SCLK: 160_000_000 - I2S clock frequency
10//!    * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
11
12crate::unstable_module! {
13    pub mod trng;
14    pub mod ulp_core;
15}
16pub mod cpu_control;
17pub mod gpio;
18pub(crate) mod regi2c;
19
20pub use esp32s3 as pac;
21
22#[cfg_attr(not(feature = "unstable"), allow(unused))]
23pub(crate) mod constants {
24    /// The base clock frequency for the I2S peripheral (Hertz).
25    pub const I2S_SCLK: u32 = 160_000_000;
26    /// The default clock source for I2S operations.
27    pub const I2S_DEFAULT_CLK_SRC: u8 = 2;
28}
29
30#[unsafe(link_section = ".rwtext")]
31pub(crate) unsafe fn configure_cpu_caches() {
32    // this is just the bare minimum we need to run code from flash
33    // consider implementing more advanced configurations
34    // see https://github.com/apache/incubator-nuttx/blob/master/arch/xtensa/src/esp32s3/esp32s3_start.c
35
36    unsafe extern "C" {
37        fn Cache_Suspend_DCache();
38
39        fn Cache_Resume_DCache(param: u32);
40
41        fn rom_config_instruction_cache_mode(
42            cfg_cache_size: u32,
43            cfg_cache_ways: u8,
44            cfg_cache_line_size: u8,
45        );
46
47        fn rom_config_data_cache_mode(
48            cfg_cache_size: u32,
49            cfg_cache_ways: u8,
50            cfg_cache_line_size: u8,
51        );
52    }
53
54    const CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE: u32 = match () {
55        _ if cfg!(instruction_cache_size_32kb) => 0x8000,
56        _ if cfg!(instruction_cache_size_16kb) => 0x4000,
57        _ => core::unreachable!(),
58    };
59    const CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS: u8 = match () {
60        _ if cfg!(icache_associated_ways_8) => 8,
61        _ if cfg!(icache_associated_ways_4) => 4,
62        _ => core::unreachable!(),
63    };
64    const CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE: u8 = match () {
65        _ if cfg!(instruction_cache_line_size_32b) => 32,
66        _ if cfg!(instruction_cache_line_size_16b) => 16,
67        _ => core::unreachable!(),
68    };
69
70    const CONFIG_ESP32S3_DATA_CACHE_SIZE: u32 = match () {
71        _ if cfg!(data_cache_size_64kb) => 0x10000,
72        _ if cfg!(data_cache_size_32kb) => 0x8000,
73        _ if cfg!(data_cache_size_16kb) => 0x4000,
74        _ => core::unreachable!(),
75    };
76    const CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS: u8 = match () {
77        _ if cfg!(dcache_associated_ways_8) => 8,
78        _ if cfg!(dcache_associated_ways_4) => 4,
79        _ => core::unreachable!(),
80    };
81    const CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE: u8 = match () {
82        _ if cfg!(data_cache_line_size_64b) => 64,
83        _ if cfg!(data_cache_line_size_32b) => 32,
84        _ if cfg!(data_cache_line_size_16b) => 16,
85        _ => core::unreachable!(),
86    };
87
88    // Configure the mode of instruction cache: cache size, cache line size.
89    unsafe {
90        rom_config_instruction_cache_mode(
91            CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE,
92            CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS,
93            CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE,
94        );
95    }
96
97    // Configure the mode of data : cache size, cache line size.
98    unsafe {
99        Cache_Suspend_DCache();
100        rom_config_data_cache_mode(
101            CONFIG_ESP32S3_DATA_CACHE_SIZE,
102            CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS,
103            CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE,
104        );
105        Cache_Resume_DCache(0);
106    }
107}
108
109/// Write back a specific range of data in the cache.
110#[doc(hidden)]
111#[unsafe(link_section = ".rwtext")]
112pub unsafe fn cache_writeback_addr(addr: u32, size: u32) {
113    unsafe extern "C" {
114        fn rom_Cache_WriteBack_Addr(addr: u32, size: u32);
115        fn Cache_Suspend_DCache_Autoload() -> u32;
116        fn Cache_Resume_DCache_Autoload(value: u32);
117    }
118    // suspend autoload, avoid load cachelines being written back
119    unsafe {
120        let autoload = Cache_Suspend_DCache_Autoload();
121        rom_Cache_WriteBack_Addr(addr, size);
122        Cache_Resume_DCache_Autoload(autoload);
123    }
124}
125
126/// Invalidate a specific range of addresses in the cache.
127#[doc(hidden)]
128#[unsafe(link_section = ".rwtext")]
129pub unsafe fn cache_invalidate_addr(addr: u32, size: u32) {
130    unsafe extern "C" {
131        fn Cache_Invalidate_Addr(addr: u32, size: u32);
132    }
133    unsafe {
134        Cache_Invalidate_Addr(addr, size);
135    }
136}
137
138/// Get the size of a cache line in the DCache.
139#[doc(hidden)]
140#[unsafe(link_section = ".rwtext")]
141pub unsafe fn cache_get_dcache_line_size() -> u32 {
142    unsafe extern "C" {
143        fn Cache_Get_DCache_Line_Size() -> u32;
144    }
145    unsafe { Cache_Get_DCache_Line_Size() }
146}
147
148pub(crate) fn pre_init() {}