forked from espressif/esp-idf
feat(esp32p4): added hal support
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
#endif
|
||||
#include "esp_lcd_panel_io_interface.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "hal/spi_ll.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
|
@@ -39,8 +39,7 @@ if(NOT BOOTLOADER_BUILD)
|
||||
"rtc_io_hal.c"
|
||||
"gpio_hal.c"
|
||||
"uart_hal.c"
|
||||
"uart_hal_iram.c"
|
||||
"${target}/clk_tree_hal.c")
|
||||
"uart_hal_iram.c")
|
||||
|
||||
if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
|
||||
list(APPEND srcs
|
||||
@@ -52,6 +51,10 @@ if(NOT BOOTLOADER_BUILD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_CLK_TREE_SUPPORTED)
|
||||
list(APPEND srcs "${target}/clk_tree_hal.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_SYSTIMER_SUPPORTED AND NOT CONFIG_HAL_SYSTIMER_USE_ROM_IMPL)
|
||||
list(APPEND srcs "systimer_hal.c")
|
||||
endif()
|
||||
@@ -236,6 +239,12 @@ if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32p4")
|
||||
list(APPEND srcs
|
||||
"spi_flash_hal_gpspi.c")
|
||||
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32h2")
|
||||
list(APPEND srcs
|
||||
"spi_flash_hal_gpspi.c"
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -34,8 +34,13 @@
|
||||
* #define DATA_AUTOLOAD_FLAG BIT(2)
|
||||
* #define INST_AUTOLOAD_FLAG BIT(2)
|
||||
*/
|
||||
#define DATA_AUTOLOAD_FLAG Cache_Disable_DCache()
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7516
|
||||
#define DATA_AUTOLOAD_FLAG Cache_Disable_L2_Cache()
|
||||
#define INST_AUTOLOAD_FLAG Cache_Disable_L2_Cache()
|
||||
#else
|
||||
#define DATA_AUTOLOAD_FLAG Cache_Disable_ICache()
|
||||
#define INST_AUTOLOAD_FLAG Cache_Disable_ICache()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Necessary hal contexts, could be maintained by upper layer in the future
|
||||
@@ -55,7 +60,11 @@ void cache_hal_init(void)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
ctx.data_autoload_flag = INST_AUTOLOAD_FLAG;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Enable_L2_Cache(ctx.data_autoload_flag);
|
||||
#else
|
||||
Cache_Enable_ICache(ctx.data_autoload_flag);
|
||||
#endif
|
||||
#else
|
||||
ctx.data_autoload_flag = DATA_AUTOLOAD_FLAG;
|
||||
Cache_Enable_DCache(ctx.data_autoload_flag);
|
||||
@@ -79,7 +88,11 @@ void cache_hal_init(void)
|
||||
void cache_hal_disable(cache_type_t type)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Disable_L2_Cache();
|
||||
#else
|
||||
Cache_Disable_ICache();
|
||||
#endif
|
||||
#else
|
||||
if (type == CACHE_TYPE_DATA) {
|
||||
Cache_Disable_DCache();
|
||||
@@ -99,7 +112,11 @@ void cache_hal_disable(cache_type_t type)
|
||||
void cache_hal_enable(cache_type_t type)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Enable_L2_Cache(ctx.inst_autoload_flag);
|
||||
#else
|
||||
Cache_Enable_ICache(ctx.inst_autoload_flag);
|
||||
#endif
|
||||
#else
|
||||
if (type == CACHE_TYPE_DATA) {
|
||||
Cache_Enable_DCache(ctx.data_autoload_flag);
|
||||
@@ -118,7 +135,9 @@ void cache_hal_enable(cache_type_t type)
|
||||
|
||||
void cache_hal_suspend(cache_type_t type)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
#if SOC_CACHE_L2_SUPPORTED
|
||||
Cache_Suspend_L2_Cache();
|
||||
#elif SOC_SHARED_IDCACHE_SUPPORTED
|
||||
Cache_Suspend_ICache();
|
||||
#else
|
||||
if (type == CACHE_TYPE_DATA) {
|
||||
@@ -138,7 +157,9 @@ void cache_hal_suspend(cache_type_t type)
|
||||
|
||||
void cache_hal_resume(cache_type_t type)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
#if SOC_CACHE_L2_SUPPORTED
|
||||
Cache_Resume_L2_Cache(ctx.inst_autoload_flag);
|
||||
#elif SOC_SHARED_IDCACHE_SUPPORTED
|
||||
Cache_Resume_ICache(ctx.inst_autoload_flag);
|
||||
#else
|
||||
if (type == CACHE_TYPE_DATA) {
|
||||
@@ -169,14 +190,23 @@ void cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size)
|
||||
{
|
||||
//Now only esp32 has 2 MMUs, this file doesn't build on esp32
|
||||
HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(0, vaddr, size, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION));
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Invalidate_Addr(CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE, vaddr, size);
|
||||
#else
|
||||
Cache_Invalidate_Addr(vaddr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOC_CACHE_WRITEBACK_SUPPORTED
|
||||
void cache_hal_writeback_addr(uint32_t vaddr, uint32_t size)
|
||||
{
|
||||
HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(0, vaddr, size, MMU_VADDR_DATA));
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_WriteBack_Addr(CACHE_MAP_L1_DCACHE, vaddr, size);
|
||||
Cache_WriteBack_Addr(CACHE_MAP_L2_CACHE, vaddr, size);
|
||||
#else
|
||||
Cache_WriteBack_Addr(vaddr, size);
|
||||
#endif
|
||||
}
|
||||
#endif //#if SOC_CACHE_WRITEBACK_SUPPORTED
|
||||
|
||||
@@ -185,7 +215,11 @@ void cache_hal_writeback_addr(uint32_t vaddr, uint32_t size)
|
||||
void cache_hal_freeze(cache_type_t type)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Freeze_L2_Cache_Enable(CACHE_FREEZE_ACK_BUSY);
|
||||
#else
|
||||
Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY);
|
||||
#endif
|
||||
#else
|
||||
if (type == CACHE_TYPE_DATA) {
|
||||
Cache_Freeze_DCache_Enable(CACHE_FREEZE_ACK_BUSY);
|
||||
@@ -201,7 +235,11 @@ void cache_hal_freeze(cache_type_t type)
|
||||
void cache_hal_unfreeze(cache_type_t type)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Freeze_L2_Cache_Disable();
|
||||
#else
|
||||
Cache_Freeze_ICache_Disable();
|
||||
#endif
|
||||
#else
|
||||
if (type == CACHE_TYPE_DATA) {
|
||||
Cache_Freeze_DCache_Disable();
|
||||
@@ -218,7 +256,11 @@ void cache_hal_unfreeze(cache_type_t type)
|
||||
uint32_t cache_hal_get_cache_line_size(cache_type_t type)
|
||||
{
|
||||
#if SOC_SHARED_IDCACHE_SUPPORTED
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
return Cache_Get_L2_Cache_Line_Size();
|
||||
#else
|
||||
return Cache_Get_ICache_Line_Size();
|
||||
#endif
|
||||
#else
|
||||
uint32_t size = 0;
|
||||
if (type == CACHE_TYPE_DATA) {
|
||||
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include <sys/param.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/efuse_ll.h"
|
||||
|
||||
#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x08 << (4 * (block))))
|
||||
#define ESP_EFUSE_BLOCK_ERROR_NUM_BITS(error_reg, block) ((error_reg) & (0x07 << (4 * (block))))
|
||||
|
||||
uint32_t efuse_hal_get_major_chip_version(void)
|
||||
{
|
||||
return efuse_ll_get_chip_wafer_version_major();
|
||||
}
|
||||
|
||||
uint32_t efuse_hal_get_minor_chip_version(void)
|
||||
{
|
||||
return efuse_ll_get_chip_wafer_version_minor();
|
||||
}
|
||||
|
||||
/******************* eFuse control functions *************************/
|
||||
|
||||
void efuse_hal_set_timing(uint32_t apb_freq_hz)
|
||||
{
|
||||
(void) apb_freq_hz;
|
||||
efuse_ll_set_pwr_off_num(0x190);
|
||||
}
|
||||
|
||||
void efuse_hal_read(void)
|
||||
{
|
||||
efuse_hal_set_timing(0);
|
||||
|
||||
efuse_ll_set_conf_read_op_code();
|
||||
efuse_ll_set_read_cmd();
|
||||
|
||||
while (efuse_ll_get_read_cmd() != 0) { }
|
||||
/*Due to a hardware error, we have to read READ_CMD again to make sure the efuse clock is normal*/
|
||||
while (efuse_ll_get_read_cmd() != 0) { }
|
||||
}
|
||||
|
||||
void efuse_hal_clear_program_registers(void)
|
||||
{
|
||||
ets_efuse_clear_program_registers();
|
||||
}
|
||||
|
||||
void efuse_hal_program(uint32_t block)
|
||||
{
|
||||
efuse_hal_set_timing(0);
|
||||
|
||||
efuse_ll_set_conf_write_op_code();
|
||||
efuse_ll_set_pgm_cmd(block);
|
||||
|
||||
while (efuse_ll_get_pgm_cmd() != 0) { }
|
||||
|
||||
efuse_hal_clear_program_registers();
|
||||
efuse_hal_read();
|
||||
}
|
||||
|
||||
void efuse_hal_rs_calculate(const void *data, void *rs_values)
|
||||
{
|
||||
ets_efuse_rs_calculate(data, rs_values);
|
||||
}
|
||||
|
||||
/******************* eFuse control functions *************************/
|
||||
|
||||
bool efuse_hal_is_coding_error_in_block(unsigned block)
|
||||
{
|
||||
if (block == 0) {
|
||||
for (unsigned i = 0; i < 5; i++) {
|
||||
if (REG_READ(EFUSE_RD_REPEAT_ERR0_REG + i * 4)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (block <= 10) {
|
||||
// EFUSE_RD_RS_ERR0_REG: (hi) BLOCK8, BLOCK7, BLOCK6, BLOCK5, BLOCK4, BLOCK3, BLOCK2, BLOCK1 (low)
|
||||
// EFUSE_RD_RS_ERR1_REG: BLOCK10, BLOCK9
|
||||
block--;
|
||||
uint32_t error_reg = REG_READ(EFUSE_RD_RS_ERR0_REG + (block / 8) * 4);
|
||||
return ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block % 8) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
140
components/hal/esp32p4/include/hal/cache_ll.h
Normal file
140
components/hal/esp32p4/include/hal/cache_ll.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for Cache register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/cache_reg.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "hal/cache_types.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CACHE_LL_ENABLE_DISABLE_STATE_SW 1 //There's no register indicating cache enable/disable state, we need to use software way for this state.
|
||||
|
||||
#define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0
|
||||
#define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_DBUS0
|
||||
|
||||
//TODO: IDF-7516
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_MASK (0x3f)
|
||||
// #define CACHE_LL_L1_ACCESS_EVENT_DBUS_WR_IC (1<<5)
|
||||
// #define CACHE_LL_L1_ACCESS_EVENT_DBUS_REJECT (1<<4)
|
||||
// #define CACHE_LL_L1_ACCESS_EVENT_DBUS_ACS_MSK_IC (1<<3)
|
||||
// #define CACHE_LL_L1_ACCESS_EVENT_IBUS_REJECT (1<<2)
|
||||
// #define CACHE_LL_L1_ACCESS_EVENT_IBUS_WR_IC (1<<1)
|
||||
// #define CACHE_LL_L1_ACCESS_EVENT_IBUS_ACS_MSK_IC (1<<0)
|
||||
|
||||
// #define CACHE_LL_L1_ILG_EVENT_MASK (0x23)
|
||||
// #define CACHE_LL_L1_ILG_EVENT_MMU_ENTRY_FAULT (1<<5)
|
||||
// #define CACHE_LL_L1_ILG_EVENT_PRELOAD_OP_FAULT (1<<1)
|
||||
// #define CACHE_LL_L1_ILG_EVENT_SYNC_OP_FAULT (1<<0)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the buses of a particular cache that are mapped to a virtual address range
|
||||
*
|
||||
* External virtual address can only be accessed when the involved cache buses are enabled.
|
||||
* This API is to get the cache buses where the memory region (from `vaddr_start` to `vaddr_start + len`) reside.
|
||||
*
|
||||
* This api in esp32p4 is not used. There is no hardware interface to mask the i/dbus to l2 cache. Needs check, TODO: IDF-7516
|
||||
*
|
||||
* @param cache_id cache ID (when l1 cache is per core)
|
||||
* @param vaddr_start virtual address start
|
||||
* @param len vaddr length
|
||||
*/
|
||||
#if !BOOTLOADER_BUILD
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline cache_bus_mask_t cache_ll_l1_get_bus(uint32_t cache_id, uint32_t vaddr_start, uint32_t len)
|
||||
{
|
||||
HAL_ASSERT(cache_id == 0 || cache_id == 1);
|
||||
cache_bus_mask_t mask = 0;
|
||||
|
||||
uint32_t vaddr_end = vaddr_start + len - 1;
|
||||
if (vaddr_start >= IRAM0_CACHE_ADDRESS_LOW && vaddr_end < SINGLE_BANK_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_IBUS0;
|
||||
mask |= CACHE_BUS_DBUS0;
|
||||
} else if (vaddr_start >= DUAL_BANK_CACHE_ADDRESS_LOW && vaddr_end < DUAL_BANK_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_IBUS1;
|
||||
mask |= CACHE_BUS_DBUS1;
|
||||
} else {
|
||||
HAL_ASSERT(0); //Out of region
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the Cache Buses
|
||||
*
|
||||
* This api is not used in esp32p4. Needs check, TODO: IDF-7516
|
||||
*
|
||||
* @param cache_id cache ID (when l1 cache is per core)
|
||||
* @param mask To know which buses should be enabled
|
||||
*/
|
||||
#if !BOOTLOADER_BUILD
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t mask)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the Cache Buses
|
||||
*
|
||||
* This api is not used in esp32p4. Needs check, TODO: IDF-7516
|
||||
*
|
||||
* @param cache_id cache ID (when l1 cache is per core)
|
||||
* @param mask To know which buses should be disabled
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t mask)
|
||||
{
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Interrupt
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable Cache access error interrupt
|
||||
*
|
||||
* @param cache_id Cache ID
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear Cache access error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Cache access error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID
|
||||
* @param mask Interrupt mask
|
||||
*
|
||||
* @return Status mask
|
||||
*/
|
||||
static inline uint32_t cache_ll_l1_get_access_error_intr_status(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
376
components/hal/esp32p4/include/hal/clk_gate_ll.h
Normal file
376
components/hal/esp32p4/include/hal/clk_gate_ll.h
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/hp_sys_clkrst_reg.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
|
||||
{
|
||||
switch (periph) {
|
||||
case PERIPH_MSPI_FLASH_MODULE:
|
||||
return HP_SYS_CLKRST_REG_FLASH_CORE_CLK_EN;
|
||||
case PERIPH_MSPI_PSRAM_MODULE:
|
||||
return HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN;
|
||||
case PERIPH_EMAC_MODULE:
|
||||
return LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN | LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN | LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN;
|
||||
case PERIPH_MIPI_DSI_MODULE:
|
||||
return HP_SYS_CLKRST_REG_MIPI_DSI_DPICLK_EN;
|
||||
// IDF-6500
|
||||
case PERIPH_MIPI_CSI_MODULE:
|
||||
return 0;
|
||||
case PERIPH_I2C0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_I2C0_CLK_EN;
|
||||
case PERIPH_I2C1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_I2C1_CLK_EN;
|
||||
case PERIPH_I2S0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_I2S0_TX_CLK_EN | HP_SYS_CLKRST_REG_I2S0_RX_CLK_EN;
|
||||
case PERIPH_I2S1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_I2S1_RX_CLK_EN | HP_SYS_CLKRST_REG_I2S1_TX_CLK_EN;
|
||||
case PERIPH_I2S2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_I2S2_RX_CLK_EN | HP_SYS_CLKRST_REG_I2S2_TX_CLK_EN;
|
||||
case PERIPH_LCD_MODULE:
|
||||
return HP_SYS_CLKRST_REG_LCD_CLK_EN;
|
||||
case PERIPH_UART0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_UART0_CLK_EN;
|
||||
case PERIPH_UART1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_UART1_CLK_EN;
|
||||
case PERIPH_UART2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_UART2_CLK_EN;
|
||||
case PERIPH_UART3_MODULE:
|
||||
return HP_SYS_CLKRST_REG_UART3_CLK_EN;
|
||||
case PERIPH_UART4_MODULE:
|
||||
return HP_SYS_CLKRST_REG_UART4_CLK_EN;
|
||||
case PERIPH_TWAI0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_TWAI0_CLK_EN;
|
||||
case PERIPH_TWAI1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_TWAI1_CLK_EN;
|
||||
case PERIPH_TWAI2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_TWAI2_CLK_EN;
|
||||
case PERIPH_GPSPI_MODULE:
|
||||
return HP_SYS_CLKRST_REG_GPSPI2_HS_CLK_EN;
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_GPSPI2_MST_CLK_EN;
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
return HP_SYS_CLKRST_REG_GPSPI3_MST_CLK_EN;
|
||||
case PERIPH_PARLIO_MODULE:
|
||||
return HP_SYS_CLKRST_REG_PARLIO_RX_CLK_EN | HP_SYS_CLKRST_REG_PARLIO_TX_CLK_EN;
|
||||
case PERIPH_I3C_MODULE:
|
||||
return HP_SYS_CLKRST_REG_I3C_MST_CLK_EN;
|
||||
case PERIPH_CAM_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CAM_CLK_EN;
|
||||
case PERIPH_MCPWM0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_MCPWM0_CLK_EN;
|
||||
case PERIPH_MCPWM1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_MCPWM1_CLK_EN;
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_TIMERGRP0_T0_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP0_T1_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP0_WDT_CLK_EN;
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_TIMERGRP1_T0_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP1_T1_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP1_WDT_CLK_EN;
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
return HP_SYS_CLKRST_REG_SYSTIMER_CLK_EN;
|
||||
case PERIPH_LEDC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_LEDC_CLK_EN;
|
||||
case PERIPH_RMT_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RMT_CLK_EN;
|
||||
case PERIPH_SARADC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_ADC_CLK_EN;
|
||||
case PERIPH_PVT_MODULE:
|
||||
return HP_SYS_CLKRST_REG_PVT_CLK_EN;
|
||||
case PERIPH_AES_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_AES_CLK_EN;
|
||||
case PERIPH_DS_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_DS_CLK_EN;
|
||||
case PERIPH_ECC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_ECC_CLK_EN;
|
||||
case PERIPH_HMAC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_HMAC_CLK_EN;
|
||||
case PERIPH_RSA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_RSA_CLK_EN;
|
||||
case PERIPH_SEC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_SEC_CLK_EN;
|
||||
case PERIPH_SHA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_SHA_CLK_EN;
|
||||
case PERIPH_ECDSA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_CRYPTO_ECDSA_CLK_EN;
|
||||
case PERIPH_ISP_MODULE:
|
||||
return HP_SYS_CLKRST_REG_ISP_CLK_EN;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool enable)
|
||||
{
|
||||
switch (periph) {
|
||||
case PERIPH_PVT_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_PVT_TOP;
|
||||
case PERIPH_GDMA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_GDMA;
|
||||
case PERIPH_MSPI_FLASH_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI;
|
||||
case PERIPH_MSPI_PSRAM_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_DUAL_MSPI_AXI;
|
||||
case PERIPH_MIPI_DSI_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_DSI_BRG;
|
||||
case PERIPH_MIPI_CSI_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CSI_BRG;
|
||||
case PERIPH_ISP_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_ISP;
|
||||
case PERIPH_JPEG_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_JPEG;
|
||||
case PERIPH_DMA2D_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_DMA2D;
|
||||
case PERIPH_PPA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_PPA;
|
||||
case PERIPH_AHB_PDMA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_AHB_PDMA;
|
||||
case PERIPH_AXI_PDMA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_AXI_PDMA;
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_STIMER;
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_TIMERGRP0;
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_TIMERGRP1;
|
||||
case PERIPH_UART0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_UART0_CORE;
|
||||
case PERIPH_UART1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_UART1_CORE;
|
||||
case PERIPH_UART2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_UART2_CORE;
|
||||
case PERIPH_UART3_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_UART3_CORE;
|
||||
case PERIPH_UART4_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_UART4_CORE;
|
||||
case PERIPH_UHCI_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_UHCI;
|
||||
case PERIPH_I3C_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_I3CMST | HP_SYS_CLKRST_REG_RST_EN_I3CSLV;
|
||||
case PERIPH_I2C0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_I2C0;
|
||||
case PERIPH_I2C1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_I2C1;
|
||||
case PERIPH_RMT_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_RMT;
|
||||
case PERIPH_MCPWM0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_PWM0;
|
||||
case PERIPH_MCPWM1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_PWM1;
|
||||
case PERIPH_TWAI0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CAN0;
|
||||
case PERIPH_TWAI1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CAN1;
|
||||
case PERIPH_TWAI2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CAN2;
|
||||
case PERIPH_LEDC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_LEDC;
|
||||
case PERIPH_PCNT_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_PCNT;
|
||||
case PERIPH_PARLIO_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_PARLIO | HP_SYS_CLKRST_REG_RST_EN_PARLIO_RX | HP_SYS_CLKRST_REG_RST_EN_PARLIO_TX;
|
||||
case PERIPH_I2S0_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_I2S0_APB;
|
||||
case PERIPH_I2S1_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_I2S1_APB;
|
||||
case PERIPH_I2S2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_I2S2_APB;
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_SPI2;
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_SPI3;
|
||||
case PERIPH_LCD_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_LCDCAM;
|
||||
case PERIPH_SARADC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_ADC;
|
||||
case PERIPH_AES_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_AES;
|
||||
case PERIPH_DS_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_DS;
|
||||
case PERIPH_ECC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_ECC;
|
||||
case PERIPH_HMAC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_HMAC;
|
||||
case PERIPH_RSA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_RSA;
|
||||
case PERIPH_SEC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_SEC;
|
||||
case PERIPH_SHA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_SHA;
|
||||
case PERIPH_ECDSA_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CRYPTO | HP_SYS_CLKRST_REG_RST_EN_ECDSA;
|
||||
case PERIPH_SDMMC_MODULE:
|
||||
return LP_CLKRST_RST_EN_SDMMC;
|
||||
case PERIPH_EMAC_MODULE:
|
||||
return LP_CLKRST_RST_EN_EMAC;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
|
||||
{
|
||||
switch (periph) {
|
||||
case PERIPH_MSPI_FLASH_MODULE:
|
||||
case PERIPH_MSPI_PSRAM_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL00_REG;
|
||||
case PERIPH_MIPI_DSI_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL03_REG;
|
||||
case PERIPH_I2C0_MODULE:
|
||||
case PERIPH_I2C1_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL10_REG;
|
||||
case PERIPH_LCD_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL110_REG;
|
||||
case PERIPH_UART0_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL111_REG;
|
||||
case PERIPH_UART1_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL112_REG;
|
||||
case PERIPH_UART2_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL113_REG;
|
||||
case PERIPH_UART3_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL114_REG;
|
||||
case PERIPH_UART4_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL115_REG;
|
||||
case PERIPH_TWAI0_MODULE:
|
||||
case PERIPH_TWAI1_MODULE:
|
||||
case PERIPH_TWAI2_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL116_REG;
|
||||
case PERIPH_GPSPI_MODULE:
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL117_REG;
|
||||
case PERIPH_I3C_MODULE:
|
||||
case PERIPH_CAM_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL119_REG;
|
||||
case PERIPH_MCPWM0_MODULE:
|
||||
case PERIPH_MCPWM1_MODULE:
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL20_REG;
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
case PERIPH_LEDC_MODULE:
|
||||
case PERIPH_RMT_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL21_REG;
|
||||
case PERIPH_SARADC_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL22_REG;
|
||||
case PERIPH_PVT_MODULE:
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_DS_MODULE:
|
||||
case PERIPH_ECC_MODULE:
|
||||
case PERIPH_HMAC_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
case PERIPH_SEC_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_ECDSA_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL24_REG;
|
||||
case PERIPH_ISP_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL25_REG;
|
||||
case PERIPH_EMAC_MODULE:
|
||||
return LP_CLKRST_HP_CLK_CTRL_REG;
|
||||
default:
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
|
||||
{
|
||||
switch (periph) {
|
||||
case PERIPH_PVT_MODULE:
|
||||
case PERIPH_GDMA_MODULE:
|
||||
case PERIPH_MSPI_FLASH_MODULE:
|
||||
case PERIPH_MSPI_PSRAM_MODULE:
|
||||
case PERIPH_ISP_MODULE:
|
||||
case PERIPH_JPEG_MODULE:
|
||||
case PERIPH_DMA2D_MODULE:
|
||||
case PERIPH_PPA_MODULE:
|
||||
case PERIPH_AHB_PDMA_MODULE:
|
||||
case PERIPH_AXI_PDMA_MODULE:
|
||||
return HP_SYS_CLKRST_HP_RST_EN0_REG;
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
case PERIPH_UART0_MODULE:
|
||||
case PERIPH_UART1_MODULE:
|
||||
case PERIPH_UART2_MODULE:
|
||||
case PERIPH_UART3_MODULE:
|
||||
case PERIPH_UART4_MODULE:
|
||||
case PERIPH_UHCI_MODULE:
|
||||
case PERIPH_I3C_MODULE:
|
||||
case PERIPH_I2C0_MODULE:
|
||||
case PERIPH_I2C1_MODULE:
|
||||
case PERIPH_RMT_MODULE:
|
||||
case PERIPH_MCPWM0_MODULE:
|
||||
case PERIPH_MCPWM1_MODULE:
|
||||
case PERIPH_TWAI0_MODULE:
|
||||
case PERIPH_TWAI1_MODULE:
|
||||
case PERIPH_TWAI2_MODULE:
|
||||
case PERIPH_LEDC_MODULE:
|
||||
case PERIPH_PCNT_MODULE:
|
||||
case PERIPH_PARLIO_MODULE:
|
||||
case PERIPH_I2S0_MODULE:
|
||||
return HP_SYS_CLKRST_HP_RST_EN1_REG;
|
||||
case PERIPH_I2S1_MODULE:
|
||||
case PERIPH_I2S2_MODULE:
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
case PERIPH_CAM_MODULE:
|
||||
case PERIPH_SARADC_MODULE:
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_DS_MODULE:
|
||||
case PERIPH_ECC_MODULE:
|
||||
case PERIPH_HMAC_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
case PERIPH_SEC_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_ECDSA_MODULE:
|
||||
return HP_SYS_CLKRST_HP_RST_EN2_REG;
|
||||
case PERIPH_SDMMC_MODULE:
|
||||
case PERIPH_EMAC_MODULE:
|
||||
return LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG;
|
||||
default:
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void periph_ll_enable_clk_clear_rst(periph_module_t periph)
|
||||
{
|
||||
SET_PERI_REG_MASK(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph));
|
||||
CLEAR_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, true));
|
||||
}
|
||||
|
||||
static inline void periph_ll_disable_clk_set_rst(periph_module_t periph)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph));
|
||||
SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
|
||||
}
|
||||
|
||||
static inline void periph_ll_reset(periph_module_t periph)
|
||||
{
|
||||
SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
|
||||
CLEAR_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
|
||||
}
|
||||
|
||||
static inline bool IRAM_ATTR periph_ll_periph_enabled(periph_module_t periph)
|
||||
{
|
||||
return REG_GET_BIT(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)) == 0 &&
|
||||
REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
550
components/hal/esp32p4/include/hal/clk_tree_ll.h
Normal file
550
components/hal/esp32p4/include/hal/clk_tree_ll.h
Normal file
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_bbpll.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/log.h"
|
||||
#include "esp32p4/rom/rtc.h"
|
||||
#include "hal/misc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
|
||||
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
|
||||
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
|
||||
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
|
||||
|
||||
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
|
||||
|
||||
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
|
||||
.dac = 3, \
|
||||
.dres = 3, \
|
||||
.dgm = 3, \
|
||||
.dbuf = 1, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief XTAL32K_CLK enable modes
|
||||
*/
|
||||
typedef enum {
|
||||
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
|
||||
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for OSC_SLOW_CLK
|
||||
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
|
||||
} clk_ll_xtal32k_enable_mode_t;
|
||||
|
||||
/**
|
||||
* @brief XTAL32K_CLK configuration structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t dac : 6;
|
||||
uint32_t dres : 3;
|
||||
uint32_t dgm : 3;
|
||||
uint32_t dbuf: 1;
|
||||
} clk_ll_xtal32k_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Power up BBPLL circuit
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down BBPLL circuit
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the 32kHz crystal oscillator
|
||||
*
|
||||
* @param mode Used to determine the xtal32k configuration parameters
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the 32kHz crystal oscillator
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal32k_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the state of the 32kHz crystal clock
|
||||
*
|
||||
* @return True if the 32kHz XTAL is enabled
|
||||
*/
|
||||
static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the internal oscillator output for RC32K_CLK
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the internal oscillator output for RC32K_CLK
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the state of the internal oscillator for RC32K_CLK
|
||||
*
|
||||
* @return True if the oscillator is enabled
|
||||
*/
|
||||
static inline __attribute__((always_inline)) bool clk_ll_rc32k_is_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the internal oscillator output for RC_FAST_CLK
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the internal oscillator output for RC_FAST_CLK
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the state of the internal oscillator for RC_FAST_CLK
|
||||
*
|
||||
* @return True if the oscillator is enabled
|
||||
*/
|
||||
static inline __attribute__((always_inline)) bool clk_ll_rc_fast_is_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_enable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the digital RC_FAST_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_fast_digi_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the state of the digital RC_FAST_CLK
|
||||
*
|
||||
* @return True if the digital RC_FAST_CLK is enabled
|
||||
*/
|
||||
static inline __attribute__((always_inline)) bool clk_ll_rc_fast_digi_is_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_enable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the state of the digital XTAL32K_CLK
|
||||
*
|
||||
* @return True if the digital XTAL32K_CLK is enabled
|
||||
*/
|
||||
static inline __attribute__((always_inline)) bool clk_ll_xtal32k_digi_is_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the digital RC32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the digital RC32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the state of the digital RC32K_CLK
|
||||
*
|
||||
* @return True if the digital RC32K_CLK is enabled
|
||||
*/
|
||||
static inline __attribute__((always_inline)) bool clk_ll_rc32k_digi_is_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PLL_CLK frequency
|
||||
*
|
||||
* @return PLL clock frequency, in MHz. Returns 0 if register field value is invalid.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||
{
|
||||
// The target has a fixed 480MHz SPLL
|
||||
return CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set BBPLL frequency from XTAL source (Digital part)
|
||||
*
|
||||
* @param pll_freq_mhz PLL frequency, in MHz
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set BBPLL frequency from XTAL source (Analog part)
|
||||
*
|
||||
* @param pll_freq_mhz PLL frequency, in MHz
|
||||
* @param xtal_freq_mhz XTAL frequency, in MHz
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the clock source for CPU_CLK (SOC Clock Root)
|
||||
*
|
||||
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the clock source for CPU_CLK (SOC Clock Root)
|
||||
*
|
||||
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
|
||||
{
|
||||
return SOC_CPU_CLK_SRC_XTAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
|
||||
*
|
||||
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
|
||||
*
|
||||
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get CPU_CLK's high-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get CPU_CLK's low-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AHB_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
|
||||
*
|
||||
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_ahb_set_hs_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AHB_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
|
||||
*
|
||||
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1) = divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_ahb_set_ls_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get AHB_CLK's high-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get AHB_CLK's low-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider
|
||||
*
|
||||
* @param divider Divider. PCR_APB_DIV_NUM = divider - 1.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get APB_CLK divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_APB_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
|
||||
*
|
||||
* @param divider Divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set MSPI_FAST_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
|
||||
*
|
||||
* @param divider Divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the calibration 32kHz clock source for timergroup0
|
||||
*
|
||||
* @param in_sel One of the 32kHz clock sources (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the calibration 32kHz clock source for timergroup0
|
||||
*
|
||||
* @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the clock source for RTC_SLOW_CLK
|
||||
*
|
||||
* @param in_sel One of the clock sources in soc_rtc_slow_clk_src_t
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the clock source for RTC_SLOW_CLK
|
||||
*
|
||||
* @return Currently selected clock source (one of soc_rtc_slow_clk_src_t values)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the clock source for RTC_FAST_CLK
|
||||
*
|
||||
* @param in_sel One of the clock sources in soc_rtc_fast_clk_src_t
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the clock source for RTC_FAST_CLK
|
||||
*
|
||||
* @return Currently selected clock source (one of soc_rtc_fast_clk_src_t values)
|
||||
*/
|
||||
static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RC_FAST_CLK divider. The output from the divider is passed into rtc_fast_clk MUX.
|
||||
*
|
||||
* @param divider Divider of RC_FAST_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_fast_set_divider(uint32_t divider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get RC_FAST_CLK divider
|
||||
*
|
||||
* @return Divider. Divider = (CK8M_DIV_SEL + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider(void)
|
||||
{
|
||||
// No divider on the target, always return divider = 1
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RC_SLOW_CLK divider
|
||||
*
|
||||
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||
{
|
||||
}
|
||||
|
||||
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
|
||||
/**
|
||||
* @brief Store XTAL_CLK frequency in RTC storage register
|
||||
*
|
||||
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||
* halves. These are the routines to work with that representation.
|
||||
*
|
||||
* @param xtal_freq_mhz XTAL frequency, in MHz. The frequency must necessarily be even,
|
||||
* otherwise there will be a conflict with the low bit, which is used to disable logs
|
||||
* in the ROM code.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load XTAL_CLK frequency from RTC storage register
|
||||
*
|
||||
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||
* halves. These are the routines to work with that representation.
|
||||
*
|
||||
* @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
|
||||
*
|
||||
* Value of RTC_SLOW_CLK_CAL_REG has to be in the same format as returned by rtc_clk_cal (microseconds,
|
||||
* in Q13.19 fixed-point format).
|
||||
*
|
||||
* @param cal_value The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load the calibration value of RTC_SLOW_CLK frequency from RTC storage register
|
||||
*
|
||||
* This value gets updated (i.e. rtc slow clock gets calibrated) every time RTC_SLOW_CLK source switches
|
||||
*
|
||||
* @return The calibration value of slow clock period in microseconds, in Q13.19 fixed point format
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
69
components/hal/esp32p4/include/hal/efuse_hal.h
Normal file
69
components/hal/esp32p4/include/hal/efuse_hal.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/efuse_ll.h"
|
||||
#include_next "hal/efuse_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO: IDF-7512
|
||||
/**
|
||||
* @brief get chip version
|
||||
*/
|
||||
uint32_t efuse_hal_get_chip_revision(void);
|
||||
|
||||
/**
|
||||
* @brief set eFuse timings
|
||||
*
|
||||
* @param apb_freq_hz APB frequency in Hz
|
||||
*/
|
||||
void efuse_hal_set_timing(uint32_t apb_freq_hz);
|
||||
|
||||
/**
|
||||
* @brief trigger eFuse read operation
|
||||
*/
|
||||
void efuse_hal_read(void);
|
||||
|
||||
/**
|
||||
* @brief clear registers for programming eFuses
|
||||
*/
|
||||
void efuse_hal_clear_program_registers(void);
|
||||
|
||||
/**
|
||||
* @brief burn eFuses written in programming registers (one block at once)
|
||||
*
|
||||
* @param block block number
|
||||
*/
|
||||
void efuse_hal_program(uint32_t block);
|
||||
|
||||
/**
|
||||
* @brief Calculate Reed-Solomon Encoding values for a block of efuse data.
|
||||
*
|
||||
* @param data Pointer to data buffer (length 32 bytes)
|
||||
* @param rs_values Pointer to write encoded data to (length 12 bytes)
|
||||
*/
|
||||
void efuse_hal_rs_calculate(const void *data, void *rs_values);
|
||||
|
||||
/**
|
||||
* @brief Checks coding error in a block
|
||||
*
|
||||
* @param block Index of efuse block
|
||||
*
|
||||
* @return True - block has an error.
|
||||
* False - no error.
|
||||
*/
|
||||
bool efuse_hal_is_coding_error_in_block(unsigned block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
130
components/hal/esp32p4/include/hal/efuse_ll.h
Normal file
130
components/hal/esp32p4/include/hal/efuse_ll.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "hal/assert.h"
|
||||
#include "esp32p4/rom/efuse.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Always inline these functions even no gcc optimization is applied.
|
||||
|
||||
//TODO: IDF-7549
|
||||
|
||||
/******************* eFuse fields *************************/
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_flash_crypt_cnt(void)
|
||||
{
|
||||
return EFUSE.rd_repeat_data1.spi_boot_crypt_cnt;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_wdt_delay_sel(void)
|
||||
{
|
||||
return EFUSE.rd_repeat_data1.wdt_delay_sel;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_mac0(void)
|
||||
{
|
||||
return EFUSE.rd_mac_sys_0.mac_0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_mac1(void)
|
||||
{
|
||||
return EFUSE.rd_mac_sys_1.mac_1;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline bool efuse_ll_get_secure_boot_v2_en(void)
|
||||
{
|
||||
return EFUSE.rd_repeat_data2.secure_boot_en;
|
||||
}
|
||||
|
||||
// use efuse_hal_get_major_chip_version() to get major chip version
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_wafer_version_major(void)
|
||||
{
|
||||
// return EFUSE.rd_mac_sys_5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// use efuse_hal_get_minor_chip_version() to get minor chip version
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_wafer_version_minor(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline bool efuse_ll_get_disable_wafer_version_major(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_blk_version_major(void)
|
||||
{
|
||||
return EFUSE.rd_sys_part1_data4.val;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_blk_version_minor(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline bool efuse_ll_get_disable_blk_version_major(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************* eFuse control functions *************************/
|
||||
|
||||
__attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void)
|
||||
{
|
||||
return EFUSE.cmd.read_cmd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline bool efuse_ll_get_pgm_cmd(void)
|
||||
{
|
||||
return EFUSE.cmd.pgm_cmd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void efuse_ll_set_read_cmd(void)
|
||||
{
|
||||
EFUSE.cmd.read_cmd = 1;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void efuse_ll_set_pgm_cmd(uint32_t block)
|
||||
{
|
||||
HAL_ASSERT(block < ETS_EFUSE_BLOCK_MAX);
|
||||
EFUSE.cmd.val = ((block << EFUSE_BLK_NUM_S) & EFUSE_BLK_NUM_M) | EFUSE_PGM_CMD;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void efuse_ll_set_conf_read_op_code(void)
|
||||
{
|
||||
EFUSE.conf.op_code = EFUSE_READ_OP_CODE;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void efuse_ll_set_conf_write_op_code(void)
|
||||
{
|
||||
EFUSE.conf.op_code = EFUSE_WRITE_OP_CODE;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void efuse_ll_set_pwr_off_num(uint16_t value)
|
||||
{
|
||||
EFUSE.wr_tim_conf2.pwr_off_num = value;
|
||||
}
|
||||
|
||||
/******************* eFuse control functions *************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
603
components/hal/esp32p4/include/hal/gpio_ll.h
Normal file
603
components/hal/esp32p4/include/hal/gpio_ll.h
Normal file
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The LL layer for ESP32-P4 GPIO register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/gpio_types.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
//TODO: IDF-6509
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Get GPIO hardware instance with giving gpio num
|
||||
#define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL)
|
||||
|
||||
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
|
||||
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
|
||||
/**
|
||||
* @brief Enable pull-up on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-up on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable pull-down on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-down on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO set interrupt trigger type
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param intr_type Interrupt type, select from gpio_int_type_t
|
||||
*/
|
||||
static inline void gpio_ll_set_intr_type(gpio_dev_t *hw, uint32_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
// hw->pin[gpio_num].int_type = intr_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get GPIO interrupt status
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param core_id interrupt core id
|
||||
* @param status interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
|
||||
{
|
||||
// *status = hw->intr_0; // need to check
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get GPIO interrupt status high
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param core_id interrupt core id
|
||||
* @param status interrupt status high
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
|
||||
{
|
||||
*status = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear GPIO interrupt status
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param mask interrupt status clear mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_clear_intr_status(gpio_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
// hw->status_w1tc = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear GPIO interrupt status high
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param mask interrupt status high clear mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
// P4 needs check
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO module interrupt signal
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param core_id Interrupt enabled CPU to corresponding ID
|
||||
* @param gpio_num GPIO number. If you want to enable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, uint32_t gpio_num)
|
||||
{
|
||||
// HAL_ASSERT(core_id == 0 && "target SoC only has a single core");
|
||||
// GPIO.pin[gpio_num].int_ena = GPIO_LL_PRO_CPU_INTR_ENA; //enable pro cpu intr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO module interrupt signal
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to disable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// hw->pin[gpio_num].int_ena = 0; //disable GPIO intr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable input mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable input mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// hw->enable_w1tc = (0x1 << gpio_num);
|
||||
// // Ensure no other output signal is routed via GPIO matrix to this pin
|
||||
// REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4),
|
||||
// CORE_GPIO_OUT_PAD_OUT0_IDX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// hw->enable_w1ts = (0x1 << gpio_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable open-drain mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_od_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// hw->pin[gpio_num].pad_driver = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable open-drain mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// hw->pin[gpio_num].pad_driver = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO set output level
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to set the output level of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param level Output level. 0: low ; 1: high
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level)
|
||||
{
|
||||
// if (level) {
|
||||
// hw->out_w1ts = (1 << gpio_num);
|
||||
// } else {
|
||||
// hw->out_w1tc = (1 << gpio_num);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO get input level
|
||||
*
|
||||
* @warning If the pad is not configured for input (or input and output) the returned value is always 0.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to get the logic level of e.g. pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return
|
||||
* - 0 the GPIO input level is 0
|
||||
* - 1 the GPIO input level is 1
|
||||
*/
|
||||
static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// return (hw->in >> gpio_num) & 0x1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO wake-up function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number.
|
||||
*/
|
||||
static inline void gpio_ll_wakeup_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// hw->pin[gpio_num].wakeup_enable = 0x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO wake-up function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// hw->pin[gpio_num].wakeup_enable = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set GPIO pad drive capability
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
* @param strength Drive capability of the pad
|
||||
*/
|
||||
static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength)
|
||||
{
|
||||
SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, strength, FUN_DRV_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get GPIO pad drive capability
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
* @param strength Pointer to accept drive capability of the pad
|
||||
*/
|
||||
static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength)
|
||||
{
|
||||
*strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all digital gpio pads hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
|
||||
{
|
||||
//SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all digital gpio pads hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
|
||||
{
|
||||
//SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable gpio pad hold function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
*/
|
||||
static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable gpio pad hold function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
*/
|
||||
static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set pad input to a peripheral signal through the IOMUX.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
* @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx)
|
||||
{
|
||||
// hw->func_in_sel_cfg[signal_idx].sig_in_sel = 0;
|
||||
// PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select a function for the pin in the IOMUX
|
||||
*
|
||||
* @param pin_name Pin name to configure
|
||||
* @param func Function to assign to the pin
|
||||
*/
|
||||
static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func)
|
||||
{
|
||||
if (pin_name == IO_MUX_GPIO18_REG || pin_name == IO_MUX_GPIO19_REG) {
|
||||
//CLEAR_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_USB_PAD_ENABLE);
|
||||
}
|
||||
PIN_FUNC_SELECT(pin_name, func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select a function for the pin in the IOMUX
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @param func Function to assign to the pin
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
|
||||
{
|
||||
// Disable USB Serial JTAG if pins 18 or pins 19 needs to select an IOMUX function
|
||||
if (gpio_num == 18 || gpio_num == 19) {
|
||||
//CLEAR_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_USB_PAD_ENABLE);
|
||||
}
|
||||
PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set peripheral output to an GPIO pad through the IOMUX.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num gpio_num GPIO number of the pad.
|
||||
* @param func The function number of the peripheral pin to output pin.
|
||||
* One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``.
|
||||
* @param oen_inv True if the output enable needs to be inverted, otherwise False.
|
||||
*/
|
||||
static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, uint32_t oen_inv)
|
||||
{
|
||||
// hw->func_out_sel_cfg[gpio_num].oe_sel = 0;
|
||||
// hw->func_out_sel_cfg[gpio_num].oe_inv_sel = oen_inv;
|
||||
// gpio_ll_iomux_func_sel(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set clock source of IO MUX module
|
||||
*
|
||||
* @param src IO MUX clock source (only a subset of soc_module_clk_t values are valid)
|
||||
*/
|
||||
static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin to use sleep mode pin functions during light sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin to use sleep mode pin functions during light sleep.
|
||||
* Pin functions remains the same in both normal execution and in light-sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO deep-sleep wake-up function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number.
|
||||
* @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used.
|
||||
*/
|
||||
static inline void gpio_ll_deepsleep_wakeup_enable(gpio_dev_t *hw, uint32_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO deep-sleep wake-up function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_deepsleep_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the status of whether an IO is used for deep-sleep wake-up.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @return True if the pin is enabled to wake up from deep-sleep
|
||||
*/
|
||||
static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
427
components/hal/esp32p4/include/hal/gpspi_flash_ll.h
Normal file
427
components/hal/esp32p4/include/hal/gpspi_flash_ll.h
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "soc/spi_periph.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "hal/spi_types.h"
|
||||
#include "hal/spi_flash_types.h"
|
||||
#include <sys/param.h> // For MIN/MAX
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "hal/misc.h"
|
||||
//TODO: IDF-7499
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on c3 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
typedef typeof(GPSPI2.clock) gpspi_flash_ll_clock_reg_t;
|
||||
#define GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (80)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Control
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Reset peripheral registers before configuration and starting control
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_reset(spi_dev_t *dev)
|
||||
{
|
||||
// dev->user.val = 0;
|
||||
// dev->ctrl.val = 0;
|
||||
|
||||
// dev->clk_gate.clk_en = 1;
|
||||
// dev->clk_gate.mst_clk_active = 1;
|
||||
// dev->clk_gate.mst_clk_sel = 1;
|
||||
|
||||
// dev->dma_conf.val = 0;
|
||||
// dev->dma_conf.tx_seg_trans_clr_en = 1;
|
||||
// dev->dma_conf.rx_seg_trans_clr_en = 1;
|
||||
// dev->dma_conf.dma_seg_trans_en = 0;
|
||||
abort(); //TODO: IDF-7499
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the previous operation is done.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return true if last command is done, otherwise false.
|
||||
*/
|
||||
static inline bool gpspi_flash_ll_cmd_is_done(const spi_dev_t *dev)
|
||||
{
|
||||
return (dev->cmd.usr == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the read data from the buffer after ``gpspi_flash_ll_read`` is done.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param buffer Buffer to hold the output data
|
||||
* @param read_len Length to get out of the buffer
|
||||
*/
|
||||
static inline void gpspi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, uint32_t read_len)
|
||||
{
|
||||
// if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) {
|
||||
// // If everything is word-aligned, do a faster memcpy
|
||||
// memcpy(buffer, (void *)dev->data_buf, read_len);
|
||||
// } else {
|
||||
// // Otherwise, slow(er) path copies word by word
|
||||
// int copy_len = read_len;
|
||||
// for (int i = 0; i < (read_len + 3) / 4; i++) {
|
||||
// int word_len = MIN(sizeof(uint32_t), copy_len);
|
||||
// uint32_t word = dev->data_buf[i];
|
||||
// memcpy(buffer, &word, word_len);
|
||||
// buffer = (void *)((intptr_t)buffer + word_len);
|
||||
// copy_len -= word_len;
|
||||
// }
|
||||
// }
|
||||
abort(); //TODO: IDF-7499
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a word to the data buffer.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param word Data to write at address 0.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_write_word(spi_dev_t *dev, uint32_t word)
|
||||
{
|
||||
// dev->data_buf[0] = word;
|
||||
abort(); //TODO: IDF-7499
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data to be written in the data buffer.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param buffer Buffer holding the data
|
||||
* @param length Length of data in bytes.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *buffer, uint32_t length)
|
||||
{
|
||||
// // Load data registers, word at a time
|
||||
// int num_words = (length + 3) / 4;
|
||||
// for (int i = 0; i < num_words; i++) {
|
||||
// uint32_t word = 0;
|
||||
// uint32_t word_len = MIN(length, sizeof(word));
|
||||
// memcpy(&word, buffer, word_len);
|
||||
// dev->data_buf[i] = word;
|
||||
// length -= word_len;
|
||||
// buffer = (void *)((intptr_t)buffer + word_len);
|
||||
// }
|
||||
abort(); //TODO: IDF-7499
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a user defined transaction. All phases, including command, address, dummy, and the data phases,
|
||||
* should be configured before this is called.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
|
||||
{
|
||||
dev->ctrl.hold_pol = 1;
|
||||
dev->cmd.update = 1;
|
||||
while (dev->cmd.update);
|
||||
dev->cmd.usr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||
{
|
||||
// Not supported on GPSPI
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HD pin high when flash work at spi mode.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_hold_pol(spi_dev_t *dev, uint32_t pol_val)
|
||||
{
|
||||
dev->ctrl.hold_pol = pol_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the host is idle to perform new commands.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return true if the host is idle, otherwise false
|
||||
*/
|
||||
static inline bool gpspi_flash_ll_host_idle(const spi_dev_t *dev)
|
||||
{
|
||||
return dev->cmd.usr == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set phases for user-defined transaction to read
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_read_phase(spi_dev_t *dev)
|
||||
{
|
||||
typeof (dev->user) user = {
|
||||
.usr_command = 1,
|
||||
.usr_mosi = 0,
|
||||
.usr_miso = 1,
|
||||
.usr_addr = 1,
|
||||
};
|
||||
dev->user = user;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Select which pin to use for the flash
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param pin Pin ID to use, 0-2. Set to other values to disable all the CS pins.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_cs_pin(spi_dev_t *dev, int pin)
|
||||
{
|
||||
dev->misc.cs0_dis = (pin == 0) ? 0 : 1;
|
||||
dev->misc.cs1_dis = (pin == 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read io mode.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param read_mode I/O mode to use in the following transactions.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mode_t read_mode)
|
||||
{
|
||||
typeof (dev->ctrl) ctrl = dev->ctrl;
|
||||
typeof (dev->user) user = dev->user;
|
||||
|
||||
ctrl.val &= ~(SPI_FCMD_QUAD_M | SPI_FADDR_QUAD_M | SPI_FREAD_QUAD_M | SPI_FCMD_DUAL_M | SPI_FADDR_DUAL_M | SPI_FREAD_DUAL_M);
|
||||
user.val &= ~(SPI_FWRITE_QUAD_M | SPI_FWRITE_DUAL_M);
|
||||
|
||||
switch (read_mode) {
|
||||
case SPI_FLASH_FASTRD:
|
||||
//the default option
|
||||
case SPI_FLASH_SLOWRD:
|
||||
break;
|
||||
case SPI_FLASH_QIO:
|
||||
ctrl.fread_quad = 1;
|
||||
ctrl.faddr_quad = 1;
|
||||
user.fwrite_quad = 1;
|
||||
break;
|
||||
case SPI_FLASH_QOUT:
|
||||
ctrl.fread_quad = 1;
|
||||
user.fwrite_quad = 1;
|
||||
break;
|
||||
case SPI_FLASH_DIO:
|
||||
ctrl.fread_dual = 1;
|
||||
ctrl.faddr_dual = 1;
|
||||
user.fwrite_dual = 1;
|
||||
break;
|
||||
case SPI_FLASH_DOUT:
|
||||
ctrl.fread_dual = 1;
|
||||
user.fwrite_dual = 1;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
dev->ctrl = ctrl;
|
||||
dev->user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set clock frequency to work at.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param clock_val pointer to the clock value to set
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_clock(spi_dev_t *dev, gpspi_flash_ll_clock_reg_t *clock_val)
|
||||
{
|
||||
dev->clock = *clock_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input length, in bits.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of input, in bits.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_miso_bitlen(spi_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_miso = bitlen > 0;
|
||||
if (bitlen) {
|
||||
dev->ms_dlen.ms_data_bitlen = bitlen - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output length, in bits (not including command, address and dummy
|
||||
* phases)
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of output, in bits.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_mosi_bitlen(spi_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_mosi = bitlen > 0;
|
||||
if (bitlen) {
|
||||
dev->ms_dlen.ms_data_bitlen = bitlen - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the command.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param command Command to send
|
||||
* @param bitlen Length of the command
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_command(spi_dev_t *dev, uint8_t command, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_command = 1;
|
||||
typeof(dev->user2) user2 = {
|
||||
.usr_command_value = command,
|
||||
.usr_command_bitlen = (bitlen - 1),
|
||||
};
|
||||
dev->user2 = user2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address length that is set in register, in bits.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
*/
|
||||
static inline int gpspi_flash_ll_get_addr_bitlen(spi_dev_t *dev)
|
||||
{
|
||||
return dev->user.usr_addr ? dev->user1.usr_addr_bitlen + 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address length to send, in bits. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of the address, in bits
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_addr_bitlen(spi_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user1.usr_addr_bitlen = (bitlen - 1);
|
||||
dev->user.usr_addr = bitlen ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address to send in user mode. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param addr Address to send
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, uint32_t bitlen)
|
||||
{
|
||||
// // The blank region should be all ones
|
||||
// uint32_t padding_ones = (bitlen == 32? 0 : UINT32_MAX >> bitlen);
|
||||
// dev->addr = (addr << (32 - bitlen)) | padding_ones;
|
||||
abort(); //TODO: IDF-7499
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address to send. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param addr Address to send
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_address(spi_dev_t *dev, uint32_t addr)
|
||||
{
|
||||
// dev->addr = addr;
|
||||
abort(); //TODO: IDF-7499
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length of dummy cycles.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param dummy_n Cycles of dummy phases
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n)
|
||||
{
|
||||
dev->user.usr_dummy = dummy_n ? 1 : 0;
|
||||
dev->user1.usr_dummy_cyclelen = dummy_n - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set D/Q output level during dummy phase
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param out_en whether to enable IO output for dummy phase
|
||||
* @param out_level dummy output level
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_dummy_out(spi_dev_t *dev, uint32_t out_en, uint32_t out_lev)
|
||||
{
|
||||
dev->ctrl.dummy_out = out_en;
|
||||
dev->ctrl.q_pol = out_lev;
|
||||
dev->ctrl.d_pol = out_lev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extra hold time of CS after the clocks.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param hold_n Cycles of clocks before CS is inactive
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
|
||||
{
|
||||
dev->user1.cs_hold_time = hold_n - 1;
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void gpspi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->user1.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate spi_flash clock frequency division parameters for register.
|
||||
*
|
||||
* @param clkdiv frequency division factor
|
||||
*
|
||||
* @return Register setting for the given clock division factor.
|
||||
*/
|
||||
static inline uint32_t gpspi_flash_ll_calculate_clock_reg(uint8_t clkdiv)
|
||||
{
|
||||
uint32_t div_parameter;
|
||||
// See comments of `clock` in `spi_struct.h`
|
||||
if (clkdiv == 1) {
|
||||
div_parameter = (1 << 31);
|
||||
} else {
|
||||
div_parameter = ((clkdiv - 1) | (((clkdiv/2 - 1) & 0xff) << 6 ) | (((clkdiv - 1) & 0xff) << 12));
|
||||
}
|
||||
return div_parameter;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
327
components/hal/esp32p4/include/hal/lpwdt_ll.h
Normal file
327
components/hal/esp32p4/include/hal/lpwdt_ll.h
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for Timer Group register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "hal/misc.h"
|
||||
#include "hal/wdt_types.h"
|
||||
#include "soc/rtc_cntl_periph.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_assert.h"
|
||||
|
||||
#include "esp32p4/rom/ets_sys.h"
|
||||
|
||||
// TODO: IDF-7539
|
||||
// //Type check wdt_stage_action_t
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == RTC_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == RTC_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == RTC_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == RTC_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_RTC == RTC_WDT_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// //Type check wdt_reset_sig_length_t
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == RTC_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == RTC_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == RTC_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == RTC_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == RTC_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == RTC_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == RTC_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == RTC_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
|
||||
/**
|
||||
* @brief Enable the RWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_enable(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the RWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @note This function does not disable the flashboot mode. Therefore, given that
|
||||
* the MWDT is disabled using this function, a timeout can still occur
|
||||
* if the flashboot mode is simultaneously enabled.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_disable(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_en = 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the RWDT is enabled
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @return True if RTC WDT is enabled
|
||||
*/
|
||||
FORCE_INLINE_ATTR bool lpwdt_ll_check_if_enabled(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// return (hw->wdtconfig0.wdt_en) ? true : false;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure a particular stage of the RWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param stage Which stage to configure
|
||||
* @param timeout Number of timer ticks for the stage to timeout (see note).
|
||||
* @param behavior What action to take when the stage times out
|
||||
*
|
||||
* @note The value of of RWDT stage 0 timeout register is special, in
|
||||
* that an implicit multiplier is applied to that value to produce
|
||||
* and effective timeout tick value. The multiplier is dependent
|
||||
* on an EFuse value. Therefore, when configuring stage 0, the valid
|
||||
* values for the timeout argument are:
|
||||
* - If Efuse value is 0, any even number between [2,2*UINT32_MAX]
|
||||
* - If Efuse value is 1, any multiple of 4 between [4,4*UINT32_MAX]
|
||||
* - If Efuse value is 2, any multiple of 8 between [8,8*UINT32_MAX]
|
||||
* - If Efuse value is 3, any multiple of 16 between [16,16*UINT32_MAX]
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_config_stage(lp_wdt_dev_t *hw, wdt_stage_t stage, uint32_t timeout_ticks, wdt_stage_action_t behavior)
|
||||
{
|
||||
// switch (stage) {
|
||||
// case WDT_STAGE0:
|
||||
// hw->wdtconfig0.wdt_stg0 = behavior;
|
||||
// //Account of implicty multiplier applied to stage 0 timeout tick config value
|
||||
// hw->wdtconfig1 = timeout_ticks >> (1 + REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_WDT_DELAY_SEL));
|
||||
// break;
|
||||
// case WDT_STAGE1:
|
||||
// hw->wdtconfig0.wdt_stg1 = behavior;
|
||||
// hw->wdtconfig2 = timeout_ticks;
|
||||
// break;
|
||||
// case WDT_STAGE2:
|
||||
// hw->wdtconfig0.wdt_stg2 = behavior;
|
||||
// hw->wdtconfig3 = timeout_ticks;
|
||||
// break;
|
||||
// case WDT_STAGE3:
|
||||
// hw->wdtconfig0.wdt_stg3 = behavior;
|
||||
// hw->wdtconfig4 = timeout_ticks;
|
||||
// break;
|
||||
// default:
|
||||
// abort();
|
||||
// }
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a particular stage of the RWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param stage Which stage to disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_disable_stage(lp_wdt_dev_t *hw, wdt_stage_t stage)
|
||||
{
|
||||
// switch (stage) {
|
||||
// case WDT_STAGE0:
|
||||
// hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// case WDT_STAGE1:
|
||||
// hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// case WDT_STAGE2:
|
||||
// hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// case WDT_STAGE3:
|
||||
// hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// default:
|
||||
// abort();
|
||||
// }
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the length of the CPU reset action
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param length Length of CPU reset signal
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_cpu_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_cpu_reset_length = length;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the length of the system reset action
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param length Length of system reset signal
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_sys_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_sys_reset_length = length;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable the RWDT flashboot mode.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param enable True to enable RWDT flashboot mode, false to disable RWDT flashboot mode.
|
||||
*
|
||||
* @note Flashboot mode is independent and can trigger a WDT timeout event if the
|
||||
* WDT's enable bit is set to 0. Flashboot mode for RWDT is automatically enabled
|
||||
* on flashboot, and should be disabled by software when flashbooting completes.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_flashboot_en(lp_wdt_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable the CPU0 to be reset on WDT_STAGE_ACTION_RESET_CPU
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param enable True to enable CPU0 to be reset, false to disable.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_procpu_reset_en(lp_wdt_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_chip_reset_en = (enable) ? 1 : 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable the CPU1 to be reset on WDT_STAGE_ACTION_RESET_CPU
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param enable True to enable CPU1 to be reset, false to disable.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_appcpu_reset_en(lp_wdt_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_chip_reset_en = (enable) ? 1 : 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable the RWDT pause during sleep functionality
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_pause_in_sleep_en(lp_wdt_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_pause_in_slp = (enable) ? 1 : 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable chip reset on RWDT timeout.
|
||||
*
|
||||
* A chip reset also resets the analog portion of the chip. It will appear as a
|
||||
* POWERON reset rather than an RTC reset.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param enable True to enable, false to disable.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_en(lp_wdt_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->wdtconfig0.wdt_chip_reset_en = (enable) ? 1 : 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set width of chip reset signal
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param width Width of chip reset signal in terms of number of RTC_SLOW_CLK cycles
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_width(lp_wdt_dev_t *hw, uint32_t width)
|
||||
{
|
||||
// HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdtconfig0, wdt_chip_reset_width, width);
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Feed the RWDT
|
||||
*
|
||||
* Resets the current timer count and current stage.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_feed(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// hw->wdtfeed.wdt_feed = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable write protection of the RWDT registers
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_write_protect_enable(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// hw->wdtwprotect = 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable write protection of the RWDT registers
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_write_protect_disable(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// hw->wdtwprotect = TIMG_WDT_WKEY_VALUE;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the RWDT interrupt.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param enable True to enable RWDT interrupt, false to disable.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_set_intr_enable(lp_wdt_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->int_ena.wdt = (enable) ? 1 : 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the RWDT interrupt has been triggered
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @return True if the RWDT interrupt was triggered
|
||||
*/
|
||||
FORCE_INLINE_ATTR bool lpwdt_ll_check_intr_status(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// return (hw->int_swd_st.wdt) ? true : false;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the RWDT interrupt status.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void lpwdt_ll_clear_intr_status(lp_wdt_dev_t *hw)
|
||||
{
|
||||
// hw->int_clr.wdt = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
450
components/hal/esp32p4/include/hal/mmu_ll.h
Normal file
450
components/hal/esp32p4/include/hal/mmu_ll.h
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for MMU register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/spi_mem_c_reg.h"
|
||||
#include "soc/spi_mem_s_reg.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/mmu_types.h"
|
||||
#include "hal/efuse_ll.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Convert MMU virtual address to linear address
|
||||
*
|
||||
* @param vaddr virtual address
|
||||
*
|
||||
* @return linear address
|
||||
*/
|
||||
static inline uint32_t mmu_ll_vaddr_to_laddr(uint32_t vaddr)
|
||||
{
|
||||
return vaddr & SOC_MMU_LINEAR_FLASH_ADDR_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert MMU linear address to virtual address
|
||||
*
|
||||
* @param laddr linear address
|
||||
* @param vaddr_type virtual address type, could be instruction type or data type. See `mmu_vaddr_t`
|
||||
*
|
||||
* @return virtual address
|
||||
*/
|
||||
static inline uint32_t mmu_ll_laddr_to_vaddr(uint32_t laddr, mmu_vaddr_t vaddr_type)
|
||||
{
|
||||
uint32_t raw_laddr = (laddr & ~SOC_MMU_MEM_PHYSICAL_LINEAR_CAP);
|
||||
uint32_t vaddr_base = 0;
|
||||
if (vaddr_type == MMU_VADDR_FLASH) {
|
||||
vaddr_base = SOC_MMU_FLASH_VADDR_BASE;
|
||||
} else {
|
||||
vaddr_base = SOC_MMU_PSRAM_VADDR_BASE;
|
||||
}
|
||||
|
||||
return vaddr_base | raw_laddr;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline bool mmu_ll_cache_encryption_enabled(void)
|
||||
{
|
||||
unsigned cnt = efuse_ll_get_flash_crypt_cnt();
|
||||
// 3 bits wide, any odd number - 1 or 3 - bits set means encryption is on
|
||||
cnt = ((cnt >> 2) ^ (cnt >> 1) ^ cnt) & 0x1;
|
||||
return (cnt == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MMU page size
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
*
|
||||
* @return MMU page size code
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline mmu_page_size_t mmu_ll_get_page_size(uint32_t mmu_id)
|
||||
{
|
||||
(void)mmu_id;
|
||||
return MMU_PAGE_64KB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set MMU page size
|
||||
*
|
||||
* @param size MMU page size
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size)
|
||||
{
|
||||
(void)mmu_id;
|
||||
(void)size;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the external memory vaddr region is valid
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param vaddr_start start of the virtual address
|
||||
* @param len length, in bytes
|
||||
* @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t`
|
||||
*
|
||||
* @return
|
||||
* True for valid
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t vaddr_start, uint32_t len, mmu_vaddr_t type)
|
||||
{
|
||||
(void)mmu_id;
|
||||
(void)type;
|
||||
uint32_t vaddr_end = vaddr_start + len;
|
||||
return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the paddr region is valid
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param paddr_start start of the physical address
|
||||
* @param len length, in bytes
|
||||
*
|
||||
* @return
|
||||
* True for valid
|
||||
*/
|
||||
static inline bool mmu_ll_check_valid_paddr_region(uint32_t mmu_id, uint32_t paddr_start, uint32_t len)
|
||||
{
|
||||
(void)mmu_id;
|
||||
return (paddr_start < (mmu_ll_get_page_size(mmu_id) * MMU_MAX_PADDR_PAGE_NUM)) &&
|
||||
(len < (mmu_ll_get_page_size(mmu_id) * MMU_MAX_PADDR_PAGE_NUM)) &&
|
||||
((paddr_start + len - 1) < (mmu_ll_get_page_size(mmu_id) * MMU_MAX_PADDR_PAGE_NUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* To get the MMU table entry id to be mapped
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param vaddr virtual address to be mapped
|
||||
*
|
||||
* @return
|
||||
* MMU table entry id
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t mmu_ll_get_entry_id(uint32_t mmu_id, uint32_t vaddr)
|
||||
{
|
||||
(void)mmu_id;
|
||||
mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
|
||||
uint32_t shift_code = 0;
|
||||
switch (page_size) {
|
||||
case MMU_PAGE_64KB:
|
||||
shift_code = 16;
|
||||
break;
|
||||
case MMU_PAGE_32KB:
|
||||
shift_code = 15;
|
||||
break;
|
||||
case MMU_PAGE_16KB:
|
||||
shift_code = 14;
|
||||
break;
|
||||
case MMU_PAGE_8KB:
|
||||
shift_code = 13;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(shift_code);
|
||||
}
|
||||
return ((vaddr & MMU_VADDR_MASK) >> shift_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the paddr to be mappable
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param paddr physical address to be mapped
|
||||
* @param target paddr memory target, not used
|
||||
*
|
||||
* @return
|
||||
* mmu_val - paddr in MMU table supported format
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t mmu_ll_format_paddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target)
|
||||
{
|
||||
(void)mmu_id;
|
||||
(void)target;
|
||||
mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
|
||||
uint32_t shift_code = 0;
|
||||
switch (page_size) {
|
||||
case MMU_PAGE_64KB:
|
||||
shift_code = 16;
|
||||
break;
|
||||
case MMU_PAGE_32KB:
|
||||
shift_code = 15;
|
||||
break;
|
||||
case MMU_PAGE_16KB:
|
||||
shift_code = 14;
|
||||
break;
|
||||
case MMU_PAGE_8KB:
|
||||
shift_code = 13;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(shift_code);
|
||||
}
|
||||
return paddr >> shift_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to the MMU table to map the virtual memory and the physical memory
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry ID
|
||||
* @param mmu_val Value to be set into an MMU entry, for physical address
|
||||
* @param target MMU target physical memory.
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32_t mmu_val, mmu_target_t target)
|
||||
{
|
||||
(void)mmu_id;
|
||||
(void)target;
|
||||
uint32_t index_reg, content_reg, sensitive, invalid_mask;
|
||||
if (mmu_id == 0) { // flash mmu
|
||||
index_reg = SPI_MEM_C_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_C_MMU_ITEM_CONTENT_REG;
|
||||
sensitive = MMU_SENSITIVE;
|
||||
invalid_mask = MMU_INVALID_MASK;
|
||||
} else { // psram mmu
|
||||
index_reg = SPI_MEM_S_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_S_MMU_ITEM_CONTENT_REG;
|
||||
sensitive = DMMU_SENSITIVE;
|
||||
invalid_mask = DMMU_INVALID_MASK;
|
||||
mmu_val |= MMU_PSRAM_ACCESS_SPIRAM;
|
||||
|
||||
}
|
||||
uint32_t mmu_raw_value;
|
||||
if (mmu_ll_cache_encryption_enabled()) {
|
||||
mmu_val |= sensitive;
|
||||
}
|
||||
/* Note: for ESP32-P4, invert invalid bit for compatible with upper-layer software */
|
||||
mmu_raw_value = mmu_val ^ invalid_mask;
|
||||
REG_WRITE(index_reg, entry_id);
|
||||
REG_WRITE(content_reg, mmu_raw_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the raw value from MMU table
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry ID
|
||||
* @param mmu_val Value to be read from MMU table
|
||||
*/
|
||||
__attribute__((always_inline)) static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
(void)mmu_id;
|
||||
uint32_t mmu_raw_value;
|
||||
uint32_t ret;
|
||||
uint32_t index_reg, content_reg, sensitive, invalid_mask;
|
||||
if (mmu_id == 0) { // flash mmu
|
||||
index_reg = SPI_MEM_C_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_C_MMU_ITEM_CONTENT_REG;
|
||||
sensitive = MMU_SENSITIVE;
|
||||
invalid_mask = MMU_INVALID_MASK;
|
||||
} else { // psram mmu
|
||||
index_reg = SPI_MEM_S_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_S_MMU_ITEM_CONTENT_REG;
|
||||
sensitive = DMMU_SENSITIVE;
|
||||
invalid_mask = DMMU_INVALID_MASK;
|
||||
}
|
||||
REG_WRITE(index_reg, entry_id);
|
||||
mmu_raw_value = REG_READ(content_reg);
|
||||
if (mmu_ll_cache_encryption_enabled()) {
|
||||
mmu_raw_value &= ~sensitive;
|
||||
}
|
||||
/* Note: for ESP32-P4, invert invalid bit for compatible with upper-layer software */
|
||||
ret = mmu_raw_value ^ invalid_mask;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set MMU table entry as invalid
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void mmu_ll_set_entry_invalid(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
uint32_t index_reg, content_reg;
|
||||
if (mmu_id == 0) { // flash mmu
|
||||
index_reg = SPI_MEM_C_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_C_MMU_ITEM_CONTENT_REG;
|
||||
} else { // psram mmu
|
||||
index_reg = SPI_MEM_S_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_S_MMU_ITEM_CONTENT_REG;
|
||||
}
|
||||
REG_WRITE(index_reg, entry_id);
|
||||
REG_WRITE(content_reg, MMU_INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmap all the items in the MMU table
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void mmu_ll_unmap_all(uint32_t mmu_id)
|
||||
{
|
||||
for (int i = 0; i < MMU_ENTRY_NUM; i++) {
|
||||
mmu_ll_set_entry_invalid(mmu_id, i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check MMU table entry value is valid
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry ID
|
||||
*
|
||||
* @return Ture for MMU entry is valid; False for invalid
|
||||
*/
|
||||
static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
uint32_t mmu_raw_value;
|
||||
uint32_t index_reg, content_reg, invalid_mask;
|
||||
if (mmu_id == 0) { // flash mmu
|
||||
index_reg = SPI_MEM_C_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_C_MMU_ITEM_CONTENT_REG;
|
||||
invalid_mask = MMU_INVALID_MASK;
|
||||
} else { // psram mmu
|
||||
index_reg = SPI_MEM_S_MMU_ITEM_INDEX_REG;
|
||||
content_reg = SPI_MEM_S_MMU_ITEM_CONTENT_REG;
|
||||
invalid_mask = DMMU_INVALID_MASK;
|
||||
}
|
||||
REG_WRITE(index_reg, entry_id);
|
||||
mmu_raw_value = REG_READ(content_reg);
|
||||
/* Note: for ESP32-P4, the invalid-bit of MMU: 0 for invalid, 1 for valid */
|
||||
return (mmu_raw_value & invalid_mask) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MMU table entry target
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry ID
|
||||
*
|
||||
* @return Target, see `mmu_target_t`
|
||||
*/
|
||||
static inline mmu_target_t mmu_ll_get_entry_target(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
if (mmu_id == 0)
|
||||
return MMU_TARGET_FLASH0;
|
||||
else
|
||||
return MMU_TARGET_PSRAM0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert MMU entry ID to paddr base
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry ID
|
||||
*
|
||||
* @return paddr base
|
||||
*/
|
||||
static inline uint32_t mmu_ll_entry_id_to_paddr_base(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
(void)mmu_id;
|
||||
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
|
||||
|
||||
mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
|
||||
uint32_t shift_code = 0;
|
||||
switch (page_size) {
|
||||
case MMU_PAGE_64KB:
|
||||
shift_code = 16;
|
||||
break;
|
||||
case MMU_PAGE_32KB:
|
||||
shift_code = 15;
|
||||
break;
|
||||
case MMU_PAGE_16KB:
|
||||
shift_code = 14;
|
||||
break;
|
||||
case MMU_PAGE_8KB:
|
||||
shift_code = 13;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(shift_code);
|
||||
}
|
||||
if (mmu_id == 0) {
|
||||
REG_WRITE(SPI_MEM_C_MMU_ITEM_INDEX_REG, entry_id);
|
||||
return (REG_READ(SPI_MEM_C_MMU_ITEM_CONTENT_REG) & MMU_VALID_VAL_MASK) << shift_code;
|
||||
} else {
|
||||
REG_WRITE(SPI_MEM_S_MMU_ITEM_INDEX_REG, entry_id);
|
||||
return (REG_READ(SPI_MEM_S_MMU_ITEM_CONTENT_REG) & MMU_VALID_VAL_MASK) << shift_code;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the MMU table entry ID based on table map value
|
||||
* @note This function can only find the first match entry ID. However it is possible that a physical address
|
||||
* is mapped to multiple virtual addresses
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param mmu_val map value to be read from MMU table standing for paddr
|
||||
* @param target physical memory target, see `mmu_target_t`
|
||||
*
|
||||
* @return MMU entry ID, -1 for invalid
|
||||
*/
|
||||
static inline int mmu_ll_find_entry_id_based_on_map_value(uint32_t mmu_id, uint32_t mmu_val, mmu_target_t target)
|
||||
{
|
||||
//TODO, should check PSRAM as well?
|
||||
(void)mmu_id;
|
||||
for (int i = 0; i < MMU_ENTRY_NUM; i++) {
|
||||
if (mmu_ll_check_entry_valid(mmu_id, i)) {
|
||||
if (mmu_ll_get_entry_target(mmu_id, i) == target) {
|
||||
REG_WRITE(SPI_MEM_C_MMU_ITEM_INDEX_REG, i);
|
||||
if ((REG_READ(SPI_MEM_C_MMU_ITEM_CONTENT_REG) & MMU_VALID_VAL_MASK) == mmu_val) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert MMU entry ID to vaddr base
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry ID
|
||||
* @param type virtual address type, could be instruction type or data type. See `mmu_vaddr_t`
|
||||
*/
|
||||
static inline uint32_t mmu_ll_entry_id_to_vaddr_base(uint32_t mmu_id, uint32_t entry_id, mmu_vaddr_t type)
|
||||
{
|
||||
(void)mmu_id;
|
||||
mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
|
||||
uint32_t shift_code = 0;
|
||||
|
||||
switch (page_size) {
|
||||
case MMU_PAGE_64KB:
|
||||
shift_code = 16;
|
||||
break;
|
||||
case MMU_PAGE_32KB:
|
||||
shift_code = 15;
|
||||
break;
|
||||
case MMU_PAGE_16KB:
|
||||
shift_code = 14;
|
||||
break;
|
||||
case MMU_PAGE_8KB:
|
||||
shift_code = 13;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(shift_code);
|
||||
}
|
||||
uint32_t laddr = entry_id << shift_code;
|
||||
return mmu_ll_laddr_to_vaddr(laddr, type);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
46
components/hal/esp32p4/include/hal/mpu_ll.h
Normal file
46
components/hal/esp32p4/include/hal/mpu_ll.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO: IDF-7542
|
||||
/* Copied from C3 */
|
||||
|
||||
static inline uint32_t mpu_ll_id_to_addr(unsigned id)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static inline void mpu_ll_set_region_rw(uint32_t addr)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static inline void mpu_ll_set_region_rwx(uint32_t addr)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static inline void mpu_ll_set_region_x(uint32_t addr)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
static inline void mpu_ll_set_region_illegal(uint32_t addr)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
296
components/hal/esp32p4/include/hal/mwdt_ll.h
Normal file
296
components/hal/esp32p4/include/hal/mwdt_ll.h
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for Timer Group register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/timer_periph.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "hal/wdt_types.h"
|
||||
#include "hal/assert.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_assert.h"
|
||||
#include "hal/misc.h"
|
||||
|
||||
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
|
||||
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
|
||||
|
||||
|
||||
//TODO: IDF-6516
|
||||
// //Type check wdt_stage_action_t
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == TIMG_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == TIMG_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
|
||||
// //Type check wdt_reset_sig_length_t
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == TIMG_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == TIMG_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == TIMG_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == TIMG_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == TIMG_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == TIMG_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == TIMG_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
|
||||
|
||||
/**
|
||||
* @brief Enable the MWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
|
||||
{
|
||||
// hw->wdt_config0.en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the MWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @note This function does not disable the flashboot mode. Therefore, given that
|
||||
* the MWDT is disabled using this function, a timeout can still occur
|
||||
* if the flashboot mode is simultaneously enabled.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
|
||||
{
|
||||
// hw->wdt_config0.en = 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the MWDT is enabled
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @return True if the MWDT is enabled, false otherwise
|
||||
*/
|
||||
FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
|
||||
{
|
||||
// return (hw->wdt_config0.en) ? true : false;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure a particular stage of the MWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param stage Which stage to configure
|
||||
* @param timeout Number of timer ticks for the stage to timeout
|
||||
* @param behavior What action to take when the stage times out
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior)
|
||||
{
|
||||
// switch (stage) {
|
||||
// case WDT_STAGE0:
|
||||
// hw->wdt_config0.stg0 = behavior;
|
||||
// hw->wdt_config2 = timeout;
|
||||
// break;
|
||||
// case WDT_STAGE1:
|
||||
// hw->wdt_config0.stg1 = behavior;
|
||||
// hw->wdt_config3 = timeout;
|
||||
// break;
|
||||
// case WDT_STAGE2:
|
||||
// hw->wdt_config0.stg2 = behavior;
|
||||
// hw->wdt_config4 = timeout;
|
||||
// break;
|
||||
// case WDT_STAGE3:
|
||||
// hw->wdt_config0.stg3 = behavior;
|
||||
// hw->wdt_config5 = timeout;
|
||||
// break;
|
||||
// default:
|
||||
// HAL_ASSERT(false && "unsupported WDT stage");
|
||||
// break;
|
||||
// }
|
||||
// //Config registers are updated asynchronously
|
||||
// //hw->wdt_config0.wdt_conf_update_en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a particular stage of the MWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param stage Which stage to disable
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
|
||||
{
|
||||
// switch (stage) {
|
||||
// case WDT_STAGE0:
|
||||
// hw->wdt_config0.stg0 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// case WDT_STAGE1:
|
||||
// hw->wdt_config0.stg1 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// case WDT_STAGE2:
|
||||
// hw->wdt_config0.stg2 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// case WDT_STAGE3:
|
||||
// hw->wdt_config0.stg3 = WDT_STAGE_ACTION_OFF;
|
||||
// break;
|
||||
// default:
|
||||
// HAL_ASSERT(false && "unsupported WDT stage");
|
||||
// break;
|
||||
// }
|
||||
// //Config registers are updated asynchronously
|
||||
// //hw->wdt_config0.wdt_conf_update_en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the length of the CPU reset action
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param length Length of CPU reset signal
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
|
||||
{
|
||||
// hw->wdt_config0.cpu_reset_length = length;
|
||||
// //Config registers are updated asynchronously
|
||||
// //hw->wdt_config0.wdt_conf_update_en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the length of the system reset action
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param length Length of system reset signal
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
|
||||
{
|
||||
// hw->wdt_config0.sys_reset_length = length;
|
||||
// //Config registers are updated asynchronously
|
||||
// //hw->wdt_config0.wdt_conf_update_en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable the MWDT flashboot mode.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable True to enable WDT flashboot mode, false to disable WDT flashboot mode.
|
||||
*
|
||||
* @note Flashboot mode is independent and can trigger a WDT timeout event if the
|
||||
* WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled
|
||||
* on flashboot, and should be disabled by software when flashbooting completes.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0;
|
||||
// //Config registers are updated asynchronously
|
||||
// //hw->wdt_config0.wdt_conf_update_en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock prescaler of the MWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
* @param prescaler Prescaler value between 1 to 65535
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
|
||||
{
|
||||
// // In case the compiler optimise a 32bit instruction (e.g. s32i) into 8/16bit instruction (e.g. s8i, which is not allowed to access a register)
|
||||
// // We take care of the "read-modify-write" procedure by ourselves.
|
||||
// HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdt_config1, clk_prescale, prescaler);
|
||||
// //Config registers are updated asynchronously
|
||||
// //hw->wdt_config0.wdt_conf_update_en = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Feed the MWDT
|
||||
*
|
||||
* Resets the current timer count and current stage.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
|
||||
{
|
||||
// hw->wdt_feed = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable write protection of the MWDT registers
|
||||
*
|
||||
* Locking the MWDT will prevent any of the MWDT's registers from being modified
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
|
||||
{
|
||||
// hw->wdt_wprotect = 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable write protection of the MWDT registers
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
|
||||
{
|
||||
// hw->wdt_wprotect = TIMG_WDT_WKEY_VALUE;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the MWDT interrupt status.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
|
||||
{
|
||||
// hw->int_clr.wdt = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the interrupt enable bit for the MWDT interrupt.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable Whether to enable the MWDT interrupt
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
|
||||
{
|
||||
// hw->int_ena.wdt = (enable) ? 1 : 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for the MWDT.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_src Clock source
|
||||
*/
|
||||
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable MWDT module clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
67
components/hal/esp32p4/include/hal/regi2c_ctrl_ll.h
Normal file
67
components/hal/esp32p4/include/hal/regi2c_ctrl_ll.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/regi2c_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO: IDF-7526
|
||||
|
||||
/**
|
||||
* @brief Start BBPLL self-calibration
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
|
||||
{
|
||||
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop BBPLL self-calibration
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void)
|
||||
{
|
||||
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
|
||||
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether BBPLL calibration is done
|
||||
*
|
||||
* @return True if calibration is done; otherwise false
|
||||
*/
|
||||
static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void)
|
||||
{
|
||||
return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register
|
||||
*/
|
||||
static inline void regi2c_ctrl_ll_i2c_saradc_enable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
|
||||
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the I2C internal bus to do I2C read/write operation to the SAR_ADC register
|
||||
*/
|
||||
static inline void regi2c_ctrl_ll_i2c_saradc_disable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PU);
|
||||
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PD);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
81
components/hal/esp32p4/include/hal/rwdt_ll.h
Normal file
81
components/hal/esp32p4/include/hal/rwdt_ll.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// The LL layer for RTC(LP) watchdog register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hal/lpwdt_ll.h"
|
||||
|
||||
//TODO: IDF-7539
|
||||
typedef lp_wdt_dev_t rwdt_dev_t;
|
||||
|
||||
#define RWDT_DEV_GET() &LP_WDT
|
||||
|
||||
#define rwdt_ll_enable(hw) \
|
||||
lpwdt_ll_enable(hw)
|
||||
|
||||
#define rwdt_ll_disable(hw) \
|
||||
lpwdt_ll_disable(hw)
|
||||
|
||||
#define rwdt_ll_check_if_enabled(hw) \
|
||||
lpwdt_ll_check_if_enabled(hw)
|
||||
|
||||
#define rwdt_ll_config_stage(hw, stage, timeout_ticks, behavior) \
|
||||
lpwdt_ll_config_stage(hw, stage, timeout_ticks, behavior)
|
||||
|
||||
#define rwdt_ll_disable_stage(hw, stage) \
|
||||
lpwdt_ll_disable_stage(hw, stage)
|
||||
|
||||
#define rwdt_ll_set_cpu_reset_length(hw, length) \
|
||||
lpwdt_ll_set_cpu_reset_length(hw, length)
|
||||
|
||||
#define rwdt_ll_set_sys_reset_length(hw, length) \
|
||||
lpwdt_ll_set_sys_reset_length(hw, length)
|
||||
|
||||
#define rwdt_ll_set_flashboot_en(hw, enable) \
|
||||
lpwdt_ll_set_flashboot_en(hw, enable)
|
||||
|
||||
#define rwdt_ll_set_procpu_reset_en(hw, enable) \
|
||||
lpwdt_ll_set_procpu_reset_en(hw, enable)
|
||||
|
||||
#define rwdt_ll_set_appcpu_reset_en(hw, enable) \
|
||||
lpwdt_ll_set_appcpu_reset_en(hw, enable)
|
||||
|
||||
#define rwdt_ll_set_pause_in_sleep_en(hw, enable) \
|
||||
lpwdt_ll_set_pause_in_sleep_en(hw, enable)
|
||||
|
||||
#define rwdt_ll_set_chip_reset_en(hw, enable) \
|
||||
lpwdt_ll_set_chip_reset_en(hw, enable)
|
||||
|
||||
#define rwdt_ll_set_chip_reset_width(hw, width) \
|
||||
lpwdt_ll_set_chip_reset_width(hw, width)
|
||||
|
||||
#define rwdt_ll_feed(hw) \
|
||||
lpwdt_ll_feed(hw)
|
||||
|
||||
#define rwdt_ll_write_protect_enable(hw) \
|
||||
lpwdt_ll_write_protect_enable(hw)
|
||||
|
||||
#define rwdt_ll_write_protect_disable(hw) \
|
||||
lpwdt_ll_write_protect_disable(hw)
|
||||
|
||||
#define rwdt_ll_set_intr_enable(hw, enable) \
|
||||
lpwdt_ll_set_intr_enable(hw, enable)
|
||||
|
||||
#define rwdt_ll_check_intr_status(hw) \
|
||||
lpwdt_ll_check_intr_status(hw)
|
||||
|
||||
#define rwdt_ll_clear_intr_status(hw) \
|
||||
lpwdt_ll_clear_intr_status(hw)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
62
components/hal/esp32p4/include/hal/sar_ctrl_ll.h
Normal file
62
components/hal/esp32p4/include/hal/sar_ctrl_ll.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* SAR related peripherals are interdependent.
|
||||
* Related peripherals are:
|
||||
* - ADC
|
||||
* - PWDET
|
||||
*
|
||||
* All of above peripherals require SAR to work correctly.
|
||||
* As SAR has some registers that will influence above mentioned peripherals.
|
||||
* This file gives an abstraction for such registers
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO: IDF-7460
|
||||
#define PWDET_LL_SAR_POWER_FORCE_BIT BIT(24)
|
||||
#define PWDET_LL_SAR_POWER_CNTL_BIT BIT(23)
|
||||
|
||||
|
||||
typedef enum {
|
||||
SAR_CTRL_LL_POWER_FSM, //SAR power controlled by FSM
|
||||
SAR_CTRL_LL_POWER_ON, //SAR power on
|
||||
SAR_CTRL_LL_POWER_OFF, //SAR power off
|
||||
} sar_ctrl_ll_power_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
SAR power control
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Set SAR power mode when controlled by PWDET
|
||||
*
|
||||
* @param[in] mode See `sar_ctrl_ll_power_t`
|
||||
*/
|
||||
static inline void sar_ctrl_ll_set_power_mode_from_pwdet(sar_ctrl_ll_power_t mode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SAR power ctrl source
|
||||
*
|
||||
* @param[in] force set PWDET as SAR power ctrl source when force is true
|
||||
*/
|
||||
static inline void sar_ctrl_ll_force_power_ctrl_from_pwdet(bool force)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
153
components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h
Normal file
153
components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash Encryption.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "soc/hp_system_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/soc.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO: IDF-7545
|
||||
|
||||
/// Choose type of chip you want to encrypt manully
|
||||
typedef enum
|
||||
{
|
||||
FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip.
|
||||
PSRAM_ENCRYPTION_MANU = 1 ///!< Manually encrypt the psram chip.
|
||||
} flash_encrypt_ll_type_t;
|
||||
|
||||
/**
|
||||
* Enable the flash encryption function under spi boot mode and download boot mode.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_enable(void)
|
||||
{
|
||||
// REG_SET_BIT(HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
|
||||
// HP_SYSTEM_ENABLE_DOWNLOAD_MANUAL_ENCRYPT |
|
||||
// HP_SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT);
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the flash encryption mode.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_disable(void)
|
||||
{
|
||||
// REG_CLR_BIT(HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
|
||||
// HP_SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT);
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose type of chip you want to encrypt manully
|
||||
*
|
||||
* @param type The type of chip to be encrypted
|
||||
*
|
||||
* @note The hardware currently support flash encryption.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_type(flash_encrypt_ll_type_t type)
|
||||
{
|
||||
// Our hardware only support flash encryption
|
||||
HAL_ASSERT(type == FLASH_ENCRYPTION_MANU);
|
||||
REG_SET_FIELD(SPI_MEM_XTS_DESTINATION_REG(0), SPI_MEM_SPI_XTS_DESTINATION, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the data size of a single encryption.
|
||||
*
|
||||
* @param block_size Size of the desired block.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size)
|
||||
{
|
||||
// Desired block should not be larger than the block size.
|
||||
REG_SET_FIELD(SPI_MEM_XTS_LINESIZE_REG(0), SPI_MEM_SPI_XTS_LINESIZE, size >> 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save 32-bit piece of plaintext.
|
||||
*
|
||||
* @param address the address of written flash partition.
|
||||
* @param buffer Buffer to store the input data.
|
||||
* @param size Buffer size.
|
||||
*
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size)
|
||||
{
|
||||
uint32_t plaintext_offs = (address % 64);
|
||||
memcpy((void *)(SPI_MEM_XTS_PLAIN_BASE_REG(0) + plaintext_offs), buffer, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the flash address to XTS_AES physical address
|
||||
*
|
||||
* @param flash_addr flash address to write.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_address_save(uint32_t flash_addr)
|
||||
{
|
||||
REG_SET_FIELD(SPI_MEM_XTS_PHYSICAL_ADDRESS_REG(0), SPI_MEM_SPI_XTS_PHYSICAL_ADDRESS, flash_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start flash encryption
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_calculate_start(void)
|
||||
{
|
||||
REG_SET_FIELD(SPI_MEM_XTS_TRIGGER_REG(0), SPI_MEM_SPI_XTS_TRIGGER, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for flash encryption termination
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_calculate_wait_idle(void)
|
||||
{
|
||||
while(REG_GET_FIELD(SPI_MEM_XTS_STATE_REG(0), SPI_MEM_SPI_XTS_STATE) == 0x1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the flash encryption and make encrypted result accessible to SPI.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_done(void)
|
||||
{
|
||||
REG_SET_BIT(SPI_MEM_XTS_RELEASE_REG(0), SPI_MEM_SPI_XTS_RELEASE);
|
||||
while(REG_GET_FIELD(SPI_MEM_XTS_STATE_REG(0), SPI_MEM_SPI_XTS_STATE) != 0x3) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to destroy encrypted result
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_destroy(void)
|
||||
{
|
||||
REG_SET_BIT(SPI_MEM_XTS_DESTROY_REG(0), SPI_MEM_SPI_XTS_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if is qualified to encrypt the buffer
|
||||
*
|
||||
* @param address the address of written flash partition.
|
||||
* @param length Buffer size.
|
||||
*/
|
||||
static inline bool spi_flash_encrypt_ll_check(uint32_t address, uint32_t length)
|
||||
{
|
||||
return ((address % length) == 0) ? true : false;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
102
components/hal/esp32p4/include/hal/spi_flash_ll.h
Normal file
102
components/hal/esp32p4/include/hal/spi_flash_ll.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpspi_flash_ll.h"
|
||||
#include "spimem_flash_ll.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define spi_flash_ll_calculate_clock_reg(host_id, clock_div) (((host_id)<=SPI1_HOST) ? spimem_flash_ll_calculate_clock_reg(clock_div) \
|
||||
: gpspi_flash_ll_calculate_clock_reg(clock_div))
|
||||
|
||||
#define spi_flash_ll_get_source_clock_freq_mhz(host_id) (((host_id)<=SPI1_HOST) ? spimem_flash_ll_get_source_freq_mhz() : GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ)
|
||||
|
||||
#define spi_flash_ll_get_hw(host_id) (((host_id)<=SPI1_HOST ? (spi_dev_t*) spimem_flash_ll_get_hw(host_id) \
|
||||
: gpspi_flash_ll_get_hw(host_id)))
|
||||
|
||||
#define spi_flash_ll_hw_get_id(dev) ({int dev_id = spimem_flash_ll_hw_get_id(dev); \
|
||||
if (dev_id < 0) {\
|
||||
dev_id = gpspi_flash_ll_hw_get_id(dev);\
|
||||
}\
|
||||
dev_id; \
|
||||
})
|
||||
// Since ESP32-P4, WB_mode is available, we extend 8 bits to occupy `Continuous Read Mode` bits.
|
||||
#define SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS (8)
|
||||
|
||||
typedef union {
|
||||
gpspi_flash_ll_clock_reg_t gpspi;
|
||||
spimem_flash_ll_clock_reg_t spimem;
|
||||
} spi_flash_ll_clock_reg_t;
|
||||
|
||||
#ifdef GPSPI_BUILD
|
||||
#define spi_flash_ll_reset(dev) gpspi_flash_ll_reset((spi_dev_t*)dev)
|
||||
#define spi_flash_ll_cmd_is_done(dev) gpspi_flash_ll_cmd_is_done((spi_dev_t*)dev)
|
||||
#define spi_flash_ll_get_buffer_data(dev, buffer, read_len) gpspi_flash_ll_get_buffer_data((spi_dev_t*)dev, buffer, read_len)
|
||||
#define spi_flash_ll_set_buffer_data(dev, buffer, len) gpspi_flash_ll_set_buffer_data((spi_dev_t*)dev, buffer, len)
|
||||
#define spi_flash_ll_user_start(dev) gpspi_flash_ll_user_start((spi_dev_t*)dev)
|
||||
#define spi_flash_ll_host_idle(dev) gpspi_flash_ll_host_idle((spi_dev_t*)dev)
|
||||
#define spi_flash_ll_read_phase(dev) gpspi_flash_ll_read_phase((spi_dev_t*)dev)
|
||||
#define spi_flash_ll_set_cs_pin(dev, pin) gpspi_flash_ll_set_cs_pin((spi_dev_t*)dev, pin)
|
||||
#define spi_flash_ll_set_read_mode(dev, read_mode) gpspi_flash_ll_set_read_mode((spi_dev_t*)dev, read_mode)
|
||||
#define spi_flash_ll_set_clock(dev, clk) gpspi_flash_ll_set_clock((spi_dev_t*)dev, (gpspi_flash_ll_clock_reg_t*)clk)
|
||||
#define spi_flash_ll_set_miso_bitlen(dev, bitlen) gpspi_flash_ll_set_miso_bitlen((spi_dev_t*)dev, bitlen)
|
||||
#define spi_flash_ll_set_mosi_bitlen(dev, bitlen) gpspi_flash_ll_set_mosi_bitlen((spi_dev_t*)dev, bitlen)
|
||||
#define spi_flash_ll_set_command(dev, cmd, bitlen) gpspi_flash_ll_set_command((spi_dev_t*)dev, cmd, bitlen)
|
||||
#define spi_flash_ll_set_addr_bitlen(dev, bitlen) gpspi_flash_ll_set_addr_bitlen((spi_dev_t*)dev, bitlen)
|
||||
#define spi_flash_ll_get_addr_bitlen(dev) gpspi_flash_ll_get_addr_bitlen((spi_dev_t*)dev)
|
||||
#define spi_flash_ll_set_address(dev, addr) gpspi_flash_ll_set_address((spi_dev_t*)dev, addr)
|
||||
#define spi_flash_ll_set_usr_address(dev, addr, bitlen) gpspi_flash_ll_set_usr_address((spi_dev_t*)dev, addr, bitlen)
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) gpspi_flash_ll_set_dummy((spi_dev_t*)dev, dummy)
|
||||
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||
#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-C6*/ }
|
||||
#define spi_flash_ll_set_pe_bit(dev) gpspi_flash_ll_set_pe_bit((spi_dev_t*)dev)
|
||||
#else
|
||||
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_erase_chip(dev) spimem_flash_ll_erase_chip((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp)
|
||||
#define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len)
|
||||
#define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len)
|
||||
#define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len)
|
||||
#define spi_flash_ll_user_start(dev) spimem_flash_ll_user_start((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_host_idle(dev) spimem_flash_ll_host_idle((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_read_phase(dev) spimem_flash_ll_read_phase((spi_mem_dev_t*)dev)
|
||||
#define spi_flash_ll_set_cs_pin(dev, pin) spimem_flash_ll_set_cs_pin((spi_mem_dev_t*)dev, pin)
|
||||
#define spi_flash_ll_set_read_mode(dev, read_mode) spimem_flash_ll_set_read_mode((spi_mem_dev_t*)dev, read_mode)
|
||||
#define spi_flash_ll_set_clock(dev, clk) spimem_flash_ll_set_clock((spi_mem_dev_t*)dev, (spimem_flash_ll_clock_reg_t*)clk)
|
||||
#define spi_flash_ll_set_miso_bitlen(dev, bitlen) spimem_flash_ll_set_miso_bitlen((spi_mem_dev_t*)dev, bitlen)
|
||||
#define spi_flash_ll_set_mosi_bitlen(dev, bitlen) spimem_flash_ll_set_mosi_bitlen((spi_mem_dev_t*)dev, bitlen)
|
||||
#define spi_flash_ll_set_command(dev, cmd, bitlen) spimem_flash_ll_set_command((spi_mem_dev_t*)dev, cmd, bitlen)
|
||||
#define spi_flash_ll_set_addr_bitlen(dev, bitlen) spimem_flash_ll_set_addr_bitlen((spi_mem_dev_t*)dev, bitlen)
|
||||
#define spi_flash_ll_get_addr_bitlen(dev) spimem_flash_ll_get_addr_bitlen((spi_mem_dev_t*) dev)
|
||||
#define spi_flash_ll_set_address(dev, addr) spimem_flash_ll_set_address((spi_mem_dev_t*)dev, addr)
|
||||
#define spi_flash_ll_set_usr_address(dev, addr, bitlen) spimem_flash_ll_set_usr_address((spi_mem_dev_t*)dev, addr, bitlen)
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) spimem_flash_ll_set_dummy((spi_mem_dev_t*)dev, dummy)
|
||||
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||
#define spi_flash_ll_set_extra_address(dev, extra_addr) spimem_flash_ll_set_extra_address((spi_mem_dev_t*)dev, extra_addr)
|
||||
#define spi_flash_ll_set_pe_bit(dev) spimem_flash_ll_set_pe_bit((spi_mem_dev_t*)dev)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
658
components/hal/esp32p4/include/hal/spimem_flash_ll.h
Normal file
658
components/hal/esp32p4/include/hal/spimem_flash_ll.h
Normal file
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h> // For MIN/MAX
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "soc/spi_periph.h"
|
||||
#include "soc/spi_mem_struct.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/spi_types.h"
|
||||
#include "hal/spi_flash_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO: IDF-7499
|
||||
|
||||
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
||||
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
||||
|
||||
#define SPIMEM_FLASH_LL_SPI0_MAX_LOCK_VAL_MSPI_TICKS (0x1f)
|
||||
|
||||
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Control
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Reset peripheral registers before configuration and starting control
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_reset(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->user.val = 0;
|
||||
dev->ctrl.val = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the previous operation is done.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return true if last command is done, otherwise false.
|
||||
*/
|
||||
static inline bool spimem_flash_ll_cmd_is_done(const spi_mem_dev_t *dev)
|
||||
{
|
||||
return (dev->cmd.val == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase the flash chip.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_erase_chip(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->cmd.flash_ce = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase the sector, the address should be set by spimem_flash_ll_set_address.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_erase_sector(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->ctrl.val = 0;
|
||||
dev->cmd.flash_se = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase the block, the address should be set by spimem_flash_ll_set_address.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_erase_block(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->cmd.flash_be = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspend erase/program operation.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_suspend(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->flash_sus_ctrl.flash_pes = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume suspended erase/program operation.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_resume(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->flash_sus_ctrl.flash_per = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize auto suspend mode, and esp32c3 doesn't support disable auto-suspend.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param auto_sus Enable/disable Flash Auto-Suspend.
|
||||
*/
|
||||
static inline void spimem_flash_ll_auto_suspend_init(spi_mem_dev_t *dev, bool auto_sus)
|
||||
{
|
||||
dev->flash_sus_ctrl.flash_pes_en = auto_sus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize auto resume mode
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param auto_res Enable/Disable Flash Auto-Resume.
|
||||
*
|
||||
*/
|
||||
static inline void spimem_flash_ll_auto_resume_init(spi_mem_dev_t *dev, bool auto_res)
|
||||
{
|
||||
dev->flash_sus_ctrl.pes_per_en = auto_res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the flash suspend command, may vary from chips to chips.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param sus_cmd Flash suspend command.
|
||||
*
|
||||
*/
|
||||
static inline void spimem_flash_ll_suspend_cmd_setup(spi_mem_dev_t *dev, uint32_t sus_cmd)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_cmd, flash_pes_command, sus_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the flash resume command, may vary from chips to chips.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param res_cmd Flash resume command.
|
||||
*
|
||||
*/
|
||||
static inline void spimem_flash_ll_resume_cmd_setup(spi_mem_dev_t *dev, uint32_t res_cmd)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->sus_status, flash_per_command, res_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the flash read suspend status command, may vary from chips to chips.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param pesr_cmd Flash read suspend status command.
|
||||
*
|
||||
*/
|
||||
static inline void spimem_flash_ll_rd_sus_cmd_setup(spi_mem_dev_t *dev, uint32_t pesr_cmd)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_cmd, wait_pesr_command, pesr_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup to check SUS/SUS1/SUS2 to ensure the suspend status of flashs.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param sus_check_sus_en 1: enable, 0: disable.
|
||||
*
|
||||
*/
|
||||
static inline void spimem_flash_ll_sus_check_sus_setup(spi_mem_dev_t *dev, bool sus_check_sus_en)
|
||||
{
|
||||
dev->flash_sus_ctrl.sus_timeout_cnt = 5;
|
||||
dev->flash_sus_ctrl.pes_end_en = sus_check_sus_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup to check SUS/SUS1/SUS2 to ensure the resume status of flashs.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param sus_check_sus_en 1: enable, 0: disable.
|
||||
*
|
||||
*/
|
||||
static inline void spimem_flash_ll_res_check_sus_setup(spi_mem_dev_t *dev, bool res_check_sus_en)
|
||||
{
|
||||
dev->flash_sus_ctrl.sus_timeout_cnt = 5;
|
||||
dev->flash_sus_ctrl.per_end_en = res_check_sus_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set 8 bit command to read suspend status
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint32_t sus_conf)
|
||||
{
|
||||
dev->flash_sus_ctrl.frd_sus_2b = 0;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the delay after Suspend/Resume
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param dly_val delay time
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dly_val)
|
||||
{
|
||||
// dev->ctrl1.cs_hold_dly_res = dly_val;
|
||||
// dev->sus_status.pes_dly_128 = 1;
|
||||
// dev->sus_status.per_dly_128 = 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the cs hold delay time(used to set the minimum CS high time tSHSL)
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param cs_hold_delay cs hold delay time
|
||||
*/
|
||||
static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t cs_hold_delay)
|
||||
{
|
||||
// SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize auto wait idle mode
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param auto_waiti Enable/disable auto wait-idle function
|
||||
*/
|
||||
static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool auto_waiti)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05);
|
||||
dev->flash_sus_ctrl.flash_per_wait_en = auto_waiti;
|
||||
dev->flash_sus_ctrl.flash_pes_wait_en = auto_waiti;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the suspend status of erase or program operations.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return true if suspended, otherwise false.
|
||||
*/
|
||||
static inline bool spimem_flash_ll_sus_status(spi_mem_dev_t *dev)
|
||||
{
|
||||
return dev->sus_status.flash_sus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set lock for SPI0 so that spi0 can request new cache request after a cache transfer.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param lock_time Lock delay time
|
||||
*/
|
||||
static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, uint32_t lock_time)
|
||||
{
|
||||
// dev->sus_status.spi0_lock_en = 1;
|
||||
// SPIMEM0.fsm.cspi_lock_delay_time = lock_time;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get tsus unit values in SPI_CLK cycles
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @return uint32_t tsus unit values
|
||||
*/
|
||||
static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *dev)
|
||||
{
|
||||
// uint32_t tsus_unit = 0;
|
||||
// if (dev->sus_status.pes_dly_128 == 1) {
|
||||
// tsus_unit = 128;
|
||||
// } else {
|
||||
// tsus_unit = 4;
|
||||
// }
|
||||
// return tsus_unit;
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable write protection for the flash chip.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param wp true to enable the protection, false to disable (write enable).
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp)
|
||||
{
|
||||
if (wp) {
|
||||
dev->cmd.flash_wrdi = 1;
|
||||
} else {
|
||||
dev->cmd.flash_wren = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the read data from the buffer after ``spimem_flash_ll_read`` is done.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param buffer Buffer to hold the output data
|
||||
* @param read_len Length to get out of the buffer
|
||||
*/
|
||||
static inline void spimem_flash_ll_get_buffer_data(spi_mem_dev_t *dev, void *buffer, uint32_t read_len)
|
||||
{
|
||||
if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) {
|
||||
// If everything is word-aligned, do a faster memcpy
|
||||
memcpy(buffer, (void *)dev->data_buf, read_len);
|
||||
} else {
|
||||
// Otherwise, slow(er) path copies word by word
|
||||
int copy_len = read_len;
|
||||
for (int i = 0; i < (read_len + 3) / 4; i++) {
|
||||
int word_len = MIN(sizeof(uint32_t), copy_len);
|
||||
uint32_t word = dev->data_buf[i];
|
||||
memcpy(buffer, &word, word_len);
|
||||
buffer = (void *)((intptr_t)buffer + word_len);
|
||||
copy_len -= word_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data to be written in the data buffer.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param buffer Buffer holding the data
|
||||
* @param length Length of data in bytes.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_buffer_data(spi_mem_dev_t *dev, const void *buffer, uint32_t length)
|
||||
{
|
||||
// Load data registers, word at a time
|
||||
int num_words = (length + 3) / 4;
|
||||
for (int i = 0; i < num_words; i++) {
|
||||
uint32_t word = 0;
|
||||
uint32_t word_len = MIN(length, sizeof(word));
|
||||
memcpy(&word, buffer, word_len);
|
||||
dev->data_buf[i] = word;
|
||||
length -= word_len;
|
||||
buffer = (void *)((intptr_t)buffer + word_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Program a page of the flash chip. Call ``spimem_flash_ll_set_address`` before
|
||||
* this to set the address to program.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param buffer Buffer holding the data to program
|
||||
* @param length Length to program.
|
||||
*/
|
||||
static inline void spimem_flash_ll_program_page(spi_mem_dev_t *dev, const void *buffer, uint32_t length)
|
||||
{
|
||||
dev->user.usr_dummy = 0;
|
||||
spimem_flash_ll_set_buffer_data(dev, buffer, length);
|
||||
dev->cmd.flash_pp = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a user defined transaction. All phases, including command, address, dummy, and the data phases,
|
||||
* should be configured before this is called.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->cmd.usr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||
* This function is combined with `spimem_flash_ll_user_start`. The pe_bit will be cleared automatically once the operation done.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_pe_bit(spi_mem_dev_t *dev)
|
||||
{
|
||||
dev->cmd.flash_pe = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the host is idle to perform new commands.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return true if the host is idle, otherwise false
|
||||
*/
|
||||
static inline bool spimem_flash_ll_host_idle(const spi_mem_dev_t *dev)
|
||||
{
|
||||
return dev->cmd.mst_st == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set phases for user-defined transaction to read
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void spimem_flash_ll_read_phase(spi_mem_dev_t *dev)
|
||||
{
|
||||
typeof (dev->user) user = {
|
||||
.usr_command = 1,
|
||||
.usr_mosi = 0,
|
||||
.usr_miso = 1,
|
||||
.usr_addr = 1,
|
||||
};
|
||||
dev->user = user;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Select which pin to use for the flash
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param pin Pin ID to use, 0-2. Set to other values to disable all the CS pins.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_cs_pin(spi_mem_dev_t *dev, int pin)
|
||||
{
|
||||
dev->misc.cs0_dis = (pin == 0) ? 0 : 1;
|
||||
dev->misc.cs1_dis = (pin == 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read io mode.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param read_mode I/O mode to use in the following transactions.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_read_mode(spi_mem_dev_t *dev, esp_flash_io_mode_t read_mode)
|
||||
{
|
||||
typeof (dev->ctrl) ctrl = dev->ctrl;
|
||||
ctrl.val &= ~(SPI_MEM_FREAD_QIO_M | SPI_MEM_FREAD_QUAD_M | SPI_MEM_FREAD_DIO_M | SPI_MEM_FREAD_DUAL_M);
|
||||
ctrl.val |= SPI_MEM_FASTRD_MODE_M;
|
||||
switch (read_mode) {
|
||||
case SPI_FLASH_FASTRD:
|
||||
//the default option
|
||||
break;
|
||||
case SPI_FLASH_QIO:
|
||||
ctrl.fread_qio = 1;
|
||||
break;
|
||||
case SPI_FLASH_QOUT:
|
||||
ctrl.fread_quad = 1;
|
||||
break;
|
||||
case SPI_FLASH_DIO:
|
||||
ctrl.fread_dio = 1;
|
||||
break;
|
||||
case SPI_FLASH_DOUT:
|
||||
ctrl.fread_dual = 1;
|
||||
break;
|
||||
case SPI_FLASH_SLOWRD:
|
||||
ctrl.fastrd_mode = 0;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
dev->ctrl = ctrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set clock frequency to work at.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param clock_val pointer to the clock value to set
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_clock(spi_mem_dev_t *dev, spimem_flash_ll_clock_reg_t *clock_val)
|
||||
{
|
||||
dev->clock.val = *clock_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input length, in bits.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of input, in bits.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_miso_bitlen(spi_mem_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_miso = bitlen > 0;
|
||||
dev->miso_dlen.usr_miso_bit_len = bitlen ? (bitlen - 1) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output length, in bits (not including command, address and dummy
|
||||
* phases)
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of output, in bits.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_mosi = bitlen > 0;
|
||||
dev->mosi_dlen.usr_mosi_bit_len = bitlen ? (bitlen - 1) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the command.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param command Command to send
|
||||
* @param bitlen Length of the command
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_command = 1;
|
||||
typeof(dev->user2) user2 = {
|
||||
.usr_command_value = command,
|
||||
.usr_command_bitlen = (bitlen - 1),
|
||||
};
|
||||
dev->user2 = user2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address length that is set in register, in bits.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
*/
|
||||
static inline int spimem_flash_ll_get_addr_bitlen(spi_mem_dev_t *dev)
|
||||
{
|
||||
return dev->user.usr_addr ? dev->user1.usr_addr_bitlen + 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address length to send, in bits. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of the address, in bits
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user1.usr_addr_bitlen = (bitlen - 1);
|
||||
dev->user.usr_addr = bitlen ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extra address for bits M0-M7 in DIO/QIO mode.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param extra_addr extra address(M0-M7) to send.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr)
|
||||
{
|
||||
dev->cache_fctrl.usr_addr_4byte = 0;
|
||||
dev->rd_status.wb_mode = extra_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address to send. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param addr Address to send
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_address(spi_mem_dev_t *dev, uint32_t addr)
|
||||
{
|
||||
dev->addr = addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address to send in user mode. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param addr Address to send
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_usr_address(spi_mem_dev_t *dev, uint32_t addr, uint32_t bitlen)
|
||||
{
|
||||
(void)bitlen;
|
||||
spimem_flash_ll_set_address(dev, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length of dummy cycles.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param dummy_n Cycles of dummy phases
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_dummy(spi_mem_dev_t *dev, uint32_t dummy_n)
|
||||
{
|
||||
dev->user.usr_dummy = dummy_n ? 1 : 0;
|
||||
dev->user1.usr_dummy_cyclelen = dummy_n - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CS hold time.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param hold_n CS hold time config used by the host.
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_hold(spi_mem_dev_t *dev, uint32_t hold_n)
|
||||
{
|
||||
if (hold_n > 0) {
|
||||
dev->ctrl2.cs_hold_time = hold_n - 1;
|
||||
}
|
||||
dev->user.cs_hold = hold_n > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CS setup time
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param cs_setup_time CS setup time
|
||||
*/
|
||||
static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
if (cs_setup_time > 0) {
|
||||
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the spi flash source clock frequency. Used for calculating
|
||||
* the divider parameters.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return the frequency of spi flash clock source.(MHz)
|
||||
*/
|
||||
static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void)
|
||||
{
|
||||
return 80;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate spi_flash clock frequency division parameters for register.
|
||||
*
|
||||
* @param clkdiv frequency division factor
|
||||
*
|
||||
* @return Register setting for the given clock division factor.
|
||||
*/
|
||||
static inline uint32_t spimem_flash_ll_calculate_clock_reg(uint8_t clkdiv)
|
||||
{
|
||||
uint32_t div_parameter;
|
||||
// See comments of `clock` in `spi_mem_struct.h`
|
||||
if (clkdiv == 1) {
|
||||
div_parameter = (1 << 31);
|
||||
} else {
|
||||
div_parameter = ((clkdiv - 1) | (((clkdiv - 1) / 2 & 0xff) << 8 ) | (((clkdiv - 1) & 0xff) << 16));
|
||||
}
|
||||
return div_parameter;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
173
components/hal/esp32p4/include/hal/systimer_ll.h
Normal file
173
components/hal/esp32p4/include/hal/systimer_ll.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/systimer_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// All these functions get invoked either from ISR or HAL that linked to IRAM.
|
||||
// Always inline these functions even no gcc optimization is applied.
|
||||
|
||||
//TODO: IDF-7486
|
||||
|
||||
/******************* Clock *************************/
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_clock(systimer_dev_t *dev, bool en)
|
||||
{
|
||||
dev->conf.clk_en = en;
|
||||
}
|
||||
|
||||
// Set clock source: XTAL(default) or RC_FAST
|
||||
static inline void systimer_ll_set_clock_source(soc_periph_systimer_clk_src_t clk_src)
|
||||
{
|
||||
}
|
||||
|
||||
static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void)
|
||||
{
|
||||
return SYSTIMER_CLK_SRC_XTAL;
|
||||
}
|
||||
|
||||
/********************** ETM *****************************/
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_etm(systimer_dev_t *dev, bool en)
|
||||
{
|
||||
}
|
||||
|
||||
/******************* Counter *************************/
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_counter(systimer_dev_t *dev, uint32_t counter_id, bool en)
|
||||
{
|
||||
if (en) {
|
||||
dev->conf.val |= 1 << (30 - counter_id);
|
||||
} else {
|
||||
dev->conf.val &= ~(1 << (30 - counter_id));
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_counter_can_stall_by_cpu(systimer_dev_t *dev, uint32_t counter_id, uint32_t cpu_id, bool can)
|
||||
{
|
||||
if (can) {
|
||||
dev->conf.val |= 1 << ((28 - counter_id * 2) - cpu_id);
|
||||
} else {
|
||||
dev->conf.val &= ~(1 << ((28 - counter_id * 2) - cpu_id));
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_counter_snapshot(systimer_dev_t *dev, uint32_t counter_id)
|
||||
{
|
||||
dev->unit_op[counter_id].timer_unit_update = 1;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline bool systimer_ll_is_counter_value_valid(systimer_dev_t *dev, uint32_t counter_id)
|
||||
{
|
||||
return dev->unit_op[counter_id].timer_unit_value_valid;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_set_counter_value(systimer_dev_t *dev, uint32_t counter_id, uint64_t value)
|
||||
{
|
||||
dev->unit_load_val[counter_id].hi.timer_unit_load_hi = value >> 32;
|
||||
dev->unit_load_val[counter_id].lo.timer_unit_load_lo = value & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_low(systimer_dev_t *dev, uint32_t counter_id)
|
||||
{
|
||||
return dev->unit_val[counter_id].lo.timer_unit_value_lo;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_high(systimer_dev_t *dev, uint32_t counter_id)
|
||||
{
|
||||
return dev->unit_val[counter_id].hi.timer_unit_value_hi;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_apply_counter_value(systimer_dev_t *dev, uint32_t counter_id)
|
||||
{
|
||||
dev->unit_load[counter_id].val = 0x01;
|
||||
}
|
||||
|
||||
/******************* Alarm *************************/
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_target(systimer_dev_t *dev, uint32_t alarm_id, uint64_t value)
|
||||
{
|
||||
dev->target_val[alarm_id].hi.timer_target_hi = value >> 32;
|
||||
dev->target_val[alarm_id].lo.timer_target_lo = value & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint64_t systimer_ll_get_alarm_target(systimer_dev_t *dev, uint32_t alarm_id)
|
||||
{
|
||||
return ((uint64_t)(dev->target_val[alarm_id].hi.timer_target_hi) << 32) | dev->target_val[alarm_id].lo.timer_target_lo;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_connect_alarm_counter(systimer_dev_t *dev, uint32_t alarm_id, uint32_t counter_id)
|
||||
{
|
||||
dev->target_conf[alarm_id].target_timer_unit_sel = counter_id;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_oneshot(systimer_dev_t *dev, uint32_t alarm_id)
|
||||
{
|
||||
dev->target_conf[alarm_id].target_period_mode = 0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_period(systimer_dev_t *dev, uint32_t alarm_id)
|
||||
{
|
||||
dev->target_conf[alarm_id].target_period_mode = 1;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(systimer_dev_t *dev, uint32_t alarm_id, uint32_t period)
|
||||
{
|
||||
HAL_ASSERT(period < (1 << 26));
|
||||
dev->target_conf[alarm_id].target_period = period;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_alarm_period(systimer_dev_t *dev, uint32_t alarm_id)
|
||||
{
|
||||
return dev->target_conf[alarm_id].target_period;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
|
||||
{
|
||||
dev->comp_load[alarm_id].val = 0x01;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm(systimer_dev_t *dev, uint32_t alarm_id, bool en)
|
||||
{
|
||||
if (en) {
|
||||
dev->conf.val |= 1 << (24 - alarm_id);
|
||||
} else {
|
||||
dev->conf.val &= ~(1 << (24 - alarm_id));
|
||||
}
|
||||
}
|
||||
|
||||
/******************* Interrupt *************************/
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_int(systimer_dev_t *dev, uint32_t alarm_id, bool en)
|
||||
{
|
||||
if (en) {
|
||||
dev->int_ena.val |= 1 << alarm_id;
|
||||
} else {
|
||||
dev->int_ena.val &= ~(1 << alarm_id);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline bool systimer_ll_is_alarm_int_fired(systimer_dev_t *dev, uint32_t alarm_id)
|
||||
{
|
||||
return dev->int_st.val & (1 << alarm_id);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_clear_alarm_int(systimer_dev_t *dev, uint32_t alarm_id)
|
||||
{
|
||||
dev->int_clr.val |= 1 << alarm_id;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1051
components/hal/esp32p4/include/hal/uart_ll.h
Normal file
1051
components/hal/esp32p4/include/hal/uart_ll.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_bit_defs.h"
|
||||
#include "sdkconfig.h" //To remove, TODO: IDF-7509
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -18,6 +19,10 @@ typedef enum {
|
||||
MMU_MEM_CAP_WRITE = BIT(2),
|
||||
MMU_MEM_CAP_32BIT = BIT(3),
|
||||
MMU_MEM_CAP_8BIT = BIT(4),
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7509
|
||||
MMU_MEM_CAP_FLASH = BIT(5),
|
||||
MMU_MEM_CAP_PSRAM = BIT(5),
|
||||
#endif
|
||||
} mmu_mem_caps_t;
|
||||
|
||||
/**
|
||||
@@ -36,6 +41,10 @@ typedef enum {
|
||||
typedef enum {
|
||||
MMU_VADDR_DATA = BIT(0),
|
||||
MMU_VADDR_INSTRUCTION = BIT(1),
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7509
|
||||
MMU_VADDR_FLASH = BIT(2),
|
||||
MMU_VADDR_PSRAM = BIT(3),
|
||||
#endif
|
||||
} mmu_vaddr_t;
|
||||
|
||||
/**
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#include "esp32c6/rom/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
#include "esp32h2/rom/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#include "esp32p4/rom/sha.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -16,9 +16,16 @@
|
||||
|
||||
void mmu_hal_init(void)
|
||||
{
|
||||
#if CONFIG_ESP_ROM_RAM_APP_NEEDS_MMU_INIT
|
||||
//TODO: IDF-7509
|
||||
#if CONFIG_ESP_ROM_RAM_APP_NEEDS_MMU_INIT || CONFIG_IDF_TARGET_ESP32P4
|
||||
ROM_Boot_Cache_Init();
|
||||
#endif
|
||||
|
||||
//TODO: IDF-7509
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Invalidate_All(CACHE_MAP_L2_CACHE);
|
||||
#endif
|
||||
|
||||
mmu_ll_set_page_size(0, CONFIG_MMU_PAGE_SIZE);
|
||||
mmu_hal_unmap_all();
|
||||
}
|
||||
@@ -83,6 +90,11 @@ void mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr,
|
||||
uint32_t entry_id = 0;
|
||||
uint32_t mmu_val; //This is the physical address in the format that MMU supported
|
||||
|
||||
//TODO: IDF-7509
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
uint32_t vaddr_orig = vaddr;
|
||||
#endif
|
||||
|
||||
*out_len = mmu_hal_pages_to_bytes(mmu_id, page_num);
|
||||
mmu_val = mmu_ll_format_paddr(mmu_id, paddr, mem_type);
|
||||
|
||||
@@ -93,11 +105,22 @@ void mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr,
|
||||
mmu_val++;
|
||||
page_num--;
|
||||
}
|
||||
|
||||
//TODO: IDF-7509
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Invalidate_Addr(CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE, vaddr_orig, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
|
||||
{
|
||||
uint32_t page_size_in_bytes = mmu_hal_pages_to_bytes(mmu_id, 1);
|
||||
|
||||
//TODO: IDF-7509
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
uint32_t vaddr_orig = vaddr;
|
||||
#endif
|
||||
|
||||
HAL_ASSERT(vaddr % page_size_in_bytes == 0);
|
||||
HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(mmu_id, vaddr, len, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION));
|
||||
|
||||
@@ -109,6 +132,11 @@ void mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
|
||||
vaddr += page_size_in_bytes;
|
||||
page_num--;
|
||||
}
|
||||
|
||||
//TODO: IDF-7509
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Invalidate_Addr(CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE, vaddr_orig, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool mmu_hal_vaddr_to_paddr(uint32_t mmu_id, uint32_t vaddr, uint32_t *out_paddr, mmu_target_t *out_target)
|
||||
|
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/soc.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@@ -11,8 +11,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PERIPH_MSPI_MODULE = 0,
|
||||
PERIPH_DUALMSPI_MODULE,
|
||||
PERIPH_MSPI_FLASH_MODULE = 0,
|
||||
PERIPH_MSPI_PSRAM_MODULE,
|
||||
PERIPH_EMAC_MODULE,
|
||||
PERIPH_MIPI_DSI_MODULE,
|
||||
PERIPH_MIPI_CSI_MODULE,
|
||||
|
Reference in New Issue
Block a user