mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'refacor/remove_esp32h4_target_stage1' into 'master'
esp32h4: remove esp32h4 target (stage 1) See merge request espressif/esp-idf!23237
This commit is contained in:
commit
4fd62bce13
@ -215,14 +215,6 @@ build_pytest_examples_esp32c2:
|
||||
IDF_TARGET: esp32c2
|
||||
TEST_DIR: examples
|
||||
|
||||
build_pytest_examples_esp32h4:
|
||||
extends:
|
||||
- .build_pytest_no_jtag_template
|
||||
- .rules:build:example_test-esp32h4
|
||||
variables:
|
||||
IDF_TARGET: esp32h4
|
||||
TEST_DIR: examples
|
||||
|
||||
build_pytest_examples_jtag: # for all targets
|
||||
extends:
|
||||
- .build_pytest_jtag_template
|
||||
@ -649,14 +641,6 @@ build_examples_cmake_esp32c3:
|
||||
IDF_TARGET: esp32c3
|
||||
TEST_DIR: examples
|
||||
|
||||
build_examples_cmake_esp32h4:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
- .rules:build:example_test-esp32h4
|
||||
variables:
|
||||
IDF_TARGET: esp32h4
|
||||
TEST_DIR: examples
|
||||
|
||||
build_examples_cmake_esp32c6:
|
||||
extends:
|
||||
- .build_cmake_template
|
||||
@ -729,13 +713,6 @@ build_clang_test_apps_esp32c6:
|
||||
variables:
|
||||
IDF_TARGET: esp32c6
|
||||
|
||||
build_clang_test_apps_esp32h4:
|
||||
extends:
|
||||
- .build_clang_test_apps_riscv
|
||||
- .rules:build:custom_test-esp32h4
|
||||
variables:
|
||||
IDF_TARGET: esp32h4
|
||||
|
||||
.test_build_system_template:
|
||||
stage: host_test
|
||||
extends:
|
||||
|
@ -3,7 +3,6 @@
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32h4
|
||||
- esp32c2
|
||||
- esp32c6
|
||||
- esp32h2
|
||||
|
@ -175,11 +175,6 @@ test_efuse_table_on_host_esp32c6:
|
||||
variables:
|
||||
IDF_TARGET: esp32c6
|
||||
|
||||
test_efuse_table_on_host_esp32h4:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
variables:
|
||||
IDF_TARGET: esp32h4
|
||||
|
||||
test_espcoredump:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
|
@ -470,9 +470,6 @@
|
||||
.if-label-component_ut_esp32h2: &if-label-component_ut_esp32h2
|
||||
if: '$BOT_LABEL_COMPONENT_UT_ESP32H2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut_esp32h2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-component_ut_esp32h4: &if-label-component_ut_esp32h4
|
||||
if: '$BOT_LABEL_COMPONENT_UT_ESP32H4 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut_esp32h4(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-component_ut_esp32s2: &if-label-component_ut_esp32s2
|
||||
if: '$BOT_LABEL_COMPONENT_UT_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
@ -497,9 +494,6 @@
|
||||
.if-label-custom_test_esp32h2: &if-label-custom_test_esp32h2
|
||||
if: '$BOT_LABEL_CUSTOM_TEST_ESP32H2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test_esp32h2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-custom_test_esp32h4: &if-label-custom_test_esp32h4
|
||||
if: '$BOT_LABEL_CUSTOM_TEST_ESP32H4 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test_esp32h4(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-custom_test_esp32s2: &if-label-custom_test_esp32s2
|
||||
if: '$BOT_LABEL_CUSTOM_TEST_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
@ -527,9 +521,6 @@
|
||||
.if-label-example_test_esp32h2: &if-label-example_test_esp32h2
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST_ESP32H2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test_esp32h2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-example_test_esp32h4: &if-label-example_test_esp32h4
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST_ESP32H4 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test_esp32h4(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-example_test_esp32s2: &if-label-example_test_esp32s2
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
@ -584,9 +575,6 @@
|
||||
.if-label-unit_test_esp32h2: &if-label-unit_test_esp32h2
|
||||
if: '$BOT_LABEL_UNIT_TEST_ESP32H2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test_esp32h2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-unit_test_esp32h4: &if-label-unit_test_esp32h4
|
||||
if: '$BOT_LABEL_UNIT_TEST_ESP32H4 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test_esp32h4(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-unit_test_esp32s2: &if-label-unit_test_esp32s2
|
||||
if: '$BOT_LABEL_UNIT_TEST_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
@ -621,7 +609,6 @@
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-component_ut_esp32c6
|
||||
- <<: *if-label-component_ut_esp32h2
|
||||
- <<: *if-label-component_ut_esp32h4
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-lan8720
|
||||
@ -632,7 +619,6 @@
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-label-unit_test_esp32c6
|
||||
- <<: *if-label-unit_test_esp32h2
|
||||
- <<: *if-label-unit_test_esp32h4
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
@ -909,7 +895,6 @@
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-label-custom_test_esp32c6
|
||||
- <<: *if-label-custom_test_esp32h2
|
||||
- <<: *if-label-custom_test_esp32h4
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
@ -1060,32 +1045,6 @@
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
.rules:build:custom_test-esp32h4:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32h4
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-downloadable-tools
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-ecdsa
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-i154
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
.rules:build:custom_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
@ -1167,7 +1126,6 @@
|
||||
- <<: *if-label-example_test_esp32c3
|
||||
- <<: *if-label-example_test_esp32c6
|
||||
- <<: *if-label-example_test_esp32h2
|
||||
- <<: *if-label-example_test_esp32h4
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
@ -1416,48 +1374,6 @@
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
.rules:build:example_test-esp32h4:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32h4
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-downloadable-tools
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ccs811
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-i154
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-sdio
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-ecdsa
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-i154
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
.rules:build:example_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
@ -1589,7 +1505,6 @@
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-component_ut_esp32c6
|
||||
- <<: *if-label-component_ut_esp32h2
|
||||
- <<: *if-label-component_ut_esp32h4
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-custom_test
|
||||
@ -1598,7 +1513,6 @@
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-label-custom_test_esp32c6
|
||||
- <<: *if-label-custom_test_esp32h2
|
||||
- <<: *if-label-custom_test_esp32h4
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-label-example_test
|
||||
@ -1607,7 +1521,6 @@
|
||||
- <<: *if-label-example_test_esp32c3
|
||||
- <<: *if-label-example_test_esp32c6
|
||||
- <<: *if-label-example_test_esp32h2
|
||||
- <<: *if-label-example_test_esp32h4
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-label-integration_test
|
||||
@ -1621,7 +1534,6 @@
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-label-unit_test_esp32c6
|
||||
- <<: *if-label-unit_test_esp32h2
|
||||
- <<: *if-label-unit_test_esp32h4
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
@ -1691,7 +1603,6 @@
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-label-unit_test_esp32c6
|
||||
- <<: *if-label-unit_test_esp32h2
|
||||
- <<: *if-label-unit_test_esp32h4
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
|
@ -1,257 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "string.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "esp32h4/rom/gpio.h"
|
||||
#include "esp32h4/rom/spi_flash.h"
|
||||
#include "esp32h4/rom/efuse.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "flash_qio_mode.h"
|
||||
#include "bootloader_flash_config.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_init.h"
|
||||
#include "hal/mmu_hal.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/mmu_ll.h"
|
||||
|
||||
#define FLASH_IO_MATRIX_DUMMY_40M 0
|
||||
#define FLASH_IO_MATRIX_DUMMY_80M 0
|
||||
|
||||
void bootloader_flash_update_id()
|
||||
{
|
||||
esp_rom_spiflash_chip_t *chip = &rom_spiflash_legacy_data->chip;
|
||||
chip->device_id = bootloader_read_flash_id();
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||
{
|
||||
SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S);
|
||||
SET_PERI_REG_MASK(SPI_MEM_USER_REG(1), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(1), SPI_MEM_CS_HOLD_TIME_V, 1, SPI_MEM_CS_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(1), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)
|
||||
{
|
||||
uint32_t spi_clk_div = 0;
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_1:
|
||||
spi_clk_div = 1;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_2:
|
||||
spi_clk_div = 2;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_3:
|
||||
spi_clk_div = 3;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_4:
|
||||
spi_clk_div = 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
esp_rom_spiflash_config_clk(spi_clk_div, 0);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_set_dummy_out(void)
|
||||
{
|
||||
REG_SET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL);
|
||||
REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr)
|
||||
{
|
||||
bootloader_configure_spi_pins(1);
|
||||
bootloader_flash_set_dummy_out();
|
||||
}
|
||||
|
||||
static const char *TAG = "boot.esp32h4";
|
||||
|
||||
void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
{
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
|
||||
uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
|
||||
uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
|
||||
uint8_t d_gpio_num = SPI_D_GPIO_NUM;
|
||||
uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
|
||||
uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
|
||||
uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
|
||||
if (spiconfig == 0) {
|
||||
|
||||
} else {
|
||||
clk_gpio_num = spiconfig & 0x3f;
|
||||
q_gpio_num = (spiconfig >> 6) & 0x3f;
|
||||
d_gpio_num = (spiconfig >> 12) & 0x3f;
|
||||
cs0_gpio_num = (spiconfig >> 18) & 0x3f;
|
||||
hd_gpio_num = (spiconfig >> 24) & 0x3f;
|
||||
wp_gpio_num = wp_pin;
|
||||
}
|
||||
esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
|
||||
esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
|
||||
if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
|
||||
esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
|
||||
}
|
||||
if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
|
||||
esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_flash_config(const esp_image_header_t *bootloader_hdr)
|
||||
{
|
||||
uint32_t size;
|
||||
switch (bootloader_hdr->spi_size) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
size = 1;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
size = 2;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
size = 4;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
size = 8;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
size = 16;
|
||||
break;
|
||||
default:
|
||||
size = 2;
|
||||
}
|
||||
cache_hal_disable(CACHE_TYPE_ALL);
|
||||
// Set flash chip size
|
||||
esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode
|
||||
cache_hal_enable(CACHE_TYPE_ALL);
|
||||
}
|
||||
|
||||
static void print_flash_info(const esp_image_header_t *bootloader_hdr)
|
||||
{
|
||||
ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic);
|
||||
ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count);
|
||||
ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode);
|
||||
ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed);
|
||||
ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size);
|
||||
|
||||
const char *str;
|
||||
switch (bootloader_hdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_2:
|
||||
str = "24MHz";
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_3:
|
||||
str = "16MHz";
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_4:
|
||||
str = "12MHz";
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_DIV_1:
|
||||
str = "48MHz";
|
||||
break;
|
||||
default:
|
||||
str = "12MHz";
|
||||
break;
|
||||
}
|
||||
ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str);
|
||||
|
||||
/* SPI mode could have been set to QIO during boot already,
|
||||
so test the SPI registers not the flash header */
|
||||
esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
|
||||
switch (spi_mode) {
|
||||
case ESP_ROM_SPIFLASH_QIO_MODE:
|
||||
str = "QIO";
|
||||
break;
|
||||
case ESP_ROM_SPIFLASH_QOUT_MODE:
|
||||
str = "QOUT";
|
||||
break;
|
||||
case ESP_ROM_SPIFLASH_DIO_MODE:
|
||||
str = "DIO";
|
||||
break;
|
||||
case ESP_ROM_SPIFLASH_DOUT_MODE:
|
||||
str = "DOUT";
|
||||
break;
|
||||
case ESP_ROM_SPIFLASH_FASTRD_MODE:
|
||||
str = "FAST READ";
|
||||
break;
|
||||
default:
|
||||
str = "SLOW READ";
|
||||
break;
|
||||
}
|
||||
ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str);
|
||||
|
||||
switch (bootloader_hdr->spi_size) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
str = "1MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
str = "2MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
str = "4MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
str = "8MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
str = "16MB";
|
||||
break;
|
||||
default:
|
||||
str = "2MB";
|
||||
break;
|
||||
}
|
||||
ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR bootloader_init_flash_configure(void)
|
||||
{
|
||||
bootloader_flash_dummy_config(&bootloader_image_hdr);
|
||||
bootloader_flash_cs_timing_config();
|
||||
}
|
||||
|
||||
static void bootloader_spi_flash_resume(void)
|
||||
{
|
||||
bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0);
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
}
|
||||
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
bootloader_init_flash_configure();
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
bootloader_spi_flash_resume();
|
||||
bootloader_flash_unlock();
|
||||
|
||||
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT
|
||||
bootloader_enable_qio_mode();
|
||||
#endif
|
||||
|
||||
print_flash_info(&bootloader_image_hdr);
|
||||
update_flash_config(&bootloader_image_hdr);
|
||||
//ensure the flash is write-protected
|
||||
bootloader_enable_wp();
|
||||
return ESP_OK;
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "flash_qio_mode.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_rom_spiflash.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/assist_debug_reg.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "soc/extmem_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "esp32h4/rom/efuse.h"
|
||||
#include "esp32h4/rom/ets_sys.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_init.h"
|
||||
#include "bootloader_clock.h"
|
||||
#include "bootloader_flash_config.h"
|
||||
#include "bootloader_mem.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_private/bootloader_flash_internal.h"
|
||||
#include "hal/mmu_hal.h"
|
||||
#include "hal/cache_hal.h"
|
||||
|
||||
static const char *TAG = "boot.esp32h4";
|
||||
|
||||
static void wdt_reset_cpu0_info_enable(void)
|
||||
{
|
||||
REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
|
||||
REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
|
||||
REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
|
||||
}
|
||||
|
||||
static void wdt_reset_info_dump(int cpu)
|
||||
{
|
||||
(void) cpu;
|
||||
// saved PC was already printed by the ROM bootloader.
|
||||
// nothing to do here.
|
||||
}
|
||||
|
||||
static void bootloader_check_wdt_reset(void)
|
||||
{
|
||||
int wdt_rst = 0;
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
|
||||
rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
|
||||
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||
wdt_rst = 1;
|
||||
}
|
||||
if (wdt_rst) {
|
||||
// if reset by WDT dump info from trace port
|
||||
wdt_reset_info_dump(0);
|
||||
}
|
||||
wdt_reset_cpu0_info_enable();
|
||||
}
|
||||
|
||||
static void bootloader_super_wdt_auto_feed(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
|
||||
REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
|
||||
}
|
||||
|
||||
static inline void bootloader_hardware_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
//Enable WDT, BOD, and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(true);
|
||||
}
|
||||
|
||||
esp_err_t bootloader_init(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
bootloader_hardware_init();
|
||||
bootloader_ana_reset_config();
|
||||
bootloader_super_wdt_auto_feed();
|
||||
|
||||
// In RAM_APP, memory will be initialized in `call_start_cpu0`
|
||||
#if !CONFIG_APP_BUILD_TYPE_RAM
|
||||
// protect memory region
|
||||
bootloader_init_mem();
|
||||
/* check that static RAM is after the stack */
|
||||
assert(&_bss_start <= &_bss_end);
|
||||
assert(&_data_start <= &_data_end);
|
||||
// clear bss section
|
||||
bootloader_clear_bss_section();
|
||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||
|
||||
// config clock
|
||||
bootloader_clock_configure();
|
||||
// initialize console, from now on, we can use esp_log
|
||||
bootloader_console_init();
|
||||
/* print 2nd bootloader banner */
|
||||
bootloader_print_banner();
|
||||
|
||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
//init cache hal
|
||||
cache_hal_init(); //TODO IDF-4649
|
||||
//init mmu
|
||||
mmu_hal_init();
|
||||
// update flash ID
|
||||
bootloader_flash_update_id();
|
||||
// Check and run XMC startup flow
|
||||
if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
|
||||
return ret;
|
||||
}
|
||||
#if !CONFIG_APP_BUILD_TYPE_RAM
|
||||
// read bootloader header
|
||||
if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
// read chip revision and check if it's compatible to bootloader
|
||||
if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif // !CONFIG_APP_BUILD_TYPE_RAM
|
||||
// initialize spi flash
|
||||
if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
|
||||
// check whether a WDT reset happend
|
||||
bootloader_check_wdt_reset();
|
||||
// config WDT
|
||||
bootloader_config_wdt();
|
||||
// enable RNG early entropy source
|
||||
bootloader_enable_random();
|
||||
return ret;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "bootloader_sha.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "esp32h4/rom/sha.h"
|
||||
|
||||
static SHA_CTX ctx;
|
||||
|
||||
bootloader_sha256_handle_t bootloader_sha256_start()
|
||||
{
|
||||
// Enable SHA hardware
|
||||
ets_sha_enable();
|
||||
ets_sha_init(&ctx, SHA2_256);
|
||||
return &ctx; // Meaningless non-NULL value
|
||||
}
|
||||
|
||||
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len)
|
||||
{
|
||||
assert(handle != NULL);
|
||||
assert(data_len % 4 == 0);
|
||||
ets_sha_update(&ctx, data, data_len, false);
|
||||
}
|
||||
|
||||
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest)
|
||||
{
|
||||
assert(handle != NULL);
|
||||
|
||||
if (digest == NULL) {
|
||||
bzero(&ctx, sizeof(ctx));
|
||||
return;
|
||||
}
|
||||
ets_sha_finish(&ctx, digest);
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOD_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_GLITCH_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <strings.h>
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "flash_encrypt";
|
||||
|
||||
esp_err_t esp_flash_encryption_enable_secure_features(void)
|
||||
{
|
||||
#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
||||
ESP_LOGI(TAG, "Disable UART bootloader encryption...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader encryption");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
|
||||
ESP_LOGI(TAG, "Disable UART bootloader cache...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader cache - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable JTAG...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
|
||||
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
|
||||
// otherwise the Flash Encryption key cannot be read protected
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_FLASH_SKIP_WRITE_PROTECTION_CACHE
|
||||
// Set write-protection for DIS_ICACHE to prevent bricking chip in case it will be set accidentally.
|
||||
// esp32h4 has DIS_ICACHE. Write-protection bit = 2.
|
||||
// List of eFuses with the same write protection bit:
|
||||
// DIS_ICACHE, DIS_USB_JTAG, POWERGLITCH_EN, DIS_FORCE_DOWNLOAD, SPI_DOWNLOAD_MSPI_DIS,
|
||||
// DIS_TWAI, JTAG_SEL_ENABLE, DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_DIS_ICACHE);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <strings.h>
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "secure_boot";
|
||||
|
||||
esp_err_t esp_secure_boot_enable_secure_features(void)
|
||||
{
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
|
||||
#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Enabling Security download mode...");
|
||||
esp_err_t err = esp_efuse_enable_rom_secure_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not enable Security download mode...");
|
||||
return err;
|
||||
}
|
||||
#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Disable ROM Download mode...");
|
||||
esp_err_t err = esp_efuse_disable_rom_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not disable ROM Download mode...");
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable hardware & software JTAG...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
|
||||
esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE);
|
||||
#endif
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
bool rd_dis_now = true;
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
/* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
|
||||
when Flash Encryption is being enabled */
|
||||
rd_dis_now = esp_flash_encryption_enabled();
|
||||
#endif
|
||||
if (rd_dis_now) {
|
||||
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
@ -61,7 +61,7 @@ typedef enum {
|
||||
ADC1_CHANNEL_9, /*!< ADC1 channel 9 is GPIO10 */
|
||||
ADC1_CHANNEL_MAX,
|
||||
} adc1_channel_t;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
|
||||
typedef enum {
|
||||
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO0 */
|
||||
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO1 */
|
||||
@ -97,7 +97,7 @@ typedef enum {
|
||||
ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO26 (ESP32), GPIO20 (ESP32-S2) */
|
||||
ADC2_CHANNEL_MAX,
|
||||
} adc2_channel_t;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
|
||||
// ESP32C6 has no ADC2
|
||||
typedef enum {
|
||||
ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO5 */
|
||||
|
@ -32,7 +32,7 @@
|
||||
#define RW_TEST_LENGTH 129 /*!<Data length for r/w test, any value from 0-DATA_LENGTH*/
|
||||
#define DELAY_TIME_BETWEEN_ITEMS_MS 1234 /*!< delay time between different test items */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H4
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define I2C_SLAVE_SCL_IO 5 /*!<gpio number for i2c slave clock */
|
||||
#define I2C_SLAVE_SDA_IO 6 /*!<gpio number for i2c slave data */
|
||||
#else
|
||||
@ -44,7 +44,7 @@
|
||||
#define I2C_SLAVE_TX_BUF_LEN (2*DATA_LENGTH) /*!<I2C slave tx buffer size */
|
||||
#define I2C_SLAVE_RX_BUF_LEN (2*DATA_LENGTH) /*!<I2C slave rx buffer size */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#define I2C_MASTER_SCL_IO 5 /*!<gpio number for i2c master clock */
|
||||
#define I2C_MASTER_SDA_IO 6 /*!<gpio number for i2c master data */
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
|
@ -29,9 +29,6 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#include "esp32c3/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#include "esp32h4/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#include "esp32c2/rom/rtc.h"
|
||||
#include "esp32c2/rtc.h"
|
||||
|
@ -44,10 +44,6 @@
|
||||
#include "esp32c6/rom/digital_signature.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H4
|
||||
#include "esp32h4/rom/digital_signature.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H2
|
||||
#include "esp32h2/rom/digital_signature.h"
|
||||
#endif
|
||||
|
@ -24,7 +24,6 @@ typedef enum {
|
||||
CHIP_ESP32S2 = 2, //!< ESP32-S2
|
||||
CHIP_ESP32S3 = 9, //!< ESP32-S3
|
||||
CHIP_ESP32C3 = 5, //!< ESP32-C3
|
||||
CHIP_ESP32H4 = 6, //!< ESP32-H4
|
||||
CHIP_ESP32C2 = 12, //!< ESP32-C2
|
||||
CHIP_ESP32C6 = 13, //!< ESP32-C6
|
||||
CHIP_ESP32H2 = 16, //!< ESP32-H2
|
||||
|
@ -40,8 +40,6 @@ typedef enum {
|
||||
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_ESP32C3_UNIVERSAL_MAC_ADDRESSES
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_ESP32H4_UNIVERSAL_MAC_ADDRESSES
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_ESP32C2_UNIVERSAL_MAC_ADDRESSES
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Acquire lock for HMAC cryptography peripheral
|
||||
*
|
||||
* Internally also locks the SHA peripheral, as the HMAC depends on the SHA peripheral
|
||||
*/
|
||||
void esp_crypto_hmac_lock_acquire(void);
|
||||
|
||||
/**
|
||||
* @brief Release lock for HMAC cryptography peripheral
|
||||
*
|
||||
* Internally also releases the SHA peripheral, as the HMAC depends on the SHA peripheral
|
||||
*/
|
||||
void esp_crypto_hmac_lock_release(void);
|
||||
|
||||
/**
|
||||
* @brief Acquire lock for DS cryptography peripheral
|
||||
*
|
||||
* Internally also locks the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
|
||||
*/
|
||||
void esp_crypto_ds_lock_acquire(void);
|
||||
|
||||
/**
|
||||
* @brief Release lock for DS cryptography peripheral
|
||||
*
|
||||
* Internally also releases the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
|
||||
*/
|
||||
void esp_crypto_ds_lock_release(void);
|
||||
|
||||
/**
|
||||
* @brief Acquire lock for the SHA and AES cryptography peripheral.
|
||||
*
|
||||
*/
|
||||
void esp_crypto_sha_aes_lock_acquire(void);
|
||||
|
||||
/**
|
||||
* @brief Release lock for the SHA and AES cryptography peripheral.
|
||||
*
|
||||
*/
|
||||
void esp_crypto_sha_aes_lock_release(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Acquire lock for the mpi cryptography peripheral.
|
||||
*
|
||||
*/
|
||||
void esp_crypto_mpi_lock_acquire(void);
|
||||
|
||||
/**
|
||||
* @brief Release lock for the mpi/rsa cryptography peripheral.
|
||||
*
|
||||
*/
|
||||
void esp_crypto_mpi_lock_release(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file esp32h4/rtc.h
|
||||
*
|
||||
* This file contains declarations of rtc related functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get current value of RTC counter in microseconds
|
||||
*
|
||||
* Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
|
||||
*
|
||||
* @return current value of RTC counter in microseconds
|
||||
*/
|
||||
uint64_t esp_rtc_get_time_us(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,117 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// ESP32-H4 PMS memory protection types
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory types recognized by PMS
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_TYPE_NONE = 0x00000000,
|
||||
MEMPROT_TYPE_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_TYPE_INVALID = 0x80000000
|
||||
} esp_mprot_mem_t;
|
||||
|
||||
/**
|
||||
* @brief Splitting address (line) type
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_SPLIT_ADDR_NONE = 0x00000000,
|
||||
MEMPROT_SPLIT_ADDR_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_SPLIT_ADDR_INVALID = 0x80000000
|
||||
} esp_mprot_split_addr_t;
|
||||
|
||||
/**
|
||||
* @brief PMS area type (memory space between adjacent splitting addresses or above/below the main splt.address)
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_PMS_AREA_NONE = 0x00000000,
|
||||
MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_PMS_AREA_INVALID = 0x80000000
|
||||
} esp_mprot_pms_area_t;
|
||||
|
||||
/**
|
||||
* @brief Memory protection configuration
|
||||
*/
|
||||
typedef struct {
|
||||
bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
|
||||
bool lock_feature; /*!< Lock all PMS settings */
|
||||
void *split_addr; /*!< Main I/D splitting address */
|
||||
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
|
||||
} esp_memp_config_t;
|
||||
|
||||
#define ESP_MEMPROT_DEFAULT_CONFIG() { \
|
||||
.invoke_panic_handler = true, \
|
||||
.lock_feature = true, \
|
||||
.split_addr = NULL, \
|
||||
.mem_type_mask = MEMPROT_TYPE_ALL \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Memory protection type to string
|
||||
*
|
||||
* @param mem_type Memory protection type
|
||||
*/
|
||||
static inline const char *esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
switch (mem_type) {
|
||||
case MEMPROT_TYPE_NONE:
|
||||
return "MEMPROT_TYPE_NONE";
|
||||
case MEMPROT_TYPE_ALL:
|
||||
return "MEMPROT_TYPE_ALL";
|
||||
default:
|
||||
return "MEMPROT_TYPE_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Splitting address type to string
|
||||
*
|
||||
* @param line_type Split line type
|
||||
*/
|
||||
static inline const char *esp_mprot_split_addr_to_str(const esp_mprot_split_addr_t line_type)
|
||||
{
|
||||
switch (line_type) {
|
||||
case MEMPROT_SPLIT_ADDR_NONE:
|
||||
return "MEMPROT_SPLIT_ADDR_NONE";
|
||||
case MEMPROT_SPLIT_ADDR_ALL:
|
||||
return "MEMPROT_SPLIT_ADDR_ALL";
|
||||
default:
|
||||
return "MEMPROT_SPLIT_ADDR_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts PMS Area type to string
|
||||
*
|
||||
* @param area_type PMS Area type
|
||||
*/
|
||||
static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t area_type)
|
||||
{
|
||||
switch (area_type) {
|
||||
case MEMPROT_PMS_AREA_NONE:
|
||||
return "MEMPROT_PMS_AREA_NONE";
|
||||
case MEMPROT_PMS_AREA_ALL:
|
||||
return "MEMPROT_PMS_AREA_ALL";
|
||||
default:
|
||||
return "MEMPROT_PMS_AREA_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,23 +0,0 @@
|
||||
set(srcs "rtc_clk_init.c"
|
||||
"rtc_clk.c"
|
||||
"rtc_init.c"
|
||||
"rtc_sleep.c"
|
||||
"rtc_time.c"
|
||||
"chip_info.c"
|
||||
)
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "esp_crypto_lock.c"
|
||||
"sar_periph_ctrl.c")
|
||||
|
||||
if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE)
|
||||
list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
|
||||
|
||||
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
|
||||
target_include_directories(${COMPONENT_LIB} PUBLIC . private_include)
|
||||
target_include_directories(${COMPONENT_LIB} PRIVATE ../hal)
|
@ -1,41 +0,0 @@
|
||||
choice ESP32H4_REV_MIN
|
||||
prompt "Minimum Supported ESP32-H4 Revision"
|
||||
default ESP32H4_REV_MIN_0
|
||||
help
|
||||
Required minimum chip revision. ESP-IDF will check for it and
|
||||
reject to boot if the chip revision fails the check.
|
||||
This ensures the chip used will have some modifications (features, or bugfixes).
|
||||
|
||||
The complied binary will only support chips above this revision,
|
||||
this will also help to reduce binary size.
|
||||
|
||||
config ESP32H4_REV_MIN_0
|
||||
bool "Rev v0.0 (ECO0)"
|
||||
endchoice
|
||||
|
||||
config ESP32H4_REV_MIN_FULL
|
||||
int
|
||||
default 0 if ESP32H4_REV_MIN_0
|
||||
|
||||
config ESP_REV_MIN_FULL
|
||||
int
|
||||
default ESP32H4_REV_MIN_FULL
|
||||
|
||||
#
|
||||
# MAX Revision
|
||||
#
|
||||
|
||||
comment "Maximum Supported ESP32-H4 Revision (Rev v1.99)"
|
||||
# Maximum revision that IDF supports.
|
||||
# It can not be changed by user.
|
||||
# Only Espressif can change it when a new version will be supported in IDF.
|
||||
# Supports all chips starting from ESP32H4_REV_MIN_FULL to ESP32H4_REV_MAX_FULL
|
||||
|
||||
config ESP32H4_REV_MAX_FULL
|
||||
int
|
||||
default 199
|
||||
# keep in sync the "Maximum Supported Revision" description with this value
|
||||
|
||||
config ESP_REV_MAX_FULL
|
||||
int
|
||||
default ESP32H4_REV_MAX_FULL
|
@ -1,19 +0,0 @@
|
||||
# ESP32H4-TODO: IDF-3390
|
||||
choice ESP32H4_UNIVERSAL_MAC_ADDRESSES
|
||||
bool "Number of universally administered (by IEEE) MAC address"
|
||||
default ESP32H4_UNIVERSAL_MAC_ADDRESSES_TWO
|
||||
help
|
||||
Configure the number of universally administered (by IEEE) MAC addresses.
|
||||
During initialization, MAC addresses for each network interface are generated or derived from a
|
||||
single base MAC address.
|
||||
|
||||
config ESP32H4_UNIVERSAL_MAC_ADDRESSES_TWO
|
||||
bool "Two"
|
||||
select ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO
|
||||
select ESP_MAC_ADDR_UNIVERSE_IEEE802154
|
||||
select ESP_MAC_ADDR_UNIVERSE_BT
|
||||
endchoice
|
||||
|
||||
config ESP32H4_UNIVERSAL_MAC_ADDRESSES
|
||||
int
|
||||
default 2 if ESP32H4_UNIVERSAL_MAC_ADDRESSES_TWO
|
@ -1,38 +0,0 @@
|
||||
choice RTC_CLK_SRC
|
||||
prompt "RTC clock source"
|
||||
default RTC_CLK_SRC_INT_RC
|
||||
help
|
||||
Choose which clock is used as RTC clock source.
|
||||
|
||||
config RTC_CLK_SRC_INT_RC
|
||||
bool "Internal 136kHz RC oscillator"
|
||||
config RTC_CLK_SRC_EXT_CRYS
|
||||
bool "External 32.768kHz crystal"
|
||||
select ESP_SYSTEM_RTC_EXT_XTAL
|
||||
config RTC_CLK_SRC_EXT_OSC
|
||||
bool "External 32kHz oscillator at 32K_XP pin"
|
||||
select ESP_SYSTEM_RTC_EXT_OSC
|
||||
config RTC_CLK_SRC_INT_RC32K
|
||||
bool "Internal 32kHz RC oscillator"
|
||||
endchoice
|
||||
|
||||
config RTC_CLK_CAL_CYCLES
|
||||
int "Number of cycles for RTC_SLOW_CLK calibration"
|
||||
default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K
|
||||
default 576 if RTC_CLK_SRC_INT_RC
|
||||
range 0 125000
|
||||
help
|
||||
When the startup code initializes RTC_SLOW_CLK, it can perform
|
||||
calibration by comparing the RTC_SLOW_CLK frequency with main XTAL
|
||||
frequency. This option sets the number of RTC_SLOW_CLK cycles measured
|
||||
by the calibration routine. Higher numbers increase calibration
|
||||
precision, which may be important for applications which spend a lot of
|
||||
time in deep sleep. Lower numbers reduce startup time.
|
||||
|
||||
When this option is set to 0, clock calibration will not be performed at
|
||||
startup, and approximate clock frequencies will be assumed:
|
||||
|
||||
- 150000 Hz if internal RC oscillator is used as clock source. For this use value 1024.
|
||||
- 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more.
|
||||
In case more value will help improve the definition of the launch of the crystal.
|
||||
If the crystal could not start, it will be switched to internal RC.
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2013-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_chip_info.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
void esp_chip_info(esp_chip_info_t *out_info)
|
||||
{
|
||||
memset(out_info, 0, sizeof(*out_info));
|
||||
out_info->model = CHIP_ESP32H4;
|
||||
out_info->revision = efuse_hal_chip_revision();
|
||||
out_info->cores = 1;
|
||||
out_info->features = CHIP_FEATURE_IEEE802154 | CHIP_FEATURE_BLE;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "clk_tree.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "hal/clk_tree_hal.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "esp_private/clk_tree_common.h"
|
||||
|
||||
static const char *TAG = "clk_tree";
|
||||
|
||||
esp_err_t clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, clk_tree_src_freq_precision_t precision,
|
||||
uint32_t *freq_value)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src");
|
||||
ESP_RETURN_ON_FALSE(precision < CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision");
|
||||
ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer");
|
||||
|
||||
uint32_t clk_src_freq = 0;
|
||||
switch (clk_src) {
|
||||
case SOC_MOD_CLK_CPU:
|
||||
clk_src_freq = clk_hal_cpu_get_freq_hz();
|
||||
break;
|
||||
case SOC_MOD_CLK_AHB:
|
||||
clk_src_freq = clk_hal_ahb_get_freq_hz();
|
||||
break;
|
||||
case SOC_MOD_CLK_APB:
|
||||
clk_src_freq = clk_hal_apb_get_freq_hz();
|
||||
break;
|
||||
case SOC_MOD_CLK_XTAL:
|
||||
clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ;
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL:
|
||||
clk_src_freq = clk_ll_bbpll_get_freq_mhz() * MHZ;
|
||||
break;
|
||||
case SOC_MOD_CLK_RTC_SLOW:
|
||||
clk_src_freq = clk_tree_lp_slow_get_freq_hz(precision);
|
||||
break;
|
||||
case SOC_MOD_CLK_RTC_FAST:
|
||||
clk_src_freq = clk_tree_lp_fast_get_freq_hz(precision);
|
||||
break;
|
||||
case SOC_MOD_CLK_RC_FAST:
|
||||
clk_src_freq = clk_tree_rc_fast_get_freq_hz(precision);
|
||||
break;
|
||||
case SOC_MOD_CLK_XTAL32K:
|
||||
clk_src_freq = clk_tree_xtal32k_get_freq_hz(precision);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG,
|
||||
"freq shouldn't be 0, calibration failed");
|
||||
*freq_value = clk_src_freq;
|
||||
return ESP_OK;
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "riscv/csr.h"
|
||||
|
||||
void esp_cpu_configure_region_protection(void)
|
||||
{
|
||||
/* Notes on implementation:
|
||||
*
|
||||
* 1) Note: ESP32-H4 CPU doesn't support overlapping PMP regions
|
||||
*
|
||||
* 2) Therefore, we use TOR (top of range) entries to map the whole address
|
||||
* space, bottom to top.
|
||||
*
|
||||
* 3) There are not enough entries to describe all the memory regions 100% accurately.
|
||||
*
|
||||
* 4) This means some gaps (invalid memory) are accessible. Priority for extending regions
|
||||
* to cover gaps is to extend read-only or read-execute regions or read-only regions only
|
||||
* (executing unmapped addresses should always fault with invalid instruction, read-only means
|
||||
* stores will correctly fault even if reads may return some invalid value.)
|
||||
*
|
||||
* 5) Entries are grouped in order with some static asserts to try and verify everything is
|
||||
* correct.
|
||||
*/
|
||||
const unsigned NONE = PMP_L | PMP_TOR;
|
||||
const unsigned R = PMP_L | PMP_TOR | PMP_R;
|
||||
const unsigned RW = PMP_L | PMP_TOR | PMP_R | PMP_W;
|
||||
const unsigned RX = PMP_L | PMP_TOR | PMP_R | PMP_X;
|
||||
const unsigned RWX = PMP_L | PMP_TOR | PMP_R | PMP_W | PMP_X;
|
||||
|
||||
// 1. Gap at bottom of address space
|
||||
PMP_ENTRY_SET(0, SOC_DEBUG_LOW, NONE);
|
||||
|
||||
// 2. Debug region
|
||||
PMP_ENTRY_SET(1, SOC_DEBUG_HIGH, RWX);
|
||||
_Static_assert(SOC_DEBUG_LOW < SOC_DEBUG_HIGH, "Invalid CPU debug region");
|
||||
|
||||
// 3. Gap between debug region & DROM (flash cache)
|
||||
PMP_ENTRY_SET(2, SOC_DROM_LOW, NONE);
|
||||
_Static_assert(SOC_DEBUG_HIGH < SOC_DROM_LOW, "Invalid PMP entry order");
|
||||
|
||||
// 4. DROM (flash cache)
|
||||
// 5. Gap between DROM & DRAM
|
||||
// (Note: To save PMP entries these two are merged into one read-only region)
|
||||
PMP_ENTRY_SET(3, SOC_DRAM_LOW, R);
|
||||
_Static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid DROM region");
|
||||
_Static_assert(SOC_DROM_HIGH < SOC_DRAM_LOW, "Invalid PMP entry order");
|
||||
|
||||
// 6. DRAM
|
||||
PMP_ENTRY_SET(4, SOC_DRAM_HIGH, RW);
|
||||
_Static_assert(SOC_DRAM_LOW < SOC_DRAM_HIGH, "Invalid DRAM region");
|
||||
|
||||
// 7. Gap between DRAM and Mask DROM
|
||||
// 8. Mask DROM
|
||||
// (Note: to save PMP entries these two are merged into one read-only region)
|
||||
PMP_ENTRY_SET(5, SOC_DROM_MASK_HIGH, R);
|
||||
_Static_assert(SOC_DRAM_HIGH < SOC_DROM_MASK_LOW, "Invalid PMP entry order");
|
||||
_Static_assert(SOC_DROM_MASK_LOW < SOC_DROM_MASK_HIGH, "Invalid mask DROM region");
|
||||
|
||||
// 9. Gap between mask DROM and mask IROM
|
||||
// 10. Mask IROM
|
||||
// (Note: to save PMP entries these two are merged into one RX region)
|
||||
PMP_ENTRY_SET(6, SOC_IROM_MASK_HIGH, RX);
|
||||
_Static_assert(SOC_DROM_MASK_HIGH < SOC_IROM_MASK_LOW, "Invalid PMP entry order");
|
||||
_Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid mask IROM region");
|
||||
|
||||
// 11. Gap between mask IROM & IRAM
|
||||
PMP_ENTRY_SET(7, SOC_IRAM_LOW, NONE);
|
||||
_Static_assert(SOC_IROM_MASK_HIGH < SOC_IRAM_LOW, "Invalid PMP entry order");
|
||||
|
||||
// 12. IRAM
|
||||
PMP_ENTRY_SET(8, SOC_IRAM_HIGH, RWX);
|
||||
_Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid IRAM region");
|
||||
|
||||
// 13. Gap between IRAM and IROM
|
||||
// 14. IROM (flash cache)
|
||||
// (Note: to save PMP entries these two are merged into one RX region)
|
||||
PMP_ENTRY_SET(9, SOC_IROM_HIGH, RX);
|
||||
_Static_assert(SOC_IRAM_HIGH < SOC_IROM_LOW, "Invalid PMP entry order");
|
||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid IROM region");
|
||||
|
||||
// 15. Gap between IROM & RTC slow memory
|
||||
PMP_ENTRY_SET(10, SOC_RTC_IRAM_LOW, NONE);
|
||||
_Static_assert(SOC_IROM_HIGH < SOC_RTC_IRAM_LOW, "Invalid PMP entry order");
|
||||
|
||||
// 16. RTC fast memory
|
||||
PMP_ENTRY_SET(11, SOC_RTC_IRAM_HIGH, RWX);
|
||||
_Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region");
|
||||
|
||||
// 17. Gap between RTC fast memory & peripheral addresses
|
||||
PMP_ENTRY_SET(12, SOC_PERIPHERAL_LOW, NONE);
|
||||
_Static_assert(SOC_RTC_IRAM_HIGH < SOC_PERIPHERAL_LOW, "Invalid PMP entry order");
|
||||
|
||||
// 18. Peripheral addresses
|
||||
PMP_ENTRY_SET(13, SOC_PERIPHERAL_HIGH, RW);
|
||||
_Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region");
|
||||
|
||||
// 19. End of address space
|
||||
PMP_ENTRY_SET(14, UINT32_MAX, NONE); // all but last 4 bytes
|
||||
PMP_ENTRY_SET(15, UINT32_MAX, PMP_L | PMP_NA4); // last 4 bytes
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <sys/lock.h>
|
||||
|
||||
#include "esp_crypto_lock.h"
|
||||
|
||||
/* Lock overview:
|
||||
SHA: peripheral independent, but DMA is shared with AES
|
||||
AES: peripheral independent, but DMA is shared with SHA
|
||||
MPI/RSA: independent
|
||||
HMAC: needs SHA
|
||||
DS: needs HMAC (which needs SHA), AES and MPI
|
||||
*/
|
||||
|
||||
/* Lock for DS peripheral */
|
||||
static _lock_t s_crypto_ds_lock;
|
||||
|
||||
/* Lock for HMAC peripheral */
|
||||
static _lock_t s_crypto_hmac_lock;
|
||||
|
||||
/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */
|
||||
static _lock_t s_crypto_mpi_lock;
|
||||
|
||||
/* Single lock for SHA and AES, sharing a reserved GDMA channel */
|
||||
static _lock_t s_crypto_sha_aes_lock;
|
||||
|
||||
void esp_crypto_hmac_lock_acquire(void)
|
||||
{
|
||||
_lock_acquire(&s_crypto_hmac_lock);
|
||||
esp_crypto_sha_aes_lock_acquire();
|
||||
}
|
||||
|
||||
void esp_crypto_hmac_lock_release(void)
|
||||
{
|
||||
esp_crypto_sha_aes_lock_release();
|
||||
_lock_release(&s_crypto_hmac_lock);
|
||||
}
|
||||
|
||||
void esp_crypto_ds_lock_acquire(void)
|
||||
{
|
||||
_lock_acquire(&s_crypto_ds_lock);
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
esp_crypto_mpi_lock_acquire();
|
||||
}
|
||||
|
||||
void esp_crypto_ds_lock_release(void)
|
||||
{
|
||||
esp_crypto_mpi_lock_release();
|
||||
esp_crypto_hmac_lock_release();
|
||||
_lock_release(&s_crypto_ds_lock);
|
||||
}
|
||||
|
||||
void esp_crypto_sha_aes_lock_acquire(void)
|
||||
{
|
||||
_lock_acquire(&s_crypto_sha_aes_lock);
|
||||
}
|
||||
|
||||
void esp_crypto_sha_aes_lock_release(void)
|
||||
{
|
||||
_lock_release(&s_crypto_sha_aes_lock);
|
||||
}
|
||||
|
||||
void esp_crypto_mpi_lock_acquire(void)
|
||||
{
|
||||
_lock_acquire(&s_crypto_mpi_lock);
|
||||
}
|
||||
|
||||
void esp_crypto_mpi_lock_release(void)
|
||||
{
|
||||
_lock_release(&s_crypto_mpi_lock);
|
||||
}
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_fault.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_memprot_err.h"
|
||||
#include "hal/memprot_types.h"
|
||||
#include "esp_private/esp_memprot_internal.h"
|
||||
#include "esp_memprot.h"
|
||||
|
||||
esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, const void *line_addr)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, void **line_addr)
|
||||
{
|
||||
if (line_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*line_addr = NULL;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_default_main_split_addr(const esp_mprot_mem_t mem_type, void **def_split_addr)
|
||||
{
|
||||
if (def_split_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*def_split_addr = NULL;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_set_split_addr_lock(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_split_addr_lock(const esp_mprot_mem_t mem_type, bool *locked)
|
||||
{
|
||||
if (locked == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*locked = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_set_pms_lock(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_pms_lock(const esp_mprot_mem_t mem_type, bool *locked)
|
||||
{
|
||||
if (locked == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*locked = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uint32_t flags)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t *flags)
|
||||
{
|
||||
if (flags == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*flags = MEMPROT_OP_NONE;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_set_monitor_lock(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_monitor_lock(const esp_mprot_mem_t mem_type, bool *locked)
|
||||
{
|
||||
if (locked == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*locked = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_set_monitor_en(const esp_mprot_mem_t mem_type, const bool enable)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_monitor_en(const esp_mprot_mem_t mem_type, bool *enabled)
|
||||
{
|
||||
if (enabled == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*enabled = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, const int core __attribute__((unused)))
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_active_intr(esp_memp_intr_source_t *active_memp_intr)
|
||||
{
|
||||
if (active_memp_intr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
active_memp_intr->mem_type = MEMPROT_TYPE_NONE;
|
||||
active_memp_intr->core = -1;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_is_conf_locked_any(bool *locked)
|
||||
{
|
||||
if (locked == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*locked = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_is_intr_ena_any(bool *enabled)
|
||||
{
|
||||
if (enabled == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*enabled = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, const int core __attribute__((unused)))
|
||||
{
|
||||
if (fault_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*fault_addr = NULL;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, const int core __attribute__((unused)))
|
||||
{
|
||||
if (world == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*world = MEMPROT_PMS_WORLD_NONE;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, const int core __attribute__((unused)))
|
||||
{
|
||||
if (oper == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*oper = MEMPROT_OP_NONE;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool esp_mprot_has_byte_enables(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, const int core __attribute__((unused)))
|
||||
{
|
||||
if (byte_en == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*byte_en = 0;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mprot_set_prot(const esp_memp_config_t *memp_config)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file i2c_brownout.h
|
||||
* @brief Register definitions for brownout detector
|
||||
*
|
||||
* This file lists register fields of the brownout detector, located on an internal configuration
|
||||
* bus. These definitions are used via macros defined in i2c_rtc_clk.h.
|
||||
*/
|
||||
|
||||
#define I2C_BOD 0x61
|
||||
#define I2C_BOD_HOSTID 1
|
||||
|
||||
#define I2C_BOD_THRESHOLD 0x5
|
||||
#define I2C_BOD_THRESHOLD_MSB 2
|
||||
#define I2C_BOD_THRESHOLD_LSB 0
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_private/io_mux.h"
|
||||
|
||||
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
|
||||
{
|
||||
// IO MUX clock source is not selectable
|
||||
return ESP_OK;
|
||||
}
|
@ -1,422 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#include "esp32h4/rom/uart.h"
|
||||
#include "esp32h4/rom/gpio.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_private/rtc_clk.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/regi2c_ctrl_ll.h"
|
||||
#include "hal/gpio_ll.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
static const char *TAG = "rtc_clk";
|
||||
|
||||
#define RTC_OSC_FREQ_RC8M 8
|
||||
|
||||
// Current PLL frequency, in 96MHZ. Zero if PLL is not enabled.
|
||||
static int s_cur_pll_freq;
|
||||
|
||||
static uint32_t rtc_clk_ahb_freq_get(void);
|
||||
static void rtc_clk_cpu_freq_to_xtal(int freq, int div);
|
||||
void rtc_clk_cpu_freq_to_8m(void);
|
||||
|
||||
// Unused as unsupported yet
|
||||
static uint32_t __attribute((unused)) s_bbpll_digi_consumers_ref_count = 0; // Currently, it only tracks whether the 48MHz PHY clock is in-use by USB Serial/JTAG
|
||||
|
||||
void rtc_clk_bbpll_add_consumer(void)
|
||||
{
|
||||
s_bbpll_digi_consumers_ref_count += 1;
|
||||
}
|
||||
|
||||
void rtc_clk_bbpll_remove_consumer(void)
|
||||
{
|
||||
s_bbpll_digi_consumers_ref_count -= 1;
|
||||
}
|
||||
|
||||
static void rtc_gpio_hangup(uint32_t gpio_no)
|
||||
{
|
||||
gpio_ll_pulldown_dis(&GPIO, gpio_no);
|
||||
gpio_ll_pullup_dis(&GPIO, gpio_no);
|
||||
gpio_ll_output_disable(&GPIO, gpio_no);
|
||||
gpio_ll_input_disable(&GPIO, gpio_no);
|
||||
gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_no], PIN_FUNC_GPIO);
|
||||
}
|
||||
|
||||
void rtc_clk_32k_enable(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
/* need to hangup 32K_P and 32K_N pins before enable xtal_32k */
|
||||
rtc_gpio_hangup(XTAL32K_P_GPIO_NUM);
|
||||
rtc_gpio_hangup(XTAL32K_N_GPIO_NUM);
|
||||
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
|
||||
} else {
|
||||
clk_ll_xtal32k_disable();
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_32k_enable_external(void)
|
||||
{
|
||||
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
|
||||
}
|
||||
|
||||
void rtc_clk_32k_bootstrap(uint32_t cycle)
|
||||
{
|
||||
/* No special bootstrapping needed for ESP32-H4, 'cycle' argument is to keep the signature
|
||||
* same as for the ESP32. Just enable the XTAL here.
|
||||
*/
|
||||
(void)cycle;
|
||||
rtc_clk_32k_enable(true);
|
||||
}
|
||||
|
||||
bool rtc_clk_32k_enabled(void)
|
||||
{
|
||||
return clk_ll_xtal32k_is_enabled();
|
||||
}
|
||||
|
||||
void rtc_clk_rc32k_enable(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
clk_ll_rc32k_enable();
|
||||
} else {
|
||||
clk_ll_rc32k_disable();
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
|
||||
{
|
||||
clk_ll_rtc_slow_set_src(clk_src);
|
||||
rtc_clk_32k_enable((clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? 1 : 0);
|
||||
rtc_clk_rc32k_enable((clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) ? 1 : 0);
|
||||
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
|
||||
}
|
||||
|
||||
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||
{
|
||||
return clk_ll_rtc_slow_get_src();
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||
{
|
||||
switch (rtc_clk_slow_src_get()) {
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
|
||||
{
|
||||
clk_ll_rtc_fast_set_src(clk_src);
|
||||
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
|
||||
}
|
||||
|
||||
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
|
||||
{
|
||||
return clk_ll_rtc_fast_get_src();
|
||||
}
|
||||
|
||||
static void rtc_clk_bbpll_disable(void)
|
||||
{
|
||||
clk_ll_bbpll_disable();
|
||||
s_cur_pll_freq = 0;
|
||||
}
|
||||
|
||||
static void rtc_clk_bbpll_enable(void)
|
||||
{
|
||||
clk_ll_bbpll_enable();
|
||||
}
|
||||
|
||||
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
||||
{
|
||||
if (!((pll_freq == CLK_LL_PLL_96M_FREQ_MHZ) && (xtal_freq == RTC_XTAL_FREQ_32M))) {
|
||||
ESP_HW_LOGE(TAG, "invalid pll or xtal frequency");
|
||||
}
|
||||
|
||||
// No digital part needs to be set, pll_freq can only be 96MHz
|
||||
|
||||
// Configure analog part
|
||||
regi2c_ctrl_ll_bbpll_calibration_start();
|
||||
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||
// Wait until calibration finishes
|
||||
while (!regi2c_ctrl_ll_bbpll_calibration_is_done());
|
||||
// Prevent BBPLL clock jitter
|
||||
regi2c_ctrl_ll_bbpll_calibration_stop();
|
||||
s_cur_pll_freq = pll_freq;
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_select_root_clk(soc_cpu_clk_src_t cpu_clk_src)
|
||||
{
|
||||
uint32_t root_clk_freq_mhz;
|
||||
switch (cpu_clk_src) {
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
|
||||
rtc_clk_bbpll_disable();
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
// SPLL_ENABLE
|
||||
root_clk_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
|
||||
rtc_clk_bbpll_enable();
|
||||
rtc_clk_bbpll_configure(RTC_XTAL_FREQ_32M, root_clk_freq_mhz);
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
root_clk_freq_mhz = RTC_OSC_FREQ_RC8M;
|
||||
rtc_dig_clk8m_enable(); // TODO: Do we need to enable digital gating here?
|
||||
rtc_clk_8m_divider_set(1);
|
||||
rtc_clk_bbpll_disable();
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_XTAL_D2:
|
||||
root_clk_freq_mhz = RTC_XTAL_FREQ_32M / 2;
|
||||
rtc_clk_bbpll_disable();
|
||||
break;
|
||||
default:
|
||||
ESP_HW_LOGE(TAG, "unsupported source clk configuration");
|
||||
// fallback to XTAL as root clock source
|
||||
root_clk_freq_mhz = RTC_XTAL_FREQ_32M;
|
||||
rtc_clk_bbpll_disable();
|
||||
cpu_clk_src = SOC_CPU_CLK_SRC_XTAL;
|
||||
break;
|
||||
}
|
||||
clk_ll_cpu_set_src(cpu_clk_src);
|
||||
return root_clk_freq_mhz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
|
||||
* PLL must already be enabled.
|
||||
* @param cpu_freq new CPU frequency
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||
{
|
||||
int div = 1;
|
||||
if (CLK_LL_PLL_96M_FREQ_MHZ % cpu_freq_mhz == 0) {
|
||||
div = CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz;
|
||||
} else {
|
||||
ESP_HW_LOGE(TAG, "invalid frequency");
|
||||
abort();
|
||||
}
|
||||
rtc_clk_cpu_freq_set(SOC_CPU_CLK_SRC_PLL, div);
|
||||
if (cpu_freq_mhz > RTC_XTAL_FREQ_32M) {
|
||||
clk_ll_ahb_set_divider(2);
|
||||
} else {
|
||||
clk_ll_ahb_set_divider(1);
|
||||
}
|
||||
|
||||
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
|
||||
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
||||
}
|
||||
|
||||
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
|
||||
{
|
||||
// TODO: This function supposes to only fill a cpu config, but it is writing to registers, needs to check
|
||||
uint32_t source_freq_mhz;
|
||||
soc_cpu_clk_src_t source;
|
||||
uint32_t divider;
|
||||
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
if (freq_mhz > xtal_freq) {
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
|
||||
divider = CLK_LL_PLL_96M_FREQ_MHZ / freq_mhz;
|
||||
clk_ll_ahb_set_divider(2);
|
||||
} else if (freq_mhz != 0) {
|
||||
source = clk_ll_cpu_get_src();
|
||||
source_freq_mhz = rtc_clk_select_root_clk(source);
|
||||
divider = source_freq_mhz / freq_mhz;
|
||||
clk_ll_ahb_set_divider(1);
|
||||
} else {
|
||||
// unsupported frequency
|
||||
return false;
|
||||
}
|
||||
*out_config = (rtc_cpu_freq_config_t) {
|
||||
.source = source,
|
||||
.div = divider,
|
||||
.source_freq_mhz = source_freq_mhz,
|
||||
.freq_mhz = freq_mhz
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||
{
|
||||
uint32_t src_freq_mhz = rtc_clk_select_root_clk(config->source);
|
||||
uint32_t div = src_freq_mhz / (config->freq_mhz);
|
||||
rtc_clk_cpu_freq_set(config->source, div);
|
||||
esp_rom_set_cpu_ticks_per_us(config->freq_mhz);
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||
{
|
||||
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||
uint32_t source_freq_mhz;
|
||||
uint32_t div;
|
||||
uint32_t freq_mhz;
|
||||
switch (source) {
|
||||
case SOC_CPU_CLK_SRC_XTAL: {
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_PLL: {
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_RC_FAST: {
|
||||
source_freq_mhz = RTC_OSC_FREQ_RC8M;
|
||||
div = clk_ll_cpu_get_divider();
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_XTAL_D2: {
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
freq_mhz = source_freq_mhz / div / 2;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
*out_config = (rtc_cpu_freq_config_t) {
|
||||
.source = source,
|
||||
.source_freq_mhz = source_freq_mhz,
|
||||
.div = div,
|
||||
.freq_mhz = freq_mhz
|
||||
};
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
||||
{
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL &&
|
||||
s_cur_pll_freq == config->source_freq_mhz) {
|
||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||
} else {
|
||||
/* fallback */
|
||||
rtc_clk_cpu_freq_set_config(config);
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set_xtal(void)
|
||||
{
|
||||
rtc_clk_cpu_set_to_default_config();
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_set_to_default_config(void)
|
||||
{
|
||||
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||
|
||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to use XTAL as the CPU clock source.
|
||||
* Must satisfy: cpu_freq = XTAL_FREQ / div.
|
||||
* Does not disable the PLL.
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
||||
{
|
||||
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||
rtc_clk_cpu_freq_set(SOC_CPU_CLK_SRC_XTAL, div);
|
||||
/* no need to adjust the REF_TICK */
|
||||
/* switch clock source */
|
||||
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_to_8m(void)
|
||||
{
|
||||
esp_rom_set_cpu_ticks_per_us(RTC_OSC_FREQ_RC8M);
|
||||
rtc_clk_select_root_clk(SOC_CPU_CLK_SRC_RC_FAST);
|
||||
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
||||
}
|
||||
|
||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||
{
|
||||
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||
if (xtal_freq_mhz == 0) {
|
||||
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 32MHz");
|
||||
return RTC_XTAL_FREQ_32M;
|
||||
}
|
||||
return (rtc_xtal_freq_t)xtal_freq_mhz;
|
||||
}
|
||||
|
||||
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
|
||||
{
|
||||
clk_ll_xtal_store_freq_mhz(xtal_freq);
|
||||
}
|
||||
|
||||
void rtc_clk_apb_freq_update(uint32_t apb_freq)
|
||||
{
|
||||
clk_ll_apb_store_freq_hz(apb_freq);
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_apb_freq_get(void)
|
||||
{
|
||||
return rtc_clk_ahb_freq_get() / clk_ll_apb_get_divider();
|
||||
}
|
||||
|
||||
static uint32_t rtc_clk_ahb_freq_get(void)
|
||||
{
|
||||
rtc_cpu_freq_config_t cpu_config;
|
||||
rtc_clk_cpu_freq_get_config(&cpu_config);
|
||||
return cpu_config.freq_mhz * MHZ / clk_ll_ahb_get_divider();
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_set(uint32_t source, uint32_t div)
|
||||
{
|
||||
if ((uint32_t)clk_ll_cpu_get_src() != source) {
|
||||
rtc_clk_select_root_clk(source);
|
||||
}
|
||||
clk_ll_cpu_set_divider(div);
|
||||
}
|
||||
|
||||
void rtc_clk_divider_set(uint32_t div)
|
||||
{
|
||||
clk_ll_rc_slow_set_divider(div);
|
||||
}
|
||||
|
||||
void rtc_clk_8m_divider_set(uint32_t div)
|
||||
{
|
||||
clk_ll_rc_fast_set_divider(div);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_enable(void)
|
||||
{
|
||||
clk_ll_rc_fast_digi_enable();
|
||||
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||
}
|
||||
|
||||
void rtc_dig_clk8m_disable(void)
|
||||
{
|
||||
clk_ll_rc_fast_digi_disable();
|
||||
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
|
||||
}
|
||||
|
||||
bool rtc_dig_8m_enabled(void)
|
||||
{
|
||||
return clk_ll_rc_fast_digi_is_enabled();
|
||||
}
|
||||
|
||||
/* Name used in libphy.a:phy_chip_v7.o
|
||||
* TODO: update the library to use rtc_clk_xtal_freq_get
|
||||
*/
|
||||
rtc_xtal_freq_t rtc_get_xtal(void) __attribute__((alias("rtc_clk_xtal_freq_get")));
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp32h4/rom/ets_sys.h"
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#include "esp32h4/rom/uart.h"
|
||||
#include "esp32h4/rom/gpio.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
static const char *TAG = "rtc_clk_init";
|
||||
|
||||
void rtc_clk_init(rtc_clk_config_t cfg)
|
||||
{
|
||||
rtc_cpu_freq_config_t old_config, new_config;
|
||||
|
||||
/* Set tuning parameters for 8M and 150k clocks.
|
||||
* Note: this doesn't attempt to set the clocks to precise frequencies.
|
||||
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
|
||||
* - SCK_DCAP value controls tuning of 150k clock.
|
||||
* The higher the value of DCAP is, the lower is the frequency.
|
||||
* - CK8M_DFREQ value controls tuning of 8M clock.
|
||||
* CLK_8M_DFREQ constant gives the best temperature characteristics.
|
||||
*/
|
||||
#if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2
|
||||
REG_SET_FIELD(RTC_CNTL_REGULATOR_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1
|
||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
|
||||
#endif
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
|
||||
|
||||
/* enable modem clk */
|
||||
REG_WRITE(SYSTEM_MODEM_CLK_EN_REG, UINT32_MAX);
|
||||
|
||||
/* Configure 150k clock division */
|
||||
rtc_clk_divider_set(cfg.clk_rtc_clk_div);
|
||||
|
||||
/* Configure 8M clock division */
|
||||
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
|
||||
|
||||
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
|
||||
esp_rom_uart_tx_wait_idle(0);
|
||||
rtc_clk_xtal_freq_update(xtal_freq);
|
||||
rtc_clk_apb_freq_update(rtc_clk_apb_freq_get());
|
||||
|
||||
/* Set CPU frequency */
|
||||
rtc_clk_cpu_freq_get_config(&old_config);
|
||||
uint32_t freq_before = old_config.freq_mhz;
|
||||
|
||||
rtc_clk_select_root_clk(cfg.root_clk_slt);
|
||||
bool res = rtc_clk_cpu_freq_mhz_to_config(cfg.cpu_freq_mhz, &new_config);
|
||||
if (!res) {
|
||||
ESP_HW_LOGE(TAG, "invalid CPU frequency value");
|
||||
abort();
|
||||
}
|
||||
rtc_clk_cpu_freq_set_config(&new_config);
|
||||
|
||||
/* Re-calculate the ccount to make time calculation correct. */
|
||||
esp_cpu_set_cycle_count( (uint64_t)esp_cpu_get_cycle_count() * cfg.cpu_freq_mhz / freq_before );
|
||||
|
||||
/* Slow & fast clocks setup */
|
||||
if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
rtc_clk_32k_enable(true);
|
||||
}
|
||||
if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) {
|
||||
rtc_dig_clk8m_enable();
|
||||
}
|
||||
rtc_clk_fast_src_set(cfg.fast_clk_src);
|
||||
rtc_clk_slow_src_set(cfg.slow_clk_src);
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/extmem_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "i2c_pmu.h"
|
||||
#include "soc/clkrst_reg.h"
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "esp_private/sar_periph_ctrl.h"
|
||||
#endif
|
||||
|
||||
void pmu_ctl(void);
|
||||
void dcdc_ctl(uint32_t mode);
|
||||
void regulator_slt(regulator_config_t regula_cfg);
|
||||
|
||||
void rtc_init(rtc_config_t cfg)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, cfg.ck8m_wait);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
|
||||
|
||||
// set default powerup & wait time
|
||||
rtc_init_config_t rtc_init_cfg = RTC_INIT_CONFIG_DEFAULT();
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_POWERUP_TIMER, rtc_init_cfg.wifi_powerup_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_WAIT_TIMER, rtc_init_cfg.wifi_wait_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_POWERUP_TIMER, rtc_init_cfg.bt_powerup_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_WAIT_TIMER, rtc_init_cfg.bt_wait_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_POWERUP_TIMER, rtc_init_cfg.cpu_top_powerup_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_WAIT_TIMER, rtc_init_cfg.cpu_top_wait_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_POWERUP_TIMER, rtc_init_cfg.dg_wrap_powerup_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_WAIT_TIMER, rtc_init_cfg.dg_wrap_wait_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_POWERUP_TIMER, rtc_init_cfg.dg_peri_powerup_cycles);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_WAIT_TIMER, rtc_init_cfg.dg_peri_wait_cycles);
|
||||
|
||||
if (cfg.clkctl_init) {
|
||||
//clear CMMU clock force on
|
||||
CLEAR_PERI_REG_MASK(EXTMEM_CACHE_MMU_POWER_CTRL_REG, EXTMEM_CACHE_MMU_MEM_FORCE_ON);
|
||||
//clear tag clock force on
|
||||
CLEAR_PERI_REG_MASK(EXTMEM_ICACHE_TAG_POWER_CTRL_REG, EXTMEM_ICACHE_TAG_MEM_FORCE_ON);
|
||||
//clear register clock force on
|
||||
CLEAR_PERI_REG_MASK(SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLK_EN);
|
||||
}
|
||||
|
||||
if (cfg.pwrctl_init) {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
|
||||
//cancel xtal force pu if no need to force power up
|
||||
//cannot cancel xtal force pu if pll is force power on
|
||||
if (!(cfg.xtal_fpu | cfg.bbpll_fpu)) {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU);
|
||||
}
|
||||
// force pd APLL
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
|
||||
|
||||
if (!cfg.bbpll_fpu) {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_I2C_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_FORCE_PU);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_I2C_FORCE_PU);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_REGULATOR_REG, RTC_CNTL_REGULATOR_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_REGULATOR_REG, RTC_CNTL_DBOOST_FORCE_PU);
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PU);
|
||||
#endif
|
||||
|
||||
// clear i2c_reset_protect pd force, need tested in low temperature.
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,RTC_CNTL_I2C_RESET_POR_FORCE_PD);
|
||||
|
||||
/* If this mask is enabled, all soc memories cannot enter power down mode */
|
||||
/* We should control soc memory power down mode from RTC, so we will not touch this register any more */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_MEM_PD_MASK_REG, SYSTEM_LSLP_MEM_PD_MASK);
|
||||
|
||||
/* If this pd_cfg is set to 1, all memory won't enter low power mode during light sleep */
|
||||
/* If this pd_cfg is set to 0, all memory will enter low power mode during light sleep */
|
||||
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(0);
|
||||
rtc_sleep_pu(pu_cfg);
|
||||
|
||||
//cancel digital PADS force pu
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU); //
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_MEM_FORCE_PU); //
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU); //
|
||||
|
||||
//cancel digital PADS force no iso
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_WRAP_FORCE_NOISO);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CPU_TOP_FORCE_NOISO);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PERI_FORCE_NOISO);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_NOISO);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO); //
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_MEM_FORCE_NOISO); //
|
||||
|
||||
if (cfg.cpu_waiti_clk_gate) {
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON);
|
||||
}
|
||||
/*if SYSTEM_CPU_WAIT_MODE_FORCE_ON == 0 , the cpu clk will be closed when cpu enter WAITI mode*/
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
|
||||
}
|
||||
|
||||
REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
|
||||
REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX);
|
||||
if (cfg.pmu_ctl) {
|
||||
/* pmu init*/
|
||||
pmu_ctl();
|
||||
}
|
||||
/* config dcdc frequency */
|
||||
REG_SET_FIELD(RTC_CNTL_DCDC_CTRL0_REG, RTC_CNTL_FSW_DCDC, RTC_CNTL_DCDC_FREQ_DEFAULT);
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
//initialise SAR related peripheral register settings
|
||||
sar_periph_ctrl_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void pmu_ctl(void)
|
||||
{
|
||||
pmu_config_t pmu_cfg = PMU_CONFIG_DEFAULT();
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_EN_CONT_CAL, pmu_cfg.or_en_cont_cal);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_ENX_RTC_DREG, pmu_cfg.enx_rtc_dreg);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_ENX_DIG_DREG, pmu_cfg.enx_dig_dreg);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, pmu_cfg.en_i2c_rtc_dreg);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, pmu_cfg.en_i2c_dig_dreg);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG_SLP, pmu_cfg.en_i2c_rtc_dreg_slp);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG_SLP, pmu_cfg.en_i2c_dig_dreg_slp);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_RTC_SLAVE_3P3, pmu_cfg.or_xpd_rtc_slave_3p3);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_RTC_REG, pmu_cfg.or_xpd_rtc_reg);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_DIG_REG, pmu_cfg.or_xpd_dig_reg);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_PD_RTC_REG_SLP, pmu_cfg.or_pd_rtc_reg_slp);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_PD_DIG_REG_SLP, pmu_cfg.or_pd_dig_reg_slp);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_DCDC, pmu_cfg.or_xpd_dcdc);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_DISALBE_DEEP_SLEEP_DCDC, pmu_cfg.or_disalbe_deep_sleep_dcdc);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_DISALBE_LIGHT_SLEEP_DCDC, pmu_cfg.or_disalbe_light_sleep_dcdc);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_ENALBE_TRX_MODE_DCDC, pmu_cfg.or_enalbe_trx_mode_dcdc);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_ENX_REG_DCDC, pmu_cfg.or_enx_reg_dcdc);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_UNLOCK_DCDC, pmu_cfg.or_unlock_dcdc);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_FORCE_LOCK_DCDC, pmu_cfg.or_force_lock_dcdc);
|
||||
// REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_ENB_SLOW_CLK, pmu_cfg.or_enb_slow_clk);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_TRX, pmu_cfg.or_xpd_trx);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_EN_RESET_CHIP, pmu_cfg.or_en_reset_chip);
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_FORCE_XPD_REG_SLAVE, pmu_cfg.or_force_xpd_reg_slave);
|
||||
}
|
||||
|
||||
void dslp_osc_pd(void){
|
||||
REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG,RTC_CNTL_RC32K_XPD, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_PLL8M_REG, RTC_CNTL_XPD_PLL8M, 0);
|
||||
}
|
@ -1,397 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/bb_reg.h"
|
||||
#include "soc/nrx_reg.h"
|
||||
#include "soc/fe_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "esp32h4/rom/ets_sys.h"
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "soc/regi2c_bias.h"
|
||||
#include "soc/regi2c_ulp.h"
|
||||
#include "i2c_pmu.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "esp_rom_uart.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2
|
||||
#define RTC_CNTL_DIG_REGULATOR_REG1 RTC_CNTL_DIG_REGULATOR_REG
|
||||
#define RTC_CNTL_DIG_REGULATOR_REG2 RTC_CNTL_DIG_REGULATOR_REG
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1
|
||||
#define RTC_CNTL_DIG_REGULATOR_REG1 RTC_CNTL_DIGULATOR_REG
|
||||
#define RTC_CNTL_DIG_REGULATOR_REG2 RTC_CNTL_REG
|
||||
#define RTC_CNTL_DIG_REGULATOR1_DBIAS_REG RTC_CNTL_DIGULATOR1_DBIAS_REG
|
||||
#define RTC_CNTL_DIG_REGULATOR0_DBIAS_REG RTC_CNTL_DIGULATOR0_DBIAS_REG
|
||||
#define RTC_CNTL_REGULATOR1_DBIAS_REG RTC_CNTL_RTCULATOR1_DBIAS_REG
|
||||
#define RTC_CNTL_REGULATOR0_DBIAS_REG RTC_CNTL_RTCULATOR0_DBIAS_REG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Configure whether certain peripherals are powered down in deep sleep
|
||||
* @param cfg power down flags as rtc_sleep_pu_config_t structure
|
||||
*/
|
||||
static const char *TAG = "rtc_sleep";
|
||||
|
||||
void rtc_sleep_pu(rtc_sleep_pu_config_t cfg)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
|
||||
REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_DC_MEM_FORCE_PU, cfg.fe_fpu);
|
||||
REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
|
||||
REG_SET_FIELD(SYSCON_FRONT_END_MEM_PD_REG, SYSCON_AGC_MEM_FORCE_PU, cfg.fe_fpu);
|
||||
REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
|
||||
REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
|
||||
REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
|
||||
REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
|
||||
REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
|
||||
REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
|
||||
REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
|
||||
if (cfg.sram_fpu) {
|
||||
REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, SYSCON_SRAM_POWER_UP);
|
||||
} else {
|
||||
REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_SRAM_POWER_UP, 0);
|
||||
}
|
||||
if (cfg.rom_ram_fpu) {
|
||||
REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, SYSCON_ROM_POWER_UP);
|
||||
} else {
|
||||
REG_SET_FIELD(SYSCON_MEM_POWER_UP_REG, SYSCON_ROM_POWER_UP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void dcdc_ctl(uint32_t mode)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_DCDC_CTRL1_REG, RTC_CNTL_DCDC_MODE_IDLE, RTC_CNTL_DCDC_TRX_MODE);
|
||||
REG_SET_FIELD(RTC_CNTL_DCDC_CTRL1_REG, RTC_CNTL_DCDC_MODE_MONITOR, RTC_CNTL_DCDC_TRX_MODE);
|
||||
if ((mode & 0x10) == 0x10) {
|
||||
REG_SET_FIELD(RTC_CNTL_DCDC_CTRL1_REG, RTC_CNTL_DCDC_MODE_SLP, mode);
|
||||
} else if (mode == 0) {
|
||||
REG_SET_FIELD(RTC_CNTL_DCDC_CTRL1_REG, RTC_CNTL_DCDC_MODE_SLP, RTC_CNTL_DCDC_TRX_MODE);
|
||||
} else if (mode == 1) {
|
||||
REG_SET_FIELD(RTC_CNTL_DCDC_CTRL1_REG, RTC_CNTL_DCDC_MODE_SLP, RTC_CNTL_DCDC_LSLP_MODE);
|
||||
} else if (mode == 2) {
|
||||
REG_SET_FIELD(RTC_CNTL_DCDC_CTRL1_REG, RTC_CNTL_DCDC_MODE_SLP, RTC_CNTL_DCDC_DSLP_MODE);
|
||||
} else {
|
||||
ESP_HW_LOGE(TAG, "invalid dcdc mode!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void regulator_set(regulator_cfg_t cfg)
|
||||
{
|
||||
// DIG REGULATOR0
|
||||
if (cfg.dig_regul0_en) {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_FORCE_PU, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_FORCE_PD, 0);
|
||||
} else {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_FORCE_PU, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_FORCE_PD, 1);
|
||||
}
|
||||
// DIG REGULATOR1
|
||||
if (cfg.dig_regul1_en) {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_SLP_FORCE_PU, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_SLP_FORCE_PD, 0);
|
||||
} else {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_SLP_FORCE_PU, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_REGULATOR_SLP_FORCE_PD, 1);
|
||||
}
|
||||
// RTC REGULATOR0
|
||||
if (cfg.rtc_regul0_en) {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_REGULATOR_FORCE_PU, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_REGULATOR_FORCE_PD, 0);
|
||||
} else {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_REGULATOR_FORCE_PU, 0);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_REGULATOR_FORCE_PD, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void regulator_slt(regulator_config_t regula_cfg)
|
||||
{
|
||||
// dig regulator
|
||||
if (regula_cfg.dig_source == 1) {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR1_DBIAS_REG, RTC_CNTL_DIG_REGULATOR1_DBIAS_SLP, regula_cfg.dig_slp_dbias);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR1_DBIAS_REG, RTC_CNTL_DIG_REGULATOR1_DBIAS_ACTIVE, regula_cfg.dig_active_dbias);
|
||||
} else {
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR0_DBIAS_REG, RTC_CNTL_DIG_REGULATOR0_DBIAS_SLP, regula_cfg.dig_slp_dbias);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR0_DBIAS_REG, RTC_CNTL_DIG_REGULATOR0_DBIAS_ACTIVE, regula_cfg.dig_active_dbias);
|
||||
}
|
||||
// rtc regulator
|
||||
if (regula_cfg.rtc_source == 1) {
|
||||
REG_SET_FIELD(RTC_CNTL_REGULATOR1_DBIAS_REG, RTC_CNTL_REGULATOR1_DBIAS_SLP, regula_cfg.rtc_slp_dbias);
|
||||
REG_SET_FIELD(RTC_CNTL_REGULATOR1_DBIAS_REG, RTC_CNTL_REGULATOR1_DBIAS_ACTIVE, regula_cfg.rtc_active_dbias);
|
||||
} else {
|
||||
REG_SET_FIELD(RTC_CNTL_REGULATOR0_DBIAS_REG, RTC_CNTL_REGULATOR0_DBIAS_SLP, regula_cfg.rtc_slp_dbias);
|
||||
REG_SET_FIELD(RTC_CNTL_REGULATOR0_DBIAS_REG, RTC_CNTL_REGULATOR0_DBIAS_ACTIVE, regula_cfg.rtc_active_dbias);
|
||||
}
|
||||
}
|
||||
|
||||
void dbias_switch_set(dbias_swt_cfg_t cfg)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_DBIAS_SWITCH_IDLE, cfg.swt_idle);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_DBIAS_SWITCH_MONITOR, cfg.swt_monitor);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_DBIAS_SWITCH_SLP, cfg.swt_slp);
|
||||
}
|
||||
|
||||
void left_up_trx_fpu(bool fpu)
|
||||
{
|
||||
if (fpu) {
|
||||
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_FORCE_DISABLE_BIAS_SLEEP, 0);
|
||||
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_BIAS_BUF, 0);
|
||||
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_IPH, 0);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_XPD_TRX_FORCE_PU);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_XPD_TRX_FORCE_PU);
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_sleep_pmu_init(void)
|
||||
{
|
||||
dcdc_ctl(DCDC_SLP_DSLP_MODE);
|
||||
dbias_swt_cfg_t swt_cfg = DBIAS_SWITCH_CONFIG_DEFAULT();
|
||||
dbias_switch_set(swt_cfg);
|
||||
regulator_config_t regula0_cfg = REGULATOR0_CONFIG_DEFAULT();
|
||||
regulator_slt(regula0_cfg);
|
||||
regulator_config_t regula1_cfg = REGULATOR1_CONFIG_DEFAULT();
|
||||
regulator_slt(regula1_cfg);
|
||||
regulator_cfg_t rg_set = REGULATOR_SET_DEFAULT();
|
||||
regulator_set(rg_set);
|
||||
left_up_trx_fpu(0);
|
||||
}
|
||||
|
||||
void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_config)
|
||||
{
|
||||
*out_config = (rtc_sleep_config_t) {
|
||||
.lslp_mem_inf_fpu = 0,
|
||||
.rtc_mem_inf_follow_cpu = ((sleep_flags) & RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU) ? 1 : 0,
|
||||
.rtc_fastmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_FAST_MEM) ? 1 : 0,
|
||||
.rtc_slowmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0,
|
||||
.rtc_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0,
|
||||
.dig_ret_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_RET) ? 1 : 0,
|
||||
.bt_pd_en = ((sleep_flags) & RTC_SLEEP_PD_BT) ? 1 : 0,
|
||||
.cpu_pd_en = ((sleep_flags) & RTC_SLEEP_PD_CPU) ? 1 : 0,
|
||||
.int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0,
|
||||
.dig_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0,
|
||||
.deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0,
|
||||
.wdt_flashboot_mod_en = 0,
|
||||
.vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0,
|
||||
.xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1,
|
||||
.deep_slp_reject = 1,
|
||||
.light_slp_reject = 1
|
||||
};
|
||||
|
||||
if ((sleep_flags) & RTC_SLEEP_PD_DIG) {
|
||||
out_config->dig_dbias_wak = RTC_CNTL_DBIAS_1V10;
|
||||
out_config->dig_dbias_slp = RTC_CNTL_DBIAS_SLP;
|
||||
out_config->rtc_dbias_wak = RTC_CNTL_DBIAS_1V10;
|
||||
out_config->rtc_dbias_slp = RTC_CNTL_DBIAS_SLP;
|
||||
|
||||
out_config->bias_sleep_monitor = RTC_CNTL_BIASSLP_MONITOR_DEFAULT;
|
||||
out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_DEFAULT;
|
||||
out_config->pd_cur_monitor = RTC_CNTL_PD_CUR_MONITOR_DEFAULT;
|
||||
out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_DEFAULT;
|
||||
} else {
|
||||
out_config->dig_dbias_wak = RTC_CNTL_DBIAS_1V10;
|
||||
out_config->dig_dbias_slp = !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 : RTC_CNTL_DBIAS_SLP;
|
||||
out_config->rtc_dbias_wak = RTC_CNTL_DBIAS_1V10;
|
||||
out_config->rtc_dbias_slp = !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 : RTC_CNTL_DBIAS_SLP;
|
||||
|
||||
out_config->bias_sleep_monitor = RTC_CNTL_BIASSLP_MONITOR_DEFAULT;
|
||||
out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_DEFAULT;
|
||||
out_config->pd_cur_monitor = RTC_CNTL_PD_CUR_MONITOR_DEFAULT;
|
||||
out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_sleep_init(rtc_sleep_config_t cfg)
|
||||
{
|
||||
if (cfg.lslp_mem_inf_fpu) {
|
||||
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
|
||||
rtc_sleep_pu(pu_cfg);
|
||||
}
|
||||
if (cfg.bt_pd_en) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
|
||||
}
|
||||
if (cfg.cpu_pd_en) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
|
||||
}
|
||||
if (cfg.dig_peri_pd_en) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
|
||||
}
|
||||
if (cfg.dig_ret_pd_en) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_RET_PD_EN);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_RET_PD_EN);
|
||||
}
|
||||
|
||||
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, cfg.bias_sleep_monitor);
|
||||
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, cfg.bias_sleep_slp);
|
||||
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, cfg.pd_cur_monitor);
|
||||
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, cfg.pd_cur_slp);
|
||||
|
||||
// ESP32-H4 TO-DO: IDF-3693
|
||||
if (cfg.deep_slp) {
|
||||
// REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
|
||||
// CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_REGULATOR_FORCE_PU);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
|
||||
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
|
||||
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_VDD_DRV_B_SLP_EN);
|
||||
REG_SET_FIELD(RTC_CNTL_DIG_REGULATOR_REG1, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
|
||||
// SET_PERI_REG_MASK(RTC_CNTL_DIG_REGULATOR_REG2, RTC_CNTL_REGULATOR_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
|
||||
}
|
||||
|
||||
if (!cfg.int_8m_pd_en) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING);
|
||||
}
|
||||
|
||||
/* enable VDDSDIO control by state machine */
|
||||
REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
|
||||
REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
|
||||
|
||||
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
|
||||
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
|
||||
|
||||
/* gating XTAL clock */
|
||||
REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING);
|
||||
esp_rom_uart_tx_wait_idle(0);
|
||||
|
||||
}
|
||||
|
||||
void rtc_sleep_low_init(uint32_t slowclk_period)
|
||||
{
|
||||
// set 5 PWC state machine times to fit in main state machine time
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu);
|
||||
|
||||
uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
|
||||
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_SLEEP_REJECT_ENA, reject_opt);
|
||||
|
||||
/* Start entry into sleep mode */
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
while (GET_PERI_REG_MASK(RTC_CNTL_INT_RAW_REG,
|
||||
RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) == 0) {
|
||||
;
|
||||
}
|
||||
|
||||
return rtc_sleep_finish(lslp_mem_inf_fpu);
|
||||
}
|
||||
|
||||
#define STR2(X) #X
|
||||
#define STR(X) STR2(X)
|
||||
|
||||
uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, reject_opt);
|
||||
|
||||
/* Calculate RTC Fast Memory CRC (for wake stub) & go to deep sleep
|
||||
|
||||
Because we may be running from RTC memory as stack, we can't easily call any
|
||||
functions to do this (as registers will spill to stack, corrupting the CRC).
|
||||
|
||||
Instead, load all the values we need into registers then use register ops only to calculate
|
||||
the CRC value, write it to the RTC CRC value register, and immediately go into deep sleep.
|
||||
*/
|
||||
|
||||
/* Values used to set the SYSTEM_RTC_FASTMEM_CONFIG_REG value */
|
||||
const unsigned CRC_START_ADDR = 0;
|
||||
const unsigned CRC_LEN = 0x7ff;
|
||||
|
||||
asm volatile(
|
||||
/* Start CRC calculation */
|
||||
"sw %1, 0(%0)\n" // set RTC_MEM_CRC_ADDR & RTC_MEM_CRC_LEN
|
||||
"or t0, %1, %2\n"
|
||||
"sw t0, 0(%0)\n" // set RTC_MEM_CRC_START
|
||||
|
||||
/* Wait for the CRC calculation to finish */
|
||||
".Lwaitcrc:\n"
|
||||
"fence\n"
|
||||
"lw t0, 0(%0)\n"
|
||||
"li t1, "STR(SYSTEM_RTC_MEM_CRC_FINISH)"\n"
|
||||
"and t0, t0, t1\n"
|
||||
"beqz t0, .Lwaitcrc\n"
|
||||
"not %2, %2\n" // %2 -> ~DPORT_RTC_MEM_CRC_START
|
||||
"and t0, t0, %2\n"
|
||||
"sw t0, 0(%0)\n" // clear RTC_MEM_CRC_START
|
||||
"fence\n"
|
||||
"not %2, %2\n" // %2 -> DPORT_RTC_MEM_CRC_START, probably unnecessary but gcc assumes inputs unchanged
|
||||
|
||||
/* Store the calculated value in RTC_MEM_CRC_REG */
|
||||
"lw t0, 0(%3)\n"
|
||||
"sw t0, 0(%4)\n"
|
||||
"fence\n"
|
||||
|
||||
/* Set register bit to go into deep sleep */
|
||||
"lw t0, 0(%5)\n"
|
||||
"or t0, t0, %6\n"
|
||||
"sw t0, 0(%5)\n"
|
||||
"fence\n"
|
||||
|
||||
/* Wait for sleep reject interrupt (never finishes if successful) */
|
||||
".Lwaitsleep:"
|
||||
"fence\n"
|
||||
"lw t0, 0(%7)\n"
|
||||
"and t0, t0, %8\n"
|
||||
"beqz t0, .Lwaitsleep\n"
|
||||
|
||||
:
|
||||
:
|
||||
"r" (SYSTEM_RTC_FASTMEM_CONFIG_REG), // %0
|
||||
"r" ( (CRC_START_ADDR << SYSTEM_RTC_MEM_CRC_START_S)
|
||||
| (CRC_LEN << SYSTEM_RTC_MEM_CRC_LEN_S)), // %1
|
||||
"r" (SYSTEM_RTC_MEM_CRC_START), // %2
|
||||
"r" (SYSTEM_RTC_FASTMEM_CRC_REG), // %3
|
||||
"r" (RTC_MEMORY_CRC_REG), // %4
|
||||
"r" (RTC_CNTL_STATE0_REG), // %5
|
||||
"r" (RTC_CNTL_SLEEP_EN), // %6
|
||||
"r" (RTC_CNTL_INT_RAW_REG), // %7
|
||||
"r" (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) // %8
|
||||
: "t0", "t1" // working registers
|
||||
);
|
||||
|
||||
return rtc_sleep_finish(0);
|
||||
}
|
||||
|
||||
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
|
||||
{
|
||||
/* In deep sleep mode, we never get here */
|
||||
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
|
||||
RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
|
||||
|
||||
/* restore config if it is a light sleep */
|
||||
if (lslp_mem_inf_fpu) {
|
||||
rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
|
||||
rtc_sleep_pu(pu_cfg);
|
||||
}
|
||||
return reject;
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp32h4/rom/ets_sys.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||
* This feature counts the number of XTAL clock cycles within a given number of
|
||||
* RTC_SLOW_CLK cycles.
|
||||
*
|
||||
* Slow clock calibration feature has two modes of operation: one-off and cycling.
|
||||
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
|
||||
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
|
||||
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
|
||||
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
|
||||
* enabled using TIMG_RTC_CALI_START bit.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
|
||||
* @param cal_clk which clock to calibrate
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||
*/
|
||||
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
/* On ESP32H4, choosing RTC_CAL_RTC_MUX results in calibration of
|
||||
* the 150k RTC clock regardless of the currenlty selected SLOW_CLK.
|
||||
* On the ESP32, it used the currently selected SLOW_CLK.
|
||||
* The following code emulates ESP32 behavior:
|
||||
*/
|
||||
if (cal_clk == RTC_CAL_RTC_MUX) {
|
||||
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
|
||||
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||
cal_clk = RTC_CAL_32K_XTAL;
|
||||
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
|
||||
cal_clk = RTC_CAL_RC32K;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable requested clock (150k clock is always on) */
|
||||
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||
clk_ll_xtal32k_digi_enable();
|
||||
}
|
||||
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
|
||||
if (cal_clk == RTC_CAL_RC32K && !dig_rc32k_enabled) {
|
||||
clk_ll_rc32k_digi_enable();
|
||||
}
|
||||
/* There may be another calibration process already running during we call this function,
|
||||
* so we should wait the last process is done.
|
||||
*/
|
||||
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
|
||||
/**
|
||||
* Set a small timeout threshold to accelerate the generation of timeout.
|
||||
* The internal circuit will be reset when the timeout occurs and will not affect the next calibration.
|
||||
*/
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1);
|
||||
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)
|
||||
&& !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
|
||||
}
|
||||
|
||||
/* Prepare calibration */
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
|
||||
/* Figure out how long to wait for calibration to finish */
|
||||
|
||||
/* Set timeout reg and expect time delay*/
|
||||
uint32_t expected_freq;
|
||||
if (cal_clk == RTC_CAL_32K_XTAL) {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||
} else if (cal_clk == RTC_CAL_RC32K) {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_RC32K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
expected_freq = SOC_CLK_RC32K_FREQ_APPROX;
|
||||
} else {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
|
||||
}
|
||||
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
|
||||
/* Start calibration */
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
|
||||
/* Wait for calibration to finish up to another us_time_estimate */
|
||||
esp_rom_delay_us(us_time_estimate * 3);
|
||||
uint32_t cal_val;
|
||||
while (true) {
|
||||
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
|
||||
cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
|
||||
break;
|
||||
}
|
||||
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
|
||||
cal_val = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
|
||||
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||
clk_ll_xtal32k_digi_disable();
|
||||
}
|
||||
/* if dig_rc32k was originally off and enabled due to calibration, then set back to off state */
|
||||
if (cal_clk == RTC_CAL_RC32K && !dig_rc32k_enabled) {
|
||||
clk_ll_rc32k_digi_disable();
|
||||
}
|
||||
|
||||
return cal_val;
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
|
||||
uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles;
|
||||
uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX);
|
||||
return ratio;
|
||||
}
|
||||
|
||||
static inline bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles)
|
||||
{
|
||||
uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768
|
||||
uint64_t delta = expected_xtal_cycles / 2000; // 5/10000
|
||||
return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta));
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
|
||||
|
||||
if ((cal_clk == RTC_CAL_32K_XTAL) && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
|
||||
uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
|
||||
uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
|
||||
return period;
|
||||
}
|
||||
|
||||
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
|
||||
{
|
||||
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
|
||||
* TODO: fix overflow.
|
||||
*/
|
||||
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
|
||||
}
|
||||
|
||||
uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
{
|
||||
return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
|
||||
}
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
return rtc_cntl_ll_get_rtc_time();
|
||||
}
|
||||
|
||||
void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_SLOW_CLK_NEXT_EDGE);
|
||||
while (GET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_SLOW_CLK_NEXT_EDGE)) {
|
||||
esp_rom_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
|
||||
{
|
||||
if (cal_val == 0) {
|
||||
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
|
||||
}
|
||||
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* SAR related peripherals are interdependent. This file
|
||||
* provides a united control to these registers, as multiple
|
||||
* components require these controls.
|
||||
*
|
||||
* Related peripherals are:
|
||||
* - ADC
|
||||
* - PWDET
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_private/sar_periph_ctrl.h"
|
||||
#include "hal/sar_ctrl_ll.h"
|
||||
|
||||
static const char *TAG = "sar_periph_ctrl";
|
||||
extern portMUX_TYPE rtc_spinlock;
|
||||
|
||||
|
||||
void sar_periph_ctrl_init(void)
|
||||
{
|
||||
//TODO: IDF-6123
|
||||
}
|
||||
|
||||
void sar_periph_ctrl_power_enable(void)
|
||||
{
|
||||
//TODO: IDF-6123
|
||||
}
|
||||
|
||||
void sar_periph_ctrl_power_disable(void)
|
||||
{
|
||||
//TODO: IDF-6123
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets incremented when s_sar_power_acquire() is called,
|
||||
* and decremented when s_sar_power_release() is called.
|
||||
* PWDET is powered down when the value reaches zero.
|
||||
* Should be modified within critical section.
|
||||
*/
|
||||
static int s_pwdet_power_on_cnt;
|
||||
|
||||
static void s_sar_power_acquire(void)
|
||||
{
|
||||
portENTER_CRITICAL_SAFE(&rtc_spinlock);
|
||||
s_pwdet_power_on_cnt++;
|
||||
if (s_pwdet_power_on_cnt == 1) {
|
||||
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_ON);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&rtc_spinlock);
|
||||
}
|
||||
|
||||
static void s_sar_power_release(void)
|
||||
{
|
||||
portENTER_CRITICAL_SAFE(&rtc_spinlock);
|
||||
s_pwdet_power_on_cnt--;
|
||||
if (s_pwdet_power_on_cnt < 0) {
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
ESP_LOGE(TAG, "%s called, but s_pwdet_power_on_cnt == 0", __func__);
|
||||
abort();
|
||||
} else if (s_pwdet_power_on_cnt == 0) {
|
||||
sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&rtc_spinlock);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* PWDET Power
|
||||
*----------------------------------------------------------------------------*/
|
||||
void sar_periph_ctrl_pwdet_power_acquire(void)
|
||||
{
|
||||
s_sar_power_acquire();
|
||||
}
|
||||
|
||||
void sar_periph_ctrl_pwdet_power_release(void)
|
||||
{
|
||||
s_sar_power_release();
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* ADC Power
|
||||
*----------------------------------------------------------------------------*/
|
||||
void sar_periph_ctrl_adc_oneshot_power_acquire(void)
|
||||
{
|
||||
s_sar_power_acquire();
|
||||
}
|
||||
|
||||
void sar_periph_ctrl_adc_oneshot_power_release(void)
|
||||
{
|
||||
s_sar_power_release();
|
||||
}
|
||||
|
||||
void sar_periph_ctrl_adc_continuous_power_acquire(void)
|
||||
{
|
||||
s_sar_power_acquire();
|
||||
}
|
||||
|
||||
void sar_periph_ctrl_adc_continuous_power_release(void)
|
||||
{
|
||||
s_sar_power_release();
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_private/systimer.h"
|
||||
|
||||
/**
|
||||
* @brief systimer's clock source is fixed to XTAL (32MHz), and has a fixed fractional divider (2.0).
|
||||
* So the resolution of the systimer is 32MHz/2.0 = 16MHz.
|
||||
*/
|
||||
|
||||
uint64_t systimer_ticks_to_us(uint64_t ticks)
|
||||
{
|
||||
return ticks / 16;
|
||||
}
|
||||
|
||||
uint64_t systimer_us_to_ticks(uint64_t us)
|
||||
{
|
||||
return us * 16;
|
||||
}
|
@ -76,8 +76,6 @@
|
||||
#include "esp_private/mspi_timing_tuning.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#include "esp32c2/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
@ -115,9 +113,6 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (105)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37)
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (105)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37)
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
||||
|
@ -41,8 +41,6 @@
|
||||
#include "esp32s3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
#include "esp32c6/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
|
@ -40,9 +40,6 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rtc.h"
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#include "esp32h4/rtc.h"
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#include "esp32c2/rtc.h"
|
||||
#include "esp32c2/rom/rtc.h"
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "../ext_mem_layout.h"
|
||||
|
||||
/**
|
||||
* The start addresses in this list should always be sorted from low to high, as MMU driver will need to
|
||||
* coalesce adjacent regions
|
||||
*/
|
||||
const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = {
|
||||
[0] = {
|
||||
.start = SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW,
|
||||
.end = SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH,
|
||||
.size = BUS_SIZE(SOC_MMU_IRAM0_LINEAR),
|
||||
.bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0,
|
||||
.targets = MMU_TARGET_FLASH0,
|
||||
.caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT,
|
||||
},
|
||||
};
|
@ -25,14 +25,6 @@ if(NOT ${target} STREQUAL "esp32" AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
|
||||
list(APPEND srcs "cache_hal.c")
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32h4")
|
||||
if(CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1)
|
||||
list(APPEND includes "${target}/include/rev1")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2)
|
||||
list(APPEND includes "${target}/include/rev2")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs
|
||||
"rtc_io_hal.c"
|
||||
@ -221,13 +213,6 @@ if(NOT BOOTLOADER_BUILD)
|
||||
"esp32c3/rtc_cntl_hal.c")
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32h4")
|
||||
list(APPEND srcs
|
||||
"spi_flash_hal_gpspi.c"
|
||||
"aes_hal.c"
|
||||
"esp32h4/rtc_cntl_hal.c")
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32c2")
|
||||
list(APPEND srcs
|
||||
"spi_flash_hal_gpspi.c"
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/clk_tree_hal.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/log.h"
|
||||
|
||||
static const char *CLK_HAL_TAG = "clk_hal";
|
||||
|
||||
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
|
||||
{
|
||||
switch (cpu_clk_src) {
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
return clk_hal_xtal_get_freq_mhz();
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
return clk_ll_bbpll_get_freq_mhz();
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
|
||||
case SOC_CPU_CLK_SRC_XTAL_D2:
|
||||
return clk_hal_xtal_get_freq_mhz() >> 1;
|
||||
default:
|
||||
// Unknown CPU_CLK mux input
|
||||
HAL_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t clk_hal_cpu_get_freq_hz(void)
|
||||
{
|
||||
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
|
||||
}
|
||||
|
||||
uint32_t clk_hal_ahb_get_freq_hz(void)
|
||||
{
|
||||
return clk_hal_cpu_get_freq_hz() / clk_ll_ahb_get_divider();
|
||||
}
|
||||
|
||||
uint32_t clk_hal_apb_get_freq_hz(void)
|
||||
{
|
||||
return clk_hal_ahb_get_freq_hz() / clk_ll_apb_get_divider();
|
||||
}
|
||||
|
||||
uint32_t clk_hal_lp_slow_get_freq_hz(void)
|
||||
{
|
||||
switch (clk_ll_rtc_slow_get_src()) {
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||
return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||
return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC32K:
|
||||
return SOC_CLK_RC32K_FREQ_APPROX;
|
||||
default:
|
||||
// Unknown RTC_SLOW_CLK mux input
|
||||
HAL_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t clk_hal_xtal_get_freq_mhz(void)
|
||||
{
|
||||
uint32_t freq = clk_ll_xtal_load_freq_mhz();
|
||||
if (freq == 0) {
|
||||
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 32MHz");
|
||||
return (uint32_t)RTC_XTAL_FREQ_32M;
|
||||
}
|
||||
return freq;
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 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"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x0F << (4 * (block))))
|
||||
|
||||
IRAM_ATTR uint32_t efuse_hal_get_major_chip_version(void)
|
||||
{
|
||||
return efuse_ll_get_chip_wafer_version_major();
|
||||
}
|
||||
|
||||
IRAM_ATTR 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;
|
||||
}
|
@ -1,862 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include "soc/adc_periph.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_types_private.h"
|
||||
#include "soc/apb_saradc_struct.h"
|
||||
#include "soc/apb_saradc_reg.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
|
||||
#include "soc/regi2c_saradc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31)
|
||||
#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Oneshot
|
||||
---------------------------------------------------------------*/
|
||||
#define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0)
|
||||
#define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) ((PERIPH_NUM==0)? 2 : 1)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
DMA
|
||||
---------------------------------------------------------------*/
|
||||
#define ADC_LL_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (0)
|
||||
#define ADC_LL_FSM_RSTB_WAIT_DEFAULT (8)
|
||||
#define ADC_LL_FSM_START_WAIT_DEFAULT (5)
|
||||
#define ADC_LL_FSM_STANDBY_WAIT_DEFAULT (100)
|
||||
#define ADC_LL_SAMPLE_CYCLE_DEFAULT (2)
|
||||
#define ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT (1)
|
||||
|
||||
#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15
|
||||
#define ADC_LL_CLKM_DIV_B_DEFAULT 1
|
||||
#define ADC_LL_CLKM_DIV_A_DEFAULT 0
|
||||
#define ADC_LL_DEFAULT_CONV_LIMIT_EN 0
|
||||
#define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
PWDET (Power Detect)
|
||||
---------------------------------------------------------------*/
|
||||
#define ADC_LL_PWDET_CCT_DEFAULT (4)
|
||||
|
||||
typedef enum {
|
||||
ADC_LL_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */
|
||||
ADC_LL_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
|
||||
ADC_LL_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */
|
||||
} adc_ll_power_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_LL_RTC_DATA_OK = 0,
|
||||
ADC_LL_RTC_CTRL_UNSELECTED = 1,
|
||||
ADC_LL_RTC_CTRL_BREAK = 2,
|
||||
ADC_LL_RTC_DATA_FAIL = -1,
|
||||
} adc_ll_rtc_raw_data_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_LL_CTRL_DIG = 0, ///< For ADC1. Select DIG controller.
|
||||
ADC_LL_CTRL_ARB = 1, ///< For ADC2. The controller is selected by the arbiter.
|
||||
} adc_ll_controller_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) work mode.
|
||||
*
|
||||
* @note The conversion mode affects the sampling frequency:
|
||||
* ESP32H4 only support ONLY_ADC1 mode
|
||||
* SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion
|
||||
} adc_ll_digi_convert_mode_t;
|
||||
|
||||
//These values should be set according to the HW
|
||||
typedef enum {
|
||||
ADC_LL_INTR_THRES1_LOW = BIT(26),
|
||||
ADC_LL_INTR_THRES0_LOW = BIT(27),
|
||||
ADC_LL_INTR_THRES1_HIGH = BIT(28),
|
||||
ADC_LL_INTR_THRES0_HIGH = BIT(29),
|
||||
ADC_LL_INTR_ADC2_DONE = BIT(30),
|
||||
ADC_LL_INTR_ADC1_DONE = BIT(31),
|
||||
} adc_ll_intr_t;
|
||||
FLAG_ATTR(adc_ll_intr_t)
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint8_t atten: 2;
|
||||
uint8_t channel: 3;
|
||||
uint8_t unit: 1;
|
||||
uint8_t reserved: 2;
|
||||
};
|
||||
uint8_t val;
|
||||
};
|
||||
} __attribute__((packed)) adc_ll_digi_pattern_table_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Set adc fsm interval parameter for digital controller. These values are fixed for same platforms.
|
||||
*
|
||||
* @param rst_wait cycles between DIG ADC controller reset ADC sensor and start ADC sensor.
|
||||
* @param start_wait Delay time after open xpd.
|
||||
* @param standby_wait Delay time to close xpd.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait)
|
||||
{
|
||||
// Internal FSM reset wait time
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.fsm_wait, rstb_wait, rst_wait);
|
||||
// Internal FSM start wait time
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.fsm_wait, xpd_wait, start_wait);
|
||||
// Internal FSM standby wait time
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.fsm_wait, standby_wait, standby_wait);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set adc sample cycle for digital controller.
|
||||
*
|
||||
* @note Normally, please use default value.
|
||||
* @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor.
|
||||
* Range: 2 ~ 0xFF.
|
||||
*/
|
||||
static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
|
||||
{
|
||||
/* Should be called before writing I2C registers. */
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SAR ADC module clock division factor.
|
||||
* SAR ADC clock divided from digital controller clock.
|
||||
*
|
||||
* @param div Division factor.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_clk_div(uint32_t div)
|
||||
{
|
||||
/* ADC clock divided from digital controller clock clk */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set adc max conversion number for digital controller.
|
||||
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
|
||||
*
|
||||
* @param meas_num Max conversion number. Range: 0 ~ 255.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl2, max_meas_num, meas_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable max conversion number detection for digital controller.
|
||||
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
|
||||
*
|
||||
* @param enable true: enable; false: disable
|
||||
*/
|
||||
static inline void adc_ll_digi_convert_limit_enable(bool enable)
|
||||
{
|
||||
APB_SARADC.ctrl2.meas_num_limit = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set adc conversion mode for digital controller.
|
||||
*
|
||||
* @note ESP32H4 only support ADC1 single mode.
|
||||
*
|
||||
* @param mode Conversion mode select.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode)
|
||||
{
|
||||
//ESP32H4 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pattern table length for digital controller.
|
||||
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 8 items, in which channel selection,
|
||||
* and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
|
||||
* pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param patt_len Items range: 1 ~ 8.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t patt_len)
|
||||
{
|
||||
APB_SARADC.ctrl.sar_patt_len = patt_len - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pattern table for digital controller.
|
||||
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 8 items, in which channel selection,
|
||||
* resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
|
||||
* pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param pattern_index Items index. Range: 0 ~ 7.
|
||||
* @param pattern Stored conversion rules.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table)
|
||||
{
|
||||
uint32_t tab;
|
||||
uint8_t index = pattern_index / 4;
|
||||
uint8_t offset = (pattern_index % 4) * 6;
|
||||
adc_ll_digi_pattern_table_t pattern = {0};
|
||||
|
||||
pattern.val = (table.atten & 0x3) | ((table.channel & 0x7) << 2) | ((table.unit & 0x1) << 5);
|
||||
tab = APB_SARADC.sar_patt_tab[index].sar_patt_tab1; // Read old register value
|
||||
tab &= (~(0xFC0000 >> offset)); // Clear old data
|
||||
tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; // Fill in the new data
|
||||
APB_SARADC.sar_patt_tab[index].sar_patt_tab1 = tab; // Write back
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the pattern table pointer, then take the measurement rule from table header in next measurement.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n)
|
||||
{
|
||||
APB_SARADC.ctrl.sar_patt_p_clear = 1;
|
||||
APB_SARADC.ctrl.sar_patt_p_clear = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize.
|
||||
*
|
||||
* @note Only ADC2 have arbiter function.
|
||||
* @param cycle range: 0 ~ 4.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_arbiter_stable_cycle(uint32_t cycle)
|
||||
{
|
||||
APB_SARADC.ctrl.wait_arb_cycle = cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC Digital controller output data invert or not.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param inv_en data invert or not.
|
||||
*/
|
||||
static inline void adc_ll_digi_output_invert(adc_unit_t adc_n, bool inv_en)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
APB_SARADC.ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert
|
||||
} else { // adc_n == ADC_UNIT_2
|
||||
APB_SARADC.ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the interval clock cycle for the digital controller to trigger the measurement.
|
||||
* Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval.
|
||||
*
|
||||
* @note The trigger interval should not be smaller than the sampling time of the SAR ADC.
|
||||
* @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle)
|
||||
{
|
||||
APB_SARADC.ctrl2.timer_target = cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable digital controller timer to trigger the measurement.
|
||||
*/
|
||||
static inline void adc_ll_digi_trigger_enable(void)
|
||||
{
|
||||
APB_SARADC.ctrl2.timer_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable digital controller timer to trigger the measurement.
|
||||
*/
|
||||
static inline void adc_ll_digi_trigger_disable(void)
|
||||
{
|
||||
APB_SARADC.ctrl2.timer_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
|
||||
* Expression: controller_clk = (APLL or APB) / (div_num + div_a / div_b + 1).
|
||||
*
|
||||
* @param div_num Division factor. Range: 0 ~ 255.
|
||||
* @param div_b Division factor. Range: 1 ~ 63.
|
||||
* @param div_a Division factor. Range: 0 ~ 63.
|
||||
*/
|
||||
static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.apb_adc_clkm_conf, clkm_div_num, div_num);
|
||||
APB_SARADC.apb_adc_clkm_conf.clkm_div_b = div_b;
|
||||
APB_SARADC.apb_adc_clkm_conf.clkm_div_a = div_a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable clock and select clock source for ADC digital controller.
|
||||
*
|
||||
* @param clk_src clock source for ADC digital controller.
|
||||
*/
|
||||
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
|
||||
{
|
||||
// TODO: temporary support
|
||||
APB_SARADC.apb_adc_clkm_conf.clk_sel = 0;
|
||||
APB_SARADC.ctrl.sar_clk_gated = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable clock for ADC digital controller.
|
||||
*/
|
||||
static inline void adc_ll_digi_controller_clk_disable(void)
|
||||
{
|
||||
APB_SARADC.ctrl.sar_clk_gated = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset adc digital controller filter.
|
||||
*
|
||||
* @param idx Filter index
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
|
||||
{
|
||||
(void)adc_n;
|
||||
APB_SARADC.filter_ctrl0.filter_reset = 1;
|
||||
APB_SARADC.filter_ctrl0.filter_reset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set adc digital controller filter coeff.
|
||||
*
|
||||
* @param idx filter index
|
||||
* @param adc_n adc unit
|
||||
* @param channel adc channel
|
||||
* @param coeff filter coeff
|
||||
*/
|
||||
static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
|
||||
{
|
||||
uint32_t factor_reg_val = 0;
|
||||
switch (coeff) {
|
||||
case ADC_DIGI_IIR_FILTER_COEFF_2:
|
||||
factor_reg_val = 1;
|
||||
break;
|
||||
case ADC_DIGI_IIR_FILTER_COEFF_4:
|
||||
factor_reg_val = 2;
|
||||
break;
|
||||
case ADC_DIGI_IIR_FILTER_COEFF_8:
|
||||
factor_reg_val = 3;
|
||||
break;
|
||||
case ADC_DIGI_IIR_FILTER_COEFF_16:
|
||||
factor_reg_val = 4;
|
||||
break;
|
||||
case ADC_DIGI_IIR_FILTER_COEFF_64:
|
||||
factor_reg_val = 6;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
|
||||
if (idx == ADC_DIGI_IIR_FILTER_0) {
|
||||
APB_SARADC.filter_ctrl0.filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7);
|
||||
APB_SARADC.filter_ctrl1.filter_factor0 = factor_reg_val;
|
||||
} else if (idx == ADC_DIGI_IIR_FILTER_1) {
|
||||
APB_SARADC.filter_ctrl0.filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7);
|
||||
APB_SARADC.filter_ctrl1.filter_factor1 = factor_reg_val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable adc digital controller filter.
|
||||
* Filtering the ADC data to obtain smooth data at higher sampling rates.
|
||||
*
|
||||
* @param idx filter index
|
||||
* @param adc_n ADC unit
|
||||
* @param enable Enable / Disable
|
||||
*/
|
||||
static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
|
||||
{
|
||||
(void)adc_n;
|
||||
if (!enable) {
|
||||
if (idx == ADC_DIGI_IIR_FILTER_0) {
|
||||
APB_SARADC.filter_ctrl0.filter_channel0 = 0xF;
|
||||
APB_SARADC.filter_ctrl1.filter_factor0 = 0;
|
||||
} else if (idx == ADC_DIGI_IIR_FILTER_1) {
|
||||
APB_SARADC.filter_ctrl0.filter_channel1 = 0xF;
|
||||
APB_SARADC.filter_ctrl1.filter_factor1 = 0;
|
||||
}
|
||||
}
|
||||
//nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled.
|
||||
}
|
||||
|
||||
/**
|
||||
* Set monitor mode of adc digital controller.
|
||||
*
|
||||
* @note If the channel info is not supported, the monitor function will not be enabled.
|
||||
* @param adc_n ADC unit.
|
||||
* @param is_larger true: If ADC_OUT > threshold, Generates monitor interrupt.
|
||||
* false: If ADC_OUT < threshold, Generates monitor interrupt.
|
||||
*/
|
||||
static inline void adc_ll_digi_monitor_set_mode(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *cfg)
|
||||
{
|
||||
if (idx == ADC_DIGI_MONITOR_IDX0) {
|
||||
APB_SARADC.thres0_ctrl.thres0_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7);
|
||||
APB_SARADC.thres0_ctrl.thres0_high = cfg->h_threshold;
|
||||
APB_SARADC.thres0_ctrl.thres0_low = cfg->l_threshold;
|
||||
} else { // ADC_DIGI_MONITOR_IDX1
|
||||
APB_SARADC.thres1_ctrl.thres1_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7);
|
||||
APB_SARADC.thres1_ctrl.thres1_high = cfg->h_threshold;
|
||||
APB_SARADC.thres1_ctrl.thres1_low = cfg->l_threshold;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable monitor of adc digital controller.
|
||||
*
|
||||
* @note If the channel info is not supported, the monitor function will not be enabled.
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx)
|
||||
{
|
||||
if (idx == ADC_DIGI_MONITOR_IDX0) {
|
||||
APB_SARADC.thres0_ctrl.thres0_channel = 0xF;
|
||||
} else { // ADC_DIGI_MONITOR_IDX1
|
||||
APB_SARADC.thres1_ctrl.thres1_channel = 0xF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DMA eof num of adc digital controller.
|
||||
* If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated.
|
||||
*
|
||||
* @param num eof num of DMA.
|
||||
*/
|
||||
static inline void adc_ll_digi_dma_set_eof_num(uint32_t num)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable output data to DMA from adc digital controller.
|
||||
*/
|
||||
static inline void adc_ll_digi_dma_enable(void)
|
||||
{
|
||||
APB_SARADC.dma_conf.apb_adc_trans = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable output data to DMA from adc digital controller.
|
||||
*/
|
||||
static inline void adc_ll_digi_dma_disable(void)
|
||||
{
|
||||
APB_SARADC.dma_conf.apb_adc_trans = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset adc digital controller.
|
||||
*/
|
||||
static inline void adc_ll_digi_reset(void)
|
||||
{
|
||||
APB_SARADC.dma_conf.apb_adc_reset_fsm = 1;
|
||||
APB_SARADC.dma_conf.apb_adc_reset_fsm = 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
PWDET(Power detect) controller setting
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Set adc cct for PWDET controller.
|
||||
*
|
||||
* @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
|
||||
* @param cct Range: 0 ~ 7.
|
||||
*/
|
||||
static inline void adc_ll_pwdet_set_cct(uint32_t cct)
|
||||
{
|
||||
/* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get adc cct for PWDET controller.
|
||||
*
|
||||
* @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
|
||||
* @return cct Range: 0 ~ 7.
|
||||
*/
|
||||
static inline uint32_t adc_ll_pwdet_get_cct(void)
|
||||
{
|
||||
/* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
|
||||
abort();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Common setting
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Set ADC module power management.
|
||||
*
|
||||
* @param manage Set ADC power status.
|
||||
*/
|
||||
static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
|
||||
{
|
||||
//HW bug, use `sar_ctrl_ll_set_power_mode_from_pwdet` instead, `APB_SARADC.ctrl.xpd_sar_force` doesn not effect
|
||||
//Leave here for a record
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t ctrl)
|
||||
{
|
||||
//Not used on ESP32H4
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ADC2 module arbiter work mode.
|
||||
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
|
||||
* the low priority controller will read the invalid ADC data, and the validity of the data can be judged by the flag bit in the data.
|
||||
*
|
||||
* @note Only ADC2 support arbiter.
|
||||
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
|
||||
*
|
||||
* @param mode Refer to `adc_arbiter_mode_t`.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode)
|
||||
{
|
||||
if (mode == ADC_ARB_MODE_FIX) {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1;
|
||||
} else if (mode == ADC_ARB_MODE_LOOP) {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 0;
|
||||
} else {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 1; // Shield arbiter.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ADC2 module controller priority in arbiter.
|
||||
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
|
||||
* the low priority controller will read the invalid ADC data, and the validity of the data can be judged by the flag bit in the data.
|
||||
*
|
||||
* @note Only ADC2 support arbiter.
|
||||
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
|
||||
* @note Default priority: Wi-Fi(2) > RTC(1) > Digital(0);
|
||||
*
|
||||
* @param pri_rtc RTC controller priority. Range: 0 ~ 2.
|
||||
* @param pri_dig Digital controller priority. Range: 0 ~ 2.
|
||||
* @param pri_pwdet Wi-Fi controller priority. Range: 0 ~ 2.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void adc_ll_set_arbiter_priority(uint8_t pri_rtc, uint8_t pri_dig, uint8_t pri_pwdet)
|
||||
{
|
||||
if (pri_rtc != pri_dig && pri_rtc != pri_pwdet && pri_dig != pri_pwdet) {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_priority = pri_rtc;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_priority = pri_dig;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_priority = pri_pwdet;
|
||||
}
|
||||
/* Should select highest priority controller. */
|
||||
if (pri_rtc > pri_dig) {
|
||||
if (pri_rtc > pri_pwdet) {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 1;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0;
|
||||
} else {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1;
|
||||
}
|
||||
} else {
|
||||
if (pri_dig > pri_pwdet) {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 1;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0;
|
||||
} else {
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0;
|
||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ADC calibration code. */
|
||||
/**
|
||||
* @brief Set common calibration configuration. Should be shared with other parts (PWDET).
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void adc_ll_calibration_init(adc_unit_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_DREF_ADDR, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
* @param channel adc channel number.
|
||||
* @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage.
|
||||
* false: Use IO external voltage as calibration voltage.
|
||||
*/
|
||||
static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, adc_channel_t channel, bool internal_gnd)
|
||||
{
|
||||
/* Enable/disable internal connect GND (for calibration). */
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
if (internal_gnd) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
|
||||
}
|
||||
} else {
|
||||
if (internal_gnd) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 1);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume register status after calibration.
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
*/
|
||||
static inline void adc_ll_calibration_finish(adc_unit_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the calibration result to ADC.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param)
|
||||
{
|
||||
uint8_t msb = param >> 8;
|
||||
uint8_t lsb = param & 0xFF;
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, msb);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, lsb);
|
||||
}
|
||||
}
|
||||
/* Temp code end. */
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Single Read
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Set adc output data format for oneshot mode
|
||||
*
|
||||
* @note ESP32C3 Oneshot mode only supports 12bit.
|
||||
* @param adc_n ADC unit.
|
||||
* @param bits Output data bits width option.
|
||||
*/
|
||||
static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// //ESP32C3 only supports 12bit, leave here for compatibility
|
||||
// HAL_ASSERT(bits == ADC_BITWIDTH_12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable adc channel to start convert.
|
||||
*
|
||||
* @note Only one channel can be selected for measurement.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable adc channel to start convert.
|
||||
*
|
||||
* @note Only one channel can be selected in once measurement.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// if (adc_n == ADC_UNIT_1) {
|
||||
// APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0xF);
|
||||
// } else { // adc_n == ADC_UNIT_2
|
||||
// APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0x1);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Start oneshot conversion by software
|
||||
*
|
||||
* @param val Usage: set to 1 to start the ADC conversion. The step signal should at least keep 3 ADC digital controller clock cycle,
|
||||
* otherwise the step signal may not be captured by the ADC digital controller when its frequency is slow.
|
||||
* This hardware limitation will be removed in future versions.
|
||||
*/
|
||||
static inline void adc_oneshot_ll_start(bool val)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// APB_SARADC.onetime_sample.onetime_start = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the event for each ADCn for Oneshot mode
|
||||
*
|
||||
* @param event ADC event
|
||||
*/
|
||||
static inline void adc_oneshot_ll_clear_event(uint32_t event_mask)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// APB_SARADC.int_clr.val |= event_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the event for each ADCn for Oneshot mode
|
||||
*
|
||||
* @param event ADC event
|
||||
*
|
||||
* @return
|
||||
* -true : The conversion process is finish.
|
||||
* -false : The conversion process is not finish.
|
||||
*/
|
||||
static inline bool adc_oneshot_ll_get_event(uint32_t event_mask)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// return (APB_SARADC.int_raw.val & event_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the converted value for each ADCn for RTC controller.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @return
|
||||
* - Converted value.
|
||||
*/
|
||||
static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// uint32_t ret_val = 0;
|
||||
// if (adc_n == ADC_UNIT_1) {
|
||||
// ret_val = APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff;
|
||||
// } else { // adc_n == ADC_UNIT_2
|
||||
// ret_val = APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff;
|
||||
// }
|
||||
// return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze whether the obtained raw data is correct.
|
||||
* ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param raw_data ADC raw data input (convert value).
|
||||
* @return
|
||||
* - 1: The data is correct to use.
|
||||
* - 0: The data is invalid.
|
||||
*/
|
||||
static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// if (adc_n == ADC_UNIT_1) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// //The raw data API returns value without channel information. Read value directly from the register
|
||||
// if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 13) & 0xF) > 9) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module RTC output data invert or not.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param inv_en data invert or not.
|
||||
*/
|
||||
static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// (void)adc_n;
|
||||
// (void)inv_en;
|
||||
// //For compatibility
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable oneshot conversion trigger
|
||||
*
|
||||
* @param adc_n ADC unit
|
||||
*/
|
||||
static inline void adc_oneshot_ll_enable(adc_unit_t adc_n)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// if (adc_n == ADC_UNIT_1) {
|
||||
// APB_SARADC.onetime_sample.adc1_onetime_sample = 1;
|
||||
// } else {
|
||||
// APB_SARADC.onetime_sample.adc2_onetime_sample = 1;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable oneshot conversion trigger for all the ADC units
|
||||
*/
|
||||
static inline void adc_oneshot_ll_disable_all_unit(void)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// APB_SARADC.onetime_sample.adc1_onetime_sample = 0;
|
||||
// APB_SARADC.onetime_sample.adc2_onetime_sample = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attenuation
|
||||
*
|
||||
* @note Attenuation is for all channels
|
||||
*
|
||||
* @param adc_n ADC unit
|
||||
* @param channel ADC channel
|
||||
* @param atten ADC attenuation
|
||||
*/
|
||||
static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten)
|
||||
{
|
||||
abort(); //TODO IDF-3908
|
||||
// (void)adc_n;
|
||||
// (void)channel;
|
||||
// // Attenuation is for all channels, unit and channel are for compatibility
|
||||
// APB_SARADC.onetime_sample.onetime_atten = atten;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,225 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "hal/aes_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief State of AES accelerator, busy, idle or done
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_AES_STATE_IDLE = 0, /* AES accelerator is idle */
|
||||
ESP_AES_STATE_BUSY, /* Transform in progress */
|
||||
ESP_AES_STATE_DONE, /* Transform completed */
|
||||
} esp_aes_state_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write the encryption/decryption key to hardware
|
||||
*
|
||||
* @param key Key to be written to the AES hardware
|
||||
* @param key_word_len Number of words in the key
|
||||
*
|
||||
* @return Number of bytes written to hardware, used for fault injection check
|
||||
*/
|
||||
static inline uint8_t aes_ll_write_key(const uint8_t *key, size_t key_word_len)
|
||||
{
|
||||
/* This variable is used for fault injection checks, so marked volatile to avoid optimisation */
|
||||
volatile uint8_t key_in_hardware = 0;
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
uint32_t key_word;
|
||||
for (int i = 0; i < key_word_len; i++) {
|
||||
memcpy(&key_word, key + 4 * i, 4);
|
||||
REG_WRITE(AES_KEY_BASE + i * 4, key_word);
|
||||
key_in_hardware += 4;
|
||||
}
|
||||
return key_in_hardware;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the mode
|
||||
*
|
||||
* @param mode ESP_AES_ENCRYPT = 1, or ESP_AES_DECRYPT = 0
|
||||
* @param key_bytes Number of bytes in the key
|
||||
*/
|
||||
static inline void aes_ll_set_mode(int mode, uint8_t key_bytes)
|
||||
{
|
||||
const uint32_t MODE_DECRYPT_BIT = 4;
|
||||
unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT;
|
||||
|
||||
/* See TRM for the mapping between keylength and mode bit */
|
||||
REG_WRITE(AES_MODE_REG, mode_reg_base + ((key_bytes / 8) - 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes message block to AES hardware
|
||||
*
|
||||
* @param input Block to be written
|
||||
*/
|
||||
static inline void aes_ll_write_block(const void *input)
|
||||
{
|
||||
uint32_t input_word;
|
||||
|
||||
for (int i = 0; i < AES_BLOCK_WORDS; i++) {
|
||||
memcpy(&input_word, (uint8_t*)input + 4 * i, 4);
|
||||
REG_WRITE(AES_TEXT_IN_BASE + i * 4, input_word);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the AES block
|
||||
*
|
||||
* @param output the output of the transform, length = AES_BLOCK_BYTES
|
||||
*/
|
||||
static inline void aes_ll_read_block(void *output)
|
||||
{
|
||||
uint32_t output_word;
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
|
||||
for (size_t i = 0; i < AES_BLOCK_WORDS; i++) {
|
||||
output_word = REG_READ(AES_TEXT_OUT_BASE + (i * REG_WIDTH));
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy( (uint8_t*)output + i * 4, &output_word, sizeof(output_word));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts block transform
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_start_transform(void)
|
||||
{
|
||||
REG_WRITE(AES_TRIGGER_REG, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read state of AES accelerator
|
||||
*
|
||||
* @return esp_aes_state_t
|
||||
*/
|
||||
static inline esp_aes_state_t aes_ll_get_state(void)
|
||||
{
|
||||
return REG_READ(AES_STATE_REG);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set mode of operation
|
||||
*
|
||||
* @note Only used for DMA transforms
|
||||
*
|
||||
* @param mode
|
||||
*/
|
||||
static inline void aes_ll_set_block_mode(esp_aes_mode_t mode)
|
||||
{
|
||||
REG_WRITE(AES_BLOCK_MODE_REG, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AES-CTR counter to INC32
|
||||
*
|
||||
* @note Only affects AES-CTR mode
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_set_inc(void)
|
||||
{
|
||||
REG_WRITE(AES_INC_SEL_REG, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the DMA
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_dma_exit(void)
|
||||
{
|
||||
REG_WRITE(AES_DMA_EXIT_REG, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of blocks to be transformed
|
||||
*
|
||||
* @note Only used for DMA transforms
|
||||
*
|
||||
* @param num_blocks Number of blocks to transform
|
||||
*/
|
||||
static inline void aes_ll_set_num_blocks(size_t num_blocks)
|
||||
{
|
||||
REG_WRITE(AES_BLOCK_NUM_REG, num_blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write IV to hardware iv registers
|
||||
*/
|
||||
static inline void aes_ll_set_iv(const uint8_t *iv)
|
||||
{
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(AES_IV_BASE);
|
||||
uint32_t iv_word;
|
||||
|
||||
for (int i = 0; i < IV_WORDS; i++ ) {
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy(&iv_word, iv + 4 * i, sizeof(iv_word));
|
||||
REG_WRITE(®_addr_buf[i], iv_word);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read IV from hardware iv registers
|
||||
*/
|
||||
static inline void aes_ll_read_iv(uint8_t *iv)
|
||||
{
|
||||
uint32_t iv_word;
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
|
||||
for (size_t i = 0; i < IV_WORDS; i++) {
|
||||
iv_word = REG_READ(AES_IV_BASE + (i * REG_WIDTH));
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy(iv + i * 4, &iv_word, sizeof(iv_word));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable DMA mode
|
||||
*
|
||||
* @param enable true to enable, false to disable.
|
||||
*/
|
||||
static inline void aes_ll_dma_enable(bool enable)
|
||||
{
|
||||
REG_WRITE(AES_DMA_ENABLE_REG, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable transform completed interrupt
|
||||
*
|
||||
* @param enable true to enable, false to disable.
|
||||
*/
|
||||
static inline void aes_ll_interrupt_enable(bool enable)
|
||||
{
|
||||
REG_WRITE(AES_INT_ENA_REG, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the interrupt
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_interrupt_clear(void)
|
||||
{
|
||||
REG_WRITE(AES_INT_CLEAR_REG, 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 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/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_brownout.h"
|
||||
#include "i2c_pmu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief power down the flash when a brown out happens.
|
||||
*
|
||||
* @param enable true: power down flash. false: not power down
|
||||
*/
|
||||
static inline void brownout_ll_enable_flash_power_down(bool enable)
|
||||
{
|
||||
RTCCNTL.brown_out.close_flash_ena = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief power down the RF circuits when a brown out happens
|
||||
*
|
||||
* @param enable true: power down. false: not power done.
|
||||
*/
|
||||
static inline void brownout_ll_enable_rf_power_down(bool enable)
|
||||
{
|
||||
RTCCNTL.brown_out.pd_rf_ena = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable this to reset brown out
|
||||
*
|
||||
* @note: If brown out interrupt is used, this should be disabled.
|
||||
*
|
||||
* @param reset_ena true: enable reset. false: disable reset.
|
||||
* @param reset_wait brown out reset wait cycles
|
||||
* @param select 1: chip reset, 0: system reset
|
||||
*/
|
||||
static inline void brownout_ll_reset_config(bool reset_ena, uint32_t reset_wait, uint8_t select)
|
||||
{
|
||||
RTCCNTL.brown_out.rst_wait = reset_wait;
|
||||
RTCCNTL.brown_out.rst_ena = reset_ena;
|
||||
RTCCNTL.brown_out.rst_sel = select;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set brown out threshold
|
||||
*
|
||||
* @param threshold brownout threshold
|
||||
*/
|
||||
static inline void brownout_ll_set_threshold(uint8_t threshold)
|
||||
{
|
||||
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OC_DREF_LVDET, threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set this bit to enable the brown out detection
|
||||
*
|
||||
* @param bod_enable true: enable, false: disable
|
||||
*/
|
||||
static inline void brownout_ll_bod_enable(bool bod_enable)
|
||||
{
|
||||
RTCCNTL.brown_out.ena = bod_enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief configure the waiting cycles before sending an interrupt
|
||||
*
|
||||
* @param cycle waiting cycles.
|
||||
*/
|
||||
static inline void brownout_ll_set_intr_wait_cycles(uint8_t cycle)
|
||||
{
|
||||
// Not supported on ESP32H4
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable brown out interrupt
|
||||
*
|
||||
* @param enable true: enable, false: disable
|
||||
*/
|
||||
static inline void brownout_ll_intr_enable(bool enable)
|
||||
{
|
||||
RTCCNTL.int_ena.rtc_brown_out = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt bits.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void brownout_ll_intr_clear(void)
|
||||
{
|
||||
RTCCNTL.int_clr.rtc_brown_out = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,189 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for Cache register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/extmem_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_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0
|
||||
#define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_DBUS0
|
||||
|
||||
#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_end`) reside.
|
||||
*
|
||||
* @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_bus_mask_t mask = 0;
|
||||
|
||||
uint32_t vaddr_end = vaddr_start + len - 1;
|
||||
if (vaddr_start >= IRAM0_CACHE_ADDRESS_LOW && vaddr_end < IRAM0_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_IBUS0;
|
||||
} else if (vaddr_start >= DRAM0_CACHE_ADDRESS_LOW && vaddr_end < DRAM0_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_DBUS0;
|
||||
} else {
|
||||
HAL_ASSERT(0); //Out of region
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the Cache Buses
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT(cache_id == 0);
|
||||
//On esp32h4, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first
|
||||
HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2| CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0);
|
||||
|
||||
uint32_t ibus_mask = 0;
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_ICACHE_SHUT_IBUS : 0;
|
||||
REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, ibus_mask);
|
||||
|
||||
uint32_t dbus_mask = 0;
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_ICACHE_SHUT_DBUS : 0;
|
||||
REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, dbus_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the Cache Buses
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT(cache_id == 0);
|
||||
//On esp32h4, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first
|
||||
HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2| CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0);
|
||||
|
||||
uint32_t ibus_mask = 0;
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_ICACHE_SHUT_IBUS : 0;
|
||||
REG_SET_BIT(EXTMEM_ICACHE_CTRL1_REG, ibus_mask);
|
||||
|
||||
uint32_t dbus_mask = 0;
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_ICACHE_SHUT_DBUS : 0;
|
||||
REG_SET_BIT(EXTMEM_ICACHE_CTRL1_REG, dbus_mask);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Interrupt
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable Cache access error interrupt
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H4. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
SET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_ENA_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear Cache access error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H4. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
SET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_CLR_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Cache access error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H4. For compabitlity
|
||||
* @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 GET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_ST_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Cache illegal error interrupt
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H4. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_enable_illegal_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
SET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_ENA_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear Cache illegal error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H4. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_clear_illegal_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
SET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_CLR_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Cache illegal error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H4. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*
|
||||
* @return Status mask
|
||||
*/
|
||||
static inline uint32_t cache_ll_l1_get_illegal_error_intr_status(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
return GET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_ST_REG, mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,224 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "soc/dport_access.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
|
||||
{
|
||||
switch (periph) {
|
||||
case PERIPH_SARADC_MODULE:
|
||||
return SYSTEM_APB_SARADC_CLK_EN;
|
||||
case PERIPH_RMT_MODULE:
|
||||
return SYSTEM_RMT_CLK_EN;
|
||||
case PERIPH_LEDC_MODULE:
|
||||
return SYSTEM_LEDC_CLK_EN;
|
||||
case PERIPH_UART0_MODULE:
|
||||
return SYSTEM_UART_CLK_EN;
|
||||
case PERIPH_UART1_MODULE:
|
||||
return SYSTEM_UART1_CLK_EN;
|
||||
case PERIPH_I2C0_MODULE:
|
||||
return SYSTEM_I2C_EXT0_CLK_EN;
|
||||
case PERIPH_I2S1_MODULE:
|
||||
return SYSTEM_I2S1_CLK_EN;
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
return SYSTEM_TIMERGROUP_CLK_EN;
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
return SYSTEM_TIMERGROUP1_CLK_EN;
|
||||
case PERIPH_UHCI0_MODULE:
|
||||
return SYSTEM_UHCI0_CLK_EN;
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
return SYSTEM_SYSTIMER_CLK_EN;
|
||||
case PERIPH_SPI_MODULE:
|
||||
return SYSTEM_SPI01_CLK_EN;
|
||||
case PERIPH_SPI2_MODULE:
|
||||
return SYSTEM_SPI2_CLK_EN;
|
||||
case PERIPH_TWAI_MODULE:
|
||||
return SYSTEM_TWAI_CLK_EN;
|
||||
case PERIPH_GDMA_MODULE:
|
||||
return SYSTEM_DMA_CLK_EN;
|
||||
case PERIPH_AES_MODULE:
|
||||
return SYSTEM_CRYPTO_AES_CLK_EN;
|
||||
case PERIPH_SHA_MODULE:
|
||||
return SYSTEM_CRYPTO_SHA_CLK_EN;
|
||||
case PERIPH_ECC_MODULE:
|
||||
return SYSTEM_CRYPTO_ECC_CLK_EN;
|
||||
case PERIPH_RSA_MODULE:
|
||||
return SYSTEM_CRYPTO_RSA_CLK_EN;
|
||||
case PERIPH_HMAC_MODULE:
|
||||
return SYSTEM_CRYPTO_HMAC_CLK_EN;
|
||||
case PERIPH_DS_MODULE:
|
||||
return SYSTEM_CRYPTO_DS_CLK_EN;
|
||||
case PERIPH_TEMPSENSOR_MODULE:
|
||||
return SYSTEM_TSENS_CLK_EN;
|
||||
case PERIPH_ETM_MODULE:
|
||||
return SYSTEM_ETM_CLK_EN;
|
||||
case PERIPH_MODEM_RPA_MODULE:
|
||||
return SYSTEM_BLE_SEC_BAH_CLK_EN;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool enable)
|
||||
{
|
||||
|
||||
(void)enable; // unused
|
||||
|
||||
switch (periph) {
|
||||
case PERIPH_SARADC_MODULE:
|
||||
return SYSTEM_APB_SARADC_RST;
|
||||
case PERIPH_RMT_MODULE:
|
||||
return SYSTEM_RMT_RST;
|
||||
case PERIPH_LEDC_MODULE:
|
||||
return SYSTEM_LEDC_RST;
|
||||
case PERIPH_UART0_MODULE:
|
||||
return SYSTEM_UART_RST;
|
||||
case PERIPH_UART1_MODULE:
|
||||
return SYSTEM_UART1_RST;
|
||||
case PERIPH_I2C0_MODULE:
|
||||
return SYSTEM_I2C_EXT0_RST;
|
||||
case PERIPH_I2S1_MODULE:
|
||||
return SYSTEM_I2S1_RST;
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
return SYSTEM_TIMERGROUP_RST;
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
return SYSTEM_TIMERGROUP1_RST;
|
||||
case PERIPH_UHCI0_MODULE:
|
||||
return SYSTEM_UHCI0_RST;
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
return SYSTEM_SYSTIMER_RST;
|
||||
case PERIPH_GDMA_MODULE:
|
||||
return SYSTEM_DMA_RST;
|
||||
case PERIPH_SPI_MODULE:
|
||||
return SYSTEM_SPI01_RST;
|
||||
case PERIPH_SPI2_MODULE:
|
||||
return SYSTEM_SPI2_RST;
|
||||
case PERIPH_TWAI_MODULE:
|
||||
return SYSTEM_TWAI_RST;
|
||||
case PERIPH_HMAC_MODULE:
|
||||
return SYSTEM_CRYPTO_HMAC_RST;
|
||||
case PERIPH_TEMPSENSOR_MODULE:
|
||||
return SYSTEM_TSENS_RST;
|
||||
case PERIPH_ECC_MODULE:
|
||||
return SYSTEM_CRYPTO_ECC_RST;
|
||||
case PERIPH_AES_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature, otherwise AES unit is held in reset also.
|
||||
return (SYSTEM_CRYPTO_AES_RST | SYSTEM_CRYPTO_DS_RST);
|
||||
} else {
|
||||
//Don't return other units to reset, as this pulls reset on RSA & SHA units, respectively.
|
||||
return SYSTEM_CRYPTO_AES_RST;
|
||||
}
|
||||
case PERIPH_SHA_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature and HMAC, otherwise SHA is held in reset
|
||||
return (SYSTEM_CRYPTO_SHA_RST | SYSTEM_CRYPTO_DS_RST | SYSTEM_CRYPTO_HMAC_RST);
|
||||
} else {
|
||||
// Don't assert reset on secure boot, otherwise AES is held in reset
|
||||
return SYSTEM_CRYPTO_SHA_RST;
|
||||
}
|
||||
case PERIPH_RSA_MODULE:
|
||||
if (enable == true) {
|
||||
/* also clear reset on digital signature, otherwise RSA is held in reset */
|
||||
return (SYSTEM_CRYPTO_RSA_RST | SYSTEM_CRYPTO_DS_RST);
|
||||
} else {
|
||||
/* don't reset digital signature unit, as this resets AES also */
|
||||
return SYSTEM_CRYPTO_RSA_RST;
|
||||
}
|
||||
case PERIPH_DS_MODULE:
|
||||
return SYSTEM_CRYPTO_DS_RST;
|
||||
case PERIPH_ETM_MODULE:
|
||||
return SYSTEM_ETM_RST;
|
||||
case PERIPH_MODEM_RPA_MODULE:
|
||||
return SYSTEM_BLE_SEC_BAH_RST;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
|
||||
{
|
||||
switch (periph) {
|
||||
case PERIPH_HMAC_MODULE:
|
||||
case PERIPH_DS_MODULE:
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_ECC_MODULE:
|
||||
case PERIPH_GDMA_MODULE:
|
||||
case PERIPH_TEMPSENSOR_MODULE:
|
||||
case PERIPH_ETM_MODULE:
|
||||
return SYSTEM_PERIP_CLK_EN1_REG;
|
||||
case PERIPH_BT_MODULE:
|
||||
return SYSTEM_MODEM_CLK_EN_REG;
|
||||
case PERIPH_MODEM_RPA_MODULE:
|
||||
return SYSTEM_MODEM_CLK_EN_REG;
|
||||
default:
|
||||
return SYSTEM_PERIP_CLK_EN0_REG;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
|
||||
{
|
||||
switch (periph) {
|
||||
case PERIPH_HMAC_MODULE:
|
||||
case PERIPH_DS_MODULE:
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_ECC_MODULE:
|
||||
case PERIPH_GDMA_MODULE:
|
||||
case PERIPH_TEMPSENSOR_MODULE:
|
||||
case PERIPH_ETM_MODULE:
|
||||
return SYSTEM_PERIP_RST_EN1_REG;
|
||||
case PERIPH_BT_MODULE:
|
||||
return SYSTEM_MODEM_RST_EN_REG;
|
||||
case PERIPH_MODEM_RPA_MODULE:
|
||||
return SYSTEM_MODEM_RST_EN_REG;
|
||||
default:
|
||||
return SYSTEM_PERIP_RST_EN0_REG;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void periph_ll_enable_clk_clear_rst(periph_module_t periph)
|
||||
{
|
||||
DPORT_SET_PERI_REG_MASK(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph));
|
||||
DPORT_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)
|
||||
{
|
||||
DPORT_CLEAR_PERI_REG_MASK(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph));
|
||||
DPORT_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)
|
||||
{
|
||||
DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
|
||||
DPORT_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 DPORT_REG_GET_BIT(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)) == 0 &&
|
||||
DPORT_REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,580 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/clkrst_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_bbpll.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/log.h"
|
||||
#include "esp32h4/rom/rtc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
#define CLK_LL_PLL_96M_FREQ_MHZ (96)
|
||||
|
||||
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
|
||||
.dac = 3, \
|
||||
.dres = 3, \
|
||||
.dgm = 3, \
|
||||
.dbuf = 1, \
|
||||
}
|
||||
|
||||
#define CLK_LL_RC32K_DFREQ_DEFAULT 707
|
||||
|
||||
/**
|
||||
* @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 XTAL32K_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)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down BBPLL circuit
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
|
||||
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// Configure xtal32k (or only for mode == CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL?)
|
||||
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
|
||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DAC_XTAL_32K, cfg.dac);
|
||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DRES_XTAL_32K, cfg.dres);
|
||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
|
||||
REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
|
||||
// Enable xtal32k xpd status
|
||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
|
||||
// Not supported yet?
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the 32kHz crystal oscillator
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal32k_disable(void)
|
||||
{
|
||||
// Set xtal32k xpd to be controlled by software
|
||||
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
|
||||
// Disable xtal32k xpd status
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
uint32_t xtal_conf = READ_PERI_REG(RTC_CNTL_EXT_XTL_CONF_REG);
|
||||
/* If xtal xpd is controlled by software */
|
||||
bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S;
|
||||
/* If xtal xpd software control is on */
|
||||
bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S;
|
||||
// disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled
|
||||
bool enabled = !xtal_xpd_sw || xtal_xpd_st;
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the internal oscillator output for RC32K_CLK
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void)
|
||||
{
|
||||
// Configure rc32k
|
||||
REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_DFREQ, CLK_LL_RC32K_DFREQ_DEFAULT);
|
||||
// Enable rc32k xpd status
|
||||
SET_PERI_REG_MASK(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_XPD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the internal oscillator output for RC32k_CLK
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void)
|
||||
{
|
||||
// Configure rc32k
|
||||
REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_DFREQ, CLK_LL_RC32K_DFREQ_DEFAULT);
|
||||
// Disable rc32k xpd status
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_RC32K_CTRL_REG, RTC_CNTL_RC32K_XPD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the digital RC32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the digital RC32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_disable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_RC32K_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_xtal32k_digi_disable(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PLL_CLK frequency
|
||||
*
|
||||
* @return PLL clock frequency, in MHz
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
|
||||
{
|
||||
uint32_t bbpll_freq = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SPLL_FREQ);
|
||||
HAL_ASSERT(bbpll_freq == CLK_LL_PLL_96M_FREQ_MHZ);
|
||||
return bbpll_freq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
(void)pll_freq_mhz;
|
||||
// ESP32H4 bbpll frequency cannot be changed, fixed to 96MHz
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
(void)xtal_freq_mhz;
|
||||
switch (pll_freq_mhz) {
|
||||
case CLK_LL_PLL_96M_FREQ_MHZ: // PLL_96M
|
||||
/* set up PLL by analog control registers */
|
||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, 0);
|
||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DIV, 1); // I2C_BBPLL_OC_DIV_5_0
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 3);
|
||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the clock source for CPU_CLK
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
switch (in_sel) {
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 0);
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 1);
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 2);
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_XTAL_D2:
|
||||
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 3);
|
||||
break;
|
||||
default:
|
||||
// Unsupported CPU_CLK mux input sel
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the clock source for CPU_CLK
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
uint32_t clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
return SOC_CPU_CLK_SRC_XTAL;
|
||||
case 1:
|
||||
return SOC_CPU_CLK_SRC_PLL;
|
||||
case 2:
|
||||
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||
case 3:
|
||||
return SOC_CPU_CLK_SRC_XTAL_D2;
|
||||
default:
|
||||
return SOC_CPU_CLK_SRC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CPU_CLK divider. freq of CPU_CLK = freq of CPU clock source / divider
|
||||
*
|
||||
* @param divider Divider. CPU_DIV_NUM = divider - 1.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
|
||||
{
|
||||
HAL_ASSERT(divider > 0);
|
||||
REG_SET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_CPU_DIV_NUM, divider - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get CPU_CLK divider
|
||||
*
|
||||
* @return Divider. Divider = (CPU_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
|
||||
{
|
||||
return REG_GET_FIELD(SYSTEM_CPUCLK_CONF_REG, SYSTEM_CPU_DIV_NUM) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AHB_CLK divider. freq of AHB_CLK = freq of CPU_CLK / divider
|
||||
*
|
||||
* @param divider Divider. AHB_DIV_NUM = divider - 1.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_ahb_set_divider(uint32_t divider)
|
||||
{
|
||||
HAL_ASSERT(divider > 0);
|
||||
REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM, divider - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get AHB_CLK divider
|
||||
*
|
||||
* @return Divider. Divider = (AHB_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_divider(void)
|
||||
{
|
||||
return REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_AHB_DIV_NUM) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider
|
||||
*
|
||||
* @param divider Divider. APB_DIV_NUM = divider - 1.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
|
||||
{
|
||||
HAL_ASSERT(divider > 0);
|
||||
REG_SET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM, divider - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get APB_CLK divider
|
||||
*
|
||||
* @return Divider. Divider = (APB_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
|
||||
{
|
||||
return REG_GET_FIELD(SYSTEM_BUSCLK_CONF_REG, SYSTEM_APB_DIV_NUM) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
switch (in_sel) {
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 0);
|
||||
break;
|
||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 1);
|
||||
break;
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC32K:
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, 2);
|
||||
break;
|
||||
default:
|
||||
// Unsupported RTC_SLOW_CLK mux input sel
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||
case 1:
|
||||
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||
case 2:
|
||||
return SOC_RTC_SLOW_CLK_SRC_RC32K;
|
||||
default:
|
||||
// Invalid ANA_CLK_RTC_SEL value
|
||||
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
switch (in_sel) {
|
||||
case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 0);
|
||||
break;
|
||||
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, 1);
|
||||
break;
|
||||
default:
|
||||
// Unsupported RTC_FAST_CLK mux input sel
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
uint32_t clk_sel = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
|
||||
case 1:
|
||||
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||
default:
|
||||
return SOC_RTC_FAST_CLK_SRC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT(divider > 0);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divider - 1);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 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)
|
||||
{
|
||||
HAL_ASSERT(divider > 0);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||
REG_SET_FIELD(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV, divider - 1);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
|
||||
}
|
||||
|
||||
/************************* RTC 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)
|
||||
{
|
||||
// Read the status of whether disabling logging from ROM code
|
||||
uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG;
|
||||
// If so, need to write back this setting
|
||||
if (reg == RTC_DISABLE_ROM_LOG) {
|
||||
xtal_freq_mhz |= 1;
|
||||
}
|
||||
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
// ESP32H4 has a fixed crystal frequency (32MHz), but we will still read from the RTC storage register
|
||||
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
|
||||
if ((xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX) != RTC_XTAL_FREQ_32M) {
|
||||
return 0;
|
||||
}
|
||||
return (uint32_t)RTC_XTAL_FREQ_32M;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store APB_CLK frequency in RTC storage register
|
||||
*
|
||||
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
|
||||
* halves. These are the routines to work with that representation.
|
||||
*
|
||||
* @param apb_freq_hz APB frequency, in Hz
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
|
||||
{
|
||||
uint32_t val = apb_freq_hz >> 12;
|
||||
WRITE_PERI_REG(RTC_APB_FREQ_REG, (val & UINT16_MAX) | ((val & UINT16_MAX) << 16));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
REG_WRITE(RTC_SLOW_CLK_CAL_REG, 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 REG_READ(RTC_SLOW_CLK_CAL_REG);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "riscv/csr.h"
|
||||
|
||||
/*fast gpio*/
|
||||
#define CSR_GPIO_OEN_USER 0x803
|
||||
#define CSR_GPIO_IN_USER 0x804
|
||||
#define CSR_GPIO_OUT_USER 0x805
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void dedic_gpio_cpu_ll_enable_output(uint32_t mask)
|
||||
{
|
||||
RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
|
||||
{
|
||||
RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
|
||||
{
|
||||
uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
|
||||
return value;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
|
||||
{
|
||||
uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
|
||||
return value;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
|
||||
{
|
||||
RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
|
||||
RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,167 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use it in application code.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void ds_ll_start(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait until DS peripheral has finished any outstanding operation.
|
||||
*/
|
||||
static inline bool ds_ll_busy(void)
|
||||
{
|
||||
return (REG_READ(DS_QUERY_BUSY_REG) > 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Busy wait until the hardware is ready.
|
||||
*/
|
||||
static inline void ds_ll_wait_busy(void)
|
||||
{
|
||||
while (ds_ll_busy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief In case of a key error, check what caused it.
|
||||
*/
|
||||
static inline ds_key_check_t ds_ll_key_error_source(void)
|
||||
{
|
||||
uint32_t key_error = REG_READ(DS_QUERY_KEY_WRONG_REG);
|
||||
if (key_error == 0) {
|
||||
return DS_NO_KEY_INPUT;
|
||||
} else {
|
||||
return DS_OTHER_WRONG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the initialization vector to the corresponding register field.
|
||||
*/
|
||||
static inline void ds_ll_configure_iv(const uint32_t *iv)
|
||||
{
|
||||
for (size_t i = 0; i < (SOC_DS_KEY_PARAM_MD_IV_LENGTH / sizeof(uint32_t)); i++) {
|
||||
REG_WRITE(DS_IV_BASE + (i * 4) , iv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the message which should be signed.
|
||||
*
|
||||
* @param msg Pointer to the message.
|
||||
* @param size Length of msg in bytes. It is the RSA signature length in bytes.
|
||||
*/
|
||||
static inline void ds_ll_write_message(const uint8_t *msg, size_t size)
|
||||
{
|
||||
memcpy((uint8_t*) DS_X_BASE, msg, size);
|
||||
asm volatile ("fence");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the encrypted private key parameters.
|
||||
*/
|
||||
static inline void ds_ll_write_private_key_params(const uint8_t *encrypted_key_params)
|
||||
{
|
||||
/* Note: as the internal peripheral still has RSA 4096 structure,
|
||||
but C is encrypted based on the actual max RSA length (ETS_DS_MAX_BITS), need to fragment it
|
||||
when copying to hardware...
|
||||
|
||||
(note if ETS_DS_MAX_BITS == 4096, this should be the same as copying data->c to hardware in one fragment)
|
||||
*/
|
||||
typedef struct { uint32_t addr; size_t len; } frag_t;
|
||||
const frag_t frags[] = {
|
||||
{DS_C_Y_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_C_M_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_C_RB_BASE, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_C_BOX_BASE, DS_IV_BASE - DS_C_BOX_BASE},
|
||||
};
|
||||
const size_t NUM_FRAGS = sizeof(frags)/sizeof(frag_t);
|
||||
const uint8_t *from = encrypted_key_params;
|
||||
|
||||
for (int i = 0; i < NUM_FRAGS; i++) {
|
||||
memcpy((uint8_t *)frags[i].addr, from, frags[i].len);
|
||||
asm volatile ("fence");
|
||||
from += frags[i].len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin signing procedure.
|
||||
*/
|
||||
static inline void ds_ll_start_sign(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_ME_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check the calculated signature.
|
||||
*
|
||||
* @return
|
||||
* - DS_SIGNATURE_OK if no issue is detected with the signature.
|
||||
* - DS_SIGNATURE_PADDING_FAIL if the padding of the private key parameters is wrong.
|
||||
* - DS_SIGNATURE_MD_FAIL if the message digest check failed. This means that the message digest calculated using
|
||||
* the private key parameters fails, i.e., the integrity of the private key parameters is not protected.
|
||||
* - DS_SIGNATURE_PADDING_AND_MD_FAIL if both padding and message digest check fail.
|
||||
*/
|
||||
static inline ds_signature_check_t ds_ll_check_signature(void)
|
||||
{
|
||||
uint32_t result = REG_READ(DS_QUERY_CHECK_REG);
|
||||
switch(result) {
|
||||
case 0:
|
||||
return DS_SIGNATURE_OK;
|
||||
case 1:
|
||||
return DS_SIGNATURE_MD_FAIL;
|
||||
case 2:
|
||||
return DS_SIGNATURE_PADDING_FAIL;
|
||||
default:
|
||||
return DS_SIGNATURE_PADDING_AND_MD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the signature from the hardware.
|
||||
*
|
||||
* @param result The signature result.
|
||||
* @param size Length of signature result in bytes. It is the RSA signature length in bytes.
|
||||
*/
|
||||
static inline void ds_ll_read_result(uint8_t *result, size_t size)
|
||||
{
|
||||
memcpy(result, (uint8_t*) DS_Z_BASE, size);
|
||||
asm volatile ("fence");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exit the signature operation.
|
||||
*
|
||||
* @note This does not deactivate the module. Corresponding clock/reset bits have to be triggered for deactivation.
|
||||
*/
|
||||
static inline void ds_ll_finish(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_FINISH_REG, 1);
|
||||
ds_ll_wait_busy();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "hal/assert.h"
|
||||
#include "rev2/soc/ecc_mult_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ECC_PARAM_PX = 0x0,
|
||||
ECC_PARAM_PY,
|
||||
ECC_PARAM_K,
|
||||
} ecc_ll_param_t;
|
||||
|
||||
static inline void ecc_ll_enable_interrupt(void)
|
||||
{
|
||||
REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1);
|
||||
}
|
||||
|
||||
static inline void ecc_ll_disable_interrupt(void)
|
||||
{
|
||||
REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 0);
|
||||
}
|
||||
|
||||
static inline void ecc_ll_clear_interrupt(void)
|
||||
{
|
||||
REG_SET_FIELD(ECC_MULT_INT_CLR_REG, ECC_MULT_CALC_DONE_INT_CLR, 1);
|
||||
}
|
||||
|
||||
static inline void ecc_ll_set_mode(ecc_mode_t mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case ECC_MODE_POINT_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0);
|
||||
break;
|
||||
case ECC_MODE_INVERSE_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 1);
|
||||
break;
|
||||
case ECC_MODE_VERIFY:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2);
|
||||
break;
|
||||
case ECC_MODE_VERIFY_THEN_POINT_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 3);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_set_curve(ecc_curve_t curve)
|
||||
{
|
||||
switch(curve) {
|
||||
case ECC_CURVE_SECP256R1:
|
||||
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
|
||||
break;
|
||||
case ECC_CURVE_SECP192R1:
|
||||
REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported curve");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t word;
|
||||
switch (param) {
|
||||
case ECC_PARAM_PX:
|
||||
reg = ECC_MULT_PX_1_REG;
|
||||
break;
|
||||
case ECC_PARAM_PY:
|
||||
reg = ECC_MULT_PY_1_REG;
|
||||
break;
|
||||
case ECC_PARAM_K:
|
||||
reg = ECC_MULT_K_1_REG;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Invalid parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i += 4) {
|
||||
memcpy(&word, buf + i, 4);
|
||||
REG_WRITE(reg + i, word);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_start_calc(void)
|
||||
{
|
||||
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_START);
|
||||
}
|
||||
|
||||
static inline int ecc_ll_is_calc_finished(void)
|
||||
{
|
||||
return REG_GET_FIELD(ECC_MULT_INT_RAW_REG, ECC_MULT_CALC_DONE_INT_RAW);
|
||||
}
|
||||
|
||||
static inline ecc_mode_t ecc_ll_get_mode(void)
|
||||
{
|
||||
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE);
|
||||
}
|
||||
|
||||
static inline int ecc_ll_get_verification_result(void)
|
||||
{
|
||||
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_VERIFICATION_RESULT);
|
||||
}
|
||||
|
||||
static inline ecc_curve_t ecc_ll_get_curve(void)
|
||||
{
|
||||
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
|
||||
}
|
||||
|
||||
static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint32_t reg;
|
||||
switch (param) {
|
||||
case ECC_PARAM_PX:
|
||||
reg = ECC_MULT_PX_1_REG;
|
||||
break;
|
||||
case ECC_PARAM_PY:
|
||||
reg = ECC_MULT_PY_1_REG;
|
||||
break;
|
||||
case ECC_PARAM_K:
|
||||
reg = ECC_MULT_K_1_REG;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Invalid parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(buf, (void *)reg, len);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 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
|
||||
|
||||
/**
|
||||
* @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
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 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 "esp32h4/rom/efuse.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Always inline these functions even no gcc optimization is applied.
|
||||
|
||||
/******************* 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_spi_sys_0.mac_0;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_mac1(void)
|
||||
{
|
||||
return EFUSE.rd_mac_spi_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_spi_sys_3.wafer_version;
|
||||
}
|
||||
|
||||
// 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 0;
|
||||
}
|
||||
|
||||
__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 EFUSE.rd_mac_spi_sys_3.pkg_version;
|
||||
}
|
||||
|
||||
/******************* 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
|
@ -1,481 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> /* Required for NULL constant */
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "hal/gdma_types.h"
|
||||
#include "soc/gdma_struct.h"
|
||||
#include "soc/gdma_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL)
|
||||
|
||||
#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5]
|
||||
|
||||
#define GDMA_LL_RX_EVENT_MASK (0x06A7)
|
||||
#define GDMA_LL_TX_EVENT_MASK (0x1958)
|
||||
|
||||
// any "valid" peripheral ID can be used for M2M mode
|
||||
#define GDMA_LL_M2M_FREE_PERIPH_ID_MASK (0x1CD)
|
||||
#define GDMA_LL_INVALID_PERIPH_ID (0x3F)
|
||||
|
||||
#define GDMA_LL_EVENT_TX_FIFO_UDF (1<<12)
|
||||
#define GDMA_LL_EVENT_TX_FIFO_OVF (1<<11)
|
||||
#define GDMA_LL_EVENT_RX_FIFO_UDF (1<<10)
|
||||
#define GDMA_LL_EVENT_RX_FIFO_OVF (1<<9)
|
||||
#define GDMA_LL_EVENT_TX_TOTAL_EOF (1<<8)
|
||||
#define GDMA_LL_EVENT_RX_DESC_EMPTY (1<<7)
|
||||
#define GDMA_LL_EVENT_TX_DESC_ERROR (1<<6)
|
||||
#define GDMA_LL_EVENT_RX_DESC_ERROR (1<<5)
|
||||
#define GDMA_LL_EVENT_TX_EOF (1<<4)
|
||||
#define GDMA_LL_EVENT_TX_DONE (1<<3)
|
||||
#define GDMA_LL_EVENT_RX_ERR_EOF (1<<2)
|
||||
#define GDMA_LL_EVENT_RX_SUC_EOF (1<<1)
|
||||
#define GDMA_LL_EVENT_RX_DONE (1<<0)
|
||||
|
||||
///////////////////////////////////// Common /////////////////////////////////////////
|
||||
/**
|
||||
* @brief Enable DMA clock gating
|
||||
*/
|
||||
static inline void gdma_ll_enable_clock(gdma_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->misc_conf.clk_en = enable;
|
||||
}
|
||||
|
||||
///////////////////////////////////// RX /////////////////////////////////////////
|
||||
/**
|
||||
* @brief Get DMA RX channel interrupt status word
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t gdma_ll_rx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->intr[channel].st.val & GDMA_LL_RX_EVENT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA RX channel interrupt
|
||||
*/
|
||||
static inline void gdma_ll_rx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
dev->intr[channel].ena.val |= (mask & GDMA_LL_RX_EVENT_MASK);
|
||||
} else {
|
||||
dev->intr[channel].ena.val &= ~(mask & GDMA_LL_RX_EVENT_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear DMA RX channel interrupt
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_rx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask)
|
||||
{
|
||||
dev->intr[channel].clr.val = (mask & GDMA_LL_RX_EVENT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get DMA RX channel interrupt status register address
|
||||
*/
|
||||
static inline volatile void *gdma_ll_rx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return (volatile void *)(&dev->intr[channel].st);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA RX channel to check the owner bit in the descriptor, disabled by default
|
||||
*/
|
||||
static inline void gdma_ll_rx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].in.in_conf1.in_check_owner = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA RX channel burst reading data, disabled by default
|
||||
*/
|
||||
static inline void gdma_ll_rx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].in.in_conf0.in_data_burst_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA RX channel burst reading descriptor link, disabled by default
|
||||
*/
|
||||
static inline void gdma_ll_rx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].in.in_conf0.indscr_burst_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset DMA RX channel FSM and FIFO pointer
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_rx_reset_channel(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].in.in_conf0.in_rst = 1;
|
||||
dev->channel[channel].in.in_conf0.in_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if DMA RX FIFO is full
|
||||
* @param fifo_level only supports level 1
|
||||
*/
|
||||
static inline bool gdma_ll_rx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level)
|
||||
{
|
||||
return dev->channel[channel].in.infifo_status.val & 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if DMA RX FIFO is empty
|
||||
* @param fifo_level only supports level 1
|
||||
*/
|
||||
static inline bool gdma_ll_rx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level)
|
||||
{
|
||||
return dev->channel[channel].in.infifo_status.val & 0x02;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of bytes in RX FIFO
|
||||
* @param fifo_level only supports level 1
|
||||
*/
|
||||
static inline uint32_t gdma_ll_rx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level)
|
||||
{
|
||||
return dev->channel[channel].in.infifo_status.infifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pop data from DMA RX FIFO
|
||||
*/
|
||||
static inline uint32_t gdma_ll_rx_pop_data(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].in.in_pop.infifo_pop = 1;
|
||||
return dev->channel[channel].in.in_pop.infifo_rdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the descriptor link base address for RX channel
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_rx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr)
|
||||
{
|
||||
dev->channel[channel].in.in_link.addr = addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start dealing with RX descriptors
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_rx_start(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].in.in_link.start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop dealing with RX descriptors
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_rx_stop(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].in.in_link.stop = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restart a new inlink right after the last descriptor
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_rx_restart(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].in.in_link.restart = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA RX to return the address of current descriptor when receives error
|
||||
*/
|
||||
static inline void gdma_ll_rx_enable_auto_return(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].in.in_link.auto_ret = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if DMA RX FSM is in IDLE state
|
||||
*/
|
||||
static inline bool gdma_ll_rx_is_fsm_idle(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->channel[channel].in.in_link.park;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get RX success EOF descriptor's address
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t gdma_ll_rx_get_success_eof_desc_addr(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->channel[channel].in.in_suc_eof_des_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get RX error EOF descriptor's address
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t gdma_ll_rx_get_error_eof_desc_addr(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->channel[channel].in.in_err_eof_des_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current RX descriptor's address
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t gdma_ll_rx_get_current_desc_addr(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->channel[channel].in.in_dscr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set priority for DMA RX channel
|
||||
*/
|
||||
static inline void gdma_ll_rx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio)
|
||||
{
|
||||
dev->channel[channel].in.in_pri.rx_pri = prio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connect DMA RX channel to a given peripheral
|
||||
*/
|
||||
static inline void gdma_ll_rx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id)
|
||||
{
|
||||
dev->channel[channel].in.in_peri_sel.sel = periph_id;
|
||||
dev->channel[channel].in.in_conf0.mem_trans_en = (periph == GDMA_TRIG_PERIPH_M2M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disconnect DMA RX channel from peripheral
|
||||
*/
|
||||
static inline void gdma_ll_rx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].in.in_peri_sel.sel = GDMA_LL_INVALID_PERIPH_ID;
|
||||
dev->channel[channel].in.in_conf0.mem_trans_en = false;
|
||||
}
|
||||
|
||||
///////////////////////////////////// TX /////////////////////////////////////////
|
||||
/**
|
||||
* @brief Get DMA TX channel interrupt status word
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t gdma_ll_tx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->intr[channel].st.val & GDMA_LL_TX_EVENT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA TX channel interrupt
|
||||
*/
|
||||
static inline void gdma_ll_tx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
dev->intr[channel].ena.val |= (mask & GDMA_LL_TX_EVENT_MASK);
|
||||
} else {
|
||||
dev->intr[channel].ena.val &= ~(mask & GDMA_LL_TX_EVENT_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear DMA TX channel interrupt
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_tx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask)
|
||||
{
|
||||
dev->intr[channel].clr.val = (mask & GDMA_LL_TX_EVENT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get DMA TX channel interrupt status register address
|
||||
*/
|
||||
static inline volatile void *gdma_ll_tx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return (volatile void *)(&dev->intr[channel].st);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA TX channel to check the owner bit in the descriptor, disabled by default
|
||||
*/
|
||||
static inline void gdma_ll_tx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].out.out_conf1.out_check_owner = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA TX channel burst sending data, disabled by default
|
||||
*/
|
||||
static inline void gdma_ll_tx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].out.out_conf0.out_data_burst_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA TX channel burst reading descriptor link, disabled by default
|
||||
*/
|
||||
static inline void gdma_ll_tx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].out.out_conf0.outdscr_burst_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set TX channel EOF mode
|
||||
*/
|
||||
static inline void gdma_ll_tx_set_eof_mode(gdma_dev_t *dev, uint32_t channel, uint32_t mode)
|
||||
{
|
||||
dev->channel[channel].out.out_conf0.out_eof_mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA TX channel automatic write results back to descriptor after all data has been sent out, disabled by default
|
||||
*/
|
||||
static inline void gdma_ll_tx_enable_auto_write_back(gdma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->channel[channel].out.out_conf0.out_auto_wrback = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset DMA TX channel FSM and FIFO pointer
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_tx_reset_channel(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].out.out_conf0.out_rst = 1;
|
||||
dev->channel[channel].out.out_conf0.out_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if DMA TX FIFO is full
|
||||
* @param fifo_level only supports level 1
|
||||
*/
|
||||
static inline bool gdma_ll_tx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level)
|
||||
{
|
||||
return dev->channel[channel].out.outfifo_status.val & 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if DMA TX FIFO is empty
|
||||
* @param fifo_level only supports level 1
|
||||
*/
|
||||
static inline bool gdma_ll_tx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level)
|
||||
{
|
||||
return dev->channel[channel].out.outfifo_status.val & 0x02;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of bytes in TX FIFO
|
||||
* @param fifo_level only supports level 1
|
||||
*/
|
||||
static inline uint32_t gdma_ll_tx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level)
|
||||
{
|
||||
return dev->channel[channel].out.outfifo_status.outfifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push data into DMA TX FIFO
|
||||
*/
|
||||
static inline void gdma_ll_tx_push_data(gdma_dev_t *dev, uint32_t channel, uint32_t data)
|
||||
{
|
||||
dev->channel[channel].out.out_push.outfifo_wdata = data;
|
||||
dev->channel[channel].out.out_push.outfifo_push = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the descriptor link base address for TX channel
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_tx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr)
|
||||
{
|
||||
dev->channel[channel].out.out_link.addr = addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start dealing with TX descriptors
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_tx_start(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].out.out_link.start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop dealing with TX descriptors
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_tx_stop(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].out.out_link.stop = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restart a new outlink right after the last descriptor
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gdma_ll_tx_restart(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].out.out_link.restart = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if DMA TX FSM is in IDLE state
|
||||
*/
|
||||
static inline bool gdma_ll_tx_is_fsm_idle(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->channel[channel].out.out_link.park;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get TX EOF descriptor's address
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t gdma_ll_tx_get_eof_desc_addr(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->channel[channel].out.out_eof_des_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current TX descriptor's address
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t gdma_ll_tx_get_current_desc_addr(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->channel[channel].out.out_dscr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set priority for DMA TX channel
|
||||
*/
|
||||
static inline void gdma_ll_tx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio)
|
||||
{
|
||||
dev->channel[channel].out.out_pri.tx_pri = prio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connect DMA TX channel to a given peripheral
|
||||
*/
|
||||
static inline void gdma_ll_tx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id)
|
||||
{
|
||||
(void)periph;
|
||||
dev->channel[channel].out.out_peri_sel.sel = periph_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disconnect DMA TX channel from peripheral
|
||||
*/
|
||||
static inline void gdma_ll_tx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->channel[channel].out.out_peri_sel.sel = GDMA_LL_INVALID_PERIPH_ID;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,409 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 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"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on h4 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.val) gpspi_flash_ll_clock_reg_t;
|
||||
|
||||
#define GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (48)
|
||||
/*------------------------------------------------------------------------------
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->cmd.update = 1;
|
||||
while (dev->cmd.update);
|
||||
dev->cmd.usr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.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 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(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
|
@ -1,191 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use it in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "hal/hmac_hal.h"
|
||||
|
||||
#define SHA256_BLOCK_SZ 64
|
||||
#define SHA256_DIGEST_SZ 32
|
||||
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG 6
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE 7
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_UP 8
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL 5
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Makes the peripheral ready for use, after enabling it.
|
||||
*/
|
||||
static inline void hmac_ll_start(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine where the HMAC output should go.
|
||||
*
|
||||
* The HMAC peripheral can be configured to deliver its output to the user directly, or to deliver
|
||||
* the output directly to another peripheral instead, e.g. the Digital Signature peripheral.
|
||||
*/
|
||||
static inline void hmac_ll_config_output(hmac_hal_output_t config)
|
||||
{
|
||||
switch(config) {
|
||||
case HMAC_OUTPUT_USER:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_UP);
|
||||
break;
|
||||
case HMAC_OUTPUT_DS:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE);
|
||||
break;
|
||||
case HMAC_OUTPUT_JTAG_ENABLE:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
|
||||
break;
|
||||
case HMAC_OUTPUT_ALL:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL);
|
||||
break;
|
||||
default:
|
||||
; // do nothing, error will be indicated by hmac_hal_config_error()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects which hardware key should be used.
|
||||
*/
|
||||
static inline void hmac_ll_config_hw_key_id(uint32_t key_id)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_PARA_KEY_REG, key_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Apply and check configuration.
|
||||
*
|
||||
* Afterwards, the configuration can be checked for errors with hmac_hal_config_error().
|
||||
*/
|
||||
static inline void hmac_ll_config_finish(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_PARA_FINISH_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Query HMAC error state after configuration actions.
|
||||
*
|
||||
* @return
|
||||
* - 1 or greater on error
|
||||
* - 0 on success
|
||||
*/
|
||||
static inline uint32_t hmac_ll_config_error(void)
|
||||
{
|
||||
return REG_READ(HMAC_QUERY_ERROR_REG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until the HAL is ready for the next interaction.
|
||||
*/
|
||||
static inline void hmac_ll_wait_idle(void)
|
||||
{
|
||||
uint32_t query;
|
||||
do {
|
||||
query = REG_READ(HMAC_QUERY_BUSY_REG);
|
||||
} while(query != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a message block of 512 bits to the HMAC peripheral.
|
||||
*/
|
||||
static inline void hmac_ll_write_block_512(const uint32_t *block)
|
||||
{
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
for (size_t i = 0; i < SHA256_BLOCK_SZ / REG_WIDTH; i++) {
|
||||
REG_WRITE(HMAC_WDATA_BASE + (i * REG_WIDTH), block[i]);
|
||||
}
|
||||
|
||||
REG_WRITE(HMAC_SET_MESSAGE_ONE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the 256 bit HMAC.
|
||||
*/
|
||||
static inline void hmac_ll_read_result_256(uint32_t *result)
|
||||
{
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
for (size_t i = 0; i < SHA256_DIGEST_SZ / REG_WIDTH; i++) {
|
||||
result[i] = REG_READ(HMAC_RDATA_BASE + (i * REG_WIDTH));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clean the HMAC result provided to other hardware.
|
||||
*/
|
||||
static inline void hmac_ll_clean(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_INVALIDATE_DS_REG, 1);
|
||||
REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Signals that the following block will be the padded last block.
|
||||
*/
|
||||
static inline void hmac_ll_msg_padding(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_MESSAGE_PAD_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Signals that all blocks have been written and a padding block will automatically be applied by hardware.
|
||||
*
|
||||
* Only applies if the message length is a multiple of 512 bits.
|
||||
* See ESP32H4 TRM HMAC chapter for more details.
|
||||
*/
|
||||
static inline void hmac_ll_msg_end(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_MESSAGE_END_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The message including padding fits into one block, so no further action needs to be taken.
|
||||
*
|
||||
* This is called after the one-block-message has been written.
|
||||
*/
|
||||
static inline void hmac_ll_msg_one_block(void)
|
||||
{
|
||||
REG_WRITE(HMAC_ONE_BLOCK_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Indicate that more blocks will be written after the last block.
|
||||
*/
|
||||
static inline void hmac_ll_msg_continue(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_MESSAGE_ING_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the HMAC result.
|
||||
*
|
||||
* Use this after reading the HMAC result or if aborting after any of the other steps above.
|
||||
*/
|
||||
static inline void hmac_ll_calc_finish(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_RESULT_FINISH_REG, 2);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,951 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for I2C register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdbool.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/i2c_struct.h"
|
||||
#include "hal/i2c_types.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief I2C hardware cmd register fields.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t byte_num: 8,
|
||||
ack_en: 1,
|
||||
ack_exp: 1,
|
||||
ack_val: 1,
|
||||
op_code: 3,
|
||||
reserved14: 17,
|
||||
done: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} i2c_ll_hw_cmd_t;
|
||||
|
||||
// I2C operation mode command
|
||||
#define I2C_LL_CMD_RESTART 6 /*!<I2C restart command */
|
||||
#define I2C_LL_CMD_WRITE 1 /*!<I2C write command */
|
||||
#define I2C_LL_CMD_READ 3 /*!<I2C read command */
|
||||
#define I2C_LL_CMD_STOP 2 /*!<I2C stop command */
|
||||
#define I2C_LL_CMD_END 4 /*!<I2C end command */
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_NACK = (1 << 10),
|
||||
I2C_INTR_TIMEOUT = (1 << 8),
|
||||
I2C_INTR_MST_COMPLETE = (1 << 7),
|
||||
I2C_INTR_ARBITRATION = (1 << 5),
|
||||
I2C_INTR_END_DETECT = (1 << 3),
|
||||
I2C_INTR_ST_TO = (1 << 13),
|
||||
} i2c_ll_master_intr_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
I2C_INTR_TXFIFO_WM = (1 << 1),
|
||||
I2C_INTR_RXFIFO_WM = (1 << 0),
|
||||
I2C_INTR_SLV_COMPLETE = (1 << 7),
|
||||
I2C_INTR_START = (1 << 15),
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
#define I2C_LL_MASTER_EVENT_INTR (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M|I2C_SCL_ST_TO_INT_ENA)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
* Note that the clock accuracy is affected by the external pull-up resistor,
|
||||
* here we try to to calculate a configuration parameter which is close to the required clock.
|
||||
* But in I2C communication, the clock accuracy is not very concerned.
|
||||
*
|
||||
* @param source_clk I2C source clock
|
||||
* @param bus_freq I2C bus frequency
|
||||
* @param clk_cal Pointer to accept the clock configuration
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t clkm_div = source_clk / (bus_freq * 1024) +1;
|
||||
uint32_t sclk_freq = source_clk / clkm_div;
|
||||
uint32_t half_cycle = sclk_freq / bus_freq / 2;
|
||||
//SCL
|
||||
clk_cal->clkm_div = clkm_div;
|
||||
clk_cal->scl_low = half_cycle;
|
||||
// default, scl_wait_high < scl_high
|
||||
// Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency
|
||||
// according to some hardware behaviors.
|
||||
clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4);
|
||||
clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high;
|
||||
clk_cal->sda_hold = half_cycle / 4;
|
||||
clk_cal->sda_sample = half_cycle / 2;
|
||||
clk_cal->setup = half_cycle;
|
||||
clk_cal->hold = half_cycle;
|
||||
//default we set the timeout value to about 10 bus cycles
|
||||
// log(20*half_cycle)/log(2) = log(half_cycle)/log(2) + log(20)/log(2)
|
||||
clk_cal->tout = (int)(sizeof(half_cycle) * 8 - __builtin_clz(5 * half_cycle)) + 2;
|
||||
|
||||
/* Verify the assumptions made by the hardware */
|
||||
HAL_ASSERT(clk_cal->scl_wait_high < clk_cal->sda_sample &&
|
||||
clk_cal->sda_sample < clk_cal->scl_high);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update I2C configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_update(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.conf_upgate = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the I2C bus timing related register.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param bus_cfg Pointer to the data structure holding the register configuration.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, bus_cfg->clkm_div - 1);
|
||||
/* According to the Technical Reference Manual, the following timings must be subtracted by 1.
|
||||
* However, according to the practical measurement and some hardware behaviour, if wait_high_period and scl_high minus one.
|
||||
* The SCL frequency would be a little higher than expected. Therefore, the solution
|
||||
* here is not to minus scl_high as well as scl_wait high, and the frequency will be absolutely accurate to all frequency
|
||||
* to some extent. */
|
||||
hw->scl_low_period.period = bus_cfg->scl_low - 1;
|
||||
hw->scl_high_period.period = bus_cfg->scl_high;
|
||||
hw->scl_high_period.scl_wait_high_period = bus_cfg->scl_wait_high;
|
||||
//sda sample
|
||||
hw->sda_hold.time = bus_cfg->sda_hold - 1;
|
||||
hw->sda_sample.time = bus_cfg->sda_sample - 1;
|
||||
//setup
|
||||
hw->scl_rstart_setup.time = bus_cfg->setup - 1;
|
||||
hw->scl_stop_setup.time = bus_cfg->setup - 1;
|
||||
//hold
|
||||
hw->scl_start_hold.time = bus_cfg->hold - 1;
|
||||
hw->scl_stop_hold.time = bus_cfg->hold - 1;
|
||||
hw->timeout.time_out_value = bus_cfg->tout;
|
||||
hw->timeout.time_out_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset I2C txFIFO
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_txfifo_rst(i2c_dev_t *hw)
|
||||
{
|
||||
hw->fifo_conf.tx_fifo_rst = 1;
|
||||
hw->fifo_conf.tx_fifo_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset I2C rxFIFO
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_rxfifo_rst(i2c_dev_t *hw)
|
||||
{
|
||||
hw->fifo_conf.rx_fifo_rst = 1;
|
||||
hw->fifo_conf.rx_fifo_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param hight_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
|
||||
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_timing(i2c_dev_t *hw, int hight_period, int low_period)
|
||||
{
|
||||
hw->scl_low_period.period = low_period - 1;
|
||||
hw->scl_high_period.period = hight_period - 10;
|
||||
hw->scl_high_period.scl_wait_high_period = hight_period - hw->scl_high_period.period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param mask Interrupt mask needs to be cleared
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_clear_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param mask Interrupt mask needs to be enabled
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_enable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val |= mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param mask Interrupt mask needs to be disabled
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_disable_intr_mask(i2c_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return I2C interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
|
||||
{
|
||||
*intr_status = hw->int_status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C memory access mode, FIFO mode or non-FIFO mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param fifo_mode_en Set true to enable FIFO access mode, else, set it false
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_fifo_mode(i2c_dev_t *hw, bool fifo_mode_en)
|
||||
{
|
||||
hw->fifo_conf.nonfifo_en = fifo_mode_en ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C timeout
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param tout_num The I2C timeout value needs to be set (2^tout in core clock cycle)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_tout(i2c_dev_t *hw, int tout)
|
||||
{
|
||||
hw->timeout.time_out_value = tout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C slave address
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slave_addr I2C slave address needs to be set
|
||||
* @param addr_10bit_en Set true to enable 10-bit slave address mode, set false to enable 7-bit address mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, bool addr_10bit_en)
|
||||
{
|
||||
hw->slave_addr.addr = slave_addr;
|
||||
hw->slave_addr.en_10bit = addr_10bit_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write I2C hardware command register
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param cmd I2C hardware command
|
||||
* @param cmd_idx The index of the command register, should be less than 16
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_write_cmd_reg(i2c_dev_t *hw, i2c_ll_hw_cmd_t cmd, int cmd_idx)
|
||||
{
|
||||
hw->command[cmd_idx].val = cmd.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C start timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param start_setup The start condition setup period (in core clock cycle)
|
||||
* @param start_hold The start condition hold period (in core clock cycle)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_start_timing(i2c_dev_t *hw, int start_setup, int start_hold)
|
||||
{
|
||||
hw->scl_rstart_setup.time = start_setup;
|
||||
hw->scl_start_hold.time = start_hold - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C stop timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param stop_setup The stop condition setup period (in core clock cycle)
|
||||
* @param stop_hold The stop condition hold period (in core clock cycle)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_stop_timing(i2c_dev_t *hw, int stop_setup, int stop_hold)
|
||||
{
|
||||
hw->scl_stop_setup.time = stop_setup;
|
||||
hw->scl_stop_hold.time = stop_hold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C stop timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param sda_sample The SDA sample time (in core clock cycle)
|
||||
* @param sda_hold The SDA hold time (in core clock cycle)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_sda_timing(i2c_dev_t *hw, int sda_sample, int sda_hold)
|
||||
{
|
||||
hw->sda_hold.time = sda_hold;
|
||||
hw->sda_sample.time = sda_sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2C txFIFO empty threshold
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param empty_thr The txFIFO empty threshold
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr)
|
||||
{
|
||||
hw->fifo_conf.tx_fifo_wm_thrhd = empty_thr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2C rxFIFO full threshold
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param full_thr The rxFIFO full threshold
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr)
|
||||
{
|
||||
hw->fifo_conf.rx_fifo_wm_thrhd = full_thr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the I2C data mode, LSB or MSB
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param tx_mode Tx data bit mode
|
||||
* @param rx_mode Rx data bit mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_data_mode(i2c_dev_t *hw, i2c_trans_mode_t tx_mode, i2c_trans_mode_t rx_mode)
|
||||
{
|
||||
hw->ctr.tx_lsb_first = tx_mode;
|
||||
hw->ctr.rx_lsb_first = rx_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the I2C data mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param tx_mode Pointer to accept the received bytes mode
|
||||
* @param rx_mode Pointer to accept the sended bytes mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_data_mode(i2c_dev_t *hw, i2c_trans_mode_t *tx_mode, i2c_trans_mode_t *rx_mode)
|
||||
{
|
||||
*tx_mode = hw->ctr.tx_lsb_first;
|
||||
*rx_mode = hw->ctr.rx_lsb_first;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C sda timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param sda_sample Pointer to accept the SDA sample timing configuration
|
||||
* @param sda_hold Pointer to accept the SDA hold timing configuration
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_sda_timing(i2c_dev_t *hw, int *sda_sample, int *sda_hold)
|
||||
{
|
||||
*sda_hold = hw->sda_hold.time;
|
||||
*sda_sample = hw->sda_sample.time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the I2C hardware version
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return The I2C hardware version
|
||||
*/
|
||||
static inline uint32_t i2c_ll_get_hw_version(i2c_dev_t *hw)
|
||||
{
|
||||
return hw->date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the I2C bus is busy
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return True if I2C state machine is busy, else false will be returned
|
||||
*/
|
||||
static inline bool i2c_ll_is_bus_busy(i2c_dev_t *hw)
|
||||
{
|
||||
return hw->sr.bus_busy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if I2C is master mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return True if I2C is master mode, else false will be returned
|
||||
*/
|
||||
static inline bool i2c_ll_is_master_mode(i2c_dev_t *hw)
|
||||
{
|
||||
return hw->ctr.ms_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the rxFIFO readable length
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return RxFIFO readable length
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
*length = hw->sr.rx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C txFIFO writable length
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return TxFIFO writable length
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_get_txfifo_len(i2c_dev_t *hw, uint32_t *length)
|
||||
{
|
||||
*length = SOC_I2C_FIFO_LEN - hw->sr.tx_fifo_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C timeout configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return The I2C timeout value
|
||||
*/
|
||||
static inline void i2c_ll_get_tout(i2c_dev_t *hw, int *timeout)
|
||||
{
|
||||
*timeout = hw->timeout.time_out_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start I2C transfer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_trans_start(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.trans_start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C start timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param setup_time Pointer to accept the start condition setup period
|
||||
* @param hold_time Pointer to accept the start condition hold period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_start_timing(i2c_dev_t *hw, int *setup_time, int *hold_time)
|
||||
{
|
||||
*setup_time = hw->scl_rstart_setup.time;
|
||||
*hold_time = hw->scl_start_hold.time + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C stop timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param setup_time Pointer to accept the stop condition setup period
|
||||
* @param hold_time Pointer to accept the stop condition hold period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *hold_time)
|
||||
{
|
||||
*setup_time = hw->scl_stop_setup.time;
|
||||
*hold_time = hw->scl_stop_hold.time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C SCL timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period Pointer to accept the SCL high period
|
||||
* @param low_period Pointer to accept the SCL low period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_scl_timing(i2c_dev_t *hw, int *high_period, int *low_period)
|
||||
{
|
||||
*high_period = hw->scl_high_period.period + hw->scl_high_period.scl_wait_high_period;
|
||||
*low_period = hw->scl_low_period.period + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the I2C hardware txFIFO
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param ptr Pointer to data buffer
|
||||
* @param len Amount of data needs to be writen
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for (int i = 0; i< len; i++) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->fifo_data, data, ptr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the I2C hardware rxFIFO
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param ptr Pointer to data buffer
|
||||
* @param len Amount of data needs read
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->fifo_data, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C hardware filter
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param filter_num If the glitch period on the line is less than this value, it can be filtered out
|
||||
* If `filter_num == 0`, the filter will be disabled
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_filter(i2c_dev_t *hw, uint8_t filter_num)
|
||||
{
|
||||
if (filter_num > 0) {
|
||||
hw->filter_cfg.scl_thres = filter_num;
|
||||
hw->filter_cfg.sda_thres = filter_num;
|
||||
hw->filter_cfg.scl_en = 1;
|
||||
hw->filter_cfg.sda_en = 1;
|
||||
} else {
|
||||
hw->filter_cfg.scl_en = 0;
|
||||
hw->filter_cfg.sda_en = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C hardware filter configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return The hardware filter configuration
|
||||
*/
|
||||
static inline void i2c_ll_get_filter(i2c_dev_t *hw, uint8_t *filter_conf)
|
||||
{
|
||||
*filter_conf = hw->filter_cfg.scl_thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reste I2C master FSM. When the master FSM is stuck, call this function to reset the FSM
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_fsm_rst(i2c_dev_t *hw)
|
||||
{
|
||||
hw->ctr.fsm_rst = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear I2C bus, when the slave is stuck in a deadlock and keeps pulling the bus low,
|
||||
* master can controls the SCL bus to generate 9 CLKs.
|
||||
*
|
||||
* Note: The master cannot detect if deadlock happens, but when the scl_st_to interrupt is generated, a deadlock may occur.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw)
|
||||
{
|
||||
hw->scl_sp_conf.scl_rst_slv_num = 9;
|
||||
hw->scl_sp_conf.scl_rst_slv_en = 1;
|
||||
hw->ctr.conf_upgate = 1;
|
||||
// hardward will clear scl_rst_slv_en after sending SCL pulses,
|
||||
// and we should set conf_upgate bit to synchronize register value.
|
||||
while (hw->scl_sp_conf.scl_rst_slv_en);
|
||||
hw->ctr.conf_upgate = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2C source clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param src_clk Source clock of the I2C
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_clk)
|
||||
{
|
||||
// src_clk : (1) for RTC_CLK, (0) for XTAL
|
||||
hw->clk_conf.sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C peripheral controller clock
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
|
||||
{
|
||||
hw->clk_conf.sclk_active = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init I2C master
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_init(i2c_dev_t *hw)
|
||||
{
|
||||
typeof(hw->ctr) ctrl_reg;
|
||||
ctrl_reg.val = 0;
|
||||
ctrl_reg.ms_mode = 1;
|
||||
ctrl_reg.clk_en = 1;
|
||||
ctrl_reg.sda_force_out = 1;
|
||||
ctrl_reg.scl_force_out = 1;
|
||||
hw->ctr.val = ctrl_reg.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init I2C slave
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_init(i2c_dev_t *hw)
|
||||
{
|
||||
typeof(hw->ctr) ctrl_reg;
|
||||
ctrl_reg.val = 0;
|
||||
ctrl_reg.sda_force_out = 1;
|
||||
ctrl_reg.scl_force_out = 1;
|
||||
hw->ctr.val = ctrl_reg.val;
|
||||
hw->fifo_conf.fifo_addr_cfg_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set whether slave should auto start, or only start with start signal from master
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
|
||||
*/
|
||||
static inline void i2c_ll_slave_tx_auto_start_en(i2c_dev_t *hw, bool slv_ex_auto_en)
|
||||
{
|
||||
hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C interrupt status register address
|
||||
*/
|
||||
static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
{
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// I2C master TX interrupt bitmap
|
||||
#define I2C_LL_MASTER_TX_INT (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M)
|
||||
// I2C master RX interrupt bitmap
|
||||
#define I2C_LL_MASTER_RX_INT (I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M)
|
||||
// I2C slave TX interrupt bitmap
|
||||
#define I2C_LL_SLAVE_TX_INT (I2C_TXFIFO_WM_INT_ENA_M)
|
||||
// I2C slave RX interrupt bitmap
|
||||
#define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_WM_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M)
|
||||
// I2C max timeout value
|
||||
#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
|
||||
|
||||
#define I2C_LL_INTR_MASK (0xffff) /*!< I2C all interrupt bitmap */
|
||||
|
||||
/**
|
||||
* @brief I2C interrupt event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_INTR_EVENT_ERR,
|
||||
I2C_INTR_EVENT_ARBIT_LOST, /*!< I2C arbition lost event */
|
||||
I2C_INTR_EVENT_NACK, /*!< I2C NACK event */
|
||||
I2C_INTR_EVENT_TOUT, /*!< I2C time out event */
|
||||
I2C_INTR_EVENT_END_DET, /*!< I2C end detected event */
|
||||
I2C_INTR_EVENT_TRANS_DONE, /*!< I2C trans done event */
|
||||
I2C_INTR_EVENT_RXFIFO_FULL, /*!< I2C rxfifo full event */
|
||||
I2C_INTR_EVENT_TXFIFO_EMPTY, /*!< I2C txfifo empty event */
|
||||
} i2c_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Configure I2C SCL timing
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period The I2C SCL hight period (in core clock cycle, hight_period > 2)
|
||||
* @param low_period The I2C SCL low period (in core clock cycle, low_period > 1)
|
||||
* @param wait_high_period The I2C SCL wait rising edge period.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void i2c_ll_set_scl_clk_timing(i2c_dev_t *hw, int high_period, int low_period, int wait_high_period)
|
||||
{
|
||||
hw->scl_low_period.period = low_period;
|
||||
hw->scl_high_period.period = high_period;
|
||||
hw->scl_high_period.scl_wait_high_period = wait_high_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C SCL timing configuration
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param high_period Pointer to accept the SCL high period
|
||||
* @param low_period Pointer to accept the SCL low period
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_get_scl_clk_timing(i2c_dev_t *hw, int *high_period, int *low_period, int *wait_high_period)
|
||||
{
|
||||
*high_period = hw->scl_high_period.period;
|
||||
*wait_high_period = hw->scl_high_period.scl_wait_high_period;
|
||||
*low_period = hw->scl_low_period.period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C master interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.arbitration_lost) {
|
||||
*event = I2C_INTR_EVENT_ARBIT_LOST;
|
||||
} else if (int_sts.nack) {
|
||||
*event = I2C_INTR_EVENT_NACK;
|
||||
} else if (int_sts.time_out) {
|
||||
*event = I2C_INTR_EVENT_TOUT;
|
||||
} else if (int_sts.end_detect) {
|
||||
*event = I2C_INTR_EVENT_END_DET;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2C slave interrupt event
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param event Pointer to accept the interrupt event
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_get_event(i2c_dev_t *hw, i2c_intr_event_t *event)
|
||||
{
|
||||
typeof(hw->int_status) int_sts = hw->int_status;
|
||||
if (int_sts.tx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
|
||||
} else if (int_sts.trans_complete) {
|
||||
*event = I2C_INTR_EVENT_TRANS_DONE;
|
||||
} else if (int_sts.rx_fifo_wm) {
|
||||
*event = I2C_INTR_EVENT_RXFIFO_FULL;
|
||||
} else {
|
||||
*event = I2C_INTR_EVENT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.val = UINT32_MAX;
|
||||
hw->int_ena.val = I2C_LL_MASTER_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C master RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_TX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable I2C slave RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_enable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val |= I2C_LL_SLAVE_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C slave TX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_disable_tx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_TX_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C slave RX interrupt
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_slave_disable_rx_it(i2c_dev_t *hw)
|
||||
{
|
||||
hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,504 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for LEDC register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/ledc_types.h"
|
||||
#include "soc/ledc_periph.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
#define LEDC_LL_DUTY_NUM_MAX (LEDC_DUTY_NUM_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_DUTY_CYCLE_LSCH0_V)
|
||||
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_DUTY_SCALE_LSCH0_V)
|
||||
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
|
||||
#define LEDC_LL_FRACTIONAL_BITS (8)
|
||||
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
|
||||
|
||||
#define LEDC_LL_GLOBAL_CLOCKS { \
|
||||
LEDC_SLOW_CLK_APB, \
|
||||
LEDC_SLOW_CLK_XTAL, \
|
||||
LEDC_SLOW_CLK_RC_FAST, \
|
||||
}
|
||||
|
||||
#define LEDC_LL_GLOBAL_CLK_DEFAULT LEDC_SLOW_CLK_RC_FAST
|
||||
|
||||
/**
|
||||
* @brief Set LEDC low speed timer clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel)
|
||||
{
|
||||
uint32_t clk_sel_val = 0;
|
||||
if (slow_clk_sel == LEDC_SLOW_CLK_APB) {
|
||||
clk_sel_val = 1;
|
||||
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
|
||||
clk_sel_val = 2;
|
||||
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
|
||||
clk_sel_val = 3;
|
||||
}
|
||||
hw->conf.apb_clk_sel = clk_sel_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC low speed timer clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel)
|
||||
{
|
||||
uint32_t clk_sel_val = hw->conf.apb_clk_sel;
|
||||
if (clk_sel_val == 1) {
|
||||
*slow_clk_sel = LEDC_SLOW_CLK_APB;
|
||||
} else if (clk_sel_val == 2) {
|
||||
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
|
||||
} else if (clk_sel_val == 3) {
|
||||
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update LEDC low speed timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.low_speed_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pause LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC timer clock divider
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider)
|
||||
{
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock divider
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider)
|
||||
{
|
||||
*clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock source
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_src Pointer to accept the timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
|
||||
{
|
||||
*clk_src = LEDC_APB_CLK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty resolution
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution)
|
||||
{
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty resolution
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Pointer to accept the resolution of duty setting in number of bits.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution)
|
||||
{
|
||||
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update channel configure when select low speed mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC max duty
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param max_duty Pointer to accept the max duty
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty)
|
||||
{
|
||||
uint32_t timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
|
||||
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC hpoint value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC hpoint value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val Pointer to accept the LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val)
|
||||
{
|
||||
*hpoint_val = hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC the integer part of duty value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val LEDC duty value, the range of duty setting is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].duty.duty = duty_val << 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val Pointer to accept the LEDC duty value
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val)
|
||||
{
|
||||
*duty_val = (hw->channel_group[speed_mode].channel[channel_num].duty_rd.duty_read >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty change direction
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_direction LEDC duty change direction, increase or decrease
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty change direction
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_direction Pointer to accept the LEDC duty change direction, increase or decrease
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction)
|
||||
{
|
||||
*duty_direction = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of increased or decreased times
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_num The number of increased or decreased times
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_num = duty_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the duty cycles of increase or decrease
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_cycle The duty cycles
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_cycle = duty_cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the step scale of increase or decrease
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_scale The step scale
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the output enable
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param sig_out_en The output enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.sig_out_en = sig_out_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the duty start
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_start The duty start
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = duty_start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set output idle level
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param idle_level The output idle level
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.idle_lv = idle_level & 0x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set fade end interrupt enable
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param fade_end_intr_en The fade end interrupt enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en)
|
||||
{
|
||||
uint32_t value = hw->int_ena.val;
|
||||
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get fade end interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param intr_status The fade end interrupt status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status)
|
||||
{
|
||||
uint32_t value = hw->int_st.val;
|
||||
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
*intr_status = (value >> int_en_base) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear fade end interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
|
||||
{
|
||||
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
hw->int_clr.val = BIT(int_en_base + channel_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set timer index of the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel)
|
||||
{
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel = timer_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get timer index of the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel Pointer to accept the LEDC timer index
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel)
|
||||
{
|
||||
*timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,564 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/sensitive_reg.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ******************************************************************************************************
|
||||
* *** GLOBALS ***
|
||||
* NOTE: in this version, all the configurations apply only to WORLD_0
|
||||
*/
|
||||
|
||||
#define IRAM_SRAM_START 0x4037C000
|
||||
#define DRAM_SRAM_START 0x3FC7C000
|
||||
|
||||
/* ICache size is fixed to 16KB on ESP32-H4 */
|
||||
#ifndef ICACHE_SIZE
|
||||
#define ICACHE_SIZE 0x4000
|
||||
#endif
|
||||
|
||||
#ifndef I_D_SRAM_SEGMENT_SIZE
|
||||
#define I_D_SRAM_SEGMENT_SIZE 0x20000
|
||||
#endif
|
||||
|
||||
#define I_D_SPLIT_LINE_SHIFT 0x9
|
||||
#define I_D_FAULT_ADDR_SHIFT 0x2
|
||||
|
||||
static inline void memprot_ll_set_iram0_dram0_split_line_lock(void)
|
||||
{
|
||||
REG_WRITE(SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_0_REG, 1);
|
||||
}
|
||||
|
||||
static inline bool memprot_ll_get_iram0_dram0_split_line_lock(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_0_REG) == 1;
|
||||
}
|
||||
|
||||
static inline void* memprot_ll_get_split_addr_from_reg(uint32_t regval, uint32_t base)
|
||||
{
|
||||
return (void*)
|
||||
(base + ((regval & SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_SPLITADDR_M)
|
||||
>> (SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_SPLITADDR_S - I_D_SPLIT_LINE_SHIFT)));
|
||||
}
|
||||
|
||||
/* ******************************************************************************************************
|
||||
* *** IRAM0 ***
|
||||
*/
|
||||
|
||||
//16kB (CACHE)
|
||||
#define IRAM0_SRAM_LEVEL_0_LOW IRAM_SRAM_START //0x40370000
|
||||
#define IRAM0_SRAM_LEVEL_0_HIGH (IRAM0_SRAM_LEVEL_0_LOW + ICACHE_SIZE - 0x1) //0x4037FFFF
|
||||
|
||||
//128kB (LEVEL 1)
|
||||
#define IRAM0_SRAM_LEVEL_1_LOW (IRAM0_SRAM_LEVEL_0_HIGH + 0x1) //0x40380000
|
||||
#define IRAM0_SRAM_LEVEL_1_HIGH (IRAM0_SRAM_LEVEL_1_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x4039FFFF
|
||||
|
||||
//128kB (LEVEL 2)
|
||||
#define IRAM0_SRAM_LEVEL_2_LOW (IRAM0_SRAM_LEVEL_1_HIGH + 0x1) //0x403A0000
|
||||
#define IRAM0_SRAM_LEVEL_2_HIGH (IRAM0_SRAM_LEVEL_2_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x403BFFFF
|
||||
|
||||
//128kB (LEVEL 3)
|
||||
#define IRAM0_SRAM_LEVEL_3_LOW (IRAM0_SRAM_LEVEL_2_HIGH + 0x1) //0x403C0000
|
||||
#define IRAM0_SRAM_LEVEL_3_HIGH (IRAM0_SRAM_LEVEL_3_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x403DFFFF
|
||||
|
||||
//permission bits
|
||||
#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_R 0x1
|
||||
#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_W 0x2
|
||||
#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_F 0x4
|
||||
|
||||
static inline uint32_t memprot_ll_iram0_get_intr_source_num(void)
|
||||
{
|
||||
return ETS_CORE0_IRAM0_PMS_INTR_SOURCE;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
// IRAM0 - SPLIT LINES
|
||||
///////////////////////////////////
|
||||
|
||||
static inline void memprot_ll_set_iram0_split_line(const void *line_addr, uint32_t sensitive_reg)
|
||||
{
|
||||
uint32_t addr = (uint32_t)line_addr;
|
||||
HAL_ASSERT( addr >= IRAM0_SRAM_LEVEL_1_LOW && addr <= IRAM0_SRAM_LEVEL_3_HIGH );
|
||||
|
||||
uint32_t category[3] = {0};
|
||||
if (addr <= IRAM0_SRAM_LEVEL_1_HIGH) {
|
||||
category[0] = 0x2;
|
||||
category[1] = category[2] = 0x3;
|
||||
} else if (addr >= IRAM0_SRAM_LEVEL_2_LOW && addr <= IRAM0_SRAM_LEVEL_2_HIGH) {
|
||||
category[1] = 0x2;
|
||||
category[2] = 0x3;
|
||||
} else {
|
||||
category[2] = 0x2;
|
||||
}
|
||||
|
||||
//NOTE: category & split line address bits are the same for all the areas
|
||||
uint32_t category_bits =
|
||||
(category[0] << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_0_S) |
|
||||
(category[1] << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_1_S) |
|
||||
(category[2] << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_2_S);
|
||||
|
||||
uint32_t conf_addr = ((addr >> I_D_SPLIT_LINE_SHIFT) & SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_SPLITADDR_V) << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_SPLITADDR_S;
|
||||
|
||||
uint32_t reg_cfg = conf_addr | category_bits;
|
||||
|
||||
REG_WRITE(sensitive_reg, reg_cfg);
|
||||
}
|
||||
|
||||
/* can be both IRAM0/DRAM0 address */
|
||||
static inline void memprot_ll_set_iram0_split_line_main_I_D(const void *line_addr)
|
||||
{
|
||||
memprot_ll_set_iram0_split_line(line_addr, SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_1_REG);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_set_iram0_split_line_I_0(const void *line_addr)
|
||||
{
|
||||
memprot_ll_set_iram0_split_line(line_addr, SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_2_REG);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_set_iram0_split_line_I_1(const void *line_addr)
|
||||
{
|
||||
memprot_ll_set_iram0_split_line(line_addr, SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_3_REG);
|
||||
}
|
||||
|
||||
static inline void* memprot_ll_get_iram0_split_line_main_I_D(void)
|
||||
{
|
||||
return memprot_ll_get_split_addr_from_reg(REG_READ(SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_1_REG), SOC_DIRAM_IRAM_LOW);
|
||||
}
|
||||
|
||||
static inline void* memprot_ll_get_iram0_split_line_I_0(void)
|
||||
{
|
||||
return memprot_ll_get_split_addr_from_reg(REG_READ(SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_2_REG), SOC_DIRAM_IRAM_LOW);
|
||||
}
|
||||
|
||||
static inline void* memprot_ll_get_iram0_split_line_I_1(void)
|
||||
{
|
||||
return memprot_ll_get_split_addr_from_reg(REG_READ(SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_3_REG), SOC_DIRAM_IRAM_LOW);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
// IRAM0 - PMS CONFIGURATION
|
||||
///////////////////////////////////
|
||||
|
||||
// lock
|
||||
static inline void memprot_ll_iram0_set_pms_lock(void)
|
||||
{
|
||||
REG_WRITE(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_0_REG, 1);
|
||||
}
|
||||
|
||||
static inline bool memprot_ll_iram0_get_pms_lock(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_0_REG) == 1;
|
||||
}
|
||||
|
||||
// permission settings
|
||||
static inline uint32_t memprot_ll_iram0_set_permissions(bool r, bool w, bool x)
|
||||
{
|
||||
uint32_t permissions = 0;
|
||||
if ( r ) {
|
||||
permissions |= SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_R;
|
||||
}
|
||||
if ( w ) {
|
||||
permissions |= SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_W;
|
||||
}
|
||||
if ( x ) {
|
||||
permissions |= SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_F;
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_set_pms_area_0(bool r, bool w, bool x)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_0, memprot_ll_iram0_set_permissions(r, w, x));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_set_pms_area_1(bool r, bool w, bool x)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_1, memprot_ll_iram0_set_permissions(r, w, x));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_set_pms_area_2(bool r, bool w, bool x)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_2, memprot_ll_iram0_set_permissions(r, w, x));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_set_pms_area_3(bool r, bool w, bool x)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_3, memprot_ll_iram0_set_permissions(r, w, x));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_get_permissions(uint32_t perms, bool *r, bool *w, bool *x)
|
||||
{
|
||||
*r = perms & SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_R;
|
||||
*w = perms & SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_W;
|
||||
*x = perms & SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_F;
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_get_pms_area_0(bool *r, bool *w, bool *x)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_0);
|
||||
memprot_ll_iram0_get_permissions( permissions, r, w, x);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_get_pms_area_1(bool *r, bool *w, bool *x)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_1);
|
||||
memprot_ll_iram0_get_permissions( permissions, r, w, x);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_get_pms_area_2(bool *r, bool *w, bool *x)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_2);
|
||||
memprot_ll_iram0_get_permissions( permissions, r, w, x);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_get_pms_area_3(bool *r, bool *w, bool *x)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_3);
|
||||
memprot_ll_iram0_get_permissions( permissions, r, w, x);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
// IRAM0 - MONITOR
|
||||
///////////////////////////////////
|
||||
|
||||
// lock
|
||||
static inline void memprot_ll_iram0_set_monitor_lock(void)
|
||||
{
|
||||
REG_WRITE(SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_0_REG, 1);
|
||||
}
|
||||
|
||||
static inline bool memprot_ll_iram0_get_monitor_lock(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_0_REG) == 1;
|
||||
}
|
||||
|
||||
// interrupt enable/clear
|
||||
static inline void memprot_ll_iram0_set_monitor_en(bool enable)
|
||||
{
|
||||
if ( enable ) {
|
||||
REG_SET_BIT( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_EN );
|
||||
} else {
|
||||
REG_CLR_BIT( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_EN );
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool memprot_ll_iram0_get_monitor_en(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_EN ) == 1;
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_clear_monitor_intr(void)
|
||||
{
|
||||
REG_SET_BIT( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_CLR );
|
||||
}
|
||||
|
||||
static inline void memprot_ll_iram0_reset_clear_monitor_intr(void)
|
||||
{
|
||||
REG_CLR_BIT( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_CLR );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_iram0_get_monitor_enable_register(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_1_REG);
|
||||
}
|
||||
|
||||
// // permission violation status
|
||||
static inline uint32_t memprot_ll_iram0_get_monitor_status_intr(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_INTR );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_iram0_get_monitor_status_fault_wr(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_STATUS_WR );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_iram0_get_monitor_status_fault_loadstore(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_STATUS_LOADSTORE );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_iram0_get_monitor_status_fault_world(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_STATUS_WORLD );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_iram0_get_monitor_status_fault_addr(void)
|
||||
{
|
||||
uint32_t addr = REG_GET_FIELD( SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_VIOLATE_STATUS_ADDR );
|
||||
return addr > 0 ? (addr << I_D_FAULT_ADDR_SHIFT) + IRAM0_ADDRESS_LOW : 0;
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_iram0_get_monitor_status_register(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_2_REG);
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************************************************************
|
||||
* *** DRAM0 ***
|
||||
*/
|
||||
|
||||
//cache not available from DRAM (!)
|
||||
#define DRAM0_SRAM_LEVEL_0_LOW DRAM_SRAM_START //0x3FC7C000
|
||||
#define DRAM0_SRAM_LEVEL_0_HIGH (DRAM0_SRAM_LEVEL_0_LOW + ICACHE_SIZE - 0x1) //0x3FC7FFFF
|
||||
|
||||
//128kB
|
||||
#define DRAM0_SRAM_LEVEL_1_LOW (DRAM0_SRAM_LEVEL_0_HIGH + 0x1) //0x3FC80000
|
||||
#define DRAM0_SRAM_LEVEL_1_HIGH (DRAM0_SRAM_LEVEL_1_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x3FC9FFFF
|
||||
|
||||
//128kB
|
||||
#define DRAM0_SRAM_LEVEL_2_LOW (DRAM0_SRAM_LEVEL_1_HIGH + 0x1) //0x3FCA0000
|
||||
#define DRAM0_SRAM_LEVEL_2_HIGH (DRAM0_SRAM_LEVEL_2_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x3FCBFFFF
|
||||
|
||||
//128kB
|
||||
#define DRAM0_SRAM_LEVEL_3_LOW (DRAM0_SRAM_LEVEL_2_HIGH + 0x1) //0x3FCC0000
|
||||
#define DRAM0_SRAM_LEVEL_3_HIGH (DRAM0_SRAM_LEVEL_3_LOW + I_D_SRAM_SEGMENT_SIZE - 0x1) //0x3FCDFFFF
|
||||
|
||||
#define SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_W 0x2
|
||||
#define SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_R 0x1
|
||||
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_intr_source_num(void)
|
||||
{
|
||||
return ETS_CORE0_DRAM0_PMS_INTR_SOURCE;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
// DRAM0 - SPLIT LINES
|
||||
///////////////////////////////////
|
||||
|
||||
static inline void memprot_ll_set_dram0_split_line(const void *line_addr, uint32_t sensitive_reg)
|
||||
{
|
||||
uint32_t addr = (uint32_t)line_addr;
|
||||
HAL_ASSERT( addr >= DRAM0_SRAM_LEVEL_1_LOW && addr <= DRAM0_SRAM_LEVEL_3_HIGH );
|
||||
|
||||
uint32_t category[3] = {0};
|
||||
if (addr <= DRAM0_SRAM_LEVEL_1_HIGH) {
|
||||
category[0] = 0x2;
|
||||
category[1] = category[2] = 0x3;
|
||||
} else if (addr >= DRAM0_SRAM_LEVEL_2_LOW && addr <= DRAM0_SRAM_LEVEL_2_HIGH) {
|
||||
category[1] = 0x2;
|
||||
category[2] = 0x3;
|
||||
} else {
|
||||
category[2] = 0x2;
|
||||
}
|
||||
|
||||
//NOTE: line address & category bits, shifts and masks are the same for all the areas
|
||||
uint32_t category_bits =
|
||||
(category[0] << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_0_S) |
|
||||
(category[1] << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_1_S) |
|
||||
(category[2] << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_2_S);
|
||||
|
||||
uint32_t conf_addr = ((addr >> I_D_SPLIT_LINE_SHIFT) & SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_SPLITADDR_V) << SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SRAM_SPLITADDR_S;
|
||||
|
||||
uint32_t reg_cfg = conf_addr | category_bits;
|
||||
|
||||
REG_WRITE(sensitive_reg, reg_cfg);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_set_dram0_split_line_D_0(const void *line_addr)
|
||||
{
|
||||
memprot_ll_set_dram0_split_line(line_addr, SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_2_REG);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_set_dram0_split_line_D_1(const void *line_addr)
|
||||
{
|
||||
memprot_ll_set_dram0_split_line(line_addr, SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_3_REG);
|
||||
}
|
||||
|
||||
static inline void* memprot_ll_get_dram0_split_line_D_0(void)
|
||||
{
|
||||
return memprot_ll_get_split_addr_from_reg(REG_READ(SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_2_REG), SOC_DIRAM_DRAM_LOW);
|
||||
}
|
||||
|
||||
static inline void* memprot_ll_get_dram0_split_line_D_1(void)
|
||||
{
|
||||
return memprot_ll_get_split_addr_from_reg(REG_READ(SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_3_REG), SOC_DIRAM_DRAM_LOW);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
// DRAM0 - PMS CONFIGURATION
|
||||
///////////////////////////////////
|
||||
|
||||
// lock
|
||||
static inline void memprot_ll_dram0_set_pms_lock(void)
|
||||
{
|
||||
REG_WRITE(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_0_REG, 1);
|
||||
}
|
||||
|
||||
static inline bool memprot_ll_dram0_get_pms_lock(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_0_REG) == 1;
|
||||
}
|
||||
|
||||
// permission settings
|
||||
static inline uint32_t memprot_ll_dram0_set_permissions(bool r, bool w)
|
||||
{
|
||||
uint32_t permissions = 0;
|
||||
if ( r ) {
|
||||
permissions |= SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_R;
|
||||
}
|
||||
if ( w ) {
|
||||
permissions |= SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_W;
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_set_pms_area_0(bool r, bool w)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_0, memprot_ll_dram0_set_permissions(r, w));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_set_pms_area_1(bool r, bool w)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_1, memprot_ll_dram0_set_permissions(r, w));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_set_pms_area_2(bool r, bool w)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_2, memprot_ll_dram0_set_permissions(r, w));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_set_pms_area_3(bool r, bool w)
|
||||
{
|
||||
REG_SET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_3, memprot_ll_dram0_set_permissions(r, w));
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_get_permissions(uint32_t perms, bool *r, bool *w )
|
||||
{
|
||||
*r = perms & SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_R;
|
||||
*w = perms & SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_W;
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_get_pms_area_0(bool *r, bool *w)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_0);
|
||||
memprot_ll_dram0_get_permissions( permissions, r, w);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_get_pms_area_1(bool *r, bool *w)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_1);
|
||||
memprot_ll_dram0_get_permissions( permissions, r, w);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_get_pms_area_2(bool *r, bool *w)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_2);
|
||||
memprot_ll_dram0_get_permissions( permissions, r, w);
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_get_pms_area_3(bool *r, bool *w)
|
||||
{
|
||||
uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_1_REG, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_PMS_3);
|
||||
memprot_ll_dram0_get_permissions( permissions, r, w);
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// DRAM0 - MONITOR
|
||||
///////////////////////////////////
|
||||
|
||||
// lock
|
||||
static inline void memprot_ll_dram0_set_monitor_lock(void)
|
||||
{
|
||||
REG_WRITE(SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_0_REG, 1);
|
||||
}
|
||||
|
||||
static inline bool memprot_ll_dram0_get_monitor_lock(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_0_REG) == 1;
|
||||
}
|
||||
|
||||
// interrupt enable/clear
|
||||
static inline void memprot_ll_dram0_set_monitor_en(bool enable)
|
||||
{
|
||||
if ( enable ) {
|
||||
REG_SET_BIT( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_EN );
|
||||
} else {
|
||||
REG_CLR_BIT( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_EN );
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool memprot_ll_dram0_get_monitor_en(void)
|
||||
{
|
||||
return REG_GET_BIT( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_EN ) == 1;
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_clear_monitor_intr(void)
|
||||
{
|
||||
REG_SET_BIT( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_CLR );
|
||||
}
|
||||
|
||||
static inline void memprot_ll_dram0_reset_clear_monitor_intr(void)
|
||||
{
|
||||
REG_CLR_BIT( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_1_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_CLR );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_enable_register(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_1_REG);
|
||||
}
|
||||
|
||||
// permission violation status
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_intr(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_INTR );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_fault_lock(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_STATUS_LOCK );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_fault_world(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_STATUS_WORLD );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_fault_addr(void)
|
||||
{
|
||||
uint32_t addr = REG_GET_FIELD( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_STATUS_ADDR );
|
||||
return addr > 0 ? (addr << I_D_FAULT_ADDR_SHIFT) + DRAM0_ADDRESS_LOW : 0;
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_fault_wr(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_3_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_STATUS_WR );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_fault_byte_en(void)
|
||||
{
|
||||
return REG_GET_FIELD( SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_2_REG, SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_VIOLATE_STATUS_BYTEEN );
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_register_1(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_2_REG);
|
||||
}
|
||||
|
||||
static inline uint32_t memprot_ll_dram0_get_monitor_status_register_2(void)
|
||||
{
|
||||
return REG_READ(SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_3_REG);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,317 +0,0 @@
|
||||
/*
|
||||
* 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 "esp_types.h"
|
||||
#include "soc/extmem_reg.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/mmu_types.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_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 vaddr_base = 0;
|
||||
if (vaddr_type == MMU_VADDR_DATA) {
|
||||
vaddr_base = SOC_MMU_DBUS_VADDR_BASE;
|
||||
} else {
|
||||
vaddr_base = SOC_MMU_IBUS_VADDR_BASE;
|
||||
}
|
||||
|
||||
return vaddr_base | laddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
//On esp32h4, MMU page size is always 64KB
|
||||
return MMU_PAGE_64KB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set MMU page size
|
||||
*
|
||||
* @param size MMU page size
|
||||
*
|
||||
* @note On esp32h4, only supports `MMU_PAGE_64KB`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void mmu_ll_set_page_size(uint32_t mmu_id, uint32_t size)
|
||||
{
|
||||
HAL_ASSERT(size == MMU_PAGE_64KB);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
uint32_t vaddr_end = vaddr_start + len - 1;
|
||||
bool valid = false;
|
||||
|
||||
if (type & MMU_VADDR_INSTRUCTION) {
|
||||
valid |= (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end));
|
||||
}
|
||||
|
||||
if (type & MMU_VADDR_DATA) {
|
||||
valid |= (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end));
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
return ((vaddr & MMU_VADDR_MASK) >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
return paddr >> 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
HAL_ASSERT(target == MMU_TARGET_FLASH0);
|
||||
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
|
||||
|
||||
*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) = mmu_val | MMU_ACCESS_FLASH | MMU_VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
|
||||
|
||||
return *(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set MMU table entry as invalid
|
||||
*
|
||||
* @param mmu_id MMU ID
|
||||
* @param entry_id MMU entry ID
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void mmu_ll_set_entry_invalid(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
(void)mmu_id;
|
||||
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
|
||||
|
||||
*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) = 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)
|
||||
{
|
||||
(void)mmu_id;
|
||||
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
|
||||
|
||||
return (*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4) & MMU_INVALID) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
(void)mmu_id;
|
||||
HAL_ASSERT(entry_id < MMU_ENTRY_NUM);
|
||||
|
||||
return MMU_TARGET_FLASH0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
return ((*(uint32_t *)(DR_REG_MMU_TABLE + entry_id * 4)) & MMU_VALID_VAL_MASK) << 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
(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) {
|
||||
if (((*(uint32_t *)(DR_REG_MMU_TABLE + i * 4)) & 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;
|
||||
uint32_t laddr = entry_id << 16;
|
||||
|
||||
return mmu_ll_laddr_to_vaddr(laddr, type);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This LL is currently unused for ESP32-H4 - IDF-2375 */
|
||||
|
||||
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
|
@ -1,291 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 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
|
||||
|
||||
//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->wdtconfig0.wdt_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtconfig0.wdt_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->wdtconfig0.wdt_en) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtconfig0.wdt_stg0 = behavior;
|
||||
hw->wdtconfig2.wdt_stg0_hold = timeout;
|
||||
break;
|
||||
case WDT_STAGE1:
|
||||
hw->wdtconfig0.wdt_stg1 = behavior;
|
||||
hw->wdtconfig3.wdt_stg1_hold = timeout;
|
||||
break;
|
||||
case WDT_STAGE2:
|
||||
hw->wdtconfig0.wdt_stg2 = behavior;
|
||||
hw->wdtconfig4.wdt_stg2_hold = timeout;
|
||||
break;
|
||||
case WDT_STAGE3:
|
||||
hw->wdtconfig0.wdt_stg3 = behavior;
|
||||
hw->wdtconfig5.wdt_stg3_hold = timeout;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "unsupported WDT stage");
|
||||
break;
|
||||
}
|
||||
//Config registers are updated asynchronously
|
||||
hw->wdtconfig0.wdt_conf_update_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->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:
|
||||
HAL_ASSERT(false && "unsupported WDT stage");
|
||||
break;
|
||||
}
|
||||
//Config registers are updated asynchronously
|
||||
hw->wdtconfig0.wdt_conf_update_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtconfig0.wdt_cpu_reset_length = length;
|
||||
//Config registers are updated asynchronously
|
||||
hw->wdtconfig0.wdt_conf_update_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtconfig0.wdt_sys_reset_length = length;
|
||||
//Config registers are updated asynchronously
|
||||
hw->wdtconfig0.wdt_conf_update_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0;
|
||||
//Config registers are updated asynchronously
|
||||
hw->wdtconfig0.wdt_conf_update_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtconfig1, wdt_clk_prescale, prescaler);
|
||||
//Config registers are updated asynchronously
|
||||
hw->wdtconfig0.wdt_conf_update_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtfeed.wdt_feed = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtwprotect.wdt_wkey = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->wdtwprotect.wdt_wkey = TIMG_WDT_WKEY_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_timers.wdt_int_clr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_timers.wdt_int_ena = (enable) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
switch (clk_src) {
|
||||
case MWDT_CLK_SRC_APB:
|
||||
hw->wdtconfig0.wdt_use_xtal = 0;
|
||||
break;
|
||||
case MWDT_CLK_SRC_XTAL:
|
||||
hw->wdtconfig0.wdt_use_xtal = 1;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
hw->regclk.wdt_clk_is_active = en;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 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
|
||||
|
||||
/**
|
||||
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
|
||||
*/
|
||||
static inline void regi2c_ctrl_ll_i2c_reset(void)
|
||||
{
|
||||
// On ESP32-H4, don't need to do anything (indeed do need? not fully supported yet?)
|
||||
|
||||
// SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
|
||||
*/
|
||||
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
|
||||
{
|
||||
// On ESP32-H4, don't need to do anything (indeed do need? not fully supported yet?)
|
||||
|
||||
// CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* This helps to prevent BBPLL jitter (phenomenon is significant on ESP32H4)
|
||||
*/
|
||||
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
|
@ -1,834 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @note TX and RX channels are index from 0 in the LL driver, i.e. tx_channel = [0,1], rx_channel = [0,1]
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/rmt_struct.h"
|
||||
#include "hal/rmt_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RMT_LL_EVENT_TX_DONE(channel) (1 << (channel))
|
||||
#define RMT_LL_EVENT_TX_THRES(channel) (1 << ((channel) + 8))
|
||||
#define RMT_LL_EVENT_TX_LOOP_END(channel) (1 << ((channel) + 12))
|
||||
#define RMT_LL_EVENT_TX_ERROR(channel) (1 << ((channel) + 4))
|
||||
#define RMT_LL_EVENT_RX_DONE(channel) (1 << ((channel) + 2))
|
||||
#define RMT_LL_EVENT_RX_THRES(channel) (1 << ((channel) + 10))
|
||||
#define RMT_LL_EVENT_RX_ERROR(channel) (1 << ((channel) + 6))
|
||||
#define RMT_LL_EVENT_TX_MASK(channel) (RMT_LL_EVENT_TX_DONE(channel) | RMT_LL_EVENT_TX_THRES(channel) | RMT_LL_EVENT_TX_LOOP_END(channel))
|
||||
#define RMT_LL_EVENT_RX_MASK(channel) (RMT_LL_EVENT_RX_DONE(channel) | RMT_LL_EVENT_RX_THRES(channel))
|
||||
|
||||
#define RMT_LL_MAX_LOOP_COUNT_PER_BATCH 1023
|
||||
|
||||
typedef enum {
|
||||
RMT_LL_MEM_OWNER_SW = 0,
|
||||
RMT_LL_MEM_OWNER_HW = 1,
|
||||
} rmt_ll_mem_owner_t;
|
||||
|
||||
/**
|
||||
* @brief Enable clock gate for register and memory
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->sys_conf.clk_en = enable; // register clock gating
|
||||
dev->sys_conf.mem_clk_force_on = enable; // memory clock gating
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->sys_conf.mem_force_pu = !enable;
|
||||
dev->sys_conf.mem_force_pd = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable APB accessing RMT memory in nonfifo mode
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->sys_conf.fifo_mask = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set clock source and divider for RMT channel group
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel not used as clock source is set for all channels
|
||||
* @param src Clock source
|
||||
* @param divider_integral Integral part of the divider
|
||||
* @param divider_denominator Denominator part of the divider
|
||||
* @param divider_numerator Numerator part of the divider
|
||||
*/
|
||||
static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src,
|
||||
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
|
||||
{
|
||||
// Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b)
|
||||
(void)channel; // the source clock is set for all channels
|
||||
HAL_ASSERT(divider_integral >= 1);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->sys_conf, sclk_div_num, divider_integral - 1);
|
||||
dev->sys_conf.sclk_div_a = divider_numerator;
|
||||
dev->sys_conf.sclk_div_b = divider_denominator;
|
||||
switch (src) {
|
||||
case RMT_CLK_SRC_AHB:
|
||||
dev->sys_conf.sclk_sel = 1;
|
||||
break;
|
||||
case RMT_CLK_SRC_XTAL:
|
||||
dev->sys_conf.sclk_sel = 3;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "unsupported RMT clock source");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable RMT peripheral source clock
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_enable_group_clock(rmt_dev_t *dev, bool en)
|
||||
{
|
||||
dev->sys_conf.sclk_active = en;
|
||||
}
|
||||
|
||||
////////////////////////////////////////TX Channel Specific/////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Reset clock divider for TX channels by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel_mask Mask of TX channels
|
||||
*/
|
||||
static inline void rmt_ll_tx_reset_channels_clock_div(rmt_dev_t *dev, uint32_t channel_mask)
|
||||
{
|
||||
// write 1 to reset
|
||||
dev->ref_cnt_rst.val |= channel_mask & 0x03;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set TX channel clock divider
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param div Division value
|
||||
*/
|
||||
static inline void rmt_ll_tx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)
|
||||
{
|
||||
HAL_ASSERT(div >= 1 && div <= 256 && "divider out of range");
|
||||
// limit the maximum divider to 256
|
||||
if (div >= 256) {
|
||||
div = 0; // 0 means 256 division
|
||||
}
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_conf[channel], div_cnt, div);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset RMT reading pointer for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_reset_pointer(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->tx_conf[channel].mem_rd_rst = 1;
|
||||
dev->tx_conf[channel].mem_rd_rst = 0;
|
||||
dev->tx_conf[channel].mem_rst = 1;
|
||||
dev->tx_conf[channel].mem_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start transmitting for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_start(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
// update other configuration registers before start transmitting
|
||||
dev->tx_conf[channel].conf_update = 1;
|
||||
dev->tx_conf[channel].tx_start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop transmitting for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_stop(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->tx_conf[channel].tx_stop = 1;
|
||||
// stop won't take place until configurations updated
|
||||
dev->tx_conf[channel].conf_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set memory block number for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param block_num memory block number
|
||||
*/
|
||||
static inline void rmt_ll_tx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num)
|
||||
{
|
||||
dev->tx_conf[channel].mem_size = block_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable TX wrap
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_wrap(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].mem_tx_wrap_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable transmitting in a loop
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_enable_loop(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].tx_conti_mode = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set loop count for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param count TX loop count
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_set_loop_count(rmt_dev_t *dev, uint32_t channel, uint32_t count)
|
||||
{
|
||||
HAL_ASSERT(count <= RMT_LL_MAX_LOOP_COUNT_PER_BATCH && "loop count out of range");
|
||||
dev->tx_lim[channel].tx_loop_num = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset loop count for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_reset_loop_count(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->tx_lim[channel].loop_count_reset = 1;
|
||||
dev->tx_lim[channel].loop_count_reset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable loop count for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_enable_loop_count(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_lim[channel].tx_loop_cnt_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable transmit multiple channels synchronously
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_sync(rmt_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->tx_sim.en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the TX channels synchronous group
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_tx_clear_sync_group(rmt_dev_t *dev)
|
||||
{
|
||||
dev->tx_sim.val &= ~(0x03);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add TX channels to the synchronous group
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel_mask Mask of TX channels to be added to the synchronous group
|
||||
*/
|
||||
static inline void rmt_ll_tx_sync_group_add_channels(rmt_dev_t *dev, uint32_t channel_mask)
|
||||
{
|
||||
dev->tx_sim.val |= (channel_mask & 0x03);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove TX channels from the synchronous group
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel_mask Mask of TX channels to be removed from the synchronous group
|
||||
*/
|
||||
static inline void rmt_ll_tx_sync_group_remove_channels(rmt_dev_t *dev, uint32_t channel_mask)
|
||||
{
|
||||
dev->tx_sim.val &= ~channel_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fix the output level when TX channel is in IDLE state
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param level IDLE level (1 => high, 0 => low)
|
||||
* @param enable True to fix the IDLE level, otherwise the IDLE level is determined by EOF encoder
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_tx_fix_idle_level(rmt_dev_t *dev, uint32_t channel, uint8_t level, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].idle_out_en = enable;
|
||||
dev->tx_conf[channel].idle_out_lv = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the amount of RMT symbols that can trigger the limitation interrupt
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param limit Specify the number of symbols
|
||||
*/
|
||||
static inline void rmt_ll_tx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
|
||||
{
|
||||
dev->tx_lim[channel].limit = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set high and low duration of carrier signal
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param high_ticks Duration of high level
|
||||
* @param low_ticks Duration of low level
|
||||
*/
|
||||
static inline void rmt_ll_tx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks)
|
||||
{
|
||||
HAL_ASSERT(high_ticks >= 1 && high_ticks <= 65536 && low_ticks >= 1 && low_ticks <= 65536 && "out of range high/low ticks");
|
||||
// ticks=0 means 65536 in hardware
|
||||
if (high_ticks >= 65536) {
|
||||
high_ticks = 0;
|
||||
}
|
||||
if (low_ticks >= 65536) {
|
||||
low_ticks = 0;
|
||||
}
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_carrier[channel], high, high_ticks);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_carrier[channel], low, low_ticks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable modulating carrier signal to TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_modulation(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].carrier_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set on high or low to modulate the carrier signal
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param level Which level to modulate on (0=>low level, 1=>high level)
|
||||
*/
|
||||
static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
|
||||
{
|
||||
dev->tx_conf[channel].carrier_out_lv = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable to always output carrier signal, regardless of a valid data transmission
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].carrier_eff_en = !enable;
|
||||
}
|
||||
|
||||
////////////////////////////////////////RX Channel Specific/////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Reset clock divider for RX channels by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel_mask Mask of RX channels
|
||||
*/
|
||||
static inline void rmt_ll_rx_reset_channels_clock_div(rmt_dev_t *dev, uint32_t channel_mask)
|
||||
{
|
||||
// write 1 to reset
|
||||
dev->ref_cnt_rst.val |= ((channel_mask & 0x03) << 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RX channel clock divider
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param div Division value
|
||||
*/
|
||||
static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)
|
||||
{
|
||||
HAL_ASSERT(div >= 1 && div <= 256 && "divider out of range");
|
||||
// limit the maximum divider to 256
|
||||
if (div >= 256) {
|
||||
div = 0; // 0 means 256 division
|
||||
}
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_conf[channel].conf0, div_cnt, div);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset RMT writing pointer for RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
*/
|
||||
static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.mem_wr_rst = 1;
|
||||
dev->rx_conf[channel].conf1.mem_wr_rst = 0;
|
||||
dev->rx_conf[channel].conf1.mem_rst = 1;
|
||||
dev->rx_conf[channel].conf1.mem_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable receiving for RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_rx_enable(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.rx_en = enable;
|
||||
// rx won't be enabled until configurations updated
|
||||
dev->rx_conf[channel].conf1.conf_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set memory block number for RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param block_num memory block number
|
||||
*/
|
||||
static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.mem_size = block_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the time length for RX channel before going into IDLE state
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param thres Time length threshold
|
||||
*/
|
||||
static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.idle_thres = thres;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RMT memory owner for RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param owner Memory owner
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt_ll_mem_owner_t owner)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.mem_owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable filter for RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX chanenl number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.rx_filter_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RX channel filter threshold (i.e. the maximum width of one pulse signal that would be treated as a noise)
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param thres Filter threshold
|
||||
*/
|
||||
static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_conf[channel].conf1, rx_filter_thres, thres);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get RMT memory write cursor offset
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @return writer offset
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_memory_writer_offset(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_status[channel].mem_waddr_ex - (channel + 2) * 48;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the amount of RMT symbols that can trigger the limitation interrupt
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param limit Specify the number of symbols
|
||||
*/
|
||||
static inline void rmt_ll_rx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
|
||||
{
|
||||
dev->rx_lim[channel].rx_lim = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set high and low duration of carrier signal
|
||||
*
|
||||
* @param dev dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param high_ticks Duration of high level
|
||||
* @param low_ticks Duration of low level
|
||||
*/
|
||||
static inline void rmt_ll_rx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks)
|
||||
{
|
||||
HAL_ASSERT(high_ticks >= 1 && high_ticks <= 65536 && low_ticks >= 1 && low_ticks <= 65536 && "out of range high/low ticks");
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_carrier[channel], high_thres, high_ticks - 1);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_carrier[channel], low_thres, low_ticks - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable demodulating the carrier on RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_rx_enable_carrier_demodulation(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.carrier_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set on high or low to demodulate the carrier signal
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param level Which level to demodulate (0=>low level, 1=>high level)
|
||||
*/
|
||||
static inline void rmt_ll_rx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.carrier_out_lv = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable RX wrap
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void rmt_ll_rx_enable_wrap(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.mem_rx_wrap_en = enable;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Interrupt Specific////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Enable RMT interrupt for specific event mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Event mask
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
dev->int_ena.val |= mask;
|
||||
} else {
|
||||
dev->int_ena.val &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->int_clr.val = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status register address
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @return Register address
|
||||
*/
|
||||
static inline volatile void *rmt_ll_get_interrupt_status_reg(rmt_dev_t *dev)
|
||||
{
|
||||
return &dev->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @return Interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_tx_get_interrupt_status(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->int_st.val & RMT_LL_EVENT_TX_MASK(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt raw status for TX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @return Interrupt raw status
|
||||
*/
|
||||
static inline uint32_t rmt_ll_tx_get_interrupt_status_raw(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->int_raw.val & (RMT_LL_EVENT_TX_MASK(channel) | RMT_LL_EVENT_TX_ERROR(channel));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt raw status for RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @return Interrupt raw status
|
||||
*/
|
||||
static inline uint32_t rmt_ll_rx_get_interrupt_status_raw(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->int_raw.val & (RMT_LL_EVENT_RX_MASK(channel) | RMT_LL_EVENT_RX_ERROR(channel));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status for RX channel
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT RX channel number
|
||||
* @return Interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_status[channel].val;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_status[channel].val;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->tx_conf[channel], div_cnt);
|
||||
return div == 0 ? 256 : div;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->rx_conf[channel].conf0, div_cnt);
|
||||
return div == 0 ? 256 : div;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_conf[channel].conf0.idle_thres;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].mem_size;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_conf[channel].conf0.mem_size;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].tx_conti_mode;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
rmt_clock_source_t clk_src = RMT_CLK_SRC_AHB;
|
||||
switch (dev->sys_conf.sclk_sel) {
|
||||
case 1:
|
||||
clk_src = RMT_CLK_SRC_AHB;
|
||||
break;
|
||||
case 3:
|
||||
clk_src = RMT_CLK_SRC_XTAL;
|
||||
break;
|
||||
}
|
||||
return clk_src;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].idle_out_en;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].idle_out_lv;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_conf[channel].conf1.mem_owner;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_lim[channel].rx_lim;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
|
||||
{
|
||||
return dev->int_st.val & 0x03;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
|
||||
{
|
||||
return (dev->int_st.val >> 2) & 0x03;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
|
||||
{
|
||||
return (dev->int_st.val >> 4) & 0x03;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
|
||||
{
|
||||
return (dev->int_st.val >> 6) & 0x03;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
|
||||
{
|
||||
return (dev->int_st.val >> 8) & 0x03;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
|
||||
{
|
||||
return (dev->int_st.val >> 10) & 0x03;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
|
||||
{
|
||||
return (dev->int_st.val >> 12) & 0x03;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
|
||||
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
|
||||
|
||||
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void)
|
||||
{
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_status(void)
|
||||
{
|
||||
REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
REG_CLR_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(uint32_t addr)
|
||||
{
|
||||
// ESP32H4-TODO: IDF-3383
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void)
|
||||
{
|
||||
// ESP32H4-TODO: IDF-3383
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
|
||||
{
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
||||
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
|
||||
return t;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
|
||||
{
|
||||
uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
|
||||
return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
|
||||
{
|
||||
return REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,307 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#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/rtc_cntl_struct.h"
|
||||
#include "hal/efuse_ll.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_assert.h"
|
||||
|
||||
//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");
|
||||
|
||||
typedef rtc_cntl_dev_t rwdt_dev_t;
|
||||
|
||||
#define RWDT_DEV_GET() &RTCCNTL
|
||||
|
||||
/**
|
||||
* @brief Enable the RWDT
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void rwdt_ll_enable(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
hw->wdt_config0.en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_disable(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
hw->wdt_config0.en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_check_if_enabled(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
return (hw->wdt_config0.en) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_config_stage(rtc_cntl_dev_t *hw, wdt_stage_t stage, uint32_t timeout_ticks, wdt_stage_action_t behavior)
|
||||
{
|
||||
switch (stage) {
|
||||
case WDT_STAGE0:
|
||||
hw->wdt_config0.stg0 = behavior;
|
||||
//Account of implicty multiplier applied to stage 0 timeout tick config value
|
||||
hw->wdt_config1 = timeout_ticks >> (1 + efuse_ll_get_wdt_delay_sel());
|
||||
break;
|
||||
case WDT_STAGE1:
|
||||
hw->wdt_config0.stg1 = behavior;
|
||||
hw->wdt_config2 = timeout_ticks;
|
||||
break;
|
||||
case WDT_STAGE2:
|
||||
hw->wdt_config0.stg2 = behavior;
|
||||
hw->wdt_config3 = timeout_ticks;
|
||||
break;
|
||||
case WDT_STAGE3:
|
||||
hw->wdt_config0.stg3 = behavior;
|
||||
hw->wdt_config4 = timeout_ticks;
|
||||
break;
|
||||
default:
|
||||
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 rwdt_ll_disable_stage(rtc_cntl_dev_t *hw, wdt_stage_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:
|
||||
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 rwdt_ll_set_cpu_reset_length(rtc_cntl_dev_t *hw, wdt_reset_sig_length_t length)
|
||||
{
|
||||
hw->wdt_config0.cpu_reset_length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_sys_reset_length(rtc_cntl_dev_t *hw, wdt_reset_sig_length_t length)
|
||||
{
|
||||
hw->wdt_config0.sys_reset_length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_flashboot_en(rtc_cntl_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_procpu_reset_en(rtc_cntl_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->wdt_config0.procpu_reset_en = (enable) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_appcpu_reset_en(rtc_cntl_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->wdt_config0.appcpu_reset_en = (enable) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_pause_in_sleep_en(rtc_cntl_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->wdt_config0.pause_in_slp = (enable) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_chip_reset_en(rtc_cntl_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->wdt_config0.chip_reset_en = (enable) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_chip_reset_width(rtc_cntl_dev_t *hw, uint32_t width)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdt_config0, chip_reset_width, width);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Feed the RWDT
|
||||
*
|
||||
* Resets the current timer count and current stage.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void rwdt_ll_feed(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
hw->wdt_feed.feed = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable write protection of the RWDT registers
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void rwdt_ll_write_protect_enable(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
hw->wdt_wprotect = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable write protection of the RWDT registers
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void rwdt_ll_write_protect_disable(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
hw->wdt_wprotect = RTC_CNTL_WDT_WKEY_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_set_intr_enable(rtc_cntl_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->int_ena.rtc_wdt = (enable) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rwdt_ll_check_intr_status(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
return (hw->int_st.rtc_wdt) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the RWDT interrupt status.
|
||||
*
|
||||
* @param hw Start address of the peripheral registers.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void rwdt_ll_clear_intr_status(rtc_cntl_dev_t *hw)
|
||||
{
|
||||
hw->int_clr.rtc_wdt = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* - Temp Sensor
|
||||
*
|
||||
* 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 "soc/soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PWDET_CONF_REG 0x600A8010
|
||||
#define PWDET_SAR_POWER_FORCE BIT(24)
|
||||
#define PWDET_SAR_POWER_CNTL 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)
|
||||
{
|
||||
if (mode == SAR_CTRL_LL_POWER_FSM) {
|
||||
REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
|
||||
} else if (mode == SAR_CTRL_LL_POWER_ON) {
|
||||
REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
|
||||
REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
|
||||
} else if (mode == SAR_CTRL_LL_POWER_OFF) {
|
||||
REG_SET_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_FORCE);
|
||||
REG_CLR_BIT(PWDET_CONF_REG, PWDET_SAR_POWER_CNTL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/gpio_sd_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta enable
|
||||
*
|
||||
* @param hw Peripheral SIGMADELTA hardware instance address.
|
||||
* @param en Sigma-delta enable value
|
||||
*/
|
||||
static inline void sdm_ll_enable_clock(gpio_sd_dev_t *hw, bool en)
|
||||
{
|
||||
hw->misc.function_clk_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta channel duty.
|
||||
*
|
||||
* @param hw Peripheral SIGMADELTA hardware instance address.
|
||||
* @param channel Sigma-delta channel number
|
||||
* @param density Sigma-delta quantized density of one channel, the value ranges from -128 to 127, recommended range is -90 ~ 90.
|
||||
* The waveform is more like a random one in this range.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void sdm_ll_set_pulse_density(gpio_sd_dev_t *hw, int channel, int8_t density)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[channel], duty, (uint32_t)density);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta channel's clock pre-scale value.
|
||||
*
|
||||
* @param hw Peripheral SIGMADELTA hardware instance address.
|
||||
* @param channel Sigma-delta channel number
|
||||
* @param prescale The divider of source clock, ranges from 1 to 256
|
||||
*/
|
||||
static inline void sdm_ll_set_prescale(gpio_sd_dev_t *hw, int channel, uint32_t prescale)
|
||||
{
|
||||
HAL_ASSERT(prescale && prescale <= 256);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[channel], prescale, prescale - 1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "hal/sha_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start a new SHA block conversions (no initial hash in HW)
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_start_block(esp_sha_type sha_type)
|
||||
{
|
||||
REG_WRITE(SHA_MODE_REG, sha_type);
|
||||
REG_WRITE(SHA_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Continue a SHA block conversion (initial hash in HW)
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_continue_block(esp_sha_type sha_type)
|
||||
{
|
||||
REG_WRITE(SHA_MODE_REG, sha_type);
|
||||
REG_WRITE(SHA_CONTINUE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a new SHA message conversion using DMA (no initial hash in HW)
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_start_dma(esp_sha_type sha_type)
|
||||
{
|
||||
REG_WRITE(SHA_MODE_REG, sha_type);
|
||||
REG_WRITE(SHA_DMA_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Continue a SHA message conversion using DMA (initial hash in HW)
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_continue_dma(esp_sha_type sha_type)
|
||||
{
|
||||
REG_WRITE(SHA_MODE_REG, sha_type);
|
||||
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load the current hash digest to digest register
|
||||
*
|
||||
* @note Happens automatically on ESP32S3
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_load(esp_sha_type sha_type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of message blocks to be hashed
|
||||
*
|
||||
* @note DMA operation only
|
||||
*
|
||||
* @param num_blocks Number of message blocks to process
|
||||
*/
|
||||
static inline void sha_ll_set_block_num(size_t num_blocks)
|
||||
{
|
||||
REG_WRITE(SHA_BLOCK_NUM_REG, num_blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the SHA engine is currently busy hashing a block
|
||||
*
|
||||
* @return true SHA engine busy
|
||||
* @return false SHA engine idle
|
||||
*/
|
||||
static inline bool sha_ll_busy(void)
|
||||
{
|
||||
return REG_READ(SHA_BUSY_REG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a text (message) block to the SHA engine
|
||||
*
|
||||
* @param input_text Input buffer to be written to the SHA engine
|
||||
* @param block_word_len Number of words in block
|
||||
*/
|
||||
static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len)
|
||||
{
|
||||
uint32_t *data_words = (uint32_t *)input_text;
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||
|
||||
for (int i = 0; i < block_word_len; i++) {
|
||||
REG_WRITE(®_addr_buf[i], data_words[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the message digest from the SHA engine
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @param digest_state Buffer that message digest will be written to
|
||||
* @param digest_word_len Length of the message digest
|
||||
*/
|
||||
static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
|
||||
{
|
||||
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
|
||||
for (size_t i = 0; i < digest_word_len; i++) {
|
||||
digest_state_words[i] = REG_READ(SHA_H_BASE + (i * REG_WIDTH));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the message digest to the SHA engine
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @param digest_state Message digest to be written to SHA engine
|
||||
* @param digest_word_len Length of the message digest
|
||||
*/
|
||||
static inline void sha_ll_write_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
|
||||
{
|
||||
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
|
||||
|
||||
for (int i = 0; i < digest_word_len; i++) {
|
||||
REG_WRITE(®_addr_buf[i], digest_state_words[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 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 "hal/assert.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/soc.h"
|
||||
#include "string.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// 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(SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
|
||||
SYSTEM_ENABLE_DOWNLOAD_MANUAL_ENCRYPT |
|
||||
SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the flash encryption mode.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_disable(void)
|
||||
{
|
||||
REG_CLR_BIT(SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
|
||||
SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_WRITE(AES_XTS_DESTINATION_REG, 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_WRITE(AES_XTS_SIZE_REG, 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 *)(AES_XTS_PLAIN_BASE + 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_WRITE(AES_XTS_PHYSICAL_ADDR_REG, flash_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start flash encryption
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_calculate_start(void)
|
||||
{
|
||||
REG_WRITE(AES_XTS_TRIGGER_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for flash encryption termination
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_calculate_wait_idle(void)
|
||||
{
|
||||
while(REG_READ(AES_XTS_STATE_REG) == 0x1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the flash encryption and make encrypted result accessible to SPI.
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_done(void)
|
||||
{
|
||||
REG_WRITE(AES_XTS_RELEASE_REG, 1);
|
||||
while(REG_READ(AES_XTS_STATE_REG) != 0x3) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to destroy encrypted result
|
||||
*/
|
||||
static inline void spi_flash_encrypt_ll_destroy(void)
|
||||
{
|
||||
REG_WRITE(AES_XTS_DESTROY_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 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; \
|
||||
})
|
||||
|
||||
|
||||
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_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
||||
#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)
|
||||
#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_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
||||
#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)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,588 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 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
|
||||
|
||||
#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)
|
||||
|
||||
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 esp32h4 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->flash_sus_cmd, 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->fsm.spi0_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 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 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 spimem_flash_ll_set_dummy_out(spi_mem_dev_t *dev, uint32_t out_en, uint32_t out_lev)
|
||||
{
|
||||
dev->ctrl.fdummy_out = out_en;
|
||||
dev->ctrl.q_pol = out_lev;
|
||||
dev->ctrl.d_pol = out_lev;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
dev->ctrl2.cs_hold_time = hold_n - 1;
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// TODO: Default is PLL480M, this is hard-coded.
|
||||
// In the future, we can get the CPU clock source by calling interface.
|
||||
uint8_t clock_val = 0;
|
||||
switch (SPIMEM0.core_clk_sel.spi01_clk_sel) {
|
||||
case 0:
|
||||
clock_val = 48;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return clock_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 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.
|
||||
|
||||
/******************* Clock *************************/
|
||||
|
||||
__attribute__((always_inline)) static inline void systimer_ll_enable_clock(systimer_dev_t *dev, bool en)
|
||||
{
|
||||
dev->conf.clk_en = en;
|
||||
}
|
||||
|
||||
static inline void systimer_ll_set_clock_source(soc_periph_systimer_clk_src_t clk_src)
|
||||
{
|
||||
(void)clk_src;
|
||||
}
|
||||
|
||||
static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void)
|
||||
{
|
||||
return SYSTIMER_CLK_SRC_XTAL;
|
||||
}
|
||||
|
||||
/******************* 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
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 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 component/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The LL for temperature sensor
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_saradc.h"
|
||||
#include "soc/apb_saradc_struct.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/temperature_sensor_types.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TEMPERATURE_SENSOR_LL_ADC_FACTOR (0.4386)
|
||||
#define TEMPERATURE_SENSOR_LL_DAC_FACTOR (27.88)
|
||||
#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR (20.52)
|
||||
|
||||
/**
|
||||
* @brief Enable the temperature sensor power.
|
||||
*
|
||||
* @param enable true: enable the power.
|
||||
*/
|
||||
static inline void temperature_sensor_ll_enable(bool enable)
|
||||
{
|
||||
APB_SARADC.apb_tsens_ctrl.tsens_pu = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the clock
|
||||
*/
|
||||
static inline void temperature_sensor_ll_clk_enable(bool enable)
|
||||
{
|
||||
// No need to enable the temperature clock on esp32h4
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the clock source for temperature sensor. On ESP32-H4, temperature sensor
|
||||
* can use XTAL or FOSC. To make it convenience, suggest using XTAL all the time.
|
||||
*
|
||||
* @param clk_src refer to ``temperature_sensor_clk_src_t``
|
||||
*/
|
||||
static inline void temperature_sensor_ll_clk_sel(temperature_sensor_clk_src_t clk_src)
|
||||
{
|
||||
uint8_t clk_sel = 0;
|
||||
switch (clk_src) {
|
||||
case TEMPERATURE_SENSOR_CLK_SRC_XTAL:
|
||||
clk_sel = 1;
|
||||
break;
|
||||
case TEMPERATURE_SENSOR_CLK_SRC_RC_FAST:
|
||||
clk_sel = 0;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = clk_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the hardware range, you can refer to the table ``temperature_sensor_attributes``
|
||||
*
|
||||
* @param tsens_dac ``reg_val`` in table ``temperature_sensor_attributes``
|
||||
*/
|
||||
static inline void temperature_sensor_ll_set_range(uint32_t range)
|
||||
{
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, range);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the raw value of temperature sensor.
|
||||
*
|
||||
* @return uint32_t raw_value
|
||||
*/
|
||||
static inline uint32_t temperature_sensor_ll_get_raw_value(void)
|
||||
{
|
||||
return APB_SARADC.apb_tsens_ctrl.tsens_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the offset value of temperature sensor.
|
||||
*
|
||||
* @note This function is only used in legacy driver
|
||||
*
|
||||
* @return uint32_t offset value
|
||||
*/
|
||||
static inline uint32_t temperature_sensor_ll_get_offset(void)
|
||||
{
|
||||
return REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the clock division factor value.
|
||||
*
|
||||
* @note This function is only used in legacy driver
|
||||
*
|
||||
* @return uint32_t clock division factor
|
||||
*/
|
||||
static inline uint32_t temperature_sensor_ll_get_clk_div(void)
|
||||
{
|
||||
return APB_SARADC.apb_tsens_ctrl.tsens_clk_div;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock division factor value, actually this has no impact on temperature sensor.
|
||||
* Suggest just keep it as default value 6.
|
||||
*
|
||||
* @note This function is only used in legacy driver
|
||||
*
|
||||
* @param clk_div clock division factor, range from 1-10
|
||||
*/
|
||||
static inline void temperature_sensor_ll_set_clk_div(uint8_t clk_div)
|
||||
{
|
||||
APB_SARADC.apb_tsens_ctrl.tsens_clk_div = clk_div;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,281 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/assert.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/timer_types.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Get timer group register base address with giving group number
|
||||
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
|
||||
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
|
||||
|
||||
/**
|
||||
* @brief Set clock source for timer
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param clk_src Clock source
|
||||
*/
|
||||
static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
|
||||
{
|
||||
switch (clk_src) {
|
||||
case GPTIMER_CLK_SRC_AHB:
|
||||
hw->hw_timer[timer_num].config.tx_use_xtal = 0;
|
||||
break;
|
||||
case GPTIMER_CLK_SRC_XTAL:
|
||||
hw->hw_timer[timer_num].config.tx_use_xtal = 1;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "unsupported clock source");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)timer_num; // only one timer in the group
|
||||
hw->regclk.timer_clk_is_active = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable alarm event
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param en True: enable alarm
|
||||
* False: disable alarm
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
hw->hw_timer[timer_num].config.tx_alarm_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set clock prescale for timer
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param divider Prescale value (0 and 1 are not valid)
|
||||
*/
|
||||
static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider)
|
||||
{
|
||||
HAL_ASSERT(divider >= 2 && divider <= 65536);
|
||||
if (divider >= 65536) {
|
||||
divider = 0;
|
||||
}
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider);
|
||||
hw->hw_timer[timer_num].config.tx_divcnt_rst = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable auto-reload mode
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param en True: enable auto reload mode
|
||||
* False: disable auto reload mode
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
hw->hw_timer[timer_num].config.tx_autoreload = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set count direction
|
||||
*
|
||||
* @param hw Timer peripheral register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param direction Count direction
|
||||
*/
|
||||
static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
|
||||
{
|
||||
hw->hw_timer[timer_num].config.tx_increase = direction == GPTIMER_COUNT_UP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable timer, start couting
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param en True: enable the counter
|
||||
* False: disable the counter
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
hw->hw_timer[timer_num].config.tx_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger software capture event
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num)
|
||||
{
|
||||
hw->hw_timer[timer_num].update.tx_update = 1;
|
||||
// Timer register is in a different clock domain from Timer hardware logic
|
||||
// We need to wait for the update to take effect before fetching the count value
|
||||
while (hw->hw_timer[timer_num].update.tx_update) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get counter value
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
*
|
||||
* @return counter value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
||||
{
|
||||
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set alarm value
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param alarm_value When counter reaches alarm value, alarm event will be triggered
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
|
||||
{
|
||||
hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t) (alarm_value >> 32);
|
||||
hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t) alarm_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set reload value
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @param reload_val Reload counter value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t load_val)
|
||||
{
|
||||
hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32);
|
||||
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get reload value
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
* @return reload count value
|
||||
*/
|
||||
static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
|
||||
{
|
||||
return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer number in the group
|
||||
*/
|
||||
static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
|
||||
{
|
||||
hw->hw_timer[timer_num].load.tx_load = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable timer interrupt by mask
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param mask Mask of interrupt events
|
||||
* @param en True: enable interrupt
|
||||
* False: disable interrupt
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
|
||||
{
|
||||
if (en) {
|
||||
hw->int_ena_timers.val |= mask;
|
||||
} else {
|
||||
hw->int_ena_timers.val &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
*
|
||||
* @return Interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
|
||||
{
|
||||
return hw->int_st_timers.val & 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt status by mask
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param mask Interrupt events mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr_timers.val = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the register clock forever
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param en True: Enable the register clock forever
|
||||
* False: Register clock is enabled only when register operation happens
|
||||
*/
|
||||
static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
|
||||
{
|
||||
hw->regclk.clk_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status register address
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
*
|
||||
* @return Interrupt status register address
|
||||
*/
|
||||
static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
|
||||
{
|
||||
return &hw->int_st_timers.val;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer for UHCI register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include "hal/uhci_types.h"
|
||||
#include "soc/uhci_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UHCI_LL_GET_HW(num) (((num) == 0) ? (&UHCI0) : (NULL))
|
||||
|
||||
typedef enum {
|
||||
UHCI_RX_BREAK_CHR_EOF = 0x1,
|
||||
UHCI_RX_IDLE_EOF = 0x2,
|
||||
UHCI_RX_LEN_EOF = 0x4,
|
||||
UHCI_RX_EOF_MAX = 0x7,
|
||||
} uhci_rxeof_cfg_t;
|
||||
|
||||
static inline void uhci_ll_init(uhci_dev_t *hw)
|
||||
{
|
||||
typeof(hw->conf0) conf0_reg;
|
||||
hw->conf0.clk_en = 1;
|
||||
conf0_reg.val = 0;
|
||||
conf0_reg.clk_en = 1;
|
||||
hw->conf0.val = conf0_reg.val;
|
||||
hw->conf1.val = 0;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_attach_uart_port(uhci_dev_t *hw, int uart_num)
|
||||
{
|
||||
hw->conf0.uart0_ce = (uart_num == 0)? 1: 0;
|
||||
hw->conf0.uart1_ce = (uart_num == 1)? 1: 0;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_set_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_char)
|
||||
{
|
||||
if (seper_char->sub_chr_en) {
|
||||
typeof(hw->esc_conf0) esc_conf0_reg = hw->esc_conf0;
|
||||
esc_conf0_reg.seper_char = seper_char->seper_chr;
|
||||
esc_conf0_reg.seper_esc_char0 = seper_char->sub_chr1;
|
||||
esc_conf0_reg.seper_esc_char1 = seper_char->sub_chr2;
|
||||
hw->esc_conf0.val = esc_conf0_reg.val;
|
||||
hw->escape_conf.tx_c0_esc_en = 1;
|
||||
hw->escape_conf.rx_c0_esc_en = 1;
|
||||
} else {
|
||||
hw->escape_conf.tx_c0_esc_en = 0;
|
||||
hw->escape_conf.rx_c0_esc_en = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void uhci_ll_get_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_chr)
|
||||
{
|
||||
(void)hw;
|
||||
(void)seper_chr;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_set_swflow_ctrl_sub_chr(uhci_dev_t *hw, uhci_swflow_ctrl_sub_chr_t *sub_ctr)
|
||||
{
|
||||
typeof(hw->escape_conf) escape_conf_reg = hw->escape_conf;
|
||||
if (sub_ctr->flow_en == 1) {
|
||||
typeof(hw->esc_conf2) esc_conf2_reg = hw->esc_conf2;
|
||||
typeof(hw->esc_conf3) esc_conf3_reg = hw->esc_conf3;
|
||||
esc_conf2_reg.seq1 = sub_ctr->xon_chr;
|
||||
esc_conf2_reg.seq1_char0 = sub_ctr->xon_sub1;
|
||||
esc_conf2_reg.seq1_char1 = sub_ctr->xon_sub2;
|
||||
esc_conf3_reg.seq2 = sub_ctr->xoff_chr;
|
||||
esc_conf3_reg.seq2_char0 = sub_ctr->xoff_sub1;
|
||||
esc_conf3_reg.seq2_char1 = sub_ctr->xoff_sub2;
|
||||
escape_conf_reg.tx_11_esc_en = 1;
|
||||
escape_conf_reg.tx_13_esc_en = 1;
|
||||
escape_conf_reg.rx_11_esc_en = 1;
|
||||
escape_conf_reg.rx_13_esc_en = 1;
|
||||
hw->esc_conf2.val = esc_conf2_reg.val;
|
||||
hw->esc_conf3.val = esc_conf3_reg.val;
|
||||
} else {
|
||||
escape_conf_reg.tx_11_esc_en = 0;
|
||||
escape_conf_reg.tx_13_esc_en = 0;
|
||||
escape_conf_reg.rx_11_esc_en = 0;
|
||||
escape_conf_reg.rx_13_esc_en = 0;
|
||||
}
|
||||
hw->escape_conf.val = escape_conf_reg.val;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_enable_intr(uhci_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
hw->int_ena.val |= intr_mask;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_disable_intr(uhci_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
hw->int_ena.val &= (~intr_mask);
|
||||
}
|
||||
|
||||
static inline void uhci_ll_clear_intr(uhci_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
hw->int_clr.val = intr_mask;
|
||||
}
|
||||
|
||||
static inline uint32_t uhci_ll_get_intr(uhci_dev_t *hw)
|
||||
{
|
||||
return hw->int_st.val;
|
||||
}
|
||||
|
||||
|
||||
static inline void uhci_ll_set_eof_mode(uhci_dev_t *hw, uint32_t eof_mode)
|
||||
{
|
||||
if (eof_mode & UHCI_RX_BREAK_CHR_EOF) {
|
||||
hw->conf0.uart_rx_brk_eof_en = 1;
|
||||
}
|
||||
if (eof_mode & UHCI_RX_IDLE_EOF) {
|
||||
hw->conf0.uart_idle_eof_en = 1;
|
||||
}
|
||||
if (eof_mode & UHCI_RX_LEN_EOF) {
|
||||
hw->conf0.len_eof_en = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Though the UHCI driver hasn't been published, some types are defined here
|
||||
// for users to develop over the HAL. See example: controller_hci_uart_esp32h4
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @brief UHCI escape sequence
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t seper_chr; /*!< escape sequence character */
|
||||
uint8_t sub_chr1; /*!< escape sequence sub-character 1 */
|
||||
uint8_t sub_chr2; /*!< escape sequence sub-character 2 */
|
||||
bool sub_chr_en; /*!< enable use of sub-chaacter of escape sequence */
|
||||
} uhci_seper_chr_t;
|
||||
|
||||
/**
|
||||
* @brief UHCI software flow control
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t xon_chr; /*!< character for XON */
|
||||
uint8_t xon_sub1; /*!< sub-character 1 for XON */
|
||||
uint8_t xon_sub2; /*!< sub-character 2 for XON */
|
||||
uint8_t xoff_chr; /*!< character 2 for XOFF */
|
||||
uint8_t xoff_sub1; /*!< sub-character 1 for XOFF */
|
||||
uint8_t xoff_sub2; /*!< sub-character 2 for XOFF */
|
||||
uint8_t flow_en; /*!< enable use of software flow control */
|
||||
} uhci_swflow_ctrl_sub_chr_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/usb_serial_jtag_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Configures the internal PHY for USB_Serial_JTAG
|
||||
*
|
||||
* @param hw Start address of the USB Serial_JTAG registers
|
||||
*/
|
||||
static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
|
||||
{
|
||||
// USB_Serial_JTAG use internal PHY
|
||||
hw->conf0.phy_sel = 0;
|
||||
// Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1)
|
||||
hw->conf0.pad_pull_override = 0;
|
||||
// Enable USB D+ pullup
|
||||
hw->conf0.dp_pullup = 1;
|
||||
// Enable USB pad function
|
||||
hw->conf0.usb_pad_enable = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The LL layer of the USB-serial-jtag controller
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/misc.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "soc/usb_serial_jtag_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//The in and out endpoints are this long.
|
||||
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
|
||||
|
||||
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
|
||||
|
||||
// Define USB_SERIAL_JTAG interrupts
|
||||
// Note the hardware has more interrupts, but they're only useful for debugging
|
||||
// the hardware.
|
||||
typedef enum {
|
||||
USB_SERIAL_JTAG_INTR_SOF = (1 << 1),
|
||||
USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT = (1 << 2),
|
||||
USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY = (1 << 3),
|
||||
USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1 = (1 << 8),
|
||||
USB_SERIAL_JTAG_INTR_BUS_RESET = (1 << 9),
|
||||
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
|
||||
} usb_serial_jtag_intr_t;
|
||||
|
||||
/**
|
||||
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
|
||||
*
|
||||
* @param mask The bitmap of the interrupts need to be enabled.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void usb_serial_jtag_ll_ena_intr_mask(uint32_t mask)
|
||||
{
|
||||
USB_SERIAL_JTAG.int_ena.val |= mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the USB_SERIAL_JTAG interrupt based on the given mask.
|
||||
*
|
||||
* @param mask The bitmap of the interrupts need to be disabled.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void usb_serial_jtag_ll_disable_intr_mask(uint32_t mask)
|
||||
{
|
||||
USB_SERIAL_JTAG.int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the USB_SERIAL_JTAG interrupt status.
|
||||
*
|
||||
* @return The USB_SERIAL_JTAG interrupt status.
|
||||
*/
|
||||
static inline uint32_t usb_serial_jtag_ll_get_intsts_mask(void)
|
||||
{
|
||||
return USB_SERIAL_JTAG.int_st.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the USB_SERIAL_JTAG raw interrupt status.
|
||||
*
|
||||
* @return The USB_SERIAL_JTAG raw interrupt status.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t usb_serial_jtag_ll_get_intraw_mask(void)
|
||||
{
|
||||
return USB_SERIAL_JTAG.int_raw.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the USB_SERIAL_JTAG interrupt status based on the given mask.
|
||||
*
|
||||
* @param mask The bitmap of the interrupts need to be cleared.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void usb_serial_jtag_ll_clr_intsts_mask(uint32_t mask)
|
||||
{
|
||||
USB_SERIAL_JTAG.int_clr.val = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get status of enabled interrupt.
|
||||
*
|
||||
* @return interrupt enable value
|
||||
*/
|
||||
static inline uint32_t usb_serial_jtag_ll_get_intr_ena_status(void)
|
||||
{
|
||||
return USB_SERIAL_JTAG.int_ena.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the bytes from the USB_SERIAL_JTAG rxfifo.
|
||||
*
|
||||
* @param buf The data buffer.
|
||||
* @param rd_len The data length needs to be read.
|
||||
*
|
||||
* @return amount of bytes read
|
||||
*/
|
||||
static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)rd_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break;
|
||||
buf[i] = HAL_FORCE_READ_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write byte to the USB_SERIAL_JTAG txfifo. Only writes bytes as long / if there
|
||||
* is room in the buffer.
|
||||
*
|
||||
* @param buf The data buffer.
|
||||
* @param wr_len The data length needs to be writen.
|
||||
*
|
||||
* @return Amount of bytes actually written. May be less than wr_len.
|
||||
*/
|
||||
static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t wr_len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)wr_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte, buf[i]);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns 1 if the USB_SERIAL_JTAG rxfifo has data available.
|
||||
*
|
||||
* @return 0 if no data available, 1 if data available
|
||||
*/
|
||||
static inline int usb_serial_jtag_ll_rxfifo_data_available(void)
|
||||
{
|
||||
return USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns 1 if the USB_SERIAL_JTAG txfifo has room.
|
||||
*
|
||||
* @return 0 if no data available, 1 if data available
|
||||
*/
|
||||
static inline int usb_serial_jtag_ll_txfifo_writable(void)
|
||||
{
|
||||
return USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flushes the TX buffer, that is, make it available for the
|
||||
* host to pick up.
|
||||
*
|
||||
* @return na
|
||||
*/
|
||||
static inline void usb_serial_jtag_ll_txfifo_flush(void)
|
||||
{
|
||||
USB_SERIAL_JTAG.ep1_conf.wr_done=1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,697 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 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-H4 GPIO register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "hal/gpio_types.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#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(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-up on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value
|
||||
// USB DP pin is default to PU enabled
|
||||
if (gpio_num == USB_DP_GPIO_NUM) {
|
||||
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
|
||||
}
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], 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(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-down on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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].pin_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->pcpu_int.procpu_int;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 = hw->pcpu_int1.procpu_int1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.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)
|
||||
{
|
||||
hw->status1_w1tc.status1_w1tc = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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].pin_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].pin_int_ena = 0; //disable GPIO intr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable input mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
PIN_FILTER_EN(GPIO_PIN_MUX_REG[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)
|
||||
{
|
||||
PIN_FILTER_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
if (gpio_num < 32) {
|
||||
hw->enable_w1tc.enable_w1tc = (0x1 << gpio_num);
|
||||
} else {
|
||||
hw->enable1_w1tc.enable1_w1tc = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
// Ensure no other output signal is routed via GPIO matrix to this pin
|
||||
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4),
|
||||
SIG_GPIO_OUT_IDX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void gpio_ll_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
if (gpio_num < 32) {
|
||||
hw->enable_w1ts.enable_w1ts = (0x1 << gpio_num);
|
||||
} else {
|
||||
hw->enable1_w1ts.enable1_w1ts = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable open-drain mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void gpio_ll_od_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->pin[gpio_num].pin_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].pin_pad_driver = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
static inline __attribute__((always_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 == USB_DM_GPIO_NUM || gpio_num == USB_DP_GPIO_NUM) {
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
|
||||
}
|
||||
PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
if (gpio_num < 32) {
|
||||
hw->out_w1ts.out_w1ts = (1 << gpio_num);
|
||||
} else {
|
||||
hw->out1_w1ts.out1_w1ts = (1 << (gpio_num - 32));
|
||||
}
|
||||
} else {
|
||||
if (gpio_num < 32) {
|
||||
hw->out_w1tc.out_w1tc = (1 << gpio_num);
|
||||
} else {
|
||||
hw->out1_w1tc.out1_w1tc = (1 << (gpio_num - 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
if (gpio_num < 32) {
|
||||
return (hw->in.in_data_next >> gpio_num) & 0x1;
|
||||
} else {
|
||||
return (hw->in1.in1_data_next >> (gpio_num - 32)) & 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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].pin_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].pin_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(GPIO_PIN_MUX_REG[gpio_num], 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(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all digital gpio pad 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)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all digital gpio pad 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 Get deep sleep hold status
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*
|
||||
* @return
|
||||
* - true deep sleep hold is enabled
|
||||
* - false deep sleep hold is disabled
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
|
||||
{
|
||||
return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
if (gpio_num <= GPIO_NUM_5) {
|
||||
REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num));
|
||||
} else if (gpio_num <= GPIO_NUM_31) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD1_REG, GPIO_HOLD_MASK[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)
|
||||
{
|
||||
if (gpio_num <= GPIO_NUM_5) {
|
||||
REG_CLR_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num));
|
||||
} else if (gpio_num <= GPIO_NUM_31) {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD1_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get digital gpio pad hold status.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
*
|
||||
* @note caller must ensure that gpio_num is a digital io pad
|
||||
*
|
||||
* @return
|
||||
* - true digital gpio pad is held
|
||||
* - false digital gpio pad is unheld
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(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)
|
||||
{
|
||||
// Disable USB Serial JTAG if pins 18 or pins 19 needs to select an IOMUX function
|
||||
if (pin_name == IO_MUX_GPIO18_REG || pin_name == IO_MUX_GPIO19_REG) {
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
|
||||
}
|
||||
PIN_FUNC_SELECT(pin_name, 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].func_oen_sel = 0;
|
||||
hw->func_out_sel_cfg[gpio_num].func_oen_inv_sel = oen_inv;
|
||||
gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
|
||||
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_hold_all(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force unhold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
|
||||
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_unhold_all(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin used for wakeup from 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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT(gpio_num <= GPIO_NUM_5 && "gpio larger than 5 does not support deep sleep wake-up function");
|
||||
|
||||
REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN_CLK_GATE);
|
||||
REG_SET_BIT(RTC_CNTL_EXT_WAKEUP_CONF_REG, RTC_CNTL_GPIO_WAKEUP_FILTER);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - gpio_num));
|
||||
uint32_t reg = REG_READ(RTC_CNTL_GPIO_WAKEUP_REG);
|
||||
reg &= (~(RTC_CNTL_GPIO_PIN0_INT_TYPE_V << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3)));
|
||||
reg |= (intr_type << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3));
|
||||
REG_WRITE(RTC_CNTL_GPIO_WAKEUP_REG, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT(gpio_num <= GPIO_NUM_5 && "gpio larger than 5 does not support deep sleep wake-up function");
|
||||
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - gpio_num));
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN0_INT_TYPE_S - gpio_num * 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT(gpio_num <= GPIO_NUM_5 && "gpio larger than 5 does not support deep sleep wake-up function");
|
||||
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - gpio_num));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,627 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 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-H4 GPIO register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "hal/gpio_types.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#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(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-up on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value
|
||||
// USB DP pin is default to PU enabled
|
||||
if (gpio_num == USB_DP_GPIO_NUM) {
|
||||
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
|
||||
}
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], 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(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-down on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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].pin_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->pcpu_int.procpu_int;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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; // Less than 32 GPIOs in ESP32-H4Beta2
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.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)
|
||||
{
|
||||
// Less than 32 GPIOs in ESP32-H4Beta2. Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* @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].pin_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].pin_int_ena = 0; //disable GPIO intr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable input mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
PIN_FILTER_EN(GPIO_PIN_MUX_REG[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)
|
||||
{
|
||||
PIN_FILTER_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->enable_w1tc.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),
|
||||
SIG_GPIO_OUT_IDX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void gpio_ll_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->enable_w1ts.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 __attribute__((always_inline)) void gpio_ll_od_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->pin[gpio_num].pin_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].pin_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.out_w1ts = (1 << gpio_num);
|
||||
} else {
|
||||
hw->out_w1tc.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.in_data_next >> gpio_num) & 0x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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].pin_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].pin_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(GPIO_PIN_MUX_REG[gpio_num], 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(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all digital gpio pad 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)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all digital gpio pad 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)
|
||||
{
|
||||
if (gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_12) {
|
||||
REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[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)
|
||||
{
|
||||
if (gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_12) {
|
||||
REG_CLR_BIT(RTC_CNTL_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[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 __attribute__((always_inline)) void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func)
|
||||
{
|
||||
// Disable USB Serial JTAG if pin 24 or pin 25 needs to select an IOMUX function
|
||||
if (pin_name == IO_MUX_GPIO24_REG || pin_name == IO_MUX_GPIO25_REG) {
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
|
||||
}
|
||||
PIN_FUNC_SELECT(pin_name, 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].func_oen_sel = 0;
|
||||
hw->func_out_sel_cfg[gpio_num].func_oen_inv_sel = oen_inv;
|
||||
gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
|
||||
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_hold_all(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force unhold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
|
||||
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_unhold_all(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin used for wakeup from 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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT((gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_12) &&
|
||||
"only gpio7~12 support deep sleep wake-up function");
|
||||
|
||||
REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN_CLK_GATE);
|
||||
REG_SET_BIT(RTC_CNTL_EXT_WAKEUP_CONF_REG, RTC_CNTL_GPIO_WAKEUP_FILTER);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - (gpio_num - 7)));
|
||||
uint32_t reg = REG_READ(RTC_CNTL_GPIO_WAKEUP_REG);
|
||||
reg &= (~(RTC_CNTL_GPIO_PIN0_INT_TYPE_V << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - (gpio_num - 7) * 3)));
|
||||
reg |= (intr_type << (RTC_CNTL_GPIO_PIN0_INT_TYPE_S - (gpio_num - 7) * 3));
|
||||
REG_WRITE(RTC_CNTL_GPIO_WAKEUP_REG, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT((gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_12) &&
|
||||
"only gpio7~12 support deep sleep wake-up function");
|
||||
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - (gpio_num - 7)));
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_PIN0_INT_TYPE_S - (gpio_num - 7) * 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HAL_ASSERT((gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_12) &&
|
||||
"only gpio7~12 support deep sleep wake-up function");
|
||||
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - (gpio_num - 7)));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The HAL layer for RTC CNTL (common part)
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "hal/rtc_hal.h"
|
||||
#include "hal/assert.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#define RTC_CNTL_HAL_LINK_BUF_SIZE_MIN (SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE) /* The minimum size of dma link buffer */
|
||||
|
||||
typedef struct rtc_cntl_link_buf_conf {
|
||||
uint32_t cfg[4]; /* 4 word for dma link buffer configuration */
|
||||
} rtc_cntl_link_buf_conf_t;
|
||||
|
||||
void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next)
|
||||
{
|
||||
HAL_ASSERT(elem != NULL);
|
||||
HAL_ASSERT(buff != NULL);
|
||||
HAL_ASSERT(size >= RTC_CNTL_HAL_LINK_BUF_SIZE_MIN);
|
||||
|
||||
lldesc_t *plink = (lldesc_t *)elem;
|
||||
|
||||
plink->eof = next ? 0 : 1;
|
||||
plink->owner = 1;
|
||||
plink->size = size >> 4; /* in unit of 16 bytes */
|
||||
plink->length = size >> 4;
|
||||
plink->buf = buff;
|
||||
plink->offset = 0;
|
||||
plink->sosf = 0;
|
||||
STAILQ_NEXT(plink, qe) = next;
|
||||
return (void *)plink;
|
||||
}
|
||||
|
||||
#if SOC_PM_SUPPORT_CPU_PD
|
||||
void rtc_cntl_hal_enable_cpu_retention(void *addr)
|
||||
{
|
||||
if (addr) {
|
||||
lldesc_t *plink = (lldesc_t *)addr;
|
||||
|
||||
/* dma link buffer configure */
|
||||
rtc_cntl_link_buf_conf_t *pbuf = (rtc_cntl_link_buf_conf_t *)plink->buf;
|
||||
pbuf->cfg[0] = 0;
|
||||
pbuf->cfg[1] = 0;
|
||||
pbuf->cfg[2] = 0;
|
||||
pbuf->cfg[3] = (uint32_t)-1;
|
||||
|
||||
rtc_cntl_ll_enable_cpu_retention((uint32_t)addr);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR rtc_cntl_hal_disable_cpu_retention(void *addr)
|
||||
{
|
||||
rtc_cntl_sleep_retent_t *retent = (rtc_cntl_sleep_retent_t *)addr;
|
||||
|
||||
if (addr) {
|
||||
if (retent->cpu_pd_mem) {
|
||||
rtc_cntl_ll_disable_cpu_retention();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SOC_PM_SUPPORT_CPU_PD
|
@ -144,7 +144,7 @@ typedef struct {
|
||||
};
|
||||
} adc_digi_output_data_t;
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) output data format.
|
||||
* Used to analyze the acquired ADC (DMA) data.
|
||||
|
@ -70,7 +70,7 @@ typedef enum {
|
||||
* MONITOR_LOW: If ADC_OUT < threshold, Generates monitor interrupt.
|
||||
*/
|
||||
typedef enum {
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
|
||||
ADC_DIGI_MONITOR_DIS = 0, /*!<Disable monitor. */
|
||||
ADC_DIGI_MONITOR_EN, /*!<If ADC_OUT < threshold, Generates monitor interrupt. */
|
||||
/*!<If ADC_OUT > threshold, Generates monitor interrupt. */
|
||||
|
@ -242,85 +242,6 @@ typedef enum {
|
||||
GPIO_NUM_MAX,
|
||||
/** @endcond */
|
||||
} gpio_num_t;
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1
|
||||
typedef enum {
|
||||
GPIO_NUM_NC = -1, /*!< Use to signal not connected to S/W */
|
||||
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
|
||||
GPIO_NUM_1 = 1, /*!< GPIO1, input and output */
|
||||
GPIO_NUM_2 = 2, /*!< GPIO2, input and output */
|
||||
GPIO_NUM_3 = 3, /*!< GPIO3, input and output */
|
||||
GPIO_NUM_4 = 4, /*!< GPIO4, input and output */
|
||||
GPIO_NUM_5 = 5, /*!< GPIO5, input and output */
|
||||
GPIO_NUM_6 = 6, /*!< GPIO6, input and output */
|
||||
GPIO_NUM_7 = 7, /*!< GPIO7, input and output */
|
||||
GPIO_NUM_8 = 8, /*!< GPIO8, input and output */
|
||||
GPIO_NUM_9 = 9, /*!< GPIO9, input and output */
|
||||
GPIO_NUM_10 = 10, /*!< GPIO10, input and output */
|
||||
GPIO_NUM_11 = 11, /*!< GPIO11, input and output */
|
||||
GPIO_NUM_12 = 12, /*!< GPIO12, input and output */
|
||||
GPIO_NUM_13 = 13, /*!< GPIO13, input and output */
|
||||
GPIO_NUM_14 = 14, /*!< GPIO14, input and output */
|
||||
GPIO_NUM_15 = 15, /*!< GPIO15, input and output */
|
||||
GPIO_NUM_16 = 16, /*!< GPIO16, input and output */
|
||||
GPIO_NUM_17 = 17, /*!< GPIO17, input and output */
|
||||
GPIO_NUM_18 = 18, /*!< GPIO18, input and output */
|
||||
GPIO_NUM_19 = 19, /*!< GPIO19, input and output */
|
||||
GPIO_NUM_20 = 20, /*!< GPIO20, input and output */
|
||||
GPIO_NUM_21 = 21, /*!< GPIO21, input and output */
|
||||
GPIO_NUM_22 = 22, /*!< GPIO22, input and output */
|
||||
GPIO_NUM_23 = 23, /*!< GPIO23, input and output */
|
||||
GPIO_NUM_24 = 24, /*!< GPIO24, input and output */
|
||||
GPIO_NUM_25 = 25, /*!< GPIO25, input and output */
|
||||
GPIO_NUM_26 = 26, /*!< GPIO26, input and output */
|
||||
GPIO_NUM_27 = 27, /*!< GPIO27, input and output */
|
||||
GPIO_NUM_28 = 28, /*!< GPIO28, input and output */
|
||||
GPIO_NUM_29 = 29, /*!< GPIO29, input and output */
|
||||
GPIO_NUM_30 = 30, /*!< GPIO30, input and output */
|
||||
GPIO_NUM_31 = 31, /*!< GPIO31, input and output */
|
||||
GPIO_NUM_32 = 32, /*!< GPIO32, input and output */
|
||||
GPIO_NUM_33 = 33, /*!< GPIO33, input and output */
|
||||
GPIO_NUM_34 = 34, /*!< GPIO34, input and output */
|
||||
GPIO_NUM_35 = 35, /*!< GPIO35, input and output */
|
||||
GPIO_NUM_36 = 36, /*!< GPIO36, input and output */
|
||||
GPIO_NUM_37 = 37, /*!< GPIO37, input and output */
|
||||
GPIO_NUM_38 = 38, /*!< GPIO38, input and output */
|
||||
GPIO_NUM_39 = 39, /*!< GPIO39, input and output */
|
||||
GPIO_NUM_40 = 40, /*!< GPIO40, input and output */
|
||||
GPIO_NUM_MAX,
|
||||
/** @endcond */
|
||||
} gpio_num_t;
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2
|
||||
typedef enum {
|
||||
GPIO_NUM_NC = -1, /*!< Use to signal not connected to S/W */
|
||||
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
|
||||
GPIO_NUM_1 = 1, /*!< GPIO1, input and output */
|
||||
GPIO_NUM_2 = 2, /*!< GPIO2, input and output */
|
||||
GPIO_NUM_3 = 3, /*!< GPIO3, input and output */
|
||||
GPIO_NUM_4 = 4, /*!< GPIO4, input and output */
|
||||
GPIO_NUM_5 = 5, /*!< GPIO5, input and output */
|
||||
GPIO_NUM_6 = 6, /*!< GPIO6, input and output */
|
||||
GPIO_NUM_7 = 7, /*!< GPIO7, input and output */
|
||||
GPIO_NUM_8 = 8, /*!< GPIO8, input and output */
|
||||
GPIO_NUM_9 = 9, /*!< GPIO9, input and output */
|
||||
GPIO_NUM_10 = 10, /*!< GPIO10, input and output */
|
||||
GPIO_NUM_11 = 11, /*!< GPIO11, input and output */
|
||||
GPIO_NUM_12 = 12, /*!< GPIO12, input and output */
|
||||
GPIO_NUM_13 = 13, /*!< GPIO13, input and output */
|
||||
GPIO_NUM_14 = 14, /*!< GPIO14, input and output */
|
||||
GPIO_NUM_15 = 15, /*!< GPIO15, input and output */
|
||||
GPIO_NUM_16 = 16, /*!< GPIO16, input and output */
|
||||
GPIO_NUM_17 = 17, /*!< GPIO17, input and output */
|
||||
GPIO_NUM_18 = 18, /*!< GPIO18, input and output */
|
||||
GPIO_NUM_19 = 19, /*!< GPIO19, input and output */
|
||||
GPIO_NUM_20 = 20, /*!< GPIO20, input and output */
|
||||
GPIO_NUM_21 = 21, /*!< GPIO21, input and output */
|
||||
GPIO_NUM_22 = 22, /*!< GPIO22, input and output */
|
||||
GPIO_NUM_23 = 23, /*!< GPIO23, input and output */
|
||||
GPIO_NUM_24 = 24, /*!< GPIO24, input and output */
|
||||
GPIO_NUM_25 = 25, /*!< GPIO25, input and output */
|
||||
GPIO_NUM_MAX,
|
||||
/** @endcond */
|
||||
} gpio_num_t;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
typedef enum {
|
||||
GPIO_NUM_NC = -1, /*!< Use to signal not connected to S/W */
|
||||
|
@ -17,8 +17,6 @@
|
||||
#include "esp32s3/rom/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
#include "esp32h4/rom/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#include "esp32c2/rom/sha.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
|
@ -13,13 +13,6 @@ set(includes "include" "${target}")
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${target}/include")
|
||||
list(APPEND includes "${target}/include")
|
||||
if(target STREQUAL "esp32h4")
|
||||
if(CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1)
|
||||
list(APPEND includes "${target}/include/rev1")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2)
|
||||
list(APPEND includes "${target}/include/rev2")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(target STREQUAL "esp32")
|
||||
|
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/adc_periph.h"
|
||||
|
||||
/* Store IO number corresponding to the ADC channel number. */
|
||||
const int adc_channel_io_map[SOC_ADC_PERIPH_NUM][SOC_ADC_MAX_CHANNEL_NUM] = {
|
||||
/* ADC1 */
|
||||
{
|
||||
ADC1_CHANNEL_0_GPIO_NUM, ADC1_CHANNEL_1_GPIO_NUM, ADC1_CHANNEL_2_GPIO_NUM, ADC1_CHANNEL_3_GPIO_NUM, ADC1_CHANNEL_4_GPIO_NUM
|
||||
}
|
||||
};
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/dedic_gpio_periph.h"
|
||||
|
||||
const dedic_gpio_signal_conn_t dedic_gpio_periph_signals = {
|
||||
.module = -1,
|
||||
.irq = -1,
|
||||
.cores = {
|
||||
[0] = {
|
||||
.in_sig_per_channel = {
|
||||
[0] = CPU_GPIO_IN0_IDX,
|
||||
[1] = CPU_GPIO_IN1_IDX,
|
||||
[2] = CPU_GPIO_IN2_IDX,
|
||||
[3] = CPU_GPIO_IN3_IDX,
|
||||
[4] = CPU_GPIO_IN4_IDX,
|
||||
[5] = CPU_GPIO_IN5_IDX,
|
||||
[6] = CPU_GPIO_IN6_IDX,
|
||||
[7] = CPU_GPIO_IN7_IDX,
|
||||
},
|
||||
.out_sig_per_channel = {
|
||||
[0] = CPU_GPIO_OUT0_IDX,
|
||||
[1] = CPU_GPIO_OUT1_IDX,
|
||||
[2] = CPU_GPIO_OUT2_IDX,
|
||||
[3] = CPU_GPIO_OUT3_IDX,
|
||||
[4] = CPU_GPIO_OUT4_IDX,
|
||||
[5] = CPU_GPIO_OUT5_IDX,
|
||||
[6] = CPU_GPIO_OUT6_IDX,
|
||||
[7] = CPU_GPIO_OUT7_IDX,
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/gdma_periph.h"
|
||||
|
||||
const gdma_signal_conn_t gdma_periph_signals = {
|
||||
.groups = {
|
||||
[0] = {
|
||||
.module = PERIPH_GDMA_MODULE,
|
||||
.pairs = {
|
||||
[0] = {
|
||||
.rx_irq_id = ETS_DMA_CH0_INTR_SOURCE,
|
||||
.tx_irq_id = ETS_DMA_CH0_INTR_SOURCE,
|
||||
},
|
||||
[1] = {
|
||||
.rx_irq_id = ETS_DMA_CH1_INTR_SOURCE,
|
||||
.tx_irq_id = ETS_DMA_CH1_INTR_SOURCE,
|
||||
},
|
||||
[2] = {
|
||||
.rx_irq_id = ETS_DMA_CH2_INTR_SOURCE,
|
||||
.tx_irq_id = ETS_DMA_CH2_INTR_SOURCE,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/gpio_periph.h"
|
||||
|
||||
const uint32_t GPIO_PIN_MUX_REG[] = {
|
||||
IO_MUX_GPIO0_REG,
|
||||
IO_MUX_GPIO1_REG,
|
||||
IO_MUX_GPIO2_REG,
|
||||
IO_MUX_GPIO3_REG,
|
||||
IO_MUX_GPIO4_REG,
|
||||
IO_MUX_GPIO5_REG,
|
||||
IO_MUX_GPIO6_REG,
|
||||
IO_MUX_GPIO7_REG,
|
||||
IO_MUX_GPIO8_REG,
|
||||
IO_MUX_GPIO9_REG,
|
||||
IO_MUX_GPIO10_REG,
|
||||
IO_MUX_GPIO11_REG,
|
||||
IO_MUX_GPIO12_REG,
|
||||
IO_MUX_GPIO13_REG,
|
||||
IO_MUX_GPIO14_REG,
|
||||
IO_MUX_GPIO15_REG,
|
||||
IO_MUX_GPIO16_REG,
|
||||
IO_MUX_GPIO17_REG,
|
||||
IO_MUX_GPIO18_REG,
|
||||
IO_MUX_GPIO19_REG,
|
||||
IO_MUX_GPIO20_REG,
|
||||
IO_MUX_GPIO21_REG,
|
||||
IO_MUX_GPIO22_REG,
|
||||
IO_MUX_GPIO23_REG,
|
||||
IO_MUX_GPIO24_REG,
|
||||
IO_MUX_GPIO25_REG,
|
||||
#if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1
|
||||
IO_MUX_GPIO26_REG,
|
||||
IO_MUX_GPIO27_REG,
|
||||
IO_MUX_GPIO28_REG,
|
||||
IO_MUX_GPIO29_REG,
|
||||
IO_MUX_GPIO30_REG,
|
||||
IO_MUX_GPIO31_REG,
|
||||
IO_MUX_GPIO32_REG,
|
||||
IO_MUX_GPIO33_REG,
|
||||
IO_MUX_GPIO34_REG,
|
||||
IO_MUX_GPIO35_REG,
|
||||
IO_MUX_GPIO36_REG,
|
||||
IO_MUX_GPIO37_REG,
|
||||
IO_MUX_GPIO38_REG,
|
||||
IO_MUX_GPIO39_REG,
|
||||
IO_MUX_GPIO40_REG,
|
||||
#endif
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(GPIO_PIN_MUX_REG) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_PIN_MUX_REG");
|
||||
|
||||
const uint32_t GPIO_HOLD_MASK[] = {
|
||||
#if CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_1
|
||||
BIT(0), //GPIO0
|
||||
BIT(1), //GPIO1
|
||||
BIT(2), //GPIO2
|
||||
BIT(3), //GPIO3
|
||||
BIT(4), //GPIO4
|
||||
BIT(5), //GPIO5
|
||||
BIT(6), //GPIO6
|
||||
BIT(7), //GPIO7
|
||||
BIT(8), //GPIO8
|
||||
BIT(9), //GPIO9
|
||||
BIT(10), //GPIO10
|
||||
BIT(11), //GPIO11
|
||||
BIT(12), //GPIO12
|
||||
BIT(13), //GPIO13
|
||||
BIT(14), //GPIO14
|
||||
BIT(15), //GPIO15
|
||||
BIT(16), //GPIO16
|
||||
BIT(17), //GPIO17
|
||||
BIT(18), //GPIO18
|
||||
BIT(19), //GPIO19
|
||||
BIT(20), //GPIO20
|
||||
BIT(21), //GPIO21
|
||||
BIT(22), //GPIO22
|
||||
BIT(23), //GPIO23
|
||||
BIT(24), //GPIO24
|
||||
BIT(25), //GPIO25
|
||||
BIT(26), //GPIO26
|
||||
BIT(27), //GPIO27
|
||||
BIT(28), //GPIO28
|
||||
BIT(29), //GPIO29
|
||||
BIT(30), //GPIO30
|
||||
BIT(31), //GPIO31
|
||||
BIT(0), //GPIO32
|
||||
BIT(1), //GPIO33
|
||||
BIT(2), //GPIO34
|
||||
BIT(3), //GPIO35
|
||||
BIT(4), //GPIO36
|
||||
BIT(5), //GPIO37
|
||||
BIT(6), //GPIO38
|
||||
BIT(7), //GPIO39
|
||||
BIT(8), //GPIO40
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4_BETA_VERSION_2
|
||||
BIT(0), //GPIO0
|
||||
BIT(1), //GPIO1
|
||||
BIT(2), //GPIO2
|
||||
BIT(3), //GPIO3
|
||||
BIT(4), //GPIO4
|
||||
BIT(5), //GPIO5
|
||||
BIT(6), //GPIO6
|
||||
BIT(0), //GPIO7
|
||||
BIT(1), //GPIO8
|
||||
BIT(2), //GPIO9
|
||||
BIT(4), //GPIO10
|
||||
BIT(3), //GPIO11
|
||||
BIT(5), //GPIO12
|
||||
BIT(13), //GPIO13
|
||||
BIT(14), //GPIO14
|
||||
BIT(15), //GPIO15
|
||||
BIT(16), //GPIO16
|
||||
BIT(17), //GPIO17
|
||||
BIT(18), //GPIO18
|
||||
BIT(19), //GPIO19
|
||||
BIT(20), //GPIO20
|
||||
BIT(21), //GPIO21
|
||||
BIT(22), //GPIO22
|
||||
BIT(23), //GPIO23
|
||||
BIT(24), //GPIO24
|
||||
BIT(25), //GPIO25
|
||||
#endif
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(GPIO_HOLD_MASK) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_HOLD_MASK");
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define I2C_BIAS 0x6a
|
||||
#define I2C_BIAS_HOSTID 0
|
||||
|
||||
#define I2C_BIAS_DREG_1P6 0
|
||||
#define I2C_BIAS_DREG_1P6_MSB 3
|
||||
#define I2C_BIAS_DREG_1P6_LSB 0
|
||||
|
||||
#define I2C_BIAS_DREG_0P8 0
|
||||
#define I2C_BIAS_DREG_0P8_MSB 7
|
||||
#define I2C_BIAS_DREG_0P8_LSB 4
|
||||
|
||||
#define I2C_BIAS_DREG_1P1_PVT 1
|
||||
#define I2C_BIAS_DREG_1P1_PVT_MSB 3
|
||||
#define I2C_BIAS_DREG_1P1_PVT_LSB 0
|
||||
|
||||
#define I2C_BIAS_DREG_1P2 1
|
||||
#define I2C_BIAS_DREG_1P2_MSB 7
|
||||
#define I2C_BIAS_DREG_1P2_LSB 4
|
||||
|
||||
#define I2C_BIAS_ENT_CPREG 2
|
||||
#define I2C_BIAS_ENT_CPREG_MSB 0
|
||||
#define I2C_BIAS_ENT_CPREG_LSB 0
|
||||
|
||||
#define I2C_BIAS_ENT_CGM 2
|
||||
#define I2C_BIAS_ENT_CGM_MSB 1
|
||||
#define I2C_BIAS_ENT_CGM_LSB 1
|
||||
|
||||
#define I2C_BIAS_CGM_BIAS 2
|
||||
#define I2C_BIAS_CGM_BIAS_MSB 3
|
||||
#define I2C_BIAS_CGM_BIAS_LSB 2
|
||||
|
||||
#define I2C_BIAS_DREF_IGM 2
|
||||
#define I2C_BIAS_DREF_IGM_MSB 4
|
||||
#define I2C_BIAS_DREF_IGM_LSB 4
|
||||
|
||||
#define I2C_BIAS_RC_DVREF 2
|
||||
#define I2C_BIAS_RC_DVREF_MSB 6
|
||||
#define I2C_BIAS_RC_DVREF_LSB 5
|
||||
|
||||
#define I2C_BIAS_FORCE_DISABLE_BIAS_SLEEP 2
|
||||
#define I2C_BIAS_FORCE_DISABLE_BIAS_SLEEP_MSB 7
|
||||
#define I2C_BIAS_FORCE_DISABLE_BIAS_SLEEP_LSB 7
|
||||
|
||||
#define I2C_BIAS_RC_ENX 3
|
||||
#define I2C_BIAS_RC_ENX_MSB 0
|
||||
#define I2C_BIAS_RC_ENX_LSB 0
|
||||
|
||||
#define I2C_BIAS_RC_START 3
|
||||
#define I2C_BIAS_RC_START_MSB 1
|
||||
#define I2C_BIAS_RC_START_LSB 1
|
||||
|
||||
#define I2C_BIAS_RC_DCAP_EXT 3
|
||||
#define I2C_BIAS_RC_DCAP_EXT_MSB 7
|
||||
#define I2C_BIAS_RC_DCAP_EXT_LSB 2
|
||||
|
||||
#define I2C_BIAS_XPD_RC 4
|
||||
#define I2C_BIAS_XPD_RC_MSB 0
|
||||
#define I2C_BIAS_XPD_RC_LSB 0
|
||||
|
||||
#define I2C_BIAS_ENT_CONSTI 4
|
||||
#define I2C_BIAS_ENT_CONSTI_MSB 1
|
||||
#define I2C_BIAS_ENT_CONSTI_LSB 1
|
||||
|
||||
#define I2C_BIAS_XPD_ICX 4
|
||||
#define I2C_BIAS_XPD_ICX_MSB 2
|
||||
#define I2C_BIAS_XPD_ICX_LSB 2
|
||||
|
||||
#define I2C_BIAS_RC_RSTB 4
|
||||
#define I2C_BIAS_RC_RSTB_MSB 3
|
||||
#define I2C_BIAS_RC_RSTB_LSB 3
|
||||
|
||||
#define I2C_BIAS_RC_DIV 4
|
||||
#define I2C_BIAS_RC_DIV_MSB 7
|
||||
#define I2C_BIAS_RC_DIV_LSB 4
|
||||
|
||||
#define I2C_BIAS_RC_CAP 5
|
||||
#define I2C_BIAS_RC_CAP_MSB 5
|
||||
#define I2C_BIAS_RC_CAP_LSB 0
|
||||
|
||||
#define I2C_BIAS_RC_UD 5
|
||||
#define I2C_BIAS_RC_UD_MSB 6
|
||||
#define I2C_BIAS_RC_UD_LSB 6
|
||||
|
||||
#define I2C_BIAS_RC_LOCKB 5
|
||||
#define I2C_BIAS_RC_LOCKB_MSB 7
|
||||
#define I2C_BIAS_RC_LOCKB_LSB 7
|
||||
|
||||
#define I2C_BIAS_RC_CHG_COUNT 6
|
||||
#define I2C_BIAS_RC_CHG_COUNT_MSB 4
|
||||
#define I2C_BIAS_RC_CHG_COUNT_LSB 0
|
||||
|
||||
#define I2C_BIAS_XPD_CPREG 7
|
||||
#define I2C_BIAS_XPD_CPREG_MSB 0
|
||||
#define I2C_BIAS_XPD_CPREG_LSB 0
|
||||
|
||||
#define I2C_BIAS_XPD_CGM 7
|
||||
#define I2C_BIAS_XPD_CGM_MSB 1
|
||||
#define I2C_BIAS_XPD_CGM_LSB 1
|
||||
|
||||
#define I2C_BIAS_DTEST 7
|
||||
#define I2C_BIAS_DTEST_MSB 3
|
||||
#define I2C_BIAS_DTEST_LSB 2
|
||||
|
||||
#define I2C_BIAS_DRES12K 7
|
||||
#define I2C_BIAS_DRES12K_MSB 7
|
||||
#define I2C_BIAS_DRES12K_LSB 4
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
/*
|
||||
Bunch of constants for every I2C peripheral: GPIO signals, irqs, hw addr of registers etc
|
||||
*/
|
||||
const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM] = {
|
||||
{
|
||||
.sda_out_sig = I2CEXT0_SDA_OUT_IDX,
|
||||
.sda_in_sig = I2CEXT0_SDA_IN_IDX,
|
||||
.scl_out_sig = I2CEXT0_SCL_OUT_IDX,
|
||||
.scl_in_sig = I2CEXT0_SCL_IN_IDX,
|
||||
.irq = ETS_I2C_EXT0_INTR_SOURCE,
|
||||
.module = PERIPH_I2C0_MODULE,
|
||||
},
|
||||
};
|
@ -1,280 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define I2C_PMU 0x6d
|
||||
#define I2C_PMU_HOSTID 0
|
||||
|
||||
#define I2C_PMU_THRES_HIGH_7_0 0
|
||||
#define I2C_PMU_THRES_HIGH_7_0_MSB 7
|
||||
#define I2C_PMU_THRES_HIGH_7_0_LSB 0
|
||||
|
||||
#define I2C_PMU_THRES_LOW_7_0 1
|
||||
#define I2C_PMU_THRES_LOW_7_0_MSB 7
|
||||
#define I2C_PMU_THRES_LOW_7_0_LSB 0
|
||||
|
||||
#define I2C_PMU_THRES_HIGH_11_8 2
|
||||
#define I2C_PMU_THRES_HIGH_11_8_MSB 3
|
||||
#define I2C_PMU_THRES_HIGH_11_8_LSB 0
|
||||
|
||||
#define I2C_PMU_THRES_LOW_11_8 2
|
||||
#define I2C_PMU_THRES_LOW_11_8_MSB 7
|
||||
#define I2C_PMU_THRES_LOW_11_8_LSB 4
|
||||
|
||||
#define I2C_PMU_PVT_DELAY_INIT 3
|
||||
#define I2C_PMU_PVT_DELAY_INIT_MSB 7
|
||||
#define I2C_PMU_PVT_DELAY_INIT_LSB 0
|
||||
|
||||
#define I2C_PMU_PVT_DELAY_COUNT 4
|
||||
#define I2C_PMU_PVT_DELAY_COUNT_MSB 5
|
||||
#define I2C_PMU_PVT_DELAY_COUNT_LSB 0
|
||||
|
||||
#define I2C_PMU_OR_EN_CONT_CAL 4
|
||||
#define I2C_PMU_OR_EN_CONT_CAL_MSB 7
|
||||
#define I2C_PMU_OR_EN_CONT_CAL_LSB 7
|
||||
|
||||
#define I2C_PMU_I2C_RTC_DREG 5
|
||||
#define I2C_PMU_I2C_RTC_DREG_MSB 4
|
||||
#define I2C_PMU_I2C_RTC_DREG_LSB 0
|
||||
|
||||
#define I2C_PMU_I2C_DIG_DREG 6
|
||||
#define I2C_PMU_I2C_DIG_DREG_MSB 4
|
||||
#define I2C_PMU_I2C_DIG_DREG_LSB 0
|
||||
|
||||
#define I2C_PMU_I2C_RTC_DREG_SLP 7
|
||||
#define I2C_PMU_I2C_RTC_DREG_SLP_MSB 3
|
||||
#define I2C_PMU_I2C_RTC_DREG_SLP_LSB 0
|
||||
|
||||
#define I2C_PMU_I2C_DIG_DREG_SLP 7
|
||||
#define I2C_PMU_I2C_DIG_DREG_SLP_MSB 7
|
||||
#define I2C_PMU_I2C_DIG_DREG_SLP_LSB 4
|
||||
|
||||
#define I2C_PMU_EN_I2C_RTC_DREG 10
|
||||
#define I2C_PMU_EN_I2C_RTC_DREG_MSB 0
|
||||
#define I2C_PMU_EN_I2C_RTC_DREG_LSB 0
|
||||
|
||||
#define I2C_PMU_EN_I2C_DIG_DREG 10
|
||||
#define I2C_PMU_EN_I2C_DIG_DREG_MSB 1
|
||||
#define I2C_PMU_EN_I2C_DIG_DREG_LSB 1
|
||||
|
||||
#define I2C_PMU_EN_I2C_RTC_DREG_SLP 10
|
||||
#define I2C_PMU_EN_I2C_RTC_DREG_SLP_MSB 2
|
||||
#define I2C_PMU_EN_I2C_RTC_DREG_SLP_LSB 2
|
||||
|
||||
#define I2C_PMU_EN_I2C_DIG_DREG_SLP 10
|
||||
#define I2C_PMU_EN_I2C_DIG_DREG_SLP_MSB 3
|
||||
#define I2C_PMU_EN_I2C_DIG_DREG_SLP_LSB 3
|
||||
|
||||
#define I2C_PMU_ENX_RTC_DREG 11
|
||||
#define I2C_PMU_ENX_RTC_DREG_MSB 0
|
||||
#define I2C_PMU_ENX_RTC_DREG_LSB 0
|
||||
|
||||
#define I2C_PMU_ENX_DIG_DREG 11
|
||||
#define I2C_PMU_ENX_DIG_DREG_MSB 1
|
||||
#define I2C_PMU_ENX_DIG_DREG_LSB 1
|
||||
|
||||
#define I2C_PMU_OR_XPD_RTC_SLAVE_3P3 11
|
||||
#define I2C_PMU_OR_XPD_RTC_SLAVE_3P3_MSB 2
|
||||
#define I2C_PMU_OR_XPD_RTC_SLAVE_3P3_LSB 2
|
||||
|
||||
#define I2C_PMU_OR_XPD_RTC_REG 11
|
||||
#define I2C_PMU_OR_XPD_RTC_REG_MSB 4
|
||||
#define I2C_PMU_OR_XPD_RTC_REG_LSB 4
|
||||
|
||||
#define I2C_PMU_OR_XPD_DIG_REG 11
|
||||
#define I2C_PMU_OR_XPD_DIG_REG_MSB 5
|
||||
#define I2C_PMU_OR_XPD_DIG_REG_LSB 5
|
||||
|
||||
#define I2C_PMU_OR_PD_RTC_REG_SLP 11
|
||||
#define I2C_PMU_OR_PD_RTC_REG_SLP_MSB 6
|
||||
#define I2C_PMU_OR_PD_RTC_REG_SLP_LSB 6
|
||||
|
||||
#define I2C_PMU_OR_PD_DIG_REG_SLP 11
|
||||
#define I2C_PMU_OR_PD_DIG_REG_SLP_MSB 7
|
||||
#define I2C_PMU_OR_PD_DIG_REG_SLP_LSB 7
|
||||
|
||||
#define I2C_PMU_INT_DREG 12
|
||||
#define I2C_PMU_INT_DREG_MSB 4
|
||||
#define I2C_PMU_INT_DREG_LSB 0
|
||||
|
||||
#define I2C_PMU_O_UDF 12
|
||||
#define I2C_PMU_O_UDF_MSB 5
|
||||
#define I2C_PMU_O_UDF_LSB 5
|
||||
|
||||
#define I2C_PMU_O_OVF 12
|
||||
#define I2C_PMU_O_OVF_MSB 6
|
||||
#define I2C_PMU_O_OVF_LSB 6
|
||||
|
||||
#define I2C_PMU_O_UPDATE 12
|
||||
#define I2C_PMU_O_UPDATE_MSB 7
|
||||
#define I2C_PMU_O_UPDATE_LSB 7
|
||||
|
||||
#define I2C_PMU_PVT_COUNT_7_0 13
|
||||
#define I2C_PMU_PVT_COUNT_7_0_MSB 7
|
||||
#define I2C_PMU_PVT_COUNT_7_0_LSB 0
|
||||
|
||||
#define I2C_PMU_PVT_COUNT_11_8 14
|
||||
#define I2C_PMU_PVT_COUNT_11_8_MSB 3
|
||||
#define I2C_PMU_PVT_COUNT_11_8_LSB 0
|
||||
|
||||
#define I2C_PMU_IC_VGOOD_LVDET 14
|
||||
#define I2C_PMU_IC_VGOOD_LVDET_MSB 4
|
||||
#define I2C_PMU_IC_VGOOD_LVDET_LSB 4
|
||||
|
||||
#define I2C_PMU_IC_POWER_GOOD_DCDC 14
|
||||
#define I2C_PMU_IC_POWER_GOOD_DCDC_MSB 5
|
||||
#define I2C_PMU_IC_POWER_GOOD_DCDC_LSB 5
|
||||
|
||||
#define I2C_PMU_IC_VGOOD_DIGDET 14
|
||||
#define I2C_PMU_IC_VGOOD_DIGDET_MSB 6
|
||||
#define I2C_PMU_IC_VGOOD_DIGDET_LSB 6
|
||||
|
||||
#define I2C_PMU_OR_XPD_DCDC 15
|
||||
#define I2C_PMU_OR_XPD_DCDC_MSB 0
|
||||
#define I2C_PMU_OR_XPD_DCDC_LSB 0
|
||||
|
||||
#define I2C_PMU_OR_DISALBE_DEEP_SLEEP_DCDC 15
|
||||
#define I2C_PMU_OR_DISALBE_DEEP_SLEEP_DCDC_MSB 1
|
||||
#define I2C_PMU_OR_DISALBE_DEEP_SLEEP_DCDC_LSB 1
|
||||
|
||||
#define I2C_PMU_OR_DISALBE_LIGHT_SLEEP_DCDC 15
|
||||
#define I2C_PMU_OR_DISALBE_LIGHT_SLEEP_DCDC_MSB 2
|
||||
#define I2C_PMU_OR_DISALBE_LIGHT_SLEEP_DCDC_LSB 2
|
||||
|
||||
#define I2C_PMU_OR_ENALBE_TRX_MODE_DCDC 15
|
||||
#define I2C_PMU_OR_ENALBE_TRX_MODE_DCDC_MSB 3
|
||||
#define I2C_PMU_OR_ENALBE_TRX_MODE_DCDC_LSB 3
|
||||
|
||||
#define I2C_PMU_OR_ENX_REG_DCDC 15
|
||||
#define I2C_PMU_OR_ENX_REG_DCDC_MSB 4
|
||||
#define I2C_PMU_OR_ENX_REG_DCDC_LSB 4
|
||||
|
||||
#define I2C_PMU_OR_UNLOCK_DCDC 15
|
||||
#define I2C_PMU_OR_UNLOCK_DCDC_MSB 5
|
||||
#define I2C_PMU_OR_UNLOCK_DCDC_LSB 5
|
||||
|
||||
#define I2C_PMU_OR_FORCE_LOCK_DCDC 15
|
||||
#define I2C_PMU_OR_FORCE_LOCK_DCDC_MSB 6
|
||||
#define I2C_PMU_OR_FORCE_LOCK_DCDC_LSB 6
|
||||
|
||||
#define I2C_PMU_OR_ENB_SLOW_CLK 15
|
||||
#define I2C_PMU_OR_ENB_SLOW_CLK_MSB 7
|
||||
#define I2C_PMU_OR_ENB_SLOW_CLK_LSB 7
|
||||
|
||||
#define I2C_PMU_OC_SCK_DCAP 16
|
||||
#define I2C_PMU_OC_SCK_DCAP_MSB 7
|
||||
#define I2C_PMU_OC_SCK_DCAP_LSB 0
|
||||
|
||||
#define I2C_PMU_OC_XPD_LVDET 17
|
||||
#define I2C_PMU_OC_XPD_LVDET_MSB 0
|
||||
#define I2C_PMU_OC_XPD_LVDET_LSB 0
|
||||
|
||||
#define I2C_PMU_OC_MODE_LVDET 17
|
||||
#define I2C_PMU_OC_MODE_LVDET_MSB 1
|
||||
#define I2C_PMU_OC_MODE_LVDET_LSB 1
|
||||
|
||||
#define I2C_PMU_OR_XPD_TRX 17
|
||||
#define I2C_PMU_OR_XPD_TRX_MSB 2
|
||||
#define I2C_PMU_OR_XPD_TRX_LSB 2
|
||||
|
||||
#define I2C_PMU_OR_EN_RESET_CHIP 17
|
||||
#define I2C_PMU_OR_EN_RESET_CHIP_MSB 3
|
||||
#define I2C_PMU_OR_EN_RESET_CHIP_LSB 3
|
||||
|
||||
#define I2C_PMU_OC_DREF_LVDET 17
|
||||
#define I2C_PMU_OC_DREF_LVDET_MSB 6
|
||||
#define I2C_PMU_OC_DREF_LVDET_LSB 4
|
||||
|
||||
#define I2C_PMU_OR_FORCE_XPD_REG_SLAVE 17
|
||||
#define I2C_PMU_OR_FORCE_XPD_REG_SLAVE_MSB 7
|
||||
#define I2C_PMU_OR_FORCE_XPD_REG_SLAVE_LSB 7
|
||||
|
||||
#define I2C_PMU_DTEST 18
|
||||
#define I2C_PMU_DTEST_MSB 1
|
||||
#define I2C_PMU_DTEST_LSB 0
|
||||
|
||||
#define I2C_PMU_ENT_BIAS 18
|
||||
#define I2C_PMU_ENT_BIAS_MSB 2
|
||||
#define I2C_PMU_ENT_BIAS_LSB 2
|
||||
|
||||
#define I2C_PMU_ENT_VDD 18
|
||||
#define I2C_PMU_ENT_VDD_MSB 5
|
||||
#define I2C_PMU_ENT_VDD_LSB 3
|
||||
|
||||
#define I2C_PMU_EN_DMUX 18
|
||||
#define I2C_PMU_EN_DMUX_MSB 6
|
||||
#define I2C_PMU_EN_DMUX_LSB 6
|
||||
|
||||
#define I2C_PMU_WD_DISABLE 18
|
||||
#define I2C_PMU_WD_DISABLE_MSB 7
|
||||
#define I2C_PMU_WD_DISABLE_LSB 7
|
||||
|
||||
#define I2C_PMU_DTEST_DCDC 19
|
||||
#define I2C_PMU_DTEST_DCDC_MSB 0
|
||||
#define I2C_PMU_DTEST_DCDC_LSB 0
|
||||
|
||||
#define I2C_PMU_TESTEN_DCDC 19
|
||||
#define I2C_PMU_TESTEN_DCDC_MSB 1
|
||||
#define I2C_PMU_TESTEN_DCDC_LSB 1
|
||||
|
||||
#define I2C_PMU_ADD_DCDC 19
|
||||
#define I2C_PMU_ADD_DCDC_MSB 6
|
||||
#define I2C_PMU_ADD_DCDC_LSB 4
|
||||
|
||||
#define I2C_PMU_OR_POCPENB_DCDC 20
|
||||
#define I2C_PMU_OR_POCPENB_DCDC_MSB 0
|
||||
#define I2C_PMU_OR_POCPENB_DCDC_LSB 0
|
||||
|
||||
#define I2C_PMU_OR_SSTIME_DCDC 20
|
||||
#define I2C_PMU_OR_SSTIME_DCDC_MSB 1
|
||||
#define I2C_PMU_OR_SSTIME_DCDC_LSB 1
|
||||
|
||||
#define I2C_PMU_OR_CCM_DCDC 20
|
||||
#define I2C_PMU_OR_CCM_DCDC_MSB 2
|
||||
#define I2C_PMU_OR_CCM_DCDC_LSB 2
|
||||
|
||||
#define I2C_PMU_OR_VSET_LOW_DCDC 20
|
||||
#define I2C_PMU_OR_VSET_LOW_DCDC_MSB 7
|
||||
#define I2C_PMU_OR_VSET_LOW_DCDC_LSB 3
|
||||
|
||||
#define I2C_PMU_OR_FSW_DCDC 21
|
||||
#define I2C_PMU_OR_FSW_DCDC_MSB 2
|
||||
#define I2C_PMU_OR_FSW_DCDC_LSB 0
|
||||
|
||||
#define I2C_PMU_OR_DCMLEVEL_DCDC 21
|
||||
#define I2C_PMU_OR_DCMLEVEL_DCDC_MSB 4
|
||||
#define I2C_PMU_OR_DCMLEVEL_DCDC_LSB 3
|
||||
|
||||
#define I2C_PMU_OR_DCM2ENB_DCDC 21
|
||||
#define I2C_PMU_OR_DCM2ENB_DCDC_MSB 5
|
||||
#define I2C_PMU_OR_DCM2ENB_DCDC_LSB 5
|
||||
|
||||
#define I2C_PMU_OR_RAMP_DCDC 21
|
||||
#define I2C_PMU_OR_RAMP_DCDC_MSB 6
|
||||
#define I2C_PMU_OR_RAMP_DCDC_LSB 6
|
||||
|
||||
#define I2C_PMU_OR_RAMPLEVEL_DCDC 21
|
||||
#define I2C_PMU_OR_RAMPLEVEL_DCDC_MSB 7
|
||||
#define I2C_PMU_OR_RAMPLEVEL_DCDC_LSB 7
|
||||
|
||||
#define I2C_PMU_OR_VSET_HIGH_DCDC 22
|
||||
#define I2C_PMU_OR_VSET_HIGH_DCDC_MSB 4
|
||||
#define I2C_PMU_OR_VSET_HIGH_DCDC_LSB 0
|
||||
|
||||
#define I2C_PMU_OC_DEL_SSEND 22
|
||||
#define I2C_PMU_OC_DEL_SSEND_MSB 7
|
||||
#define I2C_PMU_OC_DEL_SSEND_LSB 5
|
||||
|
||||
#define I2C_PMU_OC_XPD_DIGDET 23
|
||||
#define I2C_PMU_OC_XPD_DIGDET_MSB 0
|
||||
#define I2C_PMU_OC_XPD_DIGDET_LSB 0
|
||||
|
||||
#define I2C_PMU_OC_MODE_DIGDET 23
|
||||
#define I2C_PMU_OC_MODE_DIGDET_MSB 1
|
||||
#define I2C_PMU_OC_MODE_DIGDET_LSB 1
|
||||
|
||||
#define I2C_PMU_OC_DREF_DIGDET 23
|
||||
#define I2C_PMU_OC_DREF_DIGDET_MSB 6
|
||||
#define I2C_PMU_OC_DREF_DIGDET_LSB 4
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define I2C_ULP 0x61
|
||||
#define I2C_ULP_HOSTID 0
|
||||
|
||||
#define I2C_ULP_IR_RESETB 0
|
||||
#define I2C_ULP_IR_RESETB_MSB 0
|
||||
#define I2C_ULP_IR_RESETB_LSB 0
|
||||
|
||||
#define I2C_ULP_XPD_REG_SLP 0
|
||||
#define I2C_ULP_XPD_REG_SLP_MSB 1
|
||||
#define I2C_ULP_XPD_REG_SLP_LSB 1
|
||||
|
||||
#define I2C_ULP_DBIAS_SLP 0
|
||||
#define I2C_ULP_DBIAS_SLP_MSB 7
|
||||
#define I2C_ULP_DBIAS_SLP_LSB 4
|
||||
|
||||
#define I2C_ULP_IR_FORCE_XPD_BIAS_BUF 1
|
||||
#define I2C_ULP_IR_FORCE_XPD_BIAS_BUF_MSB 1
|
||||
#define I2C_ULP_IR_FORCE_XPD_BIAS_BUF_LSB 1
|
||||
|
||||
#define I2C_ULP_IR_FORCE_XPD_IPH 1
|
||||
#define I2C_ULP_IR_FORCE_XPD_IPH_MSB 2
|
||||
#define I2C_ULP_IR_FORCE_XPD_IPH_LSB 2
|
||||
|
||||
#define I2C_ULP_IR_FORCE_XPD_VGATE_BUF 1
|
||||
#define I2C_ULP_IR_FORCE_XPD_VGATE_BUF_MSB 3
|
||||
#define I2C_ULP_IR_FORCE_XPD_VGATE_BUF_LSB 3
|
||||
|
||||
#define I2C_ULP_IR_FORCE_DISABLE_BIAS_SLEEP 1
|
||||
#define I2C_ULP_IR_FORCE_DISABLE_BIAS_SLEEP_MSB 4
|
||||
#define I2C_ULP_IR_FORCE_DISABLE_BIAS_SLEEP_LSB 4
|
||||
|
||||
#define I2C_ULP_IR_ZOS_XPD 2
|
||||
#define I2C_ULP_IR_ZOS_XPD_MSB 0
|
||||
#define I2C_ULP_IR_ZOS_XPD_LSB 0
|
||||
|
||||
#define I2C_ULP_IR_ZOS_RSTB 2
|
||||
#define I2C_ULP_IR_ZOS_RSTB_MSB 1
|
||||
#define I2C_ULP_IR_ZOS_RSTB_LSB 1
|
||||
|
||||
#define I2C_ULP_IR_ZOS_RESTART 2
|
||||
#define I2C_ULP_IR_ZOS_RESTART_MSB 2
|
||||
#define I2C_ULP_IR_ZOS_RESTART_LSB 2
|
||||
|
||||
#define I2C_ULP_DTEST 3
|
||||
#define I2C_ULP_DTEST_MSB 1
|
||||
#define I2C_ULP_DTEST_LSB 0
|
||||
|
||||
#define I2C_ULP_ENT_BG 3
|
||||
#define I2C_ULP_ENT_BG_MSB 2
|
||||
#define I2C_ULP_ENT_BG_LSB 2
|
||||
|
||||
#define I2C_ULP_MODE_LVDET 3
|
||||
#define I2C_ULP_MODE_LVDET_MSB 3
|
||||
#define I2C_ULP_MODE_LVDET_LSB 3
|
||||
|
||||
#define I2C_ULP_DREF_LVDET 3
|
||||
#define I2C_ULP_DREF_LVDET_MSB 6
|
||||
#define I2C_ULP_DREF_LVDET_LSB 4
|
||||
|
||||
#define I2C_ULP_XPD_LVDET 3
|
||||
#define I2C_ULP_XPD_LVDET_MSB 7
|
||||
#define I2C_ULP_XPD_LVDET_LSB 7
|
||||
|
||||
#define I2C_ULP_INT_XPD_XTAL_CK_DIG_REG 4
|
||||
#define I2C_ULP_INT_XPD_XTAL_CK_DIG_REG_MSB 0
|
||||
#define I2C_ULP_INT_XPD_XTAL_CK_DIG_REG_LSB 0
|
||||
|
||||
#define I2C_ULP_INT_XPD_XTAL_BUF 4
|
||||
#define I2C_ULP_INT_XPD_XTAL_BUF_MSB 1
|
||||
#define I2C_ULP_INT_XPD_XTAL_BUF_LSB 1
|
||||
|
||||
#define I2C_ULP_INT_XPD_RC_CK 4
|
||||
#define I2C_ULP_INT_XPD_RC_CK_MSB 2
|
||||
#define I2C_ULP_INT_XPD_RC_CK_LSB 2
|
||||
|
||||
#define I2C_ULP_XTAL_DPHASE 4
|
||||
#define I2C_ULP_XTAL_DPHASE_MSB 3
|
||||
#define I2C_ULP_XTAL_DPHASE_LSB 3
|
||||
|
||||
#define I2C_ULP_INT_XPD_XTAL_LIN_REG 4
|
||||
#define I2C_ULP_INT_XPD_XTAL_LIN_REG_MSB 4
|
||||
#define I2C_ULP_INT_XPD_XTAL_LIN_REG_LSB 4
|
||||
|
||||
#define I2C_ULP_XTAL_RESTART_DC_CAL 4
|
||||
#define I2C_ULP_XTAL_RESTART_DC_CAL_MSB 5
|
||||
#define I2C_ULP_XTAL_RESTART_DC_CAL_LSB 5
|
||||
|
||||
#define I2C_ULP_XTAL_DAC 5
|
||||
#define I2C_ULP_XTAL_DAC_MSB 3
|
||||
#define I2C_ULP_XTAL_DAC_LSB 0
|
||||
|
||||
#define I2C_ULP_XTAL_DBLEED 6
|
||||
#define I2C_ULP_XTAL_DBLEED_MSB 4
|
||||
#define I2C_ULP_XTAL_DBLEED_LSB 0
|
||||
|
||||
#define I2C_ULP_XTAL_CAL_DONE 6
|
||||
#define I2C_ULP_XTAL_CAL_DONE_MSB 5
|
||||
#define I2C_ULP_XTAL_CAL_DONE_LSB 5
|
||||
|
||||
#define I2C_ULP_ZOS_DONE 6
|
||||
#define I2C_ULP_ZOS_DONE_MSB 6
|
||||
#define I2C_ULP_ZOS_DONE_LSB 6
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user