soc: placeholder for esp32s3 HAL driver

soc rtc
This commit is contained in:
morris 2020-07-31 18:26:07 +08:00
parent 0b9e303e93
commit edb5ddf63b
85 changed files with 16736 additions and 5828 deletions

View File

@ -14,12 +14,17 @@
#include "essl_sdio.h"
#include "esp_log.h"
#include "soc/host_reg.h"
#include "freertos/task.h"
#include "essl_internal.h"
#include "soc/soc_caps.h"
#if SOC_SDIO_SLAVE_SUPPORTED
#include "soc/host_reg.h"
static const char TAG[] = "essl_sdio";
#define HOST_SLCHOST_CONF_W_REG(pos) (HOST_SLCHOST_CONF_W0_REG+pos+(pos>23?4:0)+(pos>31?12:0))
#define ESSL_CMD53_END_ADDR 0x1f800
#define TX_BUFFER_MAX 0x1000
@ -452,4 +457,6 @@ void essl_sdio_reset_cnt(void *arg)
essl_sdio_context_t* ctx = arg;
ctx->rx_got_bytes = 0;
ctx->tx_sent_buffers = 0;
}
}
#endif // #if SOC_SDIO_SLAVE_SUPPORTED

View File

@ -1,8 +1,22 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "soc/adc_caps.h"
#include "sdkconfig.h"
#include <stdbool.h>
#include <stdint.h>
#include "sdkconfig.h"
#include "soc/adc_caps.h"
/**
* @brief ADC units selected handle.
@ -69,7 +83,7 @@ typedef enum {
ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit. Only ESP32 is supported. */
ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit. Only ESP32 is supported. */
ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit. Only ESP32 is supported. */
#ifdef CONFIG_IDF_TARGET_ESP32S2
#if !CONFIG_IDF_TARGET_ESP32
ADC_WIDTH_BIT_13 = 4, /*!< ADC capture width is 13Bit. Only ESP32S2 is supported. */
#endif
ADC_WIDTH_MAX,
@ -112,7 +126,7 @@ typedef struct {
};
} adc_digi_output_data_t;
#ifdef CONFIG_IDF_TARGET_ESP32S2
#if !CONFIG_IDF_TARGET_ESP32
/**
* @brief ADC digital controller (DMA mode) clock system setting.
@ -338,4 +352,4 @@ typedef struct {
uint32_t threshold; /*!<Set monitor threshold of adc digital controller. */
} adc_digi_monitor_t;
#endif // CONFIG_IDF_TARGET_ESP32S2
#endif // CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3

View File

@ -49,7 +49,7 @@ FLAG_ATTR(spi_event_t)
#define SPI_HOST SPI1_HOST
#define HSPI_HOST SPI2_HOST
#define VSPI_HOST SPI3_HOST
#elif CONFIG_IDF_TARGET_ESP32S2
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
// SPI_HOST (SPI1_HOST) is not supported by the SPI Master and SPI Slave driver on ESP32-S2
#define SPI_HOST SPI1_HOST
#define FSPI_HOST SPI2_HOST

View File

@ -71,6 +71,11 @@ void systimer_hal_counter_value_advance(systimer_counter_id_t counter_id, int64_
*/
void systimer_hal_init(void);
/**
* @brief connect alarm unit to selected counter
*/
void systimer_hal_connect_alarm_counter(systimer_alarm_id_t alarm_id, systimer_counter_id_t counter_id);
#ifdef __cplusplus
}
#endif

View File

@ -129,7 +129,7 @@ typedef enum {
#define TOUCH_TRIGGER_MODE_DEFAULT (TOUCH_TRIGGER_BELOW) /*!<Interrupts can be triggered if sensor value gets below or above threshold */
#define TOUCH_TRIGGER_SOURCE_DEFAULT (TOUCH_TRIGGER_SOURCE_SET1) /*!<The wakeup trigger source can be SET1 or both SET1 and SET2 */
#elif CONFIG_IDF_TARGET_ESP32S2
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
/**
* Excessive total time will slow down the touch response.
* Too small measurement time will not be sampled enough, resulting in inaccurate measurements.
@ -145,7 +145,7 @@ typedef enum {
Range: 0 ~ 0xffff */
#endif // CONFIG_IDF_TARGET_ESP32
#ifdef CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
typedef enum {
TOUCH_PAD_INTR_MASK_DONE = BIT(0), /*!<Measurement done for one of the enabled channels. */

View File

@ -20,6 +20,8 @@
#include "esp32/rom/lldesc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/lldesc.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/lldesc.h"
#endif
//the size field has 12 bits, but 0 not for 4096.

View File

@ -211,10 +211,10 @@ inline static bool IRAM_ATTR esp_ptr_external_ram(const void *p) {
}
inline static bool IRAM_ATTR esp_ptr_in_iram(const void *p) {
#if !CONFIG_FREERTOS_UNICORE || CONFIG_IDF_TARGET_ESP32S2
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
#else
#if CONFIG_IDF_TARGET_ESP32 && CONFIG_FREERTOS_UNICORE
return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH);
#else
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
#endif
}

View File

@ -36,6 +36,8 @@
#include "esp32/rom/ets_sys.h" // will be removed in idf v5.0
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/ets_sys.h"
#endif
#define SOC_LOGE(tag, fmt, ...) esp_rom_printf("%s(err): " fmt, tag, ##__VA_ARGS__)

View File

@ -812,8 +812,6 @@
#define HOST_SLCHOST_STATE4_V 0xFF
#define HOST_SLCHOST_STATE4_S 0
#define HOST_SLCHOST_CONF_W_REG(pos) (HOST_SLCHOST_CONF_W0_REG+pos+(pos>23?4:0)+(pos>31?12:0))
#define HOST_SLCHOST_CONF_W0_REG (DR_REG_SLCHOST_BASE + 0x6C)
/* HOST_SLCHOST_CONF3 : R/W ;bitpos:[31:24] ;default: 8'h0 ; */
/*description: */

View File

@ -1,248 +0,0 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SOC_HINF_REG_H_
#define _SOC_HINF_REG_H_
#include "soc.h"
#define HINF_CFG_DATA0_REG (DR_REG_HINF_BASE + 0x0)
/* HINF_DEVICE_ID_FN1 : R/W ;bitpos:[31:16] ;default: 16'h2222 ; */
/*description: */
#define HINF_DEVICE_ID_FN1 0x0000FFFF
#define HINF_DEVICE_ID_FN1_M ((HINF_DEVICE_ID_FN1_V)<<(HINF_DEVICE_ID_FN1_S))
#define HINF_DEVICE_ID_FN1_V 0xFFFF
#define HINF_DEVICE_ID_FN1_S 16
/* HINF_USER_ID_FN1 : R/W ;bitpos:[15:0] ;default: 16'h6666 ; */
/*description: */
#define HINF_USER_ID_FN1 0x0000FFFF
#define HINF_USER_ID_FN1_M ((HINF_USER_ID_FN1_V)<<(HINF_USER_ID_FN1_S))
#define HINF_USER_ID_FN1_V 0xFFFF
#define HINF_USER_ID_FN1_S 0
#define HINF_CFG_DATA1_REG (DR_REG_HINF_BASE + 0x4)
/* HINF_SDIO20_CONF1 : R/W ;bitpos:[31:29] ;default: 3'h0 ; */
/*description: */
#define HINF_SDIO20_CONF1 0x00000007
#define HINF_SDIO20_CONF1_M ((HINF_SDIO20_CONF1_V)<<(HINF_SDIO20_CONF1_S))
#define HINF_SDIO20_CONF1_V 0x7
#define HINF_SDIO20_CONF1_S 29
/* HINF_FUNC2_EPS : RO ;bitpos:[28] ;default: 1'b0 ; */
/*description: */
#define HINF_FUNC2_EPS (BIT(28))
#define HINF_FUNC2_EPS_M (BIT(28))
#define HINF_FUNC2_EPS_V 0x1
#define HINF_FUNC2_EPS_S 28
/* HINF_SDIO_VER : R/W ;bitpos:[27:16] ;default: 12'h111 ; */
/*description: */
#define HINF_SDIO_VER 0x00000FFF
#define HINF_SDIO_VER_M ((HINF_SDIO_VER_V)<<(HINF_SDIO_VER_S))
#define HINF_SDIO_VER_V 0xFFF
#define HINF_SDIO_VER_S 16
/* HINF_SDIO20_CONF0 : R/W ;bitpos:[15:12] ;default: 4'b0 ; */
/*description: */
#define HINF_SDIO20_CONF0 0x0000000F
#define HINF_SDIO20_CONF0_M ((HINF_SDIO20_CONF0_V)<<(HINF_SDIO20_CONF0_S))
#define HINF_SDIO20_CONF0_V 0xF
#define HINF_SDIO20_CONF0_S 12
/* HINF_IOENABLE1 : RO ;bitpos:[11] ;default: 1'b0 ; */
/*description: */
#define HINF_IOENABLE1 (BIT(11))
#define HINF_IOENABLE1_M (BIT(11))
#define HINF_IOENABLE1_V 0x1
#define HINF_IOENABLE1_S 11
/* HINF_EMP : RO ;bitpos:[10] ;default: 1'b0 ; */
/*description: */
#define HINF_EMP (BIT(10))
#define HINF_EMP_M (BIT(10))
#define HINF_EMP_V 0x1
#define HINF_EMP_S 10
/* HINF_FUNC1_EPS : RO ;bitpos:[9] ;default: 1'b0 ; */
/*description: */
#define HINF_FUNC1_EPS (BIT(9))
#define HINF_FUNC1_EPS_M (BIT(9))
#define HINF_FUNC1_EPS_V 0x1
#define HINF_FUNC1_EPS_S 9
/* HINF_CD_DISABLE : RO ;bitpos:[8] ;default: 1'b0 ; */
/*description: */
#define HINF_CD_DISABLE (BIT(8))
#define HINF_CD_DISABLE_M (BIT(8))
#define HINF_CD_DISABLE_V 0x1
#define HINF_CD_DISABLE_S 8
/* HINF_IOENABLE2 : RO ;bitpos:[7] ;default: 1'b0 ; */
/*description: */
#define HINF_IOENABLE2 (BIT(7))
#define HINF_IOENABLE2_M (BIT(7))
#define HINF_IOENABLE2_V 0x1
#define HINF_IOENABLE2_S 7
/* HINF_SDIO_INT_MASK : R/W ;bitpos:[6] ;default: 1'b0 ; */
/*description: */
#define HINF_SDIO_INT_MASK (BIT(6))
#define HINF_SDIO_INT_MASK_M (BIT(6))
#define HINF_SDIO_INT_MASK_V 0x1
#define HINF_SDIO_INT_MASK_S 6
/* HINF_SDIO_IOREADY2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
/*description: */
#define HINF_SDIO_IOREADY2 (BIT(5))
#define HINF_SDIO_IOREADY2_M (BIT(5))
#define HINF_SDIO_IOREADY2_V 0x1
#define HINF_SDIO_IOREADY2_S 5
/* HINF_SDIO_CD_ENABLE : R/W ;bitpos:[4] ;default: 1'b1 ; */
/*description: */
#define HINF_SDIO_CD_ENABLE (BIT(4))
#define HINF_SDIO_CD_ENABLE_M (BIT(4))
#define HINF_SDIO_CD_ENABLE_V 0x1
#define HINF_SDIO_CD_ENABLE_S 4
/* HINF_HIGHSPEED_MODE : RO ;bitpos:[3] ;default: 1'b0 ; */
/*description: */
#define HINF_HIGHSPEED_MODE (BIT(3))
#define HINF_HIGHSPEED_MODE_M (BIT(3))
#define HINF_HIGHSPEED_MODE_V 0x1
#define HINF_HIGHSPEED_MODE_S 3
/* HINF_HIGHSPEED_ENABLE : R/W ;bitpos:[2] ;default: 1'b0 ; */
/*description: */
#define HINF_HIGHSPEED_ENABLE (BIT(2))
#define HINF_HIGHSPEED_ENABLE_M (BIT(2))
#define HINF_HIGHSPEED_ENABLE_V 0x1
#define HINF_HIGHSPEED_ENABLE_S 2
/* HINF_SDIO_IOREADY1 : R/W ;bitpos:[1] ;default: 1'b0 ; */
/*description: */
#define HINF_SDIO_IOREADY1 (BIT(1))
#define HINF_SDIO_IOREADY1_M (BIT(1))
#define HINF_SDIO_IOREADY1_V 0x1
#define HINF_SDIO_IOREADY1_S 1
/* HINF_SDIO_ENABLE : R/W ;bitpos:[0] ;default: 1'b1 ; */
/*description: */
#define HINF_SDIO_ENABLE (BIT(0))
#define HINF_SDIO_ENABLE_M (BIT(0))
#define HINF_SDIO_ENABLE_V 0x1
#define HINF_SDIO_ENABLE_S 0
#define HINF_CFG_DATA7_REG (DR_REG_HINF_BASE + 0x1C)
/* HINF_SDIO_IOREADY0 : R/W ;bitpos:[17] ;default: 1'b1 ; */
/*description: */
#define HINF_SDIO_IOREADY0 (BIT(17))
#define HINF_SDIO_IOREADY0_M (BIT(17))
#define HINF_SDIO_IOREADY0_V 0x1
#define HINF_SDIO_IOREADY0_S 17
/* HINF_SDIO_RST : R/W ;bitpos:[16] ;default: 1'b0 ; */
/*description: */
#define HINF_SDIO_RST (BIT(16))
#define HINF_SDIO_RST_M (BIT(16))
#define HINF_SDIO_RST_V 0x1
#define HINF_SDIO_RST_S 16
/* HINF_CHIP_STATE : R/W ;bitpos:[15:8] ;default: 8'b0 ; */
/*description: */
#define HINF_CHIP_STATE 0x000000FF
#define HINF_CHIP_STATE_M ((HINF_CHIP_STATE_V)<<(HINF_CHIP_STATE_S))
#define HINF_CHIP_STATE_V 0xFF
#define HINF_CHIP_STATE_S 8
/* HINF_PIN_STATE : R/W ;bitpos:[7:0] ;default: 8'b0 ; */
/*description: */
#define HINF_PIN_STATE 0x000000FF
#define HINF_PIN_STATE_M ((HINF_PIN_STATE_V)<<(HINF_PIN_STATE_S))
#define HINF_PIN_STATE_V 0xFF
#define HINF_PIN_STATE_S 0
#define HINF_CIS_CONF0_REG (DR_REG_HINF_BASE + 0x20)
/* HINF_CIS_CONF_W0 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W0 0xFFFFFFFF
#define HINF_CIS_CONF_W0_M ((HINF_CIS_CONF_W0_V)<<(HINF_CIS_CONF_W0_S))
#define HINF_CIS_CONF_W0_V 0xFFFFFFFF
#define HINF_CIS_CONF_W0_S 0
#define HINF_CIS_CONF1_REG (DR_REG_HINF_BASE + 0x24)
/* HINF_CIS_CONF_W1 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W1 0xFFFFFFFF
#define HINF_CIS_CONF_W1_M ((HINF_CIS_CONF_W1_V)<<(HINF_CIS_CONF_W1_S))
#define HINF_CIS_CONF_W1_V 0xFFFFFFFF
#define HINF_CIS_CONF_W1_S 0
#define HINF_CIS_CONF2_REG (DR_REG_HINF_BASE + 0x28)
/* HINF_CIS_CONF_W2 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W2 0xFFFFFFFF
#define HINF_CIS_CONF_W2_M ((HINF_CIS_CONF_W2_V)<<(HINF_CIS_CONF_W2_S))
#define HINF_CIS_CONF_W2_V 0xFFFFFFFF
#define HINF_CIS_CONF_W2_S 0
#define HINF_CIS_CONF3_REG (DR_REG_HINF_BASE + 0x2C)
/* HINF_CIS_CONF_W3 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W3 0xFFFFFFFF
#define HINF_CIS_CONF_W3_M ((HINF_CIS_CONF_W3_V)<<(HINF_CIS_CONF_W3_S))
#define HINF_CIS_CONF_W3_V 0xFFFFFFFF
#define HINF_CIS_CONF_W3_S 0
#define HINF_CIS_CONF4_REG (DR_REG_HINF_BASE + 0x30)
/* HINF_CIS_CONF_W4 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W4 0xFFFFFFFF
#define HINF_CIS_CONF_W4_M ((HINF_CIS_CONF_W4_V)<<(HINF_CIS_CONF_W4_S))
#define HINF_CIS_CONF_W4_V 0xFFFFFFFF
#define HINF_CIS_CONF_W4_S 0
#define HINF_CIS_CONF5_REG (DR_REG_HINF_BASE + 0x34)
/* HINF_CIS_CONF_W5 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W5 0xFFFFFFFF
#define HINF_CIS_CONF_W5_M ((HINF_CIS_CONF_W5_V)<<(HINF_CIS_CONF_W5_S))
#define HINF_CIS_CONF_W5_V 0xFFFFFFFF
#define HINF_CIS_CONF_W5_S 0
#define HINF_CIS_CONF6_REG (DR_REG_HINF_BASE + 0x38)
/* HINF_CIS_CONF_W6 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W6 0xFFFFFFFF
#define HINF_CIS_CONF_W6_M ((HINF_CIS_CONF_W6_V)<<(HINF_CIS_CONF_W6_S))
#define HINF_CIS_CONF_W6_V 0xFFFFFFFF
#define HINF_CIS_CONF_W6_S 0
#define HINF_CIS_CONF7_REG (DR_REG_HINF_BASE + 0x3C)
/* HINF_CIS_CONF_W7 : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */
/*description: */
#define HINF_CIS_CONF_W7 0xFFFFFFFF
#define HINF_CIS_CONF_W7_M ((HINF_CIS_CONF_W7_V)<<(HINF_CIS_CONF_W7_S))
#define HINF_CIS_CONF_W7_V 0xFFFFFFFF
#define HINF_CIS_CONF_W7_S 0
#define HINF_CFG_DATA16_REG (DR_REG_HINF_BASE + 0x40)
/* HINF_DEVICE_ID_FN2 : R/W ;bitpos:[31:16] ;default: 16'h3333 ; */
/*description: */
#define HINF_DEVICE_ID_FN2 0x0000FFFF
#define HINF_DEVICE_ID_FN2_M ((HINF_DEVICE_ID_FN2_V)<<(HINF_DEVICE_ID_FN2_S))
#define HINF_DEVICE_ID_FN2_V 0xFFFF
#define HINF_DEVICE_ID_FN2_S 16
/* HINF_USER_ID_FN2 : R/W ;bitpos:[15:0] ;default: 16'h6666 ; */
/*description: */
#define HINF_USER_ID_FN2 0x0000FFFF
#define HINF_USER_ID_FN2_M ((HINF_USER_ID_FN2_V)<<(HINF_USER_ID_FN2_S))
#define HINF_USER_ID_FN2_V 0xFFFF
#define HINF_USER_ID_FN2_S 0
#define HINF_DATE_REG (DR_REG_HINF_BASE + 0xFC)
/* HINF_SDIO_DATE : R/W ;bitpos:[31:0] ;default: 32'h15030200 ; */
/*description: */
#define HINF_SDIO_DATE 0xFFFFFFFF
#define HINF_SDIO_DATE_M ((HINF_SDIO_DATE_V)<<(HINF_SDIO_DATE_S))
#define HINF_SDIO_DATE_V 0xFFFFFFFF
#define HINF_SDIO_DATE_S 0
#endif /*_SOC_HINF_REG_H_ */

View File

@ -1,134 +0,0 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SOC_HINF_STRUCT_H_
#define _SOC_HINF_STRUCT_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef volatile struct {
union {
struct {
uint32_t user_id_fn1: 16;
uint32_t device_id_fn1:16;
};
uint32_t val;
} cfg_data0;
union {
struct {
uint32_t sdio_enable: 1;
uint32_t sdio_ioready1: 1;
uint32_t highspeed_enable: 1;
uint32_t highspeed_mode: 1;
uint32_t sdio_cd_enable: 1;
uint32_t sdio_ioready2: 1;
uint32_t sdio_int_mask: 1;
uint32_t ioenable2: 1;
uint32_t cd_disable: 1;
uint32_t func1_eps: 1;
uint32_t emp: 1;
uint32_t ioenable1: 1;
uint32_t sdio20_conf0: 4;
uint32_t sdio_ver: 12;
uint32_t func2_eps: 1;
uint32_t sdio20_conf1: 3;
};
uint32_t val;
} cfg_data1;
uint32_t reserved_8;
uint32_t reserved_c;
uint32_t reserved_10;
uint32_t reserved_14;
uint32_t reserved_18;
union {
struct {
uint32_t pin_state: 8;
uint32_t chip_state: 8;
uint32_t sdio_rst: 1;
uint32_t sdio_ioready0: 1;
uint32_t reserved18: 14;
};
uint32_t val;
} cfg_data7;
uint32_t cis_conf0; /**/
uint32_t cis_conf1; /**/
uint32_t cis_conf2; /**/
uint32_t cis_conf3; /**/
uint32_t cis_conf4; /**/
uint32_t cis_conf5; /**/
uint32_t cis_conf6; /**/
uint32_t cis_conf7; /**/
union {
struct {
uint32_t user_id_fn2: 16;
uint32_t device_id_fn2:16;
};
uint32_t val;
} cfg_data16;
uint32_t reserved_44;
uint32_t reserved_48;
uint32_t reserved_4c;
uint32_t reserved_50;
uint32_t reserved_54;
uint32_t reserved_58;
uint32_t reserved_5c;
uint32_t reserved_60;
uint32_t reserved_64;
uint32_t reserved_68;
uint32_t reserved_6c;
uint32_t reserved_70;
uint32_t reserved_74;
uint32_t reserved_78;
uint32_t reserved_7c;
uint32_t reserved_80;
uint32_t reserved_84;
uint32_t reserved_88;
uint32_t reserved_8c;
uint32_t reserved_90;
uint32_t reserved_94;
uint32_t reserved_98;
uint32_t reserved_9c;
uint32_t reserved_a0;
uint32_t reserved_a4;
uint32_t reserved_a8;
uint32_t reserved_ac;
uint32_t reserved_b0;
uint32_t reserved_b4;
uint32_t reserved_b8;
uint32_t reserved_bc;
uint32_t reserved_c0;
uint32_t reserved_c4;
uint32_t reserved_c8;
uint32_t reserved_cc;
uint32_t reserved_d0;
uint32_t reserved_d4;
uint32_t reserved_d8;
uint32_t reserved_dc;
uint32_t reserved_e0;
uint32_t reserved_e4;
uint32_t reserved_e8;
uint32_t reserved_ec;
uint32_t reserved_f0;
uint32_t reserved_f4;
uint32_t reserved_f8;
uint32_t date; /**/
} hinf_dev_t;
extern hinf_dev_t HINF;
#ifdef __cplusplus
}
#endif
#endif /* _SOC_HINF_STRUCT_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,602 +0,0 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SOC_HOST_STRUCT_H_
#define _SOC_HOST_STRUCT_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef volatile struct {
uint32_t reserved_0;
uint32_t reserved_4;
uint32_t reserved_8;
uint32_t reserved_c;
uint32_t reserved_10;
uint32_t reserved_14;
uint32_t reserved_18;
uint32_t reserved_1c;
union {
struct {
uint32_t func1_mdstat: 1;
uint32_t reserved1: 31;
};
uint32_t val;
} func2_2;
uint32_t reserved_24;
uint32_t reserved_28;
uint32_t reserved_2c;
uint32_t reserved_30;
uint32_t gpio_status0; /**/
union {
struct {
uint32_t sdio_int1: 22;
uint32_t reserved22: 10;
};
uint32_t val;
} gpio_status1;
uint32_t gpio_in0; /**/
union {
struct {
uint32_t sdio_in1: 22;
uint32_t reserved22: 10;
};
uint32_t val;
} gpio_in1;
union {
struct {
uint32_t token0: 12;
uint32_t rx_pf_valid: 1;
uint32_t reserved13: 3;
uint32_t reg_token1: 12;
uint32_t rx_pf_eof: 4;
};
uint32_t val;
} slc0_token_rdata;
uint32_t slc0_pf; /**/
uint32_t reserved_4c;
union {
struct {
uint32_t tohost_bit0: 1;
uint32_t tohost_bit1: 1;
uint32_t tohost_bit2: 1;
uint32_t tohost_bit3: 1;
uint32_t tohost_bit4: 1;
uint32_t tohost_bit5: 1;
uint32_t tohost_bit6: 1;
uint32_t tohost_bit7: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t token0_0to1: 1;
uint32_t token1_0to1: 1;
uint32_t rx_sof: 1;
uint32_t rx_eof: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t rx_pf_valid: 1;
uint32_t ext_bit0: 1;
uint32_t ext_bit1: 1;
uint32_t ext_bit2: 1;
uint32_t ext_bit3: 1;
uint32_t rx_new_packet: 1;
uint32_t rd_retry: 1;
uint32_t gpio_sdio: 1;
uint32_t reserved26: 6;
};
uint32_t val;
} slc0_int_raw;
uint32_t reserved_54;
union {
struct {
uint32_t tohost_bit0: 1;
uint32_t tohost_bit1: 1;
uint32_t tohost_bit2: 1;
uint32_t tohost_bit3: 1;
uint32_t tohost_bit4: 1;
uint32_t tohost_bit5: 1;
uint32_t tohost_bit6: 1;
uint32_t tohost_bit7: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t token0_0to1: 1;
uint32_t token1_0to1: 1;
uint32_t rx_sof: 1;
uint32_t rx_eof: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t rx_pf_valid: 1;
uint32_t ext_bit0: 1;
uint32_t ext_bit1: 1;
uint32_t ext_bit2: 1;
uint32_t ext_bit3: 1;
uint32_t rx_new_packet: 1;
uint32_t rd_retry: 1;
uint32_t gpio_sdio: 1;
uint32_t reserved26: 6;
};
uint32_t val;
} slc0_int_st;
uint32_t reserved_5c;
union {
struct {
uint32_t reg_slc0_len: 20;
uint32_t reg_slc0_len_check:12;
};
uint32_t val;
} pkt_len;
union {
struct {
uint32_t state0: 8;
uint32_t state1: 8;
uint32_t state2: 8;
uint32_t state3: 8;
};
uint32_t val;
} state_w0;
union {
struct {
uint32_t state4: 8;
uint32_t state5: 8;
uint32_t state6: 8;
uint32_t state7: 8;
};
uint32_t val;
} state_w1;
union {
struct {
uint32_t conf0: 8;
uint32_t conf1: 8;
uint32_t conf2: 8;
uint32_t conf3: 8;
};
uint32_t val;
} conf_w0;
union {
struct {
uint32_t conf4: 8;
uint32_t conf5: 8;
uint32_t conf6: 8;
uint32_t conf7: 8;
};
uint32_t val;
} conf_w1;
union {
struct {
uint32_t conf8: 8;
uint32_t conf9: 8;
uint32_t conf10: 8;
uint32_t conf11: 8;
};
uint32_t val;
} conf_w2;
union {
struct {
uint32_t conf12: 8;
uint32_t conf13: 8;
uint32_t conf14: 8;
uint32_t conf15: 8;
};
uint32_t val;
} conf_w3;
union {
struct {
uint32_t conf16: 8; /*SLC timeout value*/
uint32_t conf17: 8; /*SLC timeout enable*/
uint32_t conf18: 8;
uint32_t conf19: 8; /*Interrupt to target CPU*/
};
uint32_t val;
} conf_w4;
union {
struct {
uint32_t conf20: 8;
uint32_t conf21: 8;
uint32_t conf22: 8;
uint32_t conf23: 8;
};
uint32_t val;
} conf_w5;
union {
struct {
uint32_t win_cmd: 16;
uint32_t reserved16: 16;
};
uint32_t val;
} win_cmd;
union {
struct {
uint32_t conf24: 8;
uint32_t conf25: 8;
uint32_t conf26: 8;
uint32_t conf27: 8;
};
uint32_t val;
} conf_w6;
union {
struct {
uint32_t conf28: 8;
uint32_t conf29: 8;
uint32_t conf30: 8;
uint32_t conf31: 8;
};
uint32_t val;
} conf_w7;
union {
struct {
uint32_t reg_slc0_len0: 20;
uint32_t reg_slc0_len0_check:12;
};
uint32_t val;
} pkt_len0;
union {
struct {
uint32_t reg_slc0_len1: 20;
uint32_t reg_slc0_len1_check:12;
};
uint32_t val;
} pkt_len1;
union {
struct {
uint32_t reg_slc0_len2: 20;
uint32_t reg_slc0_len2_check:12;
};
uint32_t val;
} pkt_len2;
union {
struct {
uint32_t conf32: 8;
uint32_t conf33: 8;
uint32_t conf34: 8;
uint32_t conf35: 8;
};
uint32_t val;
} conf_w8;
union {
struct {
uint32_t conf36: 8;
uint32_t conf37: 8;
uint32_t conf38: 8;
uint32_t conf39: 8;
};
uint32_t val;
} conf_w9;
union {
struct {
uint32_t conf40: 8;
uint32_t conf41: 8;
uint32_t conf42: 8;
uint32_t conf43: 8;
};
uint32_t val;
} conf_w10;
union {
struct {
uint32_t conf44: 8;
uint32_t conf45: 8;
uint32_t conf46: 8;
uint32_t conf47: 8;
};
uint32_t val;
} conf_w11;
union {
struct {
uint32_t conf48: 8;
uint32_t conf49: 8;
uint32_t conf50: 8;
uint32_t conf51: 8;
};
uint32_t val;
} conf_w12;
union {
struct {
uint32_t conf52: 8;
uint32_t conf53: 8;
uint32_t conf54: 8;
uint32_t conf55: 8;
};
uint32_t val;
} conf_w13;
union {
struct {
uint32_t conf56: 8;
uint32_t conf57: 8;
uint32_t conf58: 8;
uint32_t conf59: 8;
};
uint32_t val;
} conf_w14;
union {
struct {
uint32_t conf60: 8;
uint32_t conf61: 8;
uint32_t conf62: 8;
uint32_t conf63: 8;
};
uint32_t val;
} conf_w15;
uint32_t check_sum0; /**/
uint32_t check_sum1; /**/
uint32_t reserved_c4;
union {
struct {
uint32_t token0_wd: 12;
uint32_t reserved12: 4;
uint32_t token1_wd: 12;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_token_wdata;
uint32_t reserved_cc;
union {
struct {
uint32_t slc0_token0_dec: 1;
uint32_t slc0_token1_dec: 1;
uint32_t slc0_token0_wr: 1;
uint32_t slc0_token1_wr: 1;
uint32_t reserved4: 4;
uint32_t slc0_len_wr: 1;
uint32_t reserved9: 23;
};
uint32_t val;
} token_con;
union {
struct {
uint32_t tohost_bit0: 1;
uint32_t tohost_bit1: 1;
uint32_t tohost_bit2: 1;
uint32_t tohost_bit3: 1;
uint32_t tohost_bit4: 1;
uint32_t tohost_bit5: 1;
uint32_t tohost_bit6: 1;
uint32_t tohost_bit7: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t token0_0to1: 1;
uint32_t token1_0to1: 1;
uint32_t rx_sof: 1;
uint32_t rx_eof: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t rx_pf_valid: 1;
uint32_t ext_bit0: 1;
uint32_t ext_bit1: 1;
uint32_t ext_bit2: 1;
uint32_t ext_bit3: 1;
uint32_t rx_new_packet: 1;
uint32_t rd_retry: 1;
uint32_t gpio_sdio: 1;
uint32_t reserved26: 6;
};
uint32_t val;
} slc0_int_clr;
uint32_t reserved_d8;
union {
struct {
uint32_t tohost_bit0: 1;
uint32_t tohost_bit1: 1;
uint32_t tohost_bit2: 1;
uint32_t tohost_bit3: 1;
uint32_t tohost_bit4: 1;
uint32_t tohost_bit5: 1;
uint32_t tohost_bit6: 1;
uint32_t tohost_bit7: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t token0_0to1: 1;
uint32_t token1_0to1: 1;
uint32_t rx_sof: 1;
uint32_t rx_eof: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t rx_pf_valid: 1;
uint32_t ext_bit0: 1;
uint32_t ext_bit1: 1;
uint32_t ext_bit2: 1;
uint32_t ext_bit3: 1;
uint32_t rx_new_packet: 1;
uint32_t rd_retry: 1;
uint32_t gpio_sdio: 1;
uint32_t reserved26: 6;
};
uint32_t val;
} slc0_func1_int_ena;
uint32_t reserved_e0;
uint32_t reserved_e4;
uint32_t reserved_e8;
union {
struct {
uint32_t tohost_bit0: 1;
uint32_t tohost_bit1: 1;
uint32_t tohost_bit2: 1;
uint32_t tohost_bit3: 1;
uint32_t tohost_bit4: 1;
uint32_t tohost_bit5: 1;
uint32_t tohost_bit6: 1;
uint32_t tohost_bit7: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t token0_0to1: 1;
uint32_t token1_0to1: 1;
uint32_t rx_sof: 1;
uint32_t rx_eof: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t rx_pf_valid: 1;
uint32_t ext_bit0: 1;
uint32_t ext_bit1: 1;
uint32_t ext_bit2: 1;
uint32_t ext_bit3: 1;
uint32_t rx_new_packet: 1;
uint32_t rd_retry: 1;
uint32_t gpio_sdio: 1;
uint32_t reserved26: 6;
};
uint32_t val;
} slc0_int_ena;
uint32_t reserved_f0;
union {
struct {
uint32_t infor: 20;
uint32_t reserved20: 12;
};
uint32_t val;
} slc0_rx_infor;
uint32_t reserved_f8;
uint32_t slc0_len_wd; /**/
uint32_t apbwin_wdata; /**/
union {
struct {
uint32_t addr: 28;
uint32_t wr: 1;
uint32_t start: 1;
uint32_t bus: 1;
uint32_t reserved31: 1;
};
uint32_t val;
} apbwin_conf;
uint32_t apbwin_rdata; /**/
union {
struct {
uint32_t bit7_clraddr: 9;
uint32_t bit6_clraddr: 9;
uint32_t reserved18: 14;
};
uint32_t val;
} slc0_rdclr;
uint32_t reserved_110;
union {
struct {
uint32_t tohost_bit01: 1;
uint32_t tohost_bit11: 1;
uint32_t tohost_bit21: 1;
uint32_t tohost_bit31: 1;
uint32_t tohost_bit41: 1;
uint32_t tohost_bit51: 1;
uint32_t tohost_bit61: 1;
uint32_t tohost_bit71: 1;
uint32_t token0_1to01: 1;
uint32_t token1_1to01: 1;
uint32_t token0_0to11: 1;
uint32_t token1_0to11: 1;
uint32_t rx_sof1: 1;
uint32_t rx_eof1: 1;
uint32_t rx_start1: 1;
uint32_t tx_start1: 1;
uint32_t rx_udf1: 1;
uint32_t tx_ovf1: 1;
uint32_t rx_pf_valid1: 1;
uint32_t ext_bit01: 1;
uint32_t ext_bit11: 1;
uint32_t ext_bit21: 1;
uint32_t ext_bit31: 1;
uint32_t rx_new_packet1: 1;
uint32_t rd_retry1: 1;
uint32_t gpio_sdio1: 1;
uint32_t reserved26: 6;
};
uint32_t val;
} slc0_int_ena1;
uint32_t reserved_118;
uint32_t reserved_11c;
uint32_t reserved_120;
uint32_t reserved_124;
uint32_t reserved_128;
uint32_t reserved_12c;
uint32_t reserved_130;
uint32_t reserved_134;
uint32_t reserved_138;
uint32_t reserved_13c;
uint32_t reserved_140;
uint32_t reserved_144;
uint32_t reserved_148;
uint32_t reserved_14c;
uint32_t reserved_150;
uint32_t reserved_154;
uint32_t reserved_158;
uint32_t reserved_15c;
uint32_t reserved_160;
uint32_t reserved_164;
uint32_t reserved_168;
uint32_t reserved_16c;
uint32_t reserved_170;
uint32_t reserved_174;
uint32_t date; /**/
uint32_t id; /**/
uint32_t reserved_180;
uint32_t reserved_184;
uint32_t reserved_188;
uint32_t reserved_18c;
uint32_t reserved_190;
uint32_t reserved_194;
uint32_t reserved_198;
uint32_t reserved_19c;
uint32_t reserved_1a0;
uint32_t reserved_1a4;
uint32_t reserved_1a8;
uint32_t reserved_1ac;
uint32_t reserved_1b0;
uint32_t reserved_1b4;
uint32_t reserved_1b8;
uint32_t reserved_1bc;
uint32_t reserved_1c0;
uint32_t reserved_1c4;
uint32_t reserved_1c8;
uint32_t reserved_1cc;
uint32_t reserved_1d0;
uint32_t reserved_1d4;
uint32_t reserved_1d8;
uint32_t reserved_1dc;
uint32_t reserved_1e0;
uint32_t reserved_1e4;
uint32_t reserved_1e8;
uint32_t reserved_1ec;
union {
struct {
uint32_t frc_sdio11: 5;
uint32_t frc_sdio20: 5;
uint32_t frc_neg_samp: 5;
uint32_t frc_pos_samp: 5;
uint32_t frc_quick_in: 5;
uint32_t sdio20_int_delay: 1;
uint32_t sdio_pad_pullup: 1;
uint32_t hspeed_con_en: 1;
uint32_t reserved28: 4;
};
uint32_t val;
} conf;
union {
struct {
uint32_t sdio20_mode: 5;
uint32_t sdio_neg_samp: 5;
uint32_t sdio_quick_in: 5;
uint32_t reserved15: 17;
};
uint32_t val;
} inf_st;
} host_dev_t;
extern host_dev_t HOST;
#ifdef __cplusplus
}
#endif
#endif /* _SOC_HOST_STRUCT_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,588 +0,0 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SOC_SLC_STRUCT_H_
#define _SOC_SLC_STRUCT_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef volatile struct {
union {
struct {
uint32_t slc0_tx_rst: 1;
uint32_t slc0_rx_rst: 1;
uint32_t ahbm_fifo_rst: 1;
uint32_t ahbm_rst: 1;
uint32_t slc0_tx_loop_test: 1;
uint32_t slc0_rx_loop_test: 1;
uint32_t slc0_rx_auto_wrback: 1;
uint32_t slc0_rx_no_restart_clr: 1;
uint32_t slc0_rxdscr_burst_en: 1;
uint32_t slc0_rxdata_burst_en: 1;
uint32_t slc0_rxlink_auto_ret: 1;
uint32_t slc0_txlink_auto_ret: 1;
uint32_t slc0_txdscr_burst_en: 1;
uint32_t slc0_txdata_burst_en: 1;
uint32_t slc0_token_auto_clr: 1;
uint32_t slc0_token_sel: 1;
uint32_t reserved16: 2;
uint32_t slc0_wr_retry_mask_en: 1;
uint32_t reserved19: 13;
};
uint32_t val;
} conf0;
union {
struct {
uint32_t frhost_bit0: 1;
uint32_t frhost_bit1: 1;
uint32_t frhost_bit2: 1;
uint32_t frhost_bit3: 1;
uint32_t frhost_bit4: 1;
uint32_t frhost_bit5: 1;
uint32_t frhost_bit6: 1;
uint32_t frhost_bit7: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t tx_done: 1;
uint32_t tx_suc_eof: 1;
uint32_t rx_done: 1;
uint32_t rx_eof: 1;
uint32_t tohost: 1;
uint32_t tx_dscr_err: 1;
uint32_t rx_dscr_err: 1;
uint32_t tx_dscr_empty: 1;
uint32_t host_rd_ack: 1;
uint32_t wr_retry_done: 1;
uint32_t tx_err_eof: 1;
uint32_t cmd_dtc: 1;
uint32_t rx_quick_eof: 1;
uint32_t host_pop_eof_err: 1;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_int_raw;
union {
struct {
uint32_t frhost_bit0: 1;
uint32_t frhost_bit1: 1;
uint32_t frhost_bit2: 1;
uint32_t frhost_bit3: 1;
uint32_t frhost_bit4: 1;
uint32_t frhost_bit5: 1;
uint32_t frhost_bit6: 1;
uint32_t frhost_bit7: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t tx_done: 1;
uint32_t tx_suc_eof: 1;
uint32_t rx_done: 1;
uint32_t rx_eof: 1;
uint32_t tohost: 1;
uint32_t tx_dscr_err: 1;
uint32_t rx_dscr_err: 1;
uint32_t tx_dscr_empty: 1;
uint32_t host_rd_ack: 1;
uint32_t wr_retry_done: 1;
uint32_t tx_err_eof: 1;
uint32_t cmd_dtc: 1;
uint32_t rx_quick_eof: 1;
uint32_t host_pop_eof_err: 1;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_int_st;
union {
struct {
uint32_t frhost_bit0: 1;
uint32_t frhost_bit1: 1;
uint32_t frhost_bit2: 1;
uint32_t frhost_bit3: 1;
uint32_t frhost_bit4: 1;
uint32_t frhost_bit5: 1;
uint32_t frhost_bit6: 1;
uint32_t frhost_bit7: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t tx_done: 1;
uint32_t tx_suc_eof: 1;
uint32_t rx_done: 1;
uint32_t rx_eof: 1;
uint32_t tohost: 1;
uint32_t tx_dscr_err: 1;
uint32_t rx_dscr_err: 1;
uint32_t tx_dscr_empty: 1;
uint32_t host_rd_ack: 1;
uint32_t wr_retry_done: 1;
uint32_t tx_err_eof: 1;
uint32_t cmd_dtc: 1;
uint32_t rx_quick_eof: 1;
uint32_t host_pop_eof_err: 1;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_int_ena;
union {
struct {
uint32_t frhost_bit0: 1;
uint32_t frhost_bit1: 1;
uint32_t frhost_bit2: 1;
uint32_t frhost_bit3: 1;
uint32_t frhost_bit4: 1;
uint32_t frhost_bit5: 1;
uint32_t frhost_bit6: 1;
uint32_t frhost_bit7: 1;
uint32_t rx_start: 1;
uint32_t tx_start: 1;
uint32_t rx_udf: 1;
uint32_t tx_ovf: 1;
uint32_t token0_1to0: 1;
uint32_t token1_1to0: 1;
uint32_t tx_done: 1;
uint32_t tx_suc_eof: 1;
uint32_t rx_done: 1;
uint32_t rx_eof: 1;
uint32_t tohost: 1;
uint32_t tx_dscr_err: 1;
uint32_t rx_dscr_err: 1;
uint32_t tx_dscr_empty: 1;
uint32_t host_rd_ack: 1;
uint32_t wr_retry_done: 1;
uint32_t tx_err_eof: 1;
uint32_t cmd_dtc: 1;
uint32_t rx_quick_eof: 1;
uint32_t host_pop_eof_err: 1;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_int_clr;
uint32_t reserved_14;
uint32_t reserved_18;
uint32_t reserved_1c;
uint32_t reserved_20;
union {
struct {
uint32_t slc0_rx_full: 1;
uint32_t slc0_rx_empty: 1;
uint32_t slc0_rx_buf_len:12;
uint32_t reserved14: 18;
};
uint32_t val;
} rx_status;
union {
struct {
uint32_t rxfifo_wdata: 9;
uint32_t reserved9: 7;
uint32_t rxfifo_push: 1;
uint32_t reserved17: 15;
};
uint32_t val;
} slc0_rxfifo_push;
uint32_t reserved_2c;
union {
struct {
uint32_t slc0_tx_full: 1;
uint32_t slc0_tx_empty: 1;
uint32_t reserved2: 30;
};
uint32_t val;
} tx_status;
union {
struct {
uint32_t txfifo_rdata: 11;
uint32_t reserved11: 5;
uint32_t txfifo_pop: 1;
uint32_t reserved17: 15;
};
uint32_t val;
} slc0_txfifo_pop;
uint32_t reserved_38;
union {
struct {
uint32_t addr: 20;
uint32_t reserved20: 8;
uint32_t stop: 1;
uint32_t start: 1;
uint32_t restart: 1;
uint32_t park: 1;
};
uint32_t val;
} slc0_rx_link;
union {
struct {
uint32_t addr: 20;
uint32_t reserved20: 8;
uint32_t stop: 1;
uint32_t start: 1;
uint32_t restart: 1;
uint32_t park: 1;
};
uint32_t val;
} slc0_tx_link;
uint32_t reserved_44;
uint32_t reserved_48;
union {
struct {
uint32_t slc0_intvec: 8;
uint32_t reserved8: 24;
};
uint32_t val;
} intvec_tohost;
union {
struct {
uint32_t wdata: 12;
uint32_t wr: 1;
uint32_t inc: 1;
uint32_t inc_more: 1;
uint32_t reserved15: 1;
uint32_t token0: 12;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_token0;
union {
struct {
uint32_t wdata: 12;
uint32_t wr: 1;
uint32_t inc: 1;
uint32_t inc_more: 1;
uint32_t reserved15: 1;
uint32_t token1: 12;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_token1;
uint32_t reserved_58;
uint32_t reserved_5c;
union {
struct {
uint32_t slc0_check_owner: 1;
uint32_t slc0_tx_check_sum_en: 1;
uint32_t slc0_rx_check_sum_en: 1;
uint32_t cmd_hold_en: 1;
uint32_t slc0_len_auto_clr: 1;
uint32_t slc0_tx_stitch_en: 1;
uint32_t slc0_rx_stitch_en: 1;
uint32_t reserved7: 12;
uint32_t host_int_level_sel: 1;
uint32_t reserved20: 2;
uint32_t clk_en: 1;
uint32_t reserved23: 9;
};
uint32_t val;
} conf1;
uint32_t slc0_state0; /**/
uint32_t slc0_state1; /**/
uint32_t reserved_6c;
uint32_t reserved_70;
union {
struct {
uint32_t txeof_ena: 6;
uint32_t reserved6: 2;
uint32_t fifo_map_ena: 4;
uint32_t slc0_tx_dummy_mode: 1;
uint32_t hda_map_128k: 1;
uint32_t reserved14: 2;
uint32_t tx_push_idle_num: 16;
};
uint32_t val;
} bridge_conf;
uint32_t slc0_to_eof_des_addr; /**/
uint32_t slc0_tx_eof_des_addr; /**/
uint32_t slc0_to_eof_bfr_des_addr; /**/
uint32_t reserved_84;
uint32_t reserved_88;
uint32_t reserved_8c;
union {
struct {
uint32_t mode: 3;
uint32_t reserved3: 1;
uint32_t addr: 2;
uint32_t reserved6: 26;
};
uint32_t val;
} ahb_test;
union {
struct {
uint32_t cmd_st: 3;
uint32_t reserved3: 1;
uint32_t func_st: 4;
uint32_t sdio_wakeup: 1;
uint32_t reserved9: 3;
uint32_t bus_st: 3;
uint32_t reserved15: 1;
uint32_t func1_acc_state: 5;
uint32_t reserved21: 11;
};
uint32_t val;
} sdio_st;
union {
struct {
uint32_t slc0_token_no_replace: 1;
uint32_t slc0_infor_no_replace: 1;
uint32_t slc0_rx_fill_mode: 1;
uint32_t slc0_rx_eof_mode: 1;
uint32_t slc0_rx_fill_en: 1;
uint32_t slc0_rd_retry_threshold:11;
uint32_t reserved16: 16;
};
uint32_t val;
} rx_dscr_conf;
uint32_t slc0_txlink_dscr; /**/
uint32_t slc0_txlink_dscr_bf0; /**/
uint32_t slc0_txlink_dscr_bf1; /**/
uint32_t slc0_rxlink_dscr; /**/
uint32_t slc0_rxlink_dscr_bf0; /**/
uint32_t slc0_rxlink_dscr_bf1; /**/
uint32_t reserved_b4;
uint32_t reserved_b8;
uint32_t reserved_bc;
uint32_t reserved_c0;
uint32_t reserved_c4;
uint32_t reserved_c8;
uint32_t slc0_tx_erreof_des_addr; /**/
uint32_t reserved_d0;
union {
struct {
uint32_t slc0_token:12;
uint32_t reserved12:20;
};
uint32_t val;
} token_lat;
union {
struct {
uint32_t wr_retry_threshold:11;
uint32_t reserved11: 21;
};
uint32_t val;
} tx_dscr_conf;
uint32_t cmd_infor0; /**/
uint32_t cmd_infor1; /**/
union {
struct {
uint32_t len_wdata: 20;
uint32_t len_wr: 1;
uint32_t len_inc: 1;
uint32_t len_inc_more: 1;
uint32_t rx_packet_load_en: 1;
uint32_t tx_packet_load_en: 1;
uint32_t rx_get_used_dscr: 1;
uint32_t tx_get_used_dscr: 1;
uint32_t rx_new_pkt_ind: 1;
uint32_t tx_new_pkt_ind: 1;
uint32_t reserved29: 3;
};
uint32_t val;
} slc0_len_conf;
union {
struct {
uint32_t len: 20;
uint32_t reserved20:12;
};
uint32_t val;
} slc0_length;
uint32_t slc0_txpkt_h_dscr; /**/
uint32_t slc0_txpkt_e_dscr; /**/
uint32_t slc0_rxpkt_h_dscr; /**/
uint32_t slc0_rxpkt_e_dscr; /**/
uint32_t slc0_txpktu_h_dscr; /**/
uint32_t slc0_txpktu_e_dscr; /**/
uint32_t slc0_rxpktu_h_dscr; /**/
uint32_t slc0_rxpktu_e_dscr; /**/
uint32_t reserved_10c;
uint32_t reserved_110;
union {
struct {
uint32_t slc0_position: 8;
uint32_t reserved8: 24;
};
uint32_t val;
} seq_position;
union {
struct {
uint32_t rx_dscr_rec_lim: 10;
uint32_t reserved10: 22;
};
uint32_t val;
} slc0_dscr_rec_conf;
union {
struct {
uint32_t dat0_crc_err_cnt: 8;
uint32_t dat1_crc_err_cnt: 8;
uint32_t dat2_crc_err_cnt: 8;
uint32_t dat3_crc_err_cnt: 8;
};
uint32_t val;
} sdio_crc_st0;
union {
struct {
uint32_t cmd_crc_err_cnt: 8;
uint32_t reserved8: 23;
uint32_t err_cnt_clr: 1;
};
uint32_t val;
} sdio_crc_st1;
uint32_t slc0_eof_start_des; /**/
uint32_t slc0_push_dscr_addr; /**/
uint32_t slc0_done_dscr_addr; /**/
uint32_t slc0_sub_start_des; /**/
union {
struct {
uint32_t rx_dscr_cnt_lat: 10;
uint32_t reserved10: 6;
uint32_t rx_get_eof_occ: 1;
uint32_t reserved17: 15;
};
uint32_t val;
} slc0_dscr_cnt;
union {
struct {
uint32_t len_lim: 20;
uint32_t reserved20: 12;
};
uint32_t val;
} slc0_len_lim_conf;
union {
struct {
uint32_t frhost_bit01: 1;
uint32_t frhost_bit11: 1;
uint32_t frhost_bit21: 1;
uint32_t frhost_bit31: 1;
uint32_t frhost_bit41: 1;
uint32_t frhost_bit51: 1;
uint32_t frhost_bit61: 1;
uint32_t frhost_bit71: 1;
uint32_t rx_start1: 1;
uint32_t tx_start1: 1;
uint32_t rx_udf1: 1;
uint32_t tx_ovf1: 1;
uint32_t token0_1to01: 1;
uint32_t token1_1to01: 1;
uint32_t tx_done1: 1;
uint32_t tx_suc_eof1: 1;
uint32_t rx_done1: 1;
uint32_t rx_eof1: 1;
uint32_t tohost1: 1;
uint32_t tx_dscr_err1: 1;
uint32_t rx_dscr_err1: 1;
uint32_t tx_dscr_empty1: 1;
uint32_t host_rd_ack1: 1;
uint32_t wr_retry_done1: 1;
uint32_t tx_err_eof1: 1;
uint32_t cmd_dtc1: 1;
uint32_t rx_quick_eof1: 1;
uint32_t host_pop_eof_err1: 1;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_int_st1;
union {
struct {
uint32_t frhost_bit01: 1;
uint32_t frhost_bit11: 1;
uint32_t frhost_bit21: 1;
uint32_t frhost_bit31: 1;
uint32_t frhost_bit41: 1;
uint32_t frhost_bit51: 1;
uint32_t frhost_bit61: 1;
uint32_t frhost_bit71: 1;
uint32_t rx_start1: 1;
uint32_t tx_start1: 1;
uint32_t rx_udf1: 1;
uint32_t tx_ovf1: 1;
uint32_t token0_1to01: 1;
uint32_t token1_1to01: 1;
uint32_t tx_done1: 1;
uint32_t tx_suc_eof1: 1;
uint32_t rx_done1: 1;
uint32_t rx_eof1: 1;
uint32_t tohost1: 1;
uint32_t tx_dscr_err1: 1;
uint32_t rx_dscr_err1: 1;
uint32_t tx_dscr_empty1: 1;
uint32_t host_rd_ack1: 1;
uint32_t wr_retry_done1: 1;
uint32_t tx_err_eof1: 1;
uint32_t cmd_dtc1: 1;
uint32_t rx_quick_eof1: 1;
uint32_t host_pop_eof_err1: 1;
uint32_t reserved28: 4;
};
uint32_t val;
} slc0_int_ena1;
uint32_t reserved_144;
uint32_t reserved_148;
uint32_t reserved_14c;
uint32_t reserved_150;
uint32_t reserved_154;
uint32_t reserved_158;
uint32_t reserved_15c;
uint32_t reserved_160;
uint32_t reserved_164;
uint32_t reserved_168;
uint32_t reserved_16c;
uint32_t reserved_170;
uint32_t reserved_174;
uint32_t reserved_178;
uint32_t reserved_17c;
uint32_t reserved_180;
uint32_t reserved_184;
uint32_t reserved_188;
uint32_t reserved_18c;
uint32_t reserved_190;
uint32_t reserved_194;
uint32_t reserved_198;
uint32_t reserved_19c;
uint32_t reserved_1a0;
uint32_t reserved_1a4;
uint32_t reserved_1a8;
uint32_t reserved_1ac;
uint32_t reserved_1b0;
uint32_t reserved_1b4;
uint32_t reserved_1b8;
uint32_t reserved_1bc;
uint32_t reserved_1c0;
uint32_t reserved_1c4;
uint32_t reserved_1c8;
uint32_t reserved_1cc;
uint32_t reserved_1d0;
uint32_t reserved_1d4;
uint32_t reserved_1d8;
uint32_t reserved_1dc;
uint32_t reserved_1e0;
uint32_t reserved_1e4;
uint32_t reserved_1e8;
uint32_t reserved_1ec;
uint32_t reserved_1f0;
uint32_t reserved_1f4;
uint32_t date; /**/
uint32_t id; /**/
} slc_dev_t;
extern slc_dev_t SLC;
#ifdef __cplusplus
}
#endif
#endif /* _SOC_SLC_STRUCT_H_ */

View File

@ -56,3 +56,4 @@
// Only SPI1 supports this feature
#define SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT(host_id) ((host_id) == 0)
#define SOC_MEMSPI_IS_INDEPENDENT 1

View File

@ -15,7 +15,7 @@
#pragma once
/**
* @file i2c_apll.h
* @file i2c_bbpll.h
* @brief Register definitions for digital PLL (BBPLL)
*
* This file lists register fields of BBPLL, located on an internal configuration
@ -146,9 +146,9 @@
#define I2C_BBPLL_OR_LOCK_MSB 7
#define I2C_BBPLL_OR_LOCK_LSB 7
#define I2C_BBPLL_BBADC_DELAY1 9
#define I2C_BBPLL_BBADC_DELAY1_MSB 1
#define I2C_BBPLL_BBADC_DELAY1_LSB 0
#define I2C_BBPLL_OC_VCO_DBIAS 9
#define I2C_BBPLL_OC_VCO_DBIAS_MSB 1
#define I2C_BBPLL_OC_VCO_DBIAS_LSB 0
#define I2C_BBPLL_BBADC_DELAY2 9
#define I2C_BBPLL_BBADC_DELAY2_MSB 3

View File

@ -60,7 +60,6 @@ extern "C" {
#define CACHE_DROM_MMU_MAX_END 0x400
#define MMU_SIZE 0x800
#define ICACHE_MMU_SIZE 0x800
#define DCACHE_MMU_SIZE 0x800

View File

@ -22,7 +22,6 @@ extern "C" {
#define SOC_GPIO_PORT (1)
#define GPIO_PIN_COUNT (48)
// On ESP32 those PADs which have RTC functions must set pullup/down/capability via RTC register.
// On ESP32-S3, Digital IOs have their own registers to control pullup/down/capability, independent with RTC registers.
#define GPIO_SUPPORTS_RTC_INDEPENDENT (1)
// Force hold is a new function of ESP32-S3
@ -40,6 +39,9 @@ extern "C" {
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 46)) /*!< Check whether it can be a valid GPIO number of output mode */
#define GPIO_MASK_CONTAIN_INPUT_GPIO(gpio_mask) ((gpio_mask & (GPIO_SEL_46))) /*!< Check whether it contains input io */
#define GPIO_MATRIX_CONST_ONE_INPUT (0x38)
#define GPIO_MATRIX_CONST_ZERO_INPUT (0x3C)
#ifdef __cplusplus
}
#endif

View File

@ -431,3 +431,4 @@
#define RX_STATUS_IDX 248
#define CLK_GPIO_IDX 249
#define NBT_BLE_IDX 250
#define SIG_GPIO_OUT_IDX 256

View File

@ -80,15 +80,7 @@ typedef enum {
ETS_UHCI0_INTR_SOURCE, /**< interrupt of UHCI0, level*/
ETS_UHCI1_INTR_SOURCE, /**< interrupt of UHCI1, level*/
ETS_TG0_T0_LEVEL_INTR_SOURCE = 16, /**< interrupt of TIMER_GROUP0, TIMER0, level, we would like use EDGE for timer if permission*/
ETS_TG0_T1_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, TIMER1, level, we would like use EDGE for timer if permission*/
ETS_TG0_WDT_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, WATCHDOG, level*/
ETS_TG0_LACT_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, LACT, level*/
ETS_TG1_T0_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, TIMER0, level, we would like use EDGE for timer if permission*/
ETS_TG1_T1_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, TIMER1, level, we would like use EDGE for timer if permission*/
ETS_TG1_WDT_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, WATCHDOG, level*/
ETS_TG1_LACT_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, LACT, level*/
ETS_GPIO_INTR_SOURCE, /**< interrupt of GPIO, level*/
ETS_GPIO_INTR_SOURCE = 16, /**< interrupt of GPIO, level*/
ETS_GPIO_NMI_SOURCE, /**< interrupt of GPIO, NMI*/
ETS_GPIO_INTR_SOURCE2, /**< interrupt of GPIO, level*/
ETS_GPIO_NMI_SOURCE2, /**< interrupt of GPIO, NMI*/
@ -96,8 +88,7 @@ typedef enum {
ETS_SPI2_INTR_SOURCE, /**< interrupt of SPI2, level*/
ETS_SPI3_INTR_SOURCE, /**< interrupt of SPI3, level*/
ETS_SPI4_INTR_SOURCE, /**< interrupt of SPI4, level*/
ETS_LCD_CAM_INTR_SOURCE = 32, /**< interrupt of LCD camera, level*/
ETS_LCD_CAM_INTR_SOURCE, /**< interrupt of LCD camera, level*/
ETS_I2S0_INTR_SOURCE, /**< interrupt of I2S0, level*/
ETS_I2S1_INTR_SOURCE, /**< interrupt of I2S1, level*/
ETS_UART0_INTR_SOURCE, /**< interrupt of UART0, level*/
@ -105,16 +96,16 @@ typedef enum {
ETS_UART2_INTR_SOURCE, /**< interrupt of UART2, level*/
ETS_SDIO_HOST_INTR_SOURCE, /**< interrupt of SD/SDIO/MMC HOST, level*/
ETS_PWM0_INTR_SOURCE, /**< interrupt of PWM0, level, Reserved*/
ETS_PWM1_INTR_SOURCE, /**< interrupt of PWM1, level, Reserved*/
ETS_PWM1_INTR_SOURCE = 32, /**< interrupt of PWM1, level, Reserved*/
ETS_PWM2_INTR_SOURCE, /**< interrupt of PWM2, level*/
ETS_PWM3_INTR_SOURCE, /**< interruot of PWM3, level*/
ETS_LEDC_INTR_SOURCE, /**< interrupt of LED PWM, level*/
ETS_EFUSE_INTR_SOURCE, /**< interrupt of efuse, level, not likely to use*/
ETS_TWAI_INTR_SOURCE, /**< interrupt of TWAI, level*/
ETS_TWAI_INTR_SOURCE , /**< interrupt of can, level*/
ETS_USB_INTR_SOURCE, /**< interrupt of USB, level*/
ETS_RTC_CORE_INTR_SOURCE, /**< interrupt of rtc core, level, include rtc watchdog*/
ETS_RMT_INTR_SOURCE = 48, /**< interrupt of remote controller, level*/
ETS_RMT_INTR_SOURCE, /**< interrupt of remote controller, level*/
ETS_PCNT_INTR_SOURCE, /**< interrupt of pluse count, level*/
ETS_I2C_EXT0_INTR_SOURCE, /**< interrupt of I2C controller1, level*/
ETS_I2C_EXT1_INTR_SOURCE, /**< interrupt of I2C controller0, level*/
@ -122,17 +113,15 @@ typedef enum {
ETS_SPI3_DMA_INTR_SOURCE, /**< interrupt of SPI3 DMA, level*/
ETS_SPI4_DMA_INTR_SOURCE, /**< interrupt of SPI4 DMA, level*/
ETS_WDT_INTR_SOURCE, /**< will be cancelled*/
ETS_TIMER1_INTR_SOURCE, /**< will be cancelled*/
ETS_TIMER2_INTR_SOURCE, /**< will be cancelled*/
ETS_TG0_T0_EDGE_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, TIMER0, EDGE*/
ETS_TG0_T1_EDGE_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, TIMER1, EDGE*/
ETS_TG0_WDT_EDGE_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, WATCH DOG, EDGE*/
ETS_TG0_LACT_EDGE_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, LACT, EDGE*/
ETS_TG1_T0_EDGE_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, TIMER0, EDGE*/
ETS_TG1_T1_EDGE_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, TIMER1, EDGE*/
ETS_TG1_WDT_EDGE_INTR_SOURCE = 64, /**< interrupt of TIMER_GROUP1, WATCHDOG, EDGE*/
ETS_TG1_LACT_EDGE_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, LACT, EDGE*/
ETS_TIMER1_INTR_SOURCE = 48,
ETS_TIMER2_INTR_SOURCE,
ETS_TG0_T0_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, TIMER0, EDGE*/
ETS_TG0_T1_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, TIMER1, EDGE*/
ETS_TG0_WDT_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP0, WATCH DOG, EDGE*/
ETS_TG1_T0_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, TIMER0, EDGE*/
ETS_TG1_T1_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, TIMER1, EDGE*/
ETS_TG1_WDT_LEVEL_INTR_SOURCE, /**< interrupt of TIMER_GROUP1, WATCHDOG, EDGE*/
ETS_CACHE_IA_INTR_SOURCE, /**< interrupt of Cache Invalied Access, LEVEL*/
ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE, /**< interrupt of system timer 0, EDGE*/
ETS_SYSTIMER_TARGET1_EDGE_INTR_SOURCE, /**< interrupt of system timer 1, EDGE*/
@ -143,23 +132,32 @@ typedef enum {
ETS_DCACHE_SYNC0_INTR_SOURCE, /**< interrupt of data cache sync done, LEVEL*/
ETS_ICACHE_SYNC0_INTR_SOURCE, /**< interrupt of instruction cache sync done, LEVEL*/
ETS_APB_ADC_INTR_SOURCE, /**< interrupt of APB ADC, LEVEL*/
ETS_CRYPTO_DMA_INTR_SOURCE, /**< interrupt of encrypted DMA, LEVEL*/
ETS_RSA_INTR_SOURCE, /**< interrupt of RSA accelerator, level*/
ETS_SHA_INTR_SOURCE, /**< interrupt of SHA accelerator, level*/
ETS_AES_INTR_SOURCE, /**< interrupt of AES accelerator, level*/
ETS_FROM_CPU_INTR0_SOURCE = 80, /**< interrupt0 generated from a CPU, level*/ /* Used for FreeRTOS */
ETS_CRYPTO_DMA_INTR_SOURCE = 66, /**< interrupt of encrypted DMA, LEVEL*/
ETS_CRYPTO_DMA1_INTR_SOURCE,
ETS_CRYPTO_DMA2_INTR_SOURCE,
ETS_CRYPTO_DMA3_INTR_SOURCE,
ETS_CRYPTO_DMA4_INTR_SOURCE,
ETS_RSA_INTR_SOURCE, /**< interrupt of RSA accelerator, level*/
ETS_AES_INTR_SOURCE, /**< interrupt of AES accelerator, level*/
ETS_SHA_INTR_SOURCE, /**< interrupt of SHA accelerator, level*/
ETS_FROM_CPU_INTR0_SOURCE, /**< interrupt0 generated from a CPU, level*/ /* Used for FreeRTOS */
ETS_FROM_CPU_INTR1_SOURCE, /**< interrupt1 generated from a CPU, level*/ /* Used for FreeRTOS */
ETS_FROM_CPU_INTR2_SOURCE, /**< interrupt2 generated from a CPU, level*/ /* Used for DPORT Access */
ETS_FROM_CPU_INTR3_SOURCE, /**< interrupt3 generated from a CPU, level*/ /* Used for DPORT Access */
ETS_DMA_COPY_INTR_SOURCE, /**< interrupt of DMA copy, LEVEL*/
ETS_ASSIST_DEBUG_INTR_SOURCE, /**< interrupt of Assist debug module, LEVEL*/
ETS_DEDICATED_GPIO_INTR_SOURCE, /**< interrupt of dedicated GPIO, level*/
ETS_DCACHE_PRELOAD1_INTR_SOURCE, /**< interrupt of DCache preload operation, LEVEL*/
ETS_ICACHE_PRELOAD1_INTR_SOURCE, /**< interrupt of ICache perload operation, LEVEL*/
ETS_DCACHE_SYNC1_INTR_SOURCE, /**< interrupt of data cache sync done, LEVEL*/
ETS_ICACHE_SYNC1_INTR_SOURCE, /**< interrupt of instruction cache sync done, LEVEL*/
ETS_DMA_APBPERI_PMS_INTR_SOURCE,
ETS_CORE0_IRAM0_PMS_INTR_SOURCE,
ETS_CORE0_DRAM0_PMS_INTR_SOURCE,
ETS_CORE0_PIF_PMS_INTR_SOURCE,
ETS_CORE0_PIF_PMS_SIZE_INTR_SOURCE,
ETS_CORE1_IRAM0_PMS_INTR_SOURCE,
ETS_CORE1_DRAM0_PMS_INTR_SOURCE,
ETS_CORE1_PIF_PMS_INTR_SOURCE = 86,
ETS_CORE1_PIF_PMS_SIZE_INTR_SOURCE,
ETS_CACHE_CORE0_ACS_INTR_SOURCE,
ETS_CACHE_CORE1_ACS_INTR_SOURCE,
ETS_MAX_INTR_SOURCE, /**< number of interrupt sources */
} periph_interrput_t;

View File

@ -295,6 +295,40 @@ typedef volatile struct {
extern rmt_dev_t RMT;
typedef struct {
union {
struct {
uint32_t duration0 :15;
uint32_t level0 :1;
uint32_t duration1 :15;
uint32_t level1 :1;
};
uint32_t val;
};
} rmt_item32_t;
typedef struct {
union {
struct {
uint16_t duration :15;
uint16_t level :1;
};
uint16_t val;
};
} rmt_item16_t;
//Allow access to RMT memory using RMTMEM.chan[0].data32[8]
typedef volatile struct {
struct {
union {
rmt_item32_t data32[64];
rmt_item16_t data16[128];
};
} chan[4];
} rmt_mem_t;
extern rmt_mem_t RMTMEM;
#ifdef __cplusplus
}
#endif

View File

@ -68,14 +68,14 @@ extern "C" {
* RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values.
* Valid if RTC_CNTL_DBG_ATTEN is 0.
*/
#define RTC_CNTL_DBIAS_0V90 0
#define RTC_CNTL_DBIAS_0V95 1
#define RTC_CNTL_DBIAS_1V00 2
#define RTC_CNTL_DBIAS_1V05 3
#define RTC_CNTL_DBIAS_1V10 4
#define RTC_CNTL_DBIAS_1V15 5
#define RTC_CNTL_DBIAS_1V20 6
#define RTC_CNTL_DBIAS_1V25 7
#define RTC_CNTL_DBIAS_0V90 0 //voltage is about 0.68v in fact
#define RTC_CNTL_DBIAS_0V95 13
#define RTC_CNTL_DBIAS_1V00 16
#define RTC_CNTL_DBIAS_1V05 18
#define RTC_CNTL_DBIAS_1V10 20
#define RTC_CNTL_DBIAS_1V15 22
#define RTC_CNTL_DBIAS_1V20 24
#define RTC_CNTL_DBIAS_1V25 31 //voltage is about 1.34v in fact
#define DELAY_FAST_CLK_SWITCH 3
#define DELAY_SLOW_CLK_SWITCH 300
@ -102,9 +102,9 @@ extern "C" {
#define RTC_CNTL_PLL_BUF_WAIT_DEFAULT 20
#define RTC_CNTL_XTL_BUF_WAIT_DEFAULT 100
#define RTC_CNTL_CK8M_WAIT_DEFAULT 20
#define RTC_CK8M_ENABLE_WAIT_DEFAULT 1
#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 172
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
#define RTC_CNTL_SCK_DCAP_DEFAULT 255
/*
@ -118,25 +118,13 @@ set sleep_init default param
#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0
#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
#define APLL_SDM_STOP_VAL_1 0x09
#define APLL_SDM_STOP_VAL_2_REV0 0x69
#define APLL_SDM_STOP_VAL_2_REV1 0x49
#define APLL_CAL_DELAY_1 0x0f
#define APLL_CAL_DELAY_2 0x3f
#define APLL_CAL_DELAY_3 0x1f
#define i2c_ulp_block 0x61
#define i2c_ulp_hostid 0x1
#define i2c_ulp_ir_resetb 0
#define i2c_ulp_ir_resetb_msb 0
#define i2c_ulp_ir_resetb_lsb 0
/**
* @brief Possible main XTAL frequency values.
*
* Enum values should be equal to frequency in MHz.
*/
typedef enum {
RTC_XTAL_FREQ_32M = 32,
RTC_XTAL_FREQ_40M = 40, //!< 40 MHz XTAL
} rtc_xtal_freq_t;
@ -250,28 +238,6 @@ typedef struct {
.dbuf = 1, \
}
#if 0
#define X32K_CONFIG_BOOTSTRAP_DEFAULT() { \
.dac = 3, \
.dres = 3, \
.dgm = 0, \
}
typedef struct {
x32k_config_t x32k_cfg;
uint32_t bt_lpck_div_num : 12;
uint32_t bt_lpck_div_a : 12;
uint32_t bt_lpck_div_b : 12;
} x32k_bootstrap_config_t;
#define X32K_BOOTSTRAP_CONFIG_DEFAULT() { \
.x32k_cfg = X32K_CONFIG_BOOTSTRAP_DEFAULT(), \
.bt_lpck_div_num = 2441, \
.bt_lpck_div_a = 32, \
.bt_lpck_div_b = 13, \
}
#endif
typedef struct {
uint16_t wifi_powerup_cycles : 7;
uint16_t wifi_wait_cycles : 9;
@ -634,10 +600,10 @@ typedef struct {
uint32_t wifi_pd_en : 1; //!< power down WiFi
uint32_t deep_slp : 1; //!< power down digital domain
uint32_t wdt_flashboot_mod_en : 1; //!< enable WDT flashboot mode
uint32_t dig_dbias_wak : 3; //!< set bias for digital domain, in active mode
uint32_t dig_dbias_slp : 3; //!< set bias for digital domain, in sleep mode
uint32_t rtc_dbias_wak : 3; //!< set bias for RTC domain, in active mode
uint32_t rtc_dbias_slp : 3; //!< set bias for RTC domain, in sleep mode
uint32_t dig_dbias_wak : 5; //!< set bias for digital domain, in active mode
uint32_t dig_dbias_slp : 5; //!< set bias for digital domain, in sleep mode
uint32_t rtc_dbias_wak : 5; //!< set bias for RTC domain, in active mode
uint32_t rtc_dbias_slp : 5; //!< set bias for RTC domain, in sleep mode
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
uint32_t deep_slp_reject : 1;
uint32_t light_slp_reject : 1;
@ -661,9 +627,9 @@ typedef struct {
.deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \
.wdt_flashboot_mod_en = 0, \
.dig_dbias_wak = RTC_CNTL_DIG_DBIAS_1V10, \
.dig_dbias_slp = RTC_CNTL_DIG_DBIAS_0V90, \
.dig_dbias_slp = RTC_CNTL_DIG_DBIAS_0V95, \
.rtc_dbias_wak = RTC_CNTL_DBIAS_1V10, \
.rtc_dbias_slp = RTC_CNTL_DBIAS_1V00, \
.rtc_dbias_slp = RTC_CNTL_DBIAS_0V95, \
.vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \
.deep_slp_reject = 1, \
.light_slp_reject = 1 \
@ -757,6 +723,7 @@ typedef struct {
uint32_t xtal_fpu : 1;
uint32_t bbpll_fpu : 1;
uint32_t cpu_waiti_clk_gate : 1;
uint32_t cali_ocode : 1; //!< Calibrate Ocode to make bangap voltage more precise.
} rtc_config_t;
/**
@ -774,7 +741,8 @@ typedef struct {
.rtc_dboost_fpd = 1, \
.xtal_fpu = 0, \
.bbpll_fpu = 0, \
.cpu_waiti_clk_gate = 1\
.cpu_waiti_clk_gate = 1, \
.cali_ocode = 0 \
}
/**

View File

@ -1,4 +1,4 @@
// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -11,14 +11,30 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifndef _SOC_RTC_CNTL_REG_H_
#define _SOC_RTC_CNTL_REG_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "soc.h"
/* The value that needs to be written to RTC_CNTL_WDT_WKEY to write-enable the wdt registers */
#define RTC_CNTL_WDT_WKEY_VALUE 0x50D83AA1
/* Possible values for RTC_CNTL_WDT_CPU_RESET_LENGTH and RTC_CNTL_WDT_SYS_RESET_LENGTH */
#define RTC_WDT_RESET_LENGTH_100_NS 0
#define RTC_WDT_RESET_LENGTH_200_NS 1
#define RTC_WDT_RESET_LENGTH_300_NS 2
#define RTC_WDT_RESET_LENGTH_400_NS 3
#define RTC_WDT_RESET_LENGTH_500_NS 4
#define RTC_WDT_RESET_LENGTH_800_NS 5
#define RTC_WDT_RESET_LENGTH_1600_NS 6
#define RTC_WDT_RESET_LENGTH_3200_NS 7
#define RTC_CNTL_TIME0_REG RTC_CNTL_TIME_LOW0_REG
#define RTC_CNTL_TIME1_REG RTC_CNTL_TIME_HIGH0_REG
#define RTC_CNTL_OPTIONS0_REG (DR_REG_RTCCNTL_BASE + 0x0000)
/* RTC_CNTL_SW_SYS_RST : WO ;bitpos:[31] ;default: 1'd0 ; */
/*description: SW system reset*/
@ -381,6 +397,7 @@ extern "C" {
#define RTC_CNTL_MIN_SLP_VAL_M ((RTC_CNTL_MIN_SLP_VAL_V) << (RTC_CNTL_MIN_SLP_VAL_S))
#define RTC_CNTL_MIN_SLP_VAL_V 0xFF
#define RTC_CNTL_MIN_SLP_VAL_S 8
#define RTC_CNTL_MIN_SLP_VAL_MIN 2
#define RTC_CNTL_TIMER6_REG (DR_REG_RTCCNTL_BASE + 0x0030)
/* RTC_CNTL_DG_DCDC_POWERUP_TIMER : R/W ;bitpos:[31:25] ;default: 7'h8 ; */
@ -445,12 +462,18 @@ extern "C" {
#define RTC_CNTL_PLLA_FORCE_PD_M (BIT(23))
#define RTC_CNTL_PLLA_FORCE_PD_V 0x1
#define RTC_CNTL_PLLA_FORCE_PD_S 23
/* RTC_CNTL_SAR_I2C_PU : R/W ;bitpos:[22] ;default: 1'b1 ; */
/* RTC_CNTL_SAR_I2C_FORCE_PU : R/W ;bitpos:[22] ;default: 1'b0 ; */
/*description: PLLA force power up*/
#define RTC_CNTL_SAR_I2C_PU (BIT(22))
#define RTC_CNTL_SAR_I2C_PU_M (BIT(22))
#define RTC_CNTL_SAR_I2C_PU_V 0x1
#define RTC_CNTL_SAR_I2C_PU_S 22
#define RTC_CNTL_SAR_I2C_FORCE_PU (BIT(22))
#define RTC_CNTL_SAR_I2C_FORCE_PU_M (BIT(22))
#define RTC_CNTL_SAR_I2C_FORCE_PU_V 0x1
#define RTC_CNTL_SAR_I2C_FORCE_PU_S 22
/* RTC_CNTL_SAR_I2C_FORCE_PD : R/W ;bitpos:[21] ;default: 1'b1 ; */
/*description: PLLA force power down*/
#define RTC_CNTL_SAR_I2C_FORCE_PD (BIT(21))
#define RTC_CNTL_SAR_I2C_FORCE_PD_M (BIT(21))
#define RTC_CNTL_SAR_I2C_FORCE_PD_V 0x1
#define RTC_CNTL_SAR_I2C_FORCE_PD_S 21
/* RTC_CNTL_GLITCH_RST_EN : R/W ;bitpos:[20] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_GLITCH_RST_EN (BIT(20))
@ -471,78 +494,6 @@ extern "C" {
#define RTC_CNTL_I2C_RESET_POR_FORCE_PD_S 18
#define RTC_CNTL_RESET_STATE_REG (DR_REG_RTCCNTL_BASE + 0x0038)
/* RTC_CNTL_PRO_DRESET_MASK : R/W ;bitpos:[25] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_PRO_DRESET_MASK (BIT(25))
#define RTC_CNTL_PRO_DRESET_MASK_M (BIT(25))
#define RTC_CNTL_PRO_DRESET_MASK_V 0x1
#define RTC_CNTL_PRO_DRESET_MASK_S 25
/* RTC_CNTL_APP_DRESET_MASK : R/W ;bitpos:[24] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_APP_DRESET_MASK (BIT(24))
#define RTC_CNTL_APP_DRESET_MASK_M (BIT(24))
#define RTC_CNTL_APP_DRESET_MASK_V 0x1
#define RTC_CNTL_APP_DRESET_MASK_S 24
/* RTC_CNTL_RESET_FLAG_JTAG_APPCPU_CLR : WO ;bitpos:[23] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU_CLR (BIT(23))
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU_CLR_M (BIT(23))
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU_CLR_V 0x1
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU_CLR_S 23
/* RTC_CNTL_RESET_FLAG_JTAG_PROCPU_CLR : WO ;bitpos:[22] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU_CLR (BIT(22))
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU_CLR_M (BIT(22))
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU_CLR_V 0x1
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU_CLR_S 22
/* RTC_CNTL_RESET_FLAG_JTAG_APPCPU : RO ;bitpos:[21] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU (BIT(21))
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU_M (BIT(21))
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU_V 0x1
#define RTC_CNTL_RESET_FLAG_JTAG_APPCPU_S 21
/* RTC_CNTL_RESET_FLAG_JTAG_PROCPU : RO ;bitpos:[20] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU (BIT(20))
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU_M (BIT(20))
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU_V 0x1
#define RTC_CNTL_RESET_FLAG_JTAG_PROCPU_S 20
/* RTC_CNTL_PROCPU_OCD_HALT_ON_RESET : R/W ;bitpos:[19] ;default: 1'b0 ; */
/*description: PROCPU OcdHaltOnReset*/
#define RTC_CNTL_PROCPU_OCD_HALT_ON_RESET (BIT(19))
#define RTC_CNTL_PROCPU_OCD_HALT_ON_RESET_M (BIT(19))
#define RTC_CNTL_PROCPU_OCD_HALT_ON_RESET_V 0x1
#define RTC_CNTL_PROCPU_OCD_HALT_ON_RESET_S 19
/* RTC_CNTL_APPCPU_OCD_HALT_ON_RESET : R/W ;bitpos:[18] ;default: 1'b0 ; */
/*description: APPCPU OcdHaltOnReset*/
#define RTC_CNTL_APPCPU_OCD_HALT_ON_RESET (BIT(18))
#define RTC_CNTL_APPCPU_OCD_HALT_ON_RESET_M (BIT(18))
#define RTC_CNTL_APPCPU_OCD_HALT_ON_RESET_V 0x1
#define RTC_CNTL_APPCPU_OCD_HALT_ON_RESET_S 18
/* RTC_CNTL_RESET_FLAG_APPCPU_CLR : WO ;bitpos:[17] ;default: 1'b0 ; */
/*description: clear APP CPU reset flag*/
#define RTC_CNTL_RESET_FLAG_APPCPU_CLR (BIT(17))
#define RTC_CNTL_RESET_FLAG_APPCPU_CLR_M (BIT(17))
#define RTC_CNTL_RESET_FLAG_APPCPU_CLR_V 0x1
#define RTC_CNTL_RESET_FLAG_APPCPU_CLR_S 17
/* RTC_CNTL_RESET_FLAG_PROCPU_CLR : WO ;bitpos:[16] ;default: 1'b0 ; */
/*description: clear PRO CPU reset_flag*/
#define RTC_CNTL_RESET_FLAG_PROCPU_CLR (BIT(16))
#define RTC_CNTL_RESET_FLAG_PROCPU_CLR_M (BIT(16))
#define RTC_CNTL_RESET_FLAG_PROCPU_CLR_V 0x1
#define RTC_CNTL_RESET_FLAG_PROCPU_CLR_S 16
/* RTC_CNTL_RESET_FLAG_APPCPU : RO ;bitpos:[15] ;default: 1'b0 ; */
/*description: APP CPU reset flag*/
#define RTC_CNTL_RESET_FLAG_APPCPU (BIT(15))
#define RTC_CNTL_RESET_FLAG_APPCPU_M (BIT(15))
#define RTC_CNTL_RESET_FLAG_APPCPU_V 0x1
#define RTC_CNTL_RESET_FLAG_APPCPU_S 15
/* RTC_CNTL_RESET_FLAG_PROCPU : RO ;bitpos:[14] ;default: 1'b0 ; */
/*description: PRO CPU reset_flag*/
#define RTC_CNTL_RESET_FLAG_PROCPU (BIT(14))
#define RTC_CNTL_RESET_FLAG_PROCPU_M (BIT(14))
#define RTC_CNTL_RESET_FLAG_PROCPU_V 0x1
#define RTC_CNTL_RESET_FLAG_PROCPU_S 14
/* RTC_CNTL_PROCPU_STAT_VECTOR_SEL : R/W ;bitpos:[13] ;default: 1'b1 ; */
/*description: PRO CPU state vector sel*/
#define RTC_CNTL_PROCPU_STAT_VECTOR_SEL (BIT(13))
@ -1417,7 +1368,7 @@ extern "C" {
#define RTC_CNTL_DREFH_SDIO_M ((RTC_CNTL_DREFH_SDIO_V) << (RTC_CNTL_DREFH_SDIO_S))
#define RTC_CNTL_DREFH_SDIO_V 0x3
#define RTC_CNTL_DREFH_SDIO_S 29
/* RTC_CNTL_DREFM_SDIO : R/W ;bitpos:[28:27] ;default: 2'b01 ; */
/* RTC_CNTL_DREFM_SDIO : R/W ;bitpos:[28:27] ;default: 2'b00 ; */
/*description: SW option for DREFM_SDIO. Only active when reg_sdio_force = 1*/
#define RTC_CNTL_DREFM_SDIO 0x00000003
#define RTC_CNTL_DREFM_SDIO_M ((RTC_CNTL_DREFM_SDIO_V) << (RTC_CNTL_DREFM_SDIO_S))
@ -1503,6 +1454,42 @@ extern "C" {
#define RTC_CNTL_SDIO_TIMER_TARGET_S 0
#define RTC_CNTL_BIAS_CONF_REG (DR_REG_RTCCNTL_BASE + 0x0080)
/* RTC_CNTL_RST_BIAS_I2C : R/W ;bitpos:[31] ;default: 1'd0 ; */
/*description: */
#define RTC_CNTL_RST_BIAS_I2C (BIT(31))
#define RTC_CNTL_RST_BIAS_I2C_M (BIT(31))
#define RTC_CNTL_RST_BIAS_I2C_V 0x1
#define RTC_CNTL_RST_BIAS_I2C_S 31
/* RTC_CNTL_DEC_HEARTBEAT_WIDTH : R/W ;bitpos:[30] ;default: 1'd0 ; */
/*description: DEC_HEARTBEAT_WIDTH*/
#define RTC_CNTL_DEC_HEARTBEAT_WIDTH (BIT(30))
#define RTC_CNTL_DEC_HEARTBEAT_WIDTH_M (BIT(30))
#define RTC_CNTL_DEC_HEARTBEAT_WIDTH_V 0x1
#define RTC_CNTL_DEC_HEARTBEAT_WIDTH_S 30
/* RTC_CNTL_INC_HEARTBEAT_PERIOD : R/W ;bitpos:[29] ;default: 1'd0 ; */
/*description: INC_HEARTBEAT_PERIOD*/
#define RTC_CNTL_INC_HEARTBEAT_PERIOD (BIT(29))
#define RTC_CNTL_INC_HEARTBEAT_PERIOD_M (BIT(29))
#define RTC_CNTL_INC_HEARTBEAT_PERIOD_V 0x1
#define RTC_CNTL_INC_HEARTBEAT_PERIOD_S 29
/* RTC_CNTL_DEC_HEARTBEAT_PERIOD : R/W ;bitpos:[28] ;default: 1'd0 ; */
/*description: DEC_HEARTBEAT_PERIOD*/
#define RTC_CNTL_DEC_HEARTBEAT_PERIOD (BIT(28))
#define RTC_CNTL_DEC_HEARTBEAT_PERIOD_M (BIT(28))
#define RTC_CNTL_DEC_HEARTBEAT_PERIOD_V 0x1
#define RTC_CNTL_DEC_HEARTBEAT_PERIOD_S 28
/* RTC_CNTL_INC_HEARTBEAT_REFRESH : R/W ;bitpos:[27] ;default: 1'd0 ; */
/*description: INC_HEARTBEAT_REFRESH*/
#define RTC_CNTL_INC_HEARTBEAT_REFRESH (BIT(27))
#define RTC_CNTL_INC_HEARTBEAT_REFRESH_M (BIT(27))
#define RTC_CNTL_INC_HEARTBEAT_REFRESH_V 0x1
#define RTC_CNTL_INC_HEARTBEAT_REFRESH_S 27
/* RTC_CNTL_ENB_SCK_XTAL : R/W ;bitpos:[26] ;default: 1'd0 ; */
/*description: ENB_SCK_XTAL*/
#define RTC_CNTL_ENB_SCK_XTAL (BIT(26))
#define RTC_CNTL_ENB_SCK_XTAL_M (BIT(26))
#define RTC_CNTL_ENB_SCK_XTAL_V 0x1
#define RTC_CNTL_ENB_SCK_XTAL_S 26
/* RTC_CNTL_DBG_ATTEN_MONITOR : R/W ;bitpos:[25:22] ;default: 4'd0 ; */
/*description: DBG_ATTEN when rtc in monitor state*/
#define RTC_CNTL_DBG_ATTEN_MONITOR 0x0000000F
@ -1590,18 +1577,50 @@ extern "C" {
#define RTC_CNTL_DBOOST_FORCE_PD_M (BIT(28))
#define RTC_CNTL_DBOOST_FORCE_PD_V 0x1
#define RTC_CNTL_DBOOST_FORCE_PD_S 28
/* RTC_CNTL_DBIAS_WAK : R/W ;bitpos:[27:25] ;default: 3'd4 ; */
/*description: RTC_DBIAS during wakeup*/
#define RTC_CNTL_DBIAS_WAK 0x00000007
#define RTC_CNTL_DBIAS_WAK_M ((RTC_CNTL_DBIAS_WAK_V) << (RTC_CNTL_DBIAS_WAK_S))
#define RTC_CNTL_DBIAS_WAK_V 0x7
#define RTC_CNTL_DBIAS_WAK_S 25
/* Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP,
* RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values.
* Valid if RTC_CNTL_DBG_ATTEN is 0.
*/
#define RTC_CNTL_DIG_DBIAS_0V85 0
#define RTC_CNTL_DIG_DBIAS_0V90 1
#define RTC_CNTL_DIG_DBIAS_0V95 2
#define RTC_CNTL_DIG_DBIAS_1V00 3
#define RTC_CNTL_DIG_DBIAS_1V05 4
#define RTC_CNTL_DIG_DBIAS_1V10 5
#define RTC_CNTL_DIG_DBIAS_1V15 6
#define RTC_CNTL_DIG_DBIAS_1V20 7
/* RTC_CNTL_DBIAS_SLP : R/W ;bitpos:[24:22] ;default: 3'd4 ; */
/*description: RTC_DBIAS during sleep*/
#define RTC_CNTL_DBIAS_SLP 0x00000007
#define RTC_CNTL_DBIAS_SLP_M ((RTC_CNTL_DBIAS_SLP_V) << (RTC_CNTL_DBIAS_SLP_S))
#define RTC_CNTL_DBIAS_SLP_V 0x7
#define RTC_CNTL_DBIAS_SLP_S 22
/* RTC_CNTL_SCK_DCAP : R/W ;bitpos:[21:14] ;default: 8'd0 ; */
/*description: SCK_DCAP*/
#define RTC_CNTL_SCK_DCAP 0x000000FF
#define RTC_CNTL_SCK_DCAP_M ((RTC_CNTL_SCK_DCAP_V) << (RTC_CNTL_SCK_DCAP_S))
#define RTC_CNTL_SCK_DCAP_V 0xFF
#define RTC_CNTL_SCK_DCAP_S 14
/* RTC_CNTL_DIG_CAL_EN : R/W ;bitpos:[7] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_DIG_CAL_EN (BIT(7))
#define RTC_CNTL_DIG_CAL_EN_M (BIT(7))
#define RTC_CNTL_DIG_CAL_EN_V 0x1
#define RTC_CNTL_DIG_CAL_EN_S 7
/* RTC_CNTL_DIG_DBIAS_WAK : R/W ;bitpos:[13:11] ;default: 3'd4 ; */
/*description: DIG_REG_DBIAS during wakeup*/
#define RTC_CNTL_DIG_DBIAS_WAK 0x00000007
#define RTC_CNTL_DIG_DBIAS_WAK_M ((RTC_CNTL_DIG_DBIAS_WAK_V) << (RTC_CNTL_DIG_DBIAS_WAK_S))
#define RTC_CNTL_DIG_DBIAS_WAK_V 0x7
#define RTC_CNTL_DIG_DBIAS_WAK_S 11
/* RTC_CNTL_DIG_DBIAS_SLP : R/W ;bitpos:[10:8] ;default: 3'd4 ; */
/*description: DIG_REG_DBIAS during sleep*/
#define RTC_CNTL_DIG_DBIAS_SLP 0x00000007
#define RTC_CNTL_DIG_DBIAS_SLP_M ((RTC_CNTL_DIG_DBIAS_SLP_V) << (RTC_CNTL_DIG_DBIAS_SLP_S))
#define RTC_CNTL_DIG_DBIAS_SLP_V 0x7
#define RTC_CNTL_DIG_DBIAS_SLP_S 8
#define RTC_CNTL_PWC_REG (DR_REG_RTCCNTL_BASE + 0x0088)
/* RTC_CNTL_PAD_FORCE_HOLD : R/W ;bitpos:[21] ;default: 1'd0 ; */
@ -2058,7 +2077,7 @@ extern "C" {
#define RTC_CNTL_DIG_ISO_FORCE_ON_M (BIT(8))
#define RTC_CNTL_DIG_ISO_FORCE_ON_V 0x1
#define RTC_CNTL_DIG_ISO_FORCE_ON_S 8
/* RTC_CNTL_DIG_ISO_FORCE_OFF : R/W ;bitpos:[7] ;default: 1'd1 ; */
/* RTC_CNTL_DIG_ISO_FORCE_OFF : R/W ;bitpos:[7] ;default: 1'd0 ; */
/*description: */
#define RTC_CNTL_DIG_ISO_FORCE_OFF (BIT(7))
#define RTC_CNTL_DIG_ISO_FORCE_OFF_M (BIT(7))
@ -2096,6 +2115,14 @@ extern "C" {
#define RTC_CNTL_WDT_STG3_M ((RTC_CNTL_WDT_STG3_V) << (RTC_CNTL_WDT_STG3_S))
#define RTC_CNTL_WDT_STG3_V 0x7
#define RTC_CNTL_WDT_STG3_S 19
/* RTC_CNTL_WDT_STGX : */
/*description: stage action selection values */
#define RTC_WDT_STG_SEL_OFF 0
#define RTC_WDT_STG_SEL_INT 1
#define RTC_WDT_STG_SEL_RESET_CPU 2
#define RTC_WDT_STG_SEL_RESET_SYSTEM 3
#define RTC_WDT_STG_SEL_RESET_RTC 4
/* RTC_CNTL_WDT_CPU_RESET_LENGTH : R/W ;bitpos:[18:16] ;default: 3'h1 ; */
/*description: CPU reset counter length*/
#define RTC_CNTL_WDT_CPU_RESET_LENGTH 0x00000007
@ -2224,12 +2251,6 @@ extern "C" {
#define RTC_CNTL_SWD_SIGNAL_WIDTH_M ((RTC_CNTL_SWD_SIGNAL_WIDTH_V) << (RTC_CNTL_SWD_SIGNAL_WIDTH_S))
#define RTC_CNTL_SWD_SIGNAL_WIDTH_V 0x3FF
#define RTC_CNTL_SWD_SIGNAL_WIDTH_S 18
/* RTC_CNTL_SWD_BYPASS_RST : R/W ;bitpos:[17] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_SWD_BYPASS_RST (BIT(17))
#define RTC_CNTL_SWD_BYPASS_RST_M (BIT(17))
#define RTC_CNTL_SWD_BYPASS_RST_V 0x1
#define RTC_CNTL_SWD_BYPASS_RST_S 17
/* RTC_CNTL_SWD_FEED_INT : RO ;bitpos:[1] ;default: 1'b0 ; */
/*description: swd interrupt for feeding*/
#define RTC_CNTL_SWD_FEED_INT (BIT(1))
@ -2658,12 +2679,6 @@ extern "C" {
#define RTC_CNTL_BROWN_OUT_CNT_CLR_M (BIT(29))
#define RTC_CNTL_BROWN_OUT_CNT_CLR_V 0x1
#define RTC_CNTL_BROWN_OUT_CNT_CLR_S 29
/* RTC_CNTL_BROWN_OUT_ANA_RST_EN : R/W ;bitpos:[28] ;default: 1'b0 ; */
/*description: */
#define RTC_CNTL_BROWN_OUT_ANA_RST_EN (BIT(28))
#define RTC_CNTL_BROWN_OUT_ANA_RST_EN_M (BIT(28))
#define RTC_CNTL_BROWN_OUT_ANA_RST_EN_V 0x1
#define RTC_CNTL_BROWN_OUT_ANA_RST_EN_S 28
/* RTC_CNTL_BROWN_OUT_RST_SEL : R/W ;bitpos:[27] ;default: 1'b0 ; */
/*description: 1: 4-pos reset*/
#define RTC_CNTL_BROWN_OUT_RST_SEL (BIT(27))
@ -3553,30 +3568,8 @@ extern "C" {
#define RTC_CNTL_SLP_WAKEUP_INT_ENA_W1TC_V 0x1
#define RTC_CNTL_SLP_WAKEUP_INT_ENA_W1TC_S 0
#define RTC_CNTL_RETENTION_CTRL_REG (DR_REG_RTCCNTL_BASE + 0x013c)
/* RTC_CNTL_RETENTION_WAIT : R/W ;bitpos:[31:27] ;default: 5'd20 ; */
/*description: wait cycles for rention operation*/
#define RTC_CNTL_RETENTION_WAIT 0x0000001F
#define RTC_CNTL_RETENTION_WAIT_M ((RTC_CNTL_RETENTION_WAIT_V) << (RTC_CNTL_RETENTION_WAIT_S))
#define RTC_CNTL_RETENTION_WAIT_V 0x1F
#define RTC_CNTL_RETENTION_WAIT_S 27
/* RTC_CNTL_RETENTION_EN : R/W ;bitpos:[26] ;default: 1'd0 ; */
/*description: */
#define RTC_CNTL_RETENTION_EN (BIT(26))
#define RTC_CNTL_RETENTION_EN_M (BIT(26))
#define RTC_CNTL_RETENTION_EN_V 0x1
#define RTC_CNTL_RETENTION_EN_S 26
#define RTC_CNTL_FIB_SEL_REG (DR_REG_RTCCNTL_BASE + 0x0140)
/* RTC_CNTL_FIB_SEL : R/W ;bitpos:[2:0] ;default: 3'd7 ; */
/*description: select use analog fib signal*/
#define RTC_CNTL_FIB_SEL 0x00000007
#define RTC_CNTL_FIB_SEL_M ((RTC_CNTL_FIB_SEL_V) << (RTC_CNTL_FIB_SEL_S))
#define RTC_CNTL_FIB_SEL_V 0x7
#define RTC_CNTL_FIB_SEL_S 0
#define RTC_CNTL_DATE_REG (DR_REG_RTCCNTL_BASE + 0x0144)
/* RTC_CNTL_CNTL_DATE : R/W ;bitpos:[27:0] ;default: 28'h2003251 ; */
#define RTC_CNTL_DATE_REG (DR_REG_RTCCNTL_BASE + 0x013c)
/* RTC_CNTL_CNTL_DATE : R/W ;bitpos:[27:0] ;default: 28'h1910211 ; */
/*description: */
#define RTC_CNTL_CNTL_DATE 0x0FFFFFFF
#define RTC_CNTL_CNTL_DATE_M ((RTC_CNTL_CNTL_DATE_V) << (RTC_CNTL_CNTL_DATE_S))
@ -3586,3 +3579,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif
#endif /*_SOC_RTC_CNTL_REG_H_ */

View File

@ -0,0 +1,31 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 6
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 11
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 7
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 8
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2 9
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3 10
#define SDIO_SLAVE_SLOT0_FUNC 0
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK 14
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD 15
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0 2
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1 4
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2 12
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3 13
#define SDIO_SLAVE_SLOT1_FUNC 4

View File

@ -0,0 +1,35 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#define SDMMC_SLOT0_IOMUX_PIN_NUM_CLK 6
#define SDMMC_SLOT0_IOMUX_PIN_NUM_CMD 11
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D0 7
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D1 8
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D2 9
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D3 10
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D4 16
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D5 17
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D6 5
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D7 18
#define SDMMC_SLOT0_FUNC 0
#define SDMMC_SLOT1_IOMUX_PIN_NUM_CLK 14
#define SDMMC_SLOT1_IOMUX_PIN_NUM_CMD 15
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D0 2
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D1 4
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D2 12
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D3 13
#define SDMMC_SLOT1_FUNC 4

View File

@ -245,6 +245,8 @@
#define SOC_RTC_DATA_HIGH 0x50002000
#define SOC_EXTRAM_DATA_LOW 0x3D000000
#define SOC_EXTRAM_DATA_HIGH 0x3E000000
#define SOC_IROM_MASK_LOW 0x40000000
#define SOC_IROM_MASK_HIGH 0x4001A100
//First and last words of the D/IRAM region, for both the DRAM address as well as the IRAM alias.
#define SOC_DIRAM_IRAM_LOW 0x40378000

View File

@ -5,4 +5,5 @@
#pragma once
#define SOC_TWAI_SUPPORTED 1
#define SOC_CPU_CORES_NUM 2

View File

@ -51,3 +51,5 @@
// Peripheral supports output given level during its "dummy phase"
#define SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT(spi_dev) ((void*)spi_dev == (void*)&SPIMEM1)
#define SOC_MEMSPI_IS_INDEPENDENT 1

View File

@ -19,6 +19,113 @@ extern "C" {
#include "soc.h"
#define SPI_MEM_CMD_REG(i) (REG_SPI_MEM_BASE(i) + 0x000)
/* SPI_MEM_FLASH_READ : R/W ;bitpos:[31] ;default: 1'b0 ; */
/*description: Read flash enable. Read flash operation will be triggered when
the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
#define SPI_MEM_FLASH_READ (BIT(31))
#define SPI_MEM_FLASH_READ_M (BIT(31))
#define SPI_MEM_FLASH_READ_V 0x1
#define SPI_MEM_FLASH_READ_S 31
/* SPI_MEM_FLASH_WREN : R/W ;bitpos:[30] ;default: 1'b0 ; */
/*description: Write flash enable. Write enable command will be sent when the
bit is set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
#define SPI_MEM_FLASH_WREN (BIT(30))
#define SPI_MEM_FLASH_WREN_M (BIT(30))
#define SPI_MEM_FLASH_WREN_V 0x1
#define SPI_MEM_FLASH_WREN_S 30
/* SPI_MEM_FLASH_WRDI : R/W ;bitpos:[29] ;default: 1'b0 ; */
/*description: Write flash disable. Write disable command will be sent when
the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
#define SPI_MEM_FLASH_WRDI (BIT(29))
#define SPI_MEM_FLASH_WRDI_M (BIT(29))
#define SPI_MEM_FLASH_WRDI_V 0x1
#define SPI_MEM_FLASH_WRDI_S 29
/* SPI_MEM_FLASH_RDID : R/W ;bitpos:[28] ;default: 1'b0 ; */
/*description: Read JEDEC ID . Read ID command will be sent when the bit is
set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
#define SPI_MEM_FLASH_RDID (BIT(28))
#define SPI_MEM_FLASH_RDID_M (BIT(28))
#define SPI_MEM_FLASH_RDID_V 0x1
#define SPI_MEM_FLASH_RDID_S 28
/* SPI_MEM_FLASH_RDSR : R/W ;bitpos:[27] ;default: 1'b0 ; */
/*description: Read status register-1. Read status operation will be triggered
when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_RDSR (BIT(27))
#define SPI_MEM_FLASH_RDSR_M (BIT(27))
#define SPI_MEM_FLASH_RDSR_V 0x1
#define SPI_MEM_FLASH_RDSR_S 27
/* SPI_MEM_FLASH_WRSR : R/W ;bitpos:[26] ;default: 1'b0 ; */
/*description: Write status register enable. Write status operation will
be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_WRSR (BIT(26))
#define SPI_MEM_FLASH_WRSR_M (BIT(26))
#define SPI_MEM_FLASH_WRSR_V 0x1
#define SPI_MEM_FLASH_WRSR_S 26
/* SPI_MEM_FLASH_PP : R/W ;bitpos:[25] ;default: 1'b0 ; */
/*description: Page program enable(1 byte ~256 bytes data to be programmed).
Page program operation will be triggered when the bit is set. The bit will be cleared once the operation done .1: enable 0: disable.*/
#define SPI_MEM_FLASH_PP (BIT(25))
#define SPI_MEM_FLASH_PP_M (BIT(25))
#define SPI_MEM_FLASH_PP_V 0x1
#define SPI_MEM_FLASH_PP_S 25
/* SPI_MEM_FLASH_SE : R/W ;bitpos:[24] ;default: 1'b0 ; */
/*description: Sector erase enable(4KB). Sector erase operation will be triggered
when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_SE (BIT(24))
#define SPI_MEM_FLASH_SE_M (BIT(24))
#define SPI_MEM_FLASH_SE_V 0x1
#define SPI_MEM_FLASH_SE_S 24
/* SPI_MEM_FLASH_BE : R/W ;bitpos:[23] ;default: 1'b0 ; */
/*description: Block erase enable(32KB) . Block erase operation will be triggered
when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_BE (BIT(23))
#define SPI_MEM_FLASH_BE_M (BIT(23))
#define SPI_MEM_FLASH_BE_V 0x1
#define SPI_MEM_FLASH_BE_S 23
/* SPI_MEM_FLASH_CE : R/W ;bitpos:[22] ;default: 1'b0 ; */
/*description: Chip erase enable. Chip erase operation will be triggered when
the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_CE (BIT(22))
#define SPI_MEM_FLASH_CE_M (BIT(22))
#define SPI_MEM_FLASH_CE_V 0x1
#define SPI_MEM_FLASH_CE_S 22
/* SPI_MEM_FLASH_DP : R/W ;bitpos:[21] ;default: 1'b0 ; */
/*description: Drive Flash into power down. An operation will be triggered
when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_DP (BIT(21))
#define SPI_MEM_FLASH_DP_M (BIT(21))
#define SPI_MEM_FLASH_DP_V 0x1
#define SPI_MEM_FLASH_DP_S 21
/* SPI_MEM_FLASH_RES : R/W ;bitpos:[20] ;default: 1'b0 ; */
/*description: This bit combined with reg_resandres bit releases Flash from
the power-down state or high performance mode and obtains the devices ID. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_RES (BIT(20))
#define SPI_MEM_FLASH_RES_M (BIT(20))
#define SPI_MEM_FLASH_RES_V 0x1
#define SPI_MEM_FLASH_RES_S 20
/* SPI_MEM_FLASH_HPM : R/W ;bitpos:[19] ;default: 1'b0 ; */
/*description: Drive Flash into high performance mode. The bit will be cleared
once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_HPM (BIT(19))
#define SPI_MEM_FLASH_HPM_M (BIT(19))
#define SPI_MEM_FLASH_HPM_V 0x1
#define SPI_MEM_FLASH_HPM_S 19
/* SPI_MEM_USR : R/W ;bitpos:[18] ;default: 1'b0 ; */
/*description: User define command enable. An operation will be triggered when
the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_USR (BIT(18))
#define SPI_MEM_USR_M (BIT(18))
#define SPI_MEM_USR_V 0x1
#define SPI_MEM_USR_S 18
/* SPI_MEM_FLASH_PE : R/W ;bitpos:[17] ;default: 1'b0 ; */
/*description: In user mode it is set to indicate that program/erase operation
will be triggered. The bit is combined with spi_mem_usr bit. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_PE (BIT(17))
#define SPI_MEM_FLASH_PE_M (BIT(17))
#define SPI_MEM_FLASH_PE_V 0x1
#define SPI_MEM_FLASH_PE_S 17
#define SPI_MEM_ADDR_REG(i) (REG_SPI_MEM_BASE(i) + 0x004)
/* SPI_MEM_USR_ADDR_VALUE : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
/*description: In user mode it is the memory address. other then the bit0-bit23
@ -43,6 +150,13 @@ extern "C" {
#define SPI_MEM_FREAD_DIO_M (BIT(23))
#define SPI_MEM_FREAD_DIO_V 0x1
#define SPI_MEM_FREAD_DIO_S 23
/* SPI_MEM_WRSR_2B : R/W ;bitpos:[22] ;default: 1'b0 ; */
/*description: two bytes data will be written to status register when it is
set. 1: enable 0: disable.*/
#define SPI_MEM_WRSR_2B (BIT(22))
#define SPI_MEM_WRSR_2B_M (BIT(22))
#define SPI_MEM_WRSR_2B_V 0x1
#define SPI_MEM_WRSR_2B_S 22
/* SPI_MEM_WP_REG : R/W ;bitpos:[21] ;default: 1'b1 ; */
/*description: Write protect signal output when SPI is idle. 1: output high 0: output low.*/
#define SPI_MEM_WP_REG (BIT(21))
@ -67,6 +181,13 @@ extern "C" {
#define SPI_MEM_Q_POL_M (BIT(18))
#define SPI_MEM_Q_POL_V 0x1
#define SPI_MEM_Q_POL_S 18
/* SPI_MEM_RESANDRES : R/W ;bitpos:[15] ;default: 1'b1 ; */
/*description: The Device ID is read out to SPI_MEM_RD_STATUS register this
bit combine with spi_mem_flash_res bit. 1: enable 0: disable.*/
#define SPI_MEM_RESANDRES (BIT(15))
#define SPI_MEM_RESANDRES_M (BIT(15))
#define SPI_MEM_RESANDRES_V 0x1
#define SPI_MEM_RESANDRES_S 15
/* SPI_MEM_FREAD_DUAL : R/W ;bitpos:[14] ;default: 1'b0 ; */
/*description: In the read operations read-data phase apply 2 signals. 1: enable 0: disable.*/
#define SPI_MEM_FREAD_DUAL (BIT(14))
@ -138,6 +259,38 @@ extern "C" {
#define SPI_MEM_FDUMMY_OUT_S 3
#define SPI_MEM_CTRL1_REG(i) (REG_SPI_MEM_BASE(i) + 0x00C)
/* SPI_MEM_CS_DLY_EDGE : R/W ;bitpos:[31] ;default: 1'b0 ; */
/*description: The bit is used to select the spi clock edge to modify CS line timing.*/
#define SPI_MEM_CS_DLY_EDGE (BIT(31))
#define SPI_MEM_CS_DLY_EDGE_M (BIT(31))
#define SPI_MEM_CS_DLY_EDGE_V 0x1
#define SPI_MEM_CS_DLY_EDGE_S 31
/* SPI_MEM_CS_DLY_MODE : R/W ;bitpos:[29:28] ;default: 2'h0 ; */
/*description: The cs signals are delayed by system clock cycles 0: output
without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk*/
#define SPI_MEM_CS_DLY_MODE 0x00000003
#define SPI_MEM_CS_DLY_MODE_M ((SPI_MEM_CS_DLY_MODE_V) << (SPI_MEM_CS_DLY_MODE_S))
#define SPI_MEM_CS_DLY_MODE_V 0x3
#define SPI_MEM_CS_DLY_MODE_S 28
/* SPI_MEM_CS_DLY_NUM : R/W ;bitpos:[27:26] ;default: 2'h0 ; */
/*description: spi_mem_cs signal is delayed by system clock cycles*/
#define SPI_MEM_CS_DLY_NUM 0x00000003
#define SPI_MEM_CS_DLY_NUM_M ((SPI_MEM_CS_DLY_NUM_V) << (SPI_MEM_CS_DLY_NUM_S))
#define SPI_MEM_CS_DLY_NUM_V 0x3
#define SPI_MEM_CS_DLY_NUM_S 26
/* SPI_MEM_CS_HOLD_DLY : R/W ;bitpos:[25:14] ;default: 12'h1 ; */
/*description: SPI fsm is delayed to idle by spi clock cycles.*/
#define SPI_MEM_CS_HOLD_DLY 0x00000FFF
#define SPI_MEM_CS_HOLD_DLY_M ((SPI_MEM_CS_HOLD_DLY_V) << (SPI_MEM_CS_HOLD_DLY_S))
#define SPI_MEM_CS_HOLD_DLY_V 0xFFF
#define SPI_MEM_CS_HOLD_DLY_S 14
/* SPI_MEM_CS_HOLD_DLY_RES : R/W ;bitpos:[13:2] ;default: 12'hfff ; */
/*description: Delay cycles of resume Flash when resume Flash from standby mode
is enable by spi clock.*/
#define SPI_MEM_CS_HOLD_DLY_RES 0x00000FFF
#define SPI_MEM_CS_HOLD_DLY_RES_M ((SPI_MEM_CS_HOLD_DLY_RES_V) << (SPI_MEM_CS_HOLD_DLY_RES_S))
#define SPI_MEM_CS_HOLD_DLY_RES_V 0xFFF
#define SPI_MEM_CS_HOLD_DLY_RES_S 2
/* SPI_MEM_CLK_MODE : R/W ;bitpos:[1:0] ;default: 2'h0 ; */
/*description: SPI clock mode bits. 0: SPI clock is off when CS inactive 1:
SPI clock is delayed one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3: SPI clock is alwasy on.*/
@ -153,13 +306,6 @@ extern "C" {
#define SPI_MEM_SYNC_RESET_M (BIT(31))
#define SPI_MEM_SYNC_RESET_V 0x1
#define SPI_MEM_SYNC_RESET_S 31
/* SPI_MEM_CS_HOLD_DELAY : R/W ;bitpos:[30:25] ;default: 6'd0 ; */
/*description: These bits are used to set the minimum CS high time tSHSL between
SPI burst transfer when accesses to flash. tSHSL is (SPI_MEM_CS_HOLD_DELAY[5:0] + 1) MSPI core clock cycles.*/
#define SPI_MEM_CS_HOLD_DELAY 0x0000003F
#define SPI_MEM_CS_HOLD_DELAY_M ((SPI_MEM_CS_HOLD_DELAY_V) << (SPI_MEM_CS_HOLD_DELAY_S))
#define SPI_MEM_CS_HOLD_DELAY_V 0x3F
#define SPI_MEM_CS_HOLD_DELAY_S 25
/* SPI_MEM_ECC_16TO18_BYTE_EN : R/W ;bitpos:[14] ;default: 1'b0 ; */
/*description: Set this bit to enable MSPI ECC 16 bytes data with 2 ECC bytes
mode when accesses flash.*/
@ -224,18 +370,80 @@ extern "C" {
#define SPI_MEM_CLKCNT_L_S 0
#define SPI_MEM_USER_REG(i) (REG_SPI_MEM_BASE(i) + 0x018)
/* SPI_MEM_USR_COMMAND : R/W ;bitpos:[31] ;default: 1'b1 ; */
/*description: This bit enable the command phase of an operation.*/
#define SPI_MEM_USR_COMMAND (BIT(31))
#define SPI_MEM_USR_COMMAND_M (BIT(31))
#define SPI_MEM_USR_COMMAND_V 0x1
#define SPI_MEM_USR_COMMAND_S 31
/* SPI_MEM_USR_ADDR : R/W ;bitpos:[30] ;default: 1'b0 ; */
/*description: This bit enable the address phase of an operation.*/
#define SPI_MEM_USR_ADDR (BIT(30))
#define SPI_MEM_USR_ADDR_M (BIT(30))
#define SPI_MEM_USR_ADDR_V 0x1
#define SPI_MEM_USR_ADDR_S 30
/* SPI_MEM_USR_DUMMY : R/W ;bitpos:[29] ;default: 1'b0 ; */
/*description: This bit enable the dummy phase of an operation.*/
#define SPI_MEM_USR_DUMMY (BIT(29))
#define SPI_MEM_USR_DUMMY_M (BIT(29))
#define SPI_MEM_USR_DUMMY_V 0x1
#define SPI_MEM_USR_DUMMY_S 29
/* SPI_MEM_USR_MISO : R/W ;bitpos:[28] ;default: 1'b0 ; */
/*description: This bit enable the read-data phase of an operation.*/
#define SPI_MEM_USR_MISO (BIT(28))
#define SPI_MEM_USR_MISO_M (BIT(28))
#define SPI_MEM_USR_MISO_V 0x1
#define SPI_MEM_USR_MISO_S 28
/* SPI_MEM_USR_MOSI : R/W ;bitpos:[27] ;default: 1'b0 ; */
/*description: This bit enable the write-data phase of an operation.*/
#define SPI_MEM_USR_MOSI (BIT(27))
#define SPI_MEM_USR_MOSI_M (BIT(27))
#define SPI_MEM_USR_MOSI_V 0x1
#define SPI_MEM_USR_MOSI_S 27
/* SPI_MEM_USR_DUMMY_IDLE : R/W ;bitpos:[26] ;default: 1'b0 ; */
/*description: spi clock is disable in dummy phase when the bit is enable.*/
#define SPI_MEM_USR_DUMMY_IDLE (BIT(26))
#define SPI_MEM_USR_DUMMY_IDLE_M (BIT(26))
#define SPI_MEM_USR_DUMMY_IDLE_V 0x1
#define SPI_MEM_USR_DUMMY_IDLE_S 26
/* SPI_MEM_USR_MOSI_HIGHPART : R/W ;bitpos:[25] ;default: 1'b0 ; */
/*description: write-data phase only access to high-part of the buffer spi_mem_w8~spi_mem_w15.
1: enable 0: disable.*/
#define SPI_MEM_USR_MOSI_HIGHPART (BIT(25))
#define SPI_MEM_USR_MOSI_HIGHPART_M (BIT(25))
#define SPI_MEM_USR_MOSI_HIGHPART_V 0x1
#define SPI_MEM_USR_MOSI_HIGHPART_S 25
/* SPI_MEM_USR_MISO_HIGHPART : R/W ;bitpos:[24] ;default: 1'b0 ; */
/*description: read-data phase only access to high-part of the buffer spi_mem_w8~spi_mem_w15.
1: enable 0: disable.*/
#define SPI_MEM_USR_MISO_HIGHPART (BIT(24))
#define SPI_MEM_USR_MISO_HIGHPART_M (BIT(24))
#define SPI_MEM_USR_MISO_HIGHPART_V 0x1
#define SPI_MEM_USR_MISO_HIGHPART_S 24
/* SPI_MEM_FWRITE_QIO : R/W ;bitpos:[15] ;default: 1'b0 ; */
/*description: In the write operations address phase and read-data phase apply 4 signals.*/
#define SPI_MEM_FWRITE_QIO (BIT(15))
#define SPI_MEM_FWRITE_QIO_M (BIT(15))
#define SPI_MEM_FWRITE_QIO_V 0x1
#define SPI_MEM_FWRITE_QIO_S 15
/* SPI_MEM_FWRITE_DIO : R/W ;bitpos:[14] ;default: 1'b0 ; */
/*description: In the write operations address phase and read-data phase apply 2 signals.*/
#define SPI_MEM_FWRITE_DIO (BIT(14))
#define SPI_MEM_FWRITE_DIO_M (BIT(14))
#define SPI_MEM_FWRITE_DIO_V 0x1
#define SPI_MEM_FWRITE_DIO_S 14
/* SPI_MEM_FWRITE_QUAD : R/W ;bitpos:[13] ;default: 1'b0 ; */
/*description: In the write operations read-data phase apply 4 signals*/
#define SPI_MEM_FWRITE_QUAD (BIT(13))
#define SPI_MEM_FWRITE_QUAD_M (BIT(13))
#define SPI_MEM_FWRITE_QUAD_V 0x1
#define SPI_MEM_FWRITE_QUAD_S 13
/* SPI_MEM_FWRITE_DUAL : R/W ;bitpos:[12] ;default: 1'b0 ; */
/*description: In the write operations read-data phase apply 2 signals*/
#define SPI_MEM_FWRITE_DUAL (BIT(12))
#define SPI_MEM_FWRITE_DUAL_M (BIT(12))
#define SPI_MEM_FWRITE_DUAL_V 0x1
#define SPI_MEM_FWRITE_DUAL_S 12
/* SPI_MEM_CK_OUT_EDGE : R/W ;bitpos:[9] ;default: 1'b0 ; */
/*description: the bit combined with spi_mem_mosi_delay_mode bits to set mosi
signal delay mode.*/
@ -285,6 +493,22 @@ extern "C" {
#define SPI_MEM_USR_COMMAND_VALUE_V 0xFFFF
#define SPI_MEM_USR_COMMAND_VALUE_S 0
#define SPI_MEM_MOSI_DLEN_REG(i) (REG_SPI_MEM_BASE(i) + 0x024)
/* SPI_MEM_USR_MOSI_DBITLEN : R/W ;bitpos:[10:0] ;default: 11'h0 ; */
/*description: The length in bits of write-data. The register value shall be (bit_num-1).*/
#define SPI_MEM_USR_MOSI_DBITLEN 0x000007FF
#define SPI_MEM_USR_MOSI_DBITLEN_M ((SPI_MEM_USR_MOSI_DBITLEN_V) << (SPI_MEM_USR_MOSI_DBITLEN_S))
#define SPI_MEM_USR_MOSI_DBITLEN_V 0x7FF
#define SPI_MEM_USR_MOSI_DBITLEN_S 0
#define SPI_MEM_MISO_DLEN_REG(i) (REG_SPI_MEM_BASE(i) + 0x028)
/* SPI_MEM_USR_MISO_DBITLEN : R/W ;bitpos:[10:0] ;default: 11'h0 ; */
/*description: The length in bits of read-data. The register value shall be (bit_num-1).*/
#define SPI_MEM_USR_MISO_DBITLEN 0x000007FF
#define SPI_MEM_USR_MISO_DBITLEN_M ((SPI_MEM_USR_MISO_DBITLEN_V) << (SPI_MEM_USR_MISO_DBITLEN_S))
#define SPI_MEM_USR_MISO_DBITLEN_V 0x7FF
#define SPI_MEM_USR_MISO_DBITLEN_S 0
#define SPI_MEM_RD_STATUS_REG(i) (REG_SPI_MEM_BASE(i) + 0x02C)
/* SPI_MEM_WB_MODE : R/W ;bitpos:[23:16] ;default: 8'h00 ; */
/*description: Mode bits in the flash fast read mode it is combined with spi_mem_fastrd_mode
@ -293,6 +517,12 @@ extern "C" {
#define SPI_MEM_WB_MODE_M ((SPI_MEM_WB_MODE_V) << (SPI_MEM_WB_MODE_S))
#define SPI_MEM_WB_MODE_V 0xFF
#define SPI_MEM_WB_MODE_S 16
/* SPI_MEM_STATUS : R/W ;bitpos:[15:0] ;default: 16'b0 ; */
/*description: The value is stored when set spi_mem_flash_rdsr bit and spi_mem_flash_res bit.*/
#define SPI_MEM_STATUS 0x0000FFFF
#define SPI_MEM_STATUS_M ((SPI_MEM_STATUS_V) << (SPI_MEM_STATUS_S))
#define SPI_MEM_STATUS_V 0xFFFF
#define SPI_MEM_STATUS_S 0
#define SPI_MEM_EXT_ADDR_REG(i) (REG_SPI_MEM_BASE(i) + 0x030)
/* SPI_MEM_EXT_ADDR : R/W ;bitpos:[31:0] ;default: 32'b0 ; */
@ -303,6 +533,12 @@ extern "C" {
#define SPI_MEM_EXT_ADDR_S 0
#define SPI_MEM_MISC_REG(i) (REG_SPI_MEM_BASE(i) + 0x034)
/* SPI_MEM_AUTO_PER : R/W ;bitpos:[11] ;default: 1'b0 ; */
/*description: reserved*/
#define SPI_MEM_AUTO_PER (BIT(11))
#define SPI_MEM_AUTO_PER_M (BIT(11))
#define SPI_MEM_AUTO_PER_V 0x1
#define SPI_MEM_AUTO_PER_S 11
/* SPI_MEM_CS_KEEP_ACTIVE : R/W ;bitpos:[10] ;default: 1'b0 ; */
/*description: spi cs line keep low when the bit is set.*/
#define SPI_MEM_CS_KEEP_ACTIVE (BIT(10))
@ -327,6 +563,13 @@ extern "C" {
#define SPI_MEM_FSUB_PIN_M (BIT(7))
#define SPI_MEM_FSUB_PIN_V 0x1
#define SPI_MEM_FSUB_PIN_S 7
/* SPI_MEM_CS_POL : R/W ;bitpos:[6:5] ;default: 2'b0 ; */
/*description: In the master mode the bits are the polarity of spi cs line
the value is equivalent to spi_mem_cs ^ spi_mem_master_cs_pol.*/
#define SPI_MEM_CS_POL 0x00000003
#define SPI_MEM_CS_POL_M ((SPI_MEM_CS_POL_V) << (SPI_MEM_CS_POL_S))
#define SPI_MEM_CS_POL_V 0x3
#define SPI_MEM_CS_POL_S 5
/* SPI_MEM_TRANS_END_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */
/*description: The bit is used to enable the intterrupt of SPI transmitting done.*/
#define SPI_MEM_TRANS_END_INT_ENA (BIT(4))
@ -339,6 +582,18 @@ extern "C" {
#define SPI_MEM_TRANS_END_M (BIT(3))
#define SPI_MEM_TRANS_END_V 0x1
#define SPI_MEM_TRANS_END_S 3
/* SPI_MEM_CS1_DIS : R/W ;bitpos:[1] ;default: 1'b1 ; */
/*description: SPI CS1 pin enable 1: disable CS1 0: spi_mem_cs1 signal is from/to CS1 pin*/
#define SPI_MEM_CS1_DIS (BIT(1))
#define SPI_MEM_CS1_DIS_M (BIT(1))
#define SPI_MEM_CS1_DIS_V 0x1
#define SPI_MEM_CS1_DIS_S 1
/* SPI_MEM_CS0_DIS : R/W ;bitpos:[0] ;default: 1'b0 ; */
/*description: SPI CS0 pin enable 1: disable CS0 0: spi_mem_cs0 signal is from/to CS0 pin*/
#define SPI_MEM_CS0_DIS (BIT(0))
#define SPI_MEM_CS0_DIS_M (BIT(0))
#define SPI_MEM_CS0_DIS_V 0x1
#define SPI_MEM_CS0_DIS_S 0
#define SPI_MEM_TX_CRC_REG(i) (REG_SPI_MEM_BASE(i) + 0x038)
/* SPI_MEM_TX_CRC_DATA : RO ;bitpos:[31:0] ;default: 32'b0 ; */
@ -655,6 +910,205 @@ extern "C" {
#define SPI_MEM_ST_V 0x7
#define SPI_MEM_ST_S 0
#define SPI_MEM_W0_REG(i) (REG_SPI_MEM_BASE(i) + 0x058)
/* SPI_MEM_BUF0 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF0 0xFFFFFFFF
#define SPI_MEM_BUF0_M ((SPI_MEM_BUF0_V) << (SPI_MEM_BUF0_S))
#define SPI_MEM_BUF0_V 0xFFFFFFFF
#define SPI_MEM_BUF0_S 0
#define SPI_MEM_W1_REG(i) (REG_SPI_MEM_BASE(i) + 0x05C)
/* SPI_MEM_BUF1 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF1 0xFFFFFFFF
#define SPI_MEM_BUF1_M ((SPI_MEM_BUF1_V) << (SPI_MEM_BUF1_S))
#define SPI_MEM_BUF1_V 0xFFFFFFFF
#define SPI_MEM_BUF1_S 0
#define SPI_MEM_W2_REG(i) (REG_SPI_MEM_BASE(i) + 0x060)
/* SPI_MEM_BUF2 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF2 0xFFFFFFFF
#define SPI_MEM_BUF2_M ((SPI_MEM_BUF2_V) << (SPI_MEM_BUF2_S))
#define SPI_MEM_BUF2_V 0xFFFFFFFF
#define SPI_MEM_BUF2_S 0
#define SPI_MEM_W3_REG(i) (REG_SPI_MEM_BASE(i) + 0x064)
/* SPI_MEM_BUF3 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF3 0xFFFFFFFF
#define SPI_MEM_BUF3_M ((SPI_MEM_BUF3_V) << (SPI_MEM_BUF3_S))
#define SPI_MEM_BUF3_V 0xFFFFFFFF
#define SPI_MEM_BUF3_S 0
#define SPI_MEM_W4_REG(i) (REG_SPI_MEM_BASE(i) + 0x068)
/* SPI_MEM_BUF4 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF4 0xFFFFFFFF
#define SPI_MEM_BUF4_M ((SPI_MEM_BUF4_V) << (SPI_MEM_BUF4_S))
#define SPI_MEM_BUF4_V 0xFFFFFFFF
#define SPI_MEM_BUF4_S 0
#define SPI_MEM_W5_REG(i) (REG_SPI_MEM_BASE(i) + 0x06C)
/* SPI_MEM_BUF5 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF5 0xFFFFFFFF
#define SPI_MEM_BUF5_M ((SPI_MEM_BUF5_V) << (SPI_MEM_BUF5_S))
#define SPI_MEM_BUF5_V 0xFFFFFFFF
#define SPI_MEM_BUF5_S 0
#define SPI_MEM_W6_REG(i) (REG_SPI_MEM_BASE(i) + 0x070)
/* SPI_MEM_BUF6 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF6 0xFFFFFFFF
#define SPI_MEM_BUF6_M ((SPI_MEM_BUF6_V) << (SPI_MEM_BUF6_S))
#define SPI_MEM_BUF6_V 0xFFFFFFFF
#define SPI_MEM_BUF6_S 0
#define SPI_MEM_W7_REG(i) (REG_SPI_MEM_BASE(i) + 0x074)
/* SPI_MEM_BUF7 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF7 0xFFFFFFFF
#define SPI_MEM_BUF7_M ((SPI_MEM_BUF7_V) << (SPI_MEM_BUF7_S))
#define SPI_MEM_BUF7_V 0xFFFFFFFF
#define SPI_MEM_BUF7_S 0
#define SPI_MEM_W8_REG(i) (REG_SPI_MEM_BASE(i) + 0x078)
/* SPI_MEM_BUF8 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF8 0xFFFFFFFF
#define SPI_MEM_BUF8_M ((SPI_MEM_BUF8_V) << (SPI_MEM_BUF8_S))
#define SPI_MEM_BUF8_V 0xFFFFFFFF
#define SPI_MEM_BUF8_S 0
#define SPI_MEM_W9_REG(i) (REG_SPI_MEM_BASE(i) + 0x07C)
/* SPI_MEM_BUF9 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF9 0xFFFFFFFF
#define SPI_MEM_BUF9_M ((SPI_MEM_BUF9_V) << (SPI_MEM_BUF9_S))
#define SPI_MEM_BUF9_V 0xFFFFFFFF
#define SPI_MEM_BUF9_S 0
#define SPI_MEM_W10_REG(i) (REG_SPI_MEM_BASE(i) + 0x080)
/* SPI_MEM_BUF10 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF10 0xFFFFFFFF
#define SPI_MEM_BUF10_M ((SPI_MEM_BUF10_V) << (SPI_MEM_BUF10_S))
#define SPI_MEM_BUF10_V 0xFFFFFFFF
#define SPI_MEM_BUF10_S 0
#define SPI_MEM_W11_REG(i) (REG_SPI_MEM_BASE(i) + 0x084)
/* SPI_MEM_BUF11 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF11 0xFFFFFFFF
#define SPI_MEM_BUF11_M ((SPI_MEM_BUF11_V) << (SPI_MEM_BUF11_S))
#define SPI_MEM_BUF11_V 0xFFFFFFFF
#define SPI_MEM_BUF11_S 0
#define SPI_MEM_W12_REG(i) (REG_SPI_MEM_BASE(i) + 0x088)
/* SPI_MEM_BUF12 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF12 0xFFFFFFFF
#define SPI_MEM_BUF12_M ((SPI_MEM_BUF12_V) << (SPI_MEM_BUF12_S))
#define SPI_MEM_BUF12_V 0xFFFFFFFF
#define SPI_MEM_BUF12_S 0
#define SPI_MEM_W13_REG(i) (REG_SPI_MEM_BASE(i) + 0x08C)
/* SPI_MEM_BUF13 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF13 0xFFFFFFFF
#define SPI_MEM_BUF13_M ((SPI_MEM_BUF13_V) << (SPI_MEM_BUF13_S))
#define SPI_MEM_BUF13_V 0xFFFFFFFF
#define SPI_MEM_BUF13_S 0
#define SPI_MEM_W14_REG(i) (REG_SPI_MEM_BASE(i) + 0x090)
/* SPI_MEM_BUF14 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF14 0xFFFFFFFF
#define SPI_MEM_BUF14_M ((SPI_MEM_BUF14_V) << (SPI_MEM_BUF14_S))
#define SPI_MEM_BUF14_V 0xFFFFFFFF
#define SPI_MEM_BUF14_S 0
#define SPI_MEM_W15_REG(i) (REG_SPI_MEM_BASE(i) + 0x094)
/* SPI_MEM_BUF15 : SRW ;bitpos:[31:0] ;default: 32'b0 ; */
/*description: data buffer*/
#define SPI_MEM_BUF15 0xFFFFFFFF
#define SPI_MEM_BUF15_M ((SPI_MEM_BUF15_V) << (SPI_MEM_BUF15_S))
#define SPI_MEM_BUF15_V 0xFFFFFFFF
#define SPI_MEM_BUF15_S 0
#define SPI_MEM_FLASH_WAITI_CTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x098)
/* SPI_MEM_WAITI_DUMMY_CYCLELEN : R/W ;bitpos:[17:10] ;default: 8'h0 ; */
/*description: The dummy cycle length when auto wait flash idle*/
#define SPI_MEM_WAITI_DUMMY_CYCLELEN 0x000000FF
#define SPI_MEM_WAITI_DUMMY_CYCLELEN_M ((SPI_MEM_WAITI_DUMMY_CYCLELEN_V) << (SPI_MEM_WAITI_DUMMY_CYCLELEN_S))
#define SPI_MEM_WAITI_DUMMY_CYCLELEN_V 0xFF
#define SPI_MEM_WAITI_DUMMY_CYCLELEN_S 10
/* SPI_MEM_WAITI_CMD : R/W ;bitpos:[9:2] ;default: 8'h05 ; */
/*description: The command to auto wait idle*/
#define SPI_MEM_WAITI_CMD 0x000000FF
#define SPI_MEM_WAITI_CMD_M ((SPI_MEM_WAITI_CMD_V) << (SPI_MEM_WAITI_CMD_S))
#define SPI_MEM_WAITI_CMD_V 0xFF
#define SPI_MEM_WAITI_CMD_S 2
/* SPI_MEM_WAITI_DUMMY : R/W ;bitpos:[1] ;default: 1'b0 ; */
/*description: The dummy phase enable when auto wait flash idle*/
#define SPI_MEM_WAITI_DUMMY (BIT(1))
#define SPI_MEM_WAITI_DUMMY_M (BIT(1))
#define SPI_MEM_WAITI_DUMMY_V 0x1
#define SPI_MEM_WAITI_DUMMY_S 1
/* SPI_MEM_WAITI_EN : R/W ;bitpos:[0] ;default: 1'b0 ; */
/*description: auto-waiting flash idle operation when program flash or erase
flash. 1: enable 0: disable.*/
#define SPI_MEM_WAITI_EN (BIT(0))
#define SPI_MEM_WAITI_EN_M (BIT(0))
#define SPI_MEM_WAITI_EN_V 0x1
#define SPI_MEM_WAITI_EN_S 0
#define SPI_MEM_FLASH_SUS_CMD_REG(i) (REG_SPI_MEM_BASE(i) + 0x09C)
/* SPI_MEM_FLASH_PES : R/W ;bitpos:[1] ;default: 1'b0 ; */
/*description: program erase suspend bit program erase suspend operation will
be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_PES (BIT(1))
#define SPI_MEM_FLASH_PES_M (BIT(1))
#define SPI_MEM_FLASH_PES_V 0x1
#define SPI_MEM_FLASH_PES_S 1
/* SPI_MEM_FLASH_PER : R/W ;bitpos:[0] ;default: 1'b0 ; */
/*description: program erase resume bit program erase suspend operation will
be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
#define SPI_MEM_FLASH_PER (BIT(0))
#define SPI_MEM_FLASH_PER_M (BIT(0))
#define SPI_MEM_FLASH_PER_V 0x1
#define SPI_MEM_FLASH_PER_S 0
#define SPI_MEM_FLASH_SUS_CTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x0A0)
/* SPI_MEM_FLASH_PES_COMMAND : R/W ;bitpos:[16:9] ;default: 8'h75 ; */
/*description: Program/Erase suspend command.*/
#define SPI_MEM_FLASH_PES_COMMAND 0x000000FF
#define SPI_MEM_FLASH_PES_COMMAND_M ((SPI_MEM_FLASH_PES_COMMAND_V) << (SPI_MEM_FLASH_PES_COMMAND_S))
#define SPI_MEM_FLASH_PES_COMMAND_V 0xFF
#define SPI_MEM_FLASH_PES_COMMAND_S 9
/* SPI_MEM_FLASH_PER_COMMAND : R/W ;bitpos:[8:1] ;default: 8'h7a ; */
/*description: Program/Erase resume command.*/
#define SPI_MEM_FLASH_PER_COMMAND 0x000000FF
#define SPI_MEM_FLASH_PER_COMMAND_M ((SPI_MEM_FLASH_PER_COMMAND_V) << (SPI_MEM_FLASH_PER_COMMAND_S))
#define SPI_MEM_FLASH_PER_COMMAND_V 0xFF
#define SPI_MEM_FLASH_PER_COMMAND_S 1
/* SPI_MEM_FLASH_PES_EN : R/W ;bitpos:[0] ;default: 1'b0 ; */
/*description: Auto-suspending enable*/
#define SPI_MEM_FLASH_PES_EN (BIT(0))
#define SPI_MEM_FLASH_PES_EN_M (BIT(0))
#define SPI_MEM_FLASH_PES_EN_V 0x1
#define SPI_MEM_FLASH_PES_EN_S 0
#define SPI_MEM_SUS_STATUS_REG(i) (REG_SPI_MEM_BASE(i) + 0x0A4)
/* SPI_MEM_FLASH_SUS : R/W ;bitpos:[0] ;default: 1'h0 ; */
/*description: The status of flash suspend only used in SPI1.*/
#define SPI_MEM_FLASH_SUS (BIT(0))
#define SPI_MEM_FLASH_SUS_M (BIT(0))
#define SPI_MEM_FLASH_SUS_V 0x1
#define SPI_MEM_FLASH_SUS_S 0
#define SPI_MEM_TIMING_CALI_REG(i) (REG_SPI_MEM_BASE(i) + 0x0A8)
/* SPI_MEM_EXTRA_DUMMY_CYCLELEN : R/W ;bitpos:[4:2] ;default: 3'd0 ; */
/*description: add extra dummy spi clock cycle length for spi clock calibration.*/
@ -870,6 +1324,71 @@ extern "C" {
#define SPI_MEM_DOUT0_MODE_V 0x1
#define SPI_MEM_DOUT0_MODE_S 0
#define SPI_MEM_DOUT_NUM_REG(i) (REG_SPI_MEM_BASE(i) + 0x0B8)
/* SPI_MEM_DOUTS_NUM : R/W ;bitpos:[17:16] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUTS_NUM 0x00000003
#define SPI_MEM_DOUTS_NUM_M ((SPI_MEM_DOUTS_NUM_V) << (SPI_MEM_DOUTS_NUM_S))
#define SPI_MEM_DOUTS_NUM_V 0x3
#define SPI_MEM_DOUTS_NUM_S 16
/* SPI_MEM_DOUT7_NUM : R/W ;bitpos:[15:14] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT7_NUM 0x00000003
#define SPI_MEM_DOUT7_NUM_M ((SPI_MEM_DOUT7_NUM_V) << (SPI_MEM_DOUT7_NUM_S))
#define SPI_MEM_DOUT7_NUM_V 0x3
#define SPI_MEM_DOUT7_NUM_S 14
/* SPI_MEM_DOUT6_NUM : R/W ;bitpos:[13:12] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT6_NUM 0x00000003
#define SPI_MEM_DOUT6_NUM_M ((SPI_MEM_DOUT6_NUM_V) << (SPI_MEM_DOUT6_NUM_S))
#define SPI_MEM_DOUT6_NUM_V 0x3
#define SPI_MEM_DOUT6_NUM_S 12
/* SPI_MEM_DOUT5_NUM : R/W ;bitpos:[11:10] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT5_NUM 0x00000003
#define SPI_MEM_DOUT5_NUM_M ((SPI_MEM_DOUT5_NUM_V) << (SPI_MEM_DOUT5_NUM_S))
#define SPI_MEM_DOUT5_NUM_V 0x3
#define SPI_MEM_DOUT5_NUM_S 10
/* SPI_MEM_DOUT4_NUM : R/W ;bitpos:[9:8] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT4_NUM 0x00000003
#define SPI_MEM_DOUT4_NUM_M ((SPI_MEM_DOUT4_NUM_V) << (SPI_MEM_DOUT4_NUM_S))
#define SPI_MEM_DOUT4_NUM_V 0x3
#define SPI_MEM_DOUT4_NUM_S 8
/* SPI_MEM_DOUT3_NUM : R/W ;bitpos:[7:6] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT3_NUM 0x00000003
#define SPI_MEM_DOUT3_NUM_M ((SPI_MEM_DOUT3_NUM_V) << (SPI_MEM_DOUT3_NUM_S))
#define SPI_MEM_DOUT3_NUM_V 0x3
#define SPI_MEM_DOUT3_NUM_S 6
/* SPI_MEM_DOUT2_NUM : R/W ;bitpos:[5:4] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT2_NUM 0x00000003
#define SPI_MEM_DOUT2_NUM_M ((SPI_MEM_DOUT2_NUM_V) << (SPI_MEM_DOUT2_NUM_S))
#define SPI_MEM_DOUT2_NUM_V 0x3
#define SPI_MEM_DOUT2_NUM_S 4
/* SPI_MEM_DOUT1_NUM : R/W ;bitpos:[3:2] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT1_NUM 0x00000003
#define SPI_MEM_DOUT1_NUM_M ((SPI_MEM_DOUT1_NUM_V) << (SPI_MEM_DOUT1_NUM_S))
#define SPI_MEM_DOUT1_NUM_V 0x3
#define SPI_MEM_DOUT1_NUM_S 2
/* SPI_MEM_DOUT0_NUM : R/W ;bitpos:[1:0] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_DOUT0_NUM 0x00000003
#define SPI_MEM_DOUT0_NUM_M ((SPI_MEM_DOUT0_NUM_V) << (SPI_MEM_DOUT0_NUM_S))
#define SPI_MEM_DOUT0_NUM_V 0x3
#define SPI_MEM_DOUT0_NUM_S 0
#define SPI_MEM_SPI_SMEM_TIMING_CALI_REG(i) (REG_SPI_MEM_BASE(i) + 0x0BC)
/* SPI_MEM_SPI_SMEM_EXTRA_DUMMY_CYCLELEN : R/W ;bitpos:[4:2] ;default: 3'd0 ; */
/*description: For sram add extra dummy spi clock cycle length for spi clock calibration.*/
@ -1087,14 +1606,72 @@ extern "C" {
#define SPI_MEM_SPI_SMEM_DOUT0_MODE_V 0x1
#define SPI_MEM_SPI_SMEM_DOUT0_MODE_S 0
#define SPI_MEM_SPI_SMEM_DOUT_NUM_REG(i) (REG_SPI_MEM_BASE(i) + 0x0CC)
/* SPI_MEM_SPI_SMEM_DOUTS_NUM : R/W ;bitpos:[17:16] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: output
without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
#define SPI_MEM_SPI_SMEM_DOUTS_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUTS_NUM_M ((SPI_MEM_SPI_SMEM_DOUTS_NUM_V) << (SPI_MEM_SPI_SMEM_DOUTS_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUTS_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUTS_NUM_S 16
/* SPI_MEM_SPI_SMEM_DOUT7_NUM : R/W ;bitpos:[15:14] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: output
without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
#define SPI_MEM_SPI_SMEM_DOUT7_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT7_NUM_M ((SPI_MEM_SPI_SMEM_DOUT7_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT7_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT7_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT7_NUM_S 14
/* SPI_MEM_SPI_SMEM_DOUT6_NUM : R/W ;bitpos:[13:12] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: output
without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
#define SPI_MEM_SPI_SMEM_DOUT6_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT6_NUM_M ((SPI_MEM_SPI_SMEM_DOUT6_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT6_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT6_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT6_NUM_S 12
/* SPI_MEM_SPI_SMEM_DOUT5_NUM : R/W ;bitpos:[11:10] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: output
without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
#define SPI_MEM_SPI_SMEM_DOUT5_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT5_NUM_M ((SPI_MEM_SPI_SMEM_DOUT5_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT5_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT5_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT5_NUM_S 10
/* SPI_MEM_SPI_SMEM_DOUT4_NUM : R/W ;bitpos:[9:8] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: output
without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
#define SPI_MEM_SPI_SMEM_DOUT4_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT4_NUM_M ((SPI_MEM_SPI_SMEM_DOUT4_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT4_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT4_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT4_NUM_S 8
/* SPI_MEM_SPI_SMEM_DOUT3_NUM : R/W ;bitpos:[7:6] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_SPI_SMEM_DOUT3_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT3_NUM_M ((SPI_MEM_SPI_SMEM_DOUT3_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT3_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT3_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT3_NUM_S 6
/* SPI_MEM_SPI_SMEM_DOUT2_NUM : R/W ;bitpos:[5:4] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_SPI_SMEM_DOUT2_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT2_NUM_M ((SPI_MEM_SPI_SMEM_DOUT2_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT2_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT2_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT2_NUM_S 4
/* SPI_MEM_SPI_SMEM_DOUT1_NUM : R/W ;bitpos:[3:2] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_SPI_SMEM_DOUT1_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT1_NUM_M ((SPI_MEM_SPI_SMEM_DOUT1_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT1_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT1_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT1_NUM_S 2
/* SPI_MEM_SPI_SMEM_DOUT0_NUM : R/W ;bitpos:[1:0] ;default: 2'h0 ; */
/*description: the output signals are delayed by system clock cycles 0: delayed
by 1 cycle 1: delayed by 2 cycles ...*/
#define SPI_MEM_SPI_SMEM_DOUT0_NUM 0x00000003
#define SPI_MEM_SPI_SMEM_DOUT0_NUM_M ((SPI_MEM_SPI_SMEM_DOUT0_NUM_V) << (SPI_MEM_SPI_SMEM_DOUT0_NUM_S))
#define SPI_MEM_SPI_SMEM_DOUT0_NUM_V 0x3
#define SPI_MEM_SPI_SMEM_DOUT0_NUM_S 0
#define SPI_MEM_SPI_SMEM_AC_REG(i) (REG_SPI_MEM_BASE(i) + 0x0D0)
/* SPI_MEM_SPI_SMEM_CS_HOLD_DELAY : R/W ;bitpos:[30:25] ;default: 6'd0 ; */
/*description: These bits are used to set the minimum CS high time tSHSL between
SPI burst transfer when accesses to external RAM. tSHSL is (SPI_SMEM_CS_HOLD_DELAY[5:0] + 1) MSPI core clock cycles.*/
#define SPI_MEM_SPI_SMEM_CS_HOLD_DELAY 0x0000003F
#define SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_M ((SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V) << (SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S))
#define SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V 0x3F
#define SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S 25
/* SPI_MEM_SPI_SMEM_ECC_16TO18_BYTE_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
/*description: Set this bit to enable MSPI ECC 16 bytes data with 2 ECC bytes
mode when accesses external RAM.*/
@ -1395,7 +1972,7 @@ extern "C" {
#define SPI_MEM_SPI01_CLK_SEL_S 0
#define SPI_MEM_DATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x3FC)
/* SPI_MEM_DATE : R/W ;bitpos:[27:0] ;default: 28'h2004010 ; */
/* SPI_MEM_DATE : R/W ;bitpos:[27:0] ;default: 28'h2003220 ; */
/*description: SPI register version.*/
#define SPI_MEM_DATE 0x0FFFFFFF
#define SPI_MEM_DATE_M ((SPI_MEM_DATE_V) << (SPI_MEM_DATE_S))

View File

@ -20,414 +20,470 @@ extern "C" {
#include <stdint.h>
typedef volatile struct {
uint32_t addr; /*In user mode it is the memory address. other then the bit0-bit23 is the memory address the bit24-bit31 are the byte length of a transfer.*/
union {
struct {
uint32_t reserved0: 3; /*reserved*/
uint32_t fdummy_out: 1; /*In the dummy phase the signal level of spi is output by the spi controller.*/
uint32_t fdout_oct: 1; /*Apply 8 signals during write-data phase 1:enable 0: disable*/
uint32_t fdin_oct: 1; /*Apply 8 signals during read-data phase 1:enable 0: disable*/
uint32_t faddr_oct: 1; /*Apply 8 signals during address phase 1:enable 0: disable*/
uint32_t fcmd_dual: 1; /*Apply 2 signals during command phase 1:enable 0: disable*/
uint32_t fcmd_quad: 1; /*Apply 4 signals during command phase 1:enable 0: disable*/
uint32_t fcmd_oct: 1; /*Apply 8 signals during command phase 1:enable 0: disable*/
uint32_t fcs_crc_en: 1; /*For SPI1 initialize crc32 module before writing encrypted data to flash. Active low.*/
uint32_t tx_crc_en: 1; /*For SPI1 enable crc32 when writing encrypted data to flash. 1: enable 0:disable*/
uint32_t reserved12: 1; /*reserved*/
uint32_t fastrd_mode: 1; /*This bit enable the bits: spi_mem_fread_qio spi_mem_fread_dio spi_mem_fread_qout and spi_mem_fread_dout. 1: enable 0: disable.*/
uint32_t fread_dual: 1; /*In the read operations read-data phase apply 2 signals. 1: enable 0: disable.*/
uint32_t reserved15: 3; /*reserved*/
uint32_t q_pol: 1; /*The bit is used to set MISO line polarity 1: high 0 low*/
uint32_t d_pol: 1; /*The bit is used to set MOSI line polarity 1: high 0 low*/
uint32_t fread_quad: 1; /*In the read operations read-data phase apply 4 signals. 1: enable 0: disable.*/
uint32_t wp: 1; /*Write protect signal output when SPI is idle. 1: output high 0: output low.*/
uint32_t reserved22: 1; /*reserved*/
uint32_t fread_dio: 1; /*In the read operations address phase and read-data phase apply 2 signals. 1: enable 0: disable.*/
uint32_t fread_qio: 1; /*In the read operations address phase and read-data phase apply 4 signals. 1: enable 0: disable.*/
uint32_t reserved25: 7; /*reserved*/
uint32_t reserved0 : 17; /*reserved*/
uint32_t flash_pe : 1; /*In user mode it is set to indicate that program/erase operation will be triggered. The bit is combined with spi_mem_usr bit. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t usr : 1; /*User define command enable. An operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_hpm : 1; /*Drive Flash into high performance mode. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_res : 1; /*This bit combined with reg_resandres bit releases Flash from the power-down state or high performance mode and obtains the devices ID. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_dp : 1; /*Drive Flash into power down. An operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_ce : 1; /*Chip erase enable. Chip erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_be : 1; /*Block erase enable(32KB) . Block erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_se : 1; /*Sector erase enable(4KB). Sector erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_pp : 1; /*Page program enable(1 byte ~256 bytes data to be programmed). Page program operation will be triggered when the bit is set. The bit will be cleared once the operation done .1: enable 0: disable.*/
uint32_t flash_wrsr : 1; /*Write status register enable. Write status operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_rdsr : 1; /*Read status register-1. Read status operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_rdid : 1; /*Read JEDEC ID . Read ID command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
uint32_t flash_wrdi : 1; /*Write flash disable. Write disable command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
uint32_t flash_wren : 1; /*Write flash enable. Write enable command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
uint32_t flash_read : 1; /*Read flash enable. Read flash operation will be triggered when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable.*/
};
uint32_t val;
} cmd;
uint32_t addr; /*In user mode it is the memory address. other then the bit0-bit23 is the memory address the bit24-bit31 are the byte length of a transfer.*/
union {
struct {
uint32_t reserved0 : 3; /*reserved*/
uint32_t fdummy_out : 1; /*In the dummy phase the signal level of spi is output by the spi controller.*/
uint32_t fdout_oct : 1; /*Apply 8 signals during write-data phase 1:enable 0: disable*/
uint32_t fdin_oct : 1; /*Apply 8 signals during read-data phase 1:enable 0: disable*/
uint32_t faddr_oct : 1; /*Apply 8 signals during address phase 1:enable 0: disable*/
uint32_t fcmd_dual : 1; /*Apply 2 signals during command phase 1:enable 0: disable*/
uint32_t fcmd_quad : 1; /*Apply 4 signals during command phase 1:enable 0: disable*/
uint32_t fcmd_oct : 1; /*Apply 8 signals during command phase 1:enable 0: disable*/
uint32_t fcs_crc_en : 1; /*For SPI1 initialize crc32 module before writing encrypted data to flash. Active low.*/
uint32_t tx_crc_en : 1; /*For SPI1 enable crc32 when writing encrypted data to flash. 1: enable 0:disable*/
uint32_t reserved12 : 1; /*reserved*/
uint32_t fastrd_mode : 1; /*This bit enable the bits: spi_mem_fread_qio spi_mem_fread_dio spi_mem_fread_qout and spi_mem_fread_dout. 1: enable 0: disable.*/
uint32_t fread_dual : 1; /*In the read operations read-data phase apply 2 signals. 1: enable 0: disable.*/
uint32_t reserved15 : 3; /*reserved*/
uint32_t q_pol : 1; /*The bit is used to set MISO line polarity 1: high 0 low*/
uint32_t d_pol : 1; /*The bit is used to set MOSI line polarity 1: high 0 low*/
uint32_t fread_quad : 1; /*In the read operations read-data phase apply 4 signals. 1: enable 0: disable.*/
uint32_t wp : 1; /*Write protect signal output when SPI is idle. 1: output high 0: output low.*/
uint32_t reserved22 : 1; /*reserved*/
uint32_t fread_dio : 1; /*In the read operations address phase and read-data phase apply 2 signals. 1: enable 0: disable.*/
uint32_t fread_qio : 1; /*In the read operations address phase and read-data phase apply 4 signals. 1: enable 0: disable.*/
uint32_t reserved25 : 7; /*reserved*/
};
uint32_t val;
} ctrl;
union {
struct {
uint32_t clk_mode: 2; /*SPI clock mode bits. 0: SPI clock is off when CS inactive 1: SPI clock is delayed one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3: SPI clock is alwasy on.*/
uint32_t reserved2: 30; /*reserved*/
uint32_t clk_mode : 2; /*SPI clock mode bits. 0: SPI clock is off when CS inactive 1: SPI clock is delayed one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3: SPI clock is alwasy on.*/
uint32_t cs_hold_dly_res : 12; /*Delay cycles of resume Flash when resume Flash from standby mode is enable by spi clock.*/
uint32_t cs_hold_dly : 12; /*SPI fsm is delayed to idle by spi clock cycles.*/
uint32_t cs_dly_num : 2; /*spi_mem_cs signal is delayed by system clock cycles*/
uint32_t cs_dly_mode : 2; /*The cs signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk*/
uint32_t reserved30 : 1;
uint32_t cs_dly_edge : 1; /*The bit is used to select the spi clock edge to modify CS line timing.*/
};
uint32_t val;
} ctrl1;
union {
struct {
uint32_t cs_setup_time: 5; /*(cycles-1) of prepare phase by spi clock this bits are combined with spi_mem_cs_setup bit.*/
uint32_t cs_hold_time: 5; /*Spi cs signal is delayed to inactive by spi clock this bits are combined with spi_mem_cs_hold bit.*/
uint32_t ecc_cs_hold_time: 3; /*SPI_MEM_CS_HOLD_TIME + SPI_MEM_ECC_CS_HOLD_TIME is the MSPI CS hold cycle in ECC mode when accessed flash.*/
uint32_t ecc_skip_page_corner: 1; /*1: MSPI skips page corner when accesses flash. 0: Not skip page corner when accesses flash.*/
uint32_t ecc_16to18_byte_en: 1; /*Set this bit to enable MSPI ECC 16 bytes data with 2 ECC bytes mode when accesses flash.*/
uint32_t reserved15: 10; /*reserved*/
uint32_t cs_hold_delay: 6; /*These bits are used to set the minimum CS high time tSHSL between SPI burst transfer when accesses to flash. tSHSL is (SPI_MEM_CS_HOLD_DELAY[5:0] + 1) MSPI core clock cycles.*/
uint32_t sync_reset: 1; /*The FSM will be reset.*/
uint32_t cs_setup_time : 5; /*(cycles-1) of prepare phase by spi clock this bits are combined with spi_mem_cs_setup bit.*/
uint32_t cs_hold_time : 5; /*Spi cs signal is delayed to inactive by spi clock this bits are combined with spi_mem_cs_hold bit.*/
uint32_t ecc_cs_hold_time : 3; /*SPI_MEM_CS_HOLD_TIME + SPI_MEM_ECC_CS_HOLD_TIME is the MSPI CS hold cycle in ECC mode when accessed flash.*/
uint32_t reserved13 : 18; /*reserved*/
uint32_t sync_reset : 1; /*The FSM will be reset.*/
};
uint32_t val;
} ctrl2;
union {
struct {
uint32_t clkcnt_l: 8; /*In the master mode it must be equal to spi_mem_clkcnt_N.*/
uint32_t clkcnt_h: 8; /*In the master mode it must be floor((spi_mem_clkcnt_N+1)/2-1).*/
uint32_t clkcnt_n: 8; /*In the master mode it is the divider of spi_mem_clk. So spi_mem_clk frequency is system/(spi_mem_clkcnt_N+1)*/
uint32_t reserved24: 7; /*reserved*/
uint32_t clk_equ_sysclk: 1; /*Set this bit in 1-division mode.*/
uint32_t clkcnt_l : 8; /*In the master mode it must be equal to spi_mem_clkcnt_N.*/
uint32_t clkcnt_h : 8; /*In the master mode it must be floor((spi_mem_clkcnt_N+1)/2-1).*/
uint32_t clkcnt_n : 8; /*In the master mode it is the divider of spi_mem_clk. So spi_mem_clk frequency is system/(spi_mem_clkcnt_N+1)*/
uint32_t reserved24 : 7; /*In the master mode it is pre-divider of spi_mem_clk.*/
uint32_t clk_equ_sysclk : 1; /*reserved*/
};
uint32_t val;
} clock;
union {
struct {
uint32_t reserved0: 6; /*reserved*/
uint32_t cs_hold: 1; /*spi cs keep low when spi is in done phase. 1: enable 0: disable.*/
uint32_t cs_setup: 1; /*spi cs is enable when spi is in prepare phase. 1: enable 0: disable.*/
uint32_t reserved8: 1; /*reserved*/
uint32_t ck_out_edge: 1; /*the bit combined with spi_mem_mosi_delay_mode bits to set mosi signal delay mode.*/
uint32_t reserved10: 16; /*reserved*/
uint32_t usr_dummy_idle: 1; /*spi clock is disable in dummy phase when the bit is enable.*/
uint32_t reserved27: 1; /*reserved*/
uint32_t reserved28: 1; /*reserved*/
uint32_t usr_dummy: 1; /*This bit enable the dummy phase of an operation.*/
uint32_t reserved30: 1; /*reserved*/
uint32_t reserved31: 1; /*reserved*/
uint32_t reserved0 : 6; /*reserved*/
uint32_t cs_hold : 1; /*spi cs keep low when spi is in done phase. 1: enable 0: disable.*/
uint32_t cs_setup : 1; /*spi cs is enable when spi is in prepare phase. 1: enable 0: disable.*/
uint32_t reserved8 : 1; /*reserved*/
uint32_t ck_out_edge : 1; /*the bit combined with spi_mem_mosi_delay_mode bits to set mosi signal delay mode.*/
uint32_t reserved10 : 2; /*reserved*/
uint32_t fwrite_dual : 1; /*In the write operations read-data phase apply 2 signals*/
uint32_t fwrite_quad : 1; /*In the write operations read-data phase apply 4 signals*/
uint32_t fwrite_dio : 1; /*In the write operations address phase and read-data phase apply 2 signals.*/
uint32_t fwrite_qio : 1; /*In the write operations address phase and read-data phase apply 4 signals.*/
uint32_t reserved16 : 8; /*reserved*/
uint32_t usr_miso_highpart : 1; /*read-data phase only access to high-part of the buffer spi_mem_w8~spi_mem_w15. 1: enable 0: disable.*/
uint32_t usr_mosi_highpart : 1; /*write-data phase only access to high-part of the buffer spi_mem_w8~spi_mem_w15. 1: enable 0: disable.*/
uint32_t usr_dummy_idle : 1; /*spi clock is disable in dummy phase when the bit is enable.*/
uint32_t usr_mosi : 1; /*This bit enable the write-data phase of an operation.*/
uint32_t usr_miso : 1; /*This bit enable the read-data phase of an operation.*/
uint32_t usr_dummy : 1; /*This bit enable the dummy phase of an operation.*/
uint32_t usr_addr : 1; /*This bit enable the address phase of an operation.*/
uint32_t usr_command : 1; /*This bit enable the command phase of an operation.*/
};
uint32_t val;
} user;
union {
struct {
uint32_t usr_dummy_cyclelen: 6; /*The length in spi_mem_clk cycles of dummy phase. The register value shall be (cycle_num-1).*/
uint32_t reserved6: 20; /*reserved*/
uint32_t usr_addr_bitlen: 6; /*The length in bits of address phase. The register value shall be (bit_num-1).*/
uint32_t usr_dummy_cyclelen : 6; /*The length in spi_mem_clk cycles of dummy phase. The register value shall be (cycle_num-1).*/
uint32_t reserved6 : 20; /*reserved*/
uint32_t usr_addr_bitlen : 6; /*The length in bits of address phase. The register value shall be (bit_num-1).*/
};
uint32_t val;
} user1;
union {
struct {
uint32_t usr_command_value: 16; /*The value of command.*/
uint32_t reserved16: 12; /*reserved*/
uint32_t usr_command_bitlen: 4; /*The length in bits of command phase. The register value shall be (bit_num-1)*/
uint32_t usr_command_value : 16; /*The value of command.*/
uint32_t reserved16 : 12; /*reserved*/
uint32_t usr_command_bitlen : 4; /*The length in bits of command phase. The register value shall be (bit_num-1)*/
};
uint32_t val;
} user2;
uint32_t reserved_24;
uint32_t reserved_28;
union {
struct {
uint32_t reserved0: 16; /*reserved*/
uint32_t wb_mode: 8; /*Mode bits in the flash fast read mode it is combined with spi_mem_fastrd_mode bit.*/
uint32_t reserved24: 8; /*reserved*/
uint32_t usr_mosi_bit_len : 11; /*The length in bits of write-data. The register value shall be (bit_num-1).*/
uint32_t reserved11 : 21; /*reserved*/
};
uint32_t val;
} mosi_dlen;
union {
struct {
uint32_t usr_miso_bit_len : 11; /*The length in bits of read-data. The register value shall be (bit_num-1).*/
uint32_t reserved11 : 21; /*reserved*/
};
uint32_t val;
} miso_dlen;
union {
struct {
uint32_t status : 16; /*The value is stored when set spi_mem_flash_rdsr bit and spi_mem_flash_res bit.*/
uint32_t wb_mode : 8; /*Mode bits in the flash fast read mode it is combined with spi_mem_fastrd_mode bit.*/
uint32_t reserved24 : 8; /*reserved*/
};
uint32_t val;
} rd_status;
uint32_t ext_addr; /*The register are the higher 32bits in the 64 bits address mode.*/
uint32_t ext_addr; /*The register are the higher 32bits in the 64 bits address mode.*/
union {
struct {
uint32_t reserved0: 3; /*reserved*/
uint32_t trans_end: 1; /*The bit is used to indicate the transimitting is done.*/
uint32_t trans_end_en: 1; /*The bit is used to enable the intterrupt of SPI transmitting done.*/
uint32_t reserved5: 2; /*reserved*/
uint32_t fsub_pin: 1; /*For SPI0 flash is connected to SUBPINs.*/
uint32_t ssub_pin: 1; /*For SPI0 sram is connected to SUBPINs.*/
uint32_t ck_idle_edge: 1; /*1: spi clk line is high when idle 0: spi clk line is low when idle*/
uint32_t cs_keep_active: 1; /*spi cs line keep low when the bit is set.*/
uint32_t reserved11: 21; /*reserved*/
uint32_t cs0_dis : 1; /*SPI CS0 pin enable 1: disable CS0 0: spi_mem_cs0 signal is from/to CS0 pin*/
uint32_t cs1_dis : 1; /*SPI CS1 pin enable 1: disable CS1 0: spi_mem_cs1 signal is from/to CS1 pin*/
uint32_t reserved2 : 1; /*reserved*/
uint32_t trans_end : 1; /*The bit is used to indicate the transimitting is done.*/
uint32_t trans_end_en : 1; /*The bit is used to enable the intterrupt of SPI transmitting done.*/
uint32_t cs_pol : 2; /*In the master mode the bits are the polarity of spi cs line the value is equivalent to spi_mem_cs ^ spi_mem_master_cs_pol.*/
uint32_t fsub_pin : 1; /*For SPI0 flash is connected to SUBPINs.*/
uint32_t ssub_pin : 1; /*For SPI0 sram is connected to SUBPINs.*/
uint32_t ck_idle_edge : 1; /*1: spi clk line is high when idle 0: spi clk line is low when idle*/
uint32_t cs_keep_active : 1; /*spi cs line keep low when the bit is set.*/
uint32_t auto_per : 1; /*reserved*/
uint32_t reserved12 : 20; /*reserved*/
};
uint32_t val;
} misc;
uint32_t tx_crc; /*For SPI1 the value of crc32.*/
uint32_t tx_crc; /*For SPI1 the value of crc32.*/
union {
struct {
uint32_t req_en: 1; /*For SPI0 Cache access enable 1: enable 0:disable.*/
uint32_t usr_cmd_4byte: 1; /*For SPI0 cache read flash with 4 bytes command 1: enable 0:disable.*/
uint32_t flash_usr_cmd: 1; /*For SPI0 cache read flash for user define command 1: enable 0:disable.*/
uint32_t fdin_dual: 1; /*For SPI0 flash din phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_dio.*/
uint32_t fdout_dual: 1; /*For SPI0 flash dout phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_dio.*/
uint32_t faddr_dual: 1; /*For SPI0 flash address phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_dio.*/
uint32_t fdin_quad: 1; /*For SPI0 flash din phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_qio.*/
uint32_t fdout_quad: 1; /*For SPI0 flash dout phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_qio.*/
uint32_t faddr_quad: 1; /*For SPI0 flash address phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_qio.*/
uint32_t reserved9: 23; /*reserved*/
uint32_t req_en : 1; /*For SPI0 Cache access enable 1: enable 0:disable.*/
uint32_t usr_cmd_4byte : 1; /*For SPI0 cache read flash with 4 bytes command 1: enable 0:disable.*/
uint32_t flash_usr_cmd : 1; /*For SPI0 cache read flash for user define command 1: enable 0:disable.*/
uint32_t fdin_dual : 1; /*For SPI0 flash din phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_dio.*/
uint32_t fdout_dual : 1; /*For SPI0 flash dout phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_dio.*/
uint32_t faddr_dual : 1; /*For SPI0 flash address phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_dio.*/
uint32_t fdin_quad : 1; /*For SPI0 flash din phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_qio.*/
uint32_t fdout_quad : 1; /*For SPI0 flash dout phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_qio.*/
uint32_t faddr_quad : 1; /*For SPI0 flash address phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_fread_qio.*/
uint32_t reserved9 : 23; /*reserved*/
};
uint32_t val;
} cache_fctrl;
union {
struct {
uint32_t usr_scmd_4byte: 1; /*For SPI0 In the spi sram mode cache read flash with 4 bytes command 1: enable 0:disable.*/
uint32_t usr_sram_dio: 1; /*For SPI0 In the spi sram mode spi dual I/O mode enable 1: enable 0:disable*/
uint32_t usr_sram_qio: 1; /*For SPI0 In the spi sram mode spi quad I/O mode enable 1: enable 0:disable*/
uint32_t usr_wr_sram_dummy: 1; /*For SPI0 In the spi sram mode it is the enable bit of dummy phase for write operations.*/
uint32_t usr_rd_sram_dummy: 1; /*For SPI0 In the spi sram mode it is the enable bit of dummy phase for read operations.*/
uint32_t cache_sram_usr_rcmd: 1; /*For SPI0 In the spi sram mode cache read sram for user define command.*/
uint32_t sram_rdummy_cyclelen: 6; /*For SPI0 In the sram mode it is the length in bits of read dummy phase. The register value shall be (bit_num-1).*/
uint32_t reserved12: 2; /*reserved*/
uint32_t sram_addr_bitlen: 6; /*For SPI0 In the sram mode it is the length in bits of address phase. The register value shall be (bit_num-1).*/
uint32_t cache_sram_usr_wcmd: 1; /*For SPI0 In the spi sram mode cache write sram for user define command*/
uint32_t sram_oct: 1; /*reserved*/
uint32_t sram_wdummy_cyclelen: 6; /*For SPI0 In the sram mode it is the length in bits of write dummy phase. The register value shall be (bit_num-1).*/
uint32_t reserved28: 4; /*reserved*/
uint32_t usr_scmd_4byte : 1; /*For SPI0 In the spi sram mode cache read flash with 4 bytes command 1: enable 0:disable.*/
uint32_t usr_sram_dio : 1; /*For SPI0 In the spi sram mode spi dual I/O mode enable 1: enable 0:disable*/
uint32_t usr_sram_qio : 1; /*For SPI0 In the spi sram mode spi quad I/O mode enable 1: enable 0:disable*/
uint32_t usr_wr_sram_dummy : 1; /*For SPI0 In the spi sram mode it is the enable bit of dummy phase for write operations.*/
uint32_t usr_rd_sram_dummy : 1; /*For SPI0 In the spi sram mode it is the enable bit of dummy phase for read operations.*/
uint32_t cache_sram_usr_rcmd : 1; /*For SPI0 In the spi sram mode cache read sram for user define command.*/
uint32_t sram_rdummy_cyclelen : 6; /*For SPI0 In the sram mode it is the length in bits of read dummy phase. The register value shall be (bit_num-1).*/
uint32_t reserved12 : 2; /*reserved*/
uint32_t sram_addr_bitlen : 6; /*For SPI0 In the sram mode it is the length in bits of address phase. The register value shall be (bit_num-1).*/
uint32_t cache_sram_usr_wcmd : 1; /*For SPI0 In the spi sram mode cache write sram for user define command*/
uint32_t sram_oct : 1; /*reserved*/
uint32_t sram_wdummy_cyclelen : 6; /*For SPI0 In the sram mode it is the length in bits of write dummy phase. The register value shall be (bit_num-1).*/
uint32_t reserved28 : 4; /*reserved*/
};
uint32_t val;
} cache_sctrl;
union {
struct {
uint32_t sclk_mode: 2; /*SPI clock mode bits. 0: SPI clock is off when CS inactive 1: SPI clock is delayed one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3: SPI clock is alwasy on.*/
uint32_t swb_mode: 8; /*Mode bits in the psram fast read mode it is combined with spi_mem_fastrd_mode bit.*/
uint32_t sdin_dual: 1; /*For SPI0 sram din phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t sdout_dual: 1; /*For SPI0 sram dout phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t saddr_dual: 1; /*For SPI0 sram address phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t scmd_dual: 1; /*For SPI0 sram cmd phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t sdin_quad: 1; /*For SPI0 sram din phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t sdout_quad: 1; /*For SPI0 sram dout phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t saddr_quad: 1; /*For SPI0 sram address phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t scmd_quad: 1; /*For SPI0 sram cmd phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t sdin_oct: 1; /*For SPI0 sram din phase apply 8 signals. 1: enable 0: disable.*/
uint32_t sdout_oct: 1; /*For SPI0 sram dout phase apply 8 signals. 1: enable 0: disable.*/
uint32_t saddr_oct: 1; /*For SPI0 sram address phase apply 4 signals. 1: enable 0: disable.*/
uint32_t scmd_oct: 1; /*For SPI0 sram cmd phase apply 8 signals. 1: enable 0: disable.*/
uint32_t sdummy_out: 1; /*In the dummy phase the signal level of spi is output by the spi controller.*/
uint32_t reserved23: 9; /*reserved*/
uint32_t sclk_mode : 2; /*SPI clock mode bits. 0: SPI clock is off when CS inactive 1: SPI clock is delayed one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3: SPI clock is alwasy on.*/
uint32_t swb_mode : 8; /*Mode bits in the psram fast read mode it is combined with spi_mem_fastrd_mode bit.*/
uint32_t sdin_dual : 1; /*For SPI0 sram din phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t sdout_dual : 1; /*For SPI0 sram dout phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t saddr_dual : 1; /*For SPI0 sram address phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t scmd_dual : 1; /*For SPI0 sram cmd phase apply 2 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_dio.*/
uint32_t sdin_quad : 1; /*For SPI0 sram din phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t sdout_quad : 1; /*For SPI0 sram dout phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t saddr_quad : 1; /*For SPI0 sram address phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t scmd_quad : 1; /*For SPI0 sram cmd phase apply 4 signals. 1: enable 0: disable. The bit is the same with spi_mem_usr_sram_qio.*/
uint32_t sdin_oct : 1; /*For SPI0 sram din phase apply 8 signals. 1: enable 0: disable.*/
uint32_t sdout_oct : 1; /*For SPI0 sram dout phase apply 8 signals. 1: enable 0: disable.*/
uint32_t saddr_oct : 1; /*For SPI0 sram address phase apply 4 signals. 1: enable 0: disable.*/
uint32_t scmd_oct : 1; /*For SPI0 sram cmd phase apply 8 signals. 1: enable 0: disable.*/
uint32_t sdummy_out : 1; /*In the dummy phase the signal level of spi is output by the spi controller.*/
uint32_t reserved23 : 9; /*reserved*/
};
uint32_t val;
} sram_cmd;
union {
struct {
uint32_t usr_rd_cmd_value: 16; /*For SPI0 When cache mode is enable it is the read command value of command phase for sram.*/
uint32_t reserved16: 12; /*reserved*/
uint32_t usr_rd_cmd_bitlen: 4; /*For SPI0 When cache mode is enable it is the length in bits of command phase for sram. The register value shall be (bit_num-1).*/
uint32_t usr_rd_cmd_value : 16; /*For SPI0 When cache mode is enable it is the read command value of command phase for sram.*/
uint32_t reserved16 : 12; /*reserved*/
uint32_t usr_rd_cmd_bitlen : 4; /*For SPI0 When cache mode is enable it is the length in bits of command phase for sram. The register value shall be (bit_num-1).*/
};
uint32_t val;
} sram_drd_cmd;
union {
struct {
uint32_t usr_wr_cmd_value: 16; /*For SPI0 When cache mode is enable it is the write command value of command phase for sram.*/
uint32_t reserved16: 12; /*reserved*/
uint32_t usr_wr_cmd_bitlen: 4; /*For SPI0 When cache mode is enable it is the in bits of command phase for sram. The register value shall be (bit_num-1).*/
uint32_t usr_wr_cmd_value : 16; /*For SPI0 When cache mode is enable it is the write command value of command phase for sram.*/
uint32_t reserved16 : 12; /*reserved*/
uint32_t usr_wr_cmd_bitlen : 4; /*For SPI0 When cache mode is enable it is the in bits of command phase for sram. The register value shall be (bit_num-1).*/
};
uint32_t val;
} sram_dwr_cmd;
union {
struct {
uint32_t cnt_l: 8; /*For SPI0 sram interface it must be equal to spi_mem_clkcnt_N.*/
uint32_t cnt_h: 8; /*For SPI0 sram interface it must be floor((spi_mem_clkcnt_N+1)/2-1).*/
uint32_t cnt_n: 8; /*For SPI0 sram interface it is the divider of spi_mem_clk. So spi_mem_clk frequency is system/(spi_mem_clkcnt_N+1)*/
uint32_t reserved24: 7; /*reserved*/
uint32_t equ_sysclk: 1; /*For SPI0 sram interface 1: spi_mem_clk is eqaul to system 0: spi_mem_clk is divided from system clock.*/
uint32_t cnt_l : 8; /*For SPI0 sram interface it must be equal to spi_mem_clkcnt_N.*/
uint32_t cnt_h : 8; /*For SPI0 sram interface it must be floor((spi_mem_clkcnt_N+1)/2-1).*/
uint32_t cnt_n : 8; /*For SPI0 sram interface it is the divider of spi_mem_clk. So spi_mem_clk frequency is system/(spi_mem_clkcnt_N+1)*/
uint32_t reserved24 : 7; /*reserved*/
uint32_t equ_sysclk : 1; /*For SPI0 sram interface 1: spi_mem_clk is eqaul to system 0: spi_mem_clk is divided from system clock.*/
};
uint32_t val;
} sram_clk;
union {
struct {
uint32_t st: 3; /*The status of spi state machine. 0: idle state 1: preparation state 2: send command state 3: send data state 4: red data state 5:write data state 6: wait state 7: done state.*/
uint32_t reserved3: 29; /*reserved*/
uint32_t st : 3; /*The status of spi state machine. 0: idle state 1: preparation state 2: send command state 3: send data state 4: red data state 5:write data state 6: wait state 7: done state.*/
uint32_t reserved3 : 29; /*reserved*/
};
uint32_t val;
} fsm;
uint32_t reserved_58;
uint32_t reserved_5c;
uint32_t reserved_60;
uint32_t reserved_64;
uint32_t reserved_68;
uint32_t reserved_6c;
uint32_t reserved_70;
uint32_t reserved_74;
uint32_t reserved_78;
uint32_t reserved_7c;
uint32_t reserved_80;
uint32_t reserved_84;
uint32_t reserved_88;
uint32_t reserved_8c;
uint32_t reserved_90;
uint32_t reserved_94;
uint32_t reserved_98;
uint32_t reserved_9c;
uint32_t reserved_a0;
uint32_t reserved_a4;
uint32_t data_buf[18]; /*data buffer*/
union {
struct {
uint32_t timing_clk_ena: 1; /*The bit is used to enable timing adjust clock for all reading operations.*/
uint32_t timing_cali: 1; /*The bit is used to enable timing auto-calibration for all reading operations.*/
uint32_t extra_dummy_cyclelen: 3; /*add extra dummy spi clock cycle length for spi clock calibration.*/
uint32_t reserved5: 27;
uint32_t waiti_en : 1; /*auto-waiting flash idle operation when program flash or erase flash. 1: enable 0: disable.*/
uint32_t waiti_dummy : 1; /*The dummy phase enable when auto wait flash idle*/
uint32_t waiti_cmd : 8; /*The command to auto wait idle*/
uint32_t waiti_dummy_cyclelen : 8; /*The dummy cycle length when auto wait flash idle*/
uint32_t reserved18 : 14; /*reserved*/
};
uint32_t val;
} flash_waiti_ctrl;
union {
struct {
uint32_t flash_per : 1; /*program erase resume bit program erase suspend operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t flash_pes : 1; /*program erase suspend bit program erase suspend operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/
uint32_t reserved2 : 30;
};
uint32_t val;
} flash_sus_cmd;
union {
struct {
uint32_t flash_pes_en : 1; /*Auto-suspending enable*/
uint32_t flash_per_command : 8; /*Program/Erase resume command.*/
uint32_t flash_pes_command : 8; /*Program/Erase suspend command.*/
uint32_t reserved17 : 15;
};
uint32_t val;
} flash_sus_ctrl;
union {
struct {
uint32_t flash_sus : 1; /*The status of flash suspend only used in SPI1.*/
uint32_t reserved1 : 31;
};
uint32_t val;
} sus_status;
union {
struct {
uint32_t timing_clk_ena : 1; /*The bit is used to enable timing adjust clock for all reading operations.*/
uint32_t timing_cali : 1; /*The bit is used to enable timing auto-calibration for all reading operations.*/
uint32_t extra_dummy_cyclelen : 3; /*add extra dummy spi clock cycle length for spi clock calibration.*/
uint32_t reserved5 : 27;
};
uint32_t val;
} timing_cali;
union {
struct {
uint32_t din0_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din1_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din2_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din3_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din4_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t din5_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t din6_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t din7_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t dins_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t reserved18: 14; /*reserved*/
uint32_t din0_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din1_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din2_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din3_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t din4_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t din5_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t din6_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t din7_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t dins_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the spi_clk*/
uint32_t reserved18 : 14; /*reserved*/
};
uint32_t val;
} din_mode;
union {
struct {
uint32_t din0_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din1_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din2_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din3_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din4_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din5_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din6_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din7_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t dins_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t reserved18: 14; /*reserved*/
uint32_t din0_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din1_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din2_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din3_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din4_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din5_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din6_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t din7_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t dins_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t reserved18 : 14; /*reserved*/
};
uint32_t val;
} din_num;
union {
struct {
uint32_t dout0_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout1_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout2_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout3_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout4_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t dout5_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t dout6_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t dout7_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t douts_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t reserved9: 23; /*reserved*/
uint32_t dout0_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout1_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout2_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout3_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t dout4_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t dout5_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t dout6_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t dout7_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t douts_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the spi_clk*/
uint32_t reserved9 : 23; /*reserved*/
};
uint32_t val;
} dout_mode;
uint32_t reserved_b8;
union {
struct {
uint32_t spi_smem_timing_clk_ena: 1; /*For sram the bit is used to enable timing adjust clock for all reading operations.*/
uint32_t spi_smem_timing_cali: 1; /*For sram the bit is used to enable timing auto-calibration for all reading operations.*/
uint32_t spi_smem_extra_dummy_cyclelen: 3; /*For sram add extra dummy spi clock cycle length for spi clock calibration.*/
uint32_t reserved5: 27;
uint32_t spi_smem_timing_clk_ena : 1; /*For sram the bit is used to enable timing adjust clock for all reading operations.*/
uint32_t spi_smem_timing_cali : 1; /*For sram the bit is used to enable timing auto-calibration for all reading operations.*/
uint32_t spi_smem_extra_dummy_cyclelen : 3; /*For sram add extra dummy spi clock cycle length for spi clock calibration.*/
uint32_t reserved5 : 27;
};
uint32_t val;
} spi_smem_timing_cali;
union {
struct {
uint32_t spi_smem_din0_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din1_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din2_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din3_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din4_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din5_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din6_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din7_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_dins_mode: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t reserved18: 14; /*reserved*/
uint32_t spi_smem_din0_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din1_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din2_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din3_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din4_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din5_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din6_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_din7_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t spi_smem_dins_mode : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t reserved18 : 14; /*reserved*/
};
uint32_t val;
} spi_smem_din_mode;
union {
struct {
uint32_t spi_smem_din0_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din1_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din2_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din3_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din4_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din5_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din6_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din7_num: 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_dins_num: 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t reserved18: 14; /*reserved*/
uint32_t spi_smem_din0_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din1_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din2_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din3_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din4_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din5_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din6_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_din7_num : 2; /*the input signals are delayed by system clock cycles 0: delayed by 1 cycle 1: delayed by 2 cycles ...*/
uint32_t spi_smem_dins_num : 2; /*the input signals are delayed by system clock cycles 0: input without delayed 1: input with the posedge of clk_apb 2 input with the negedge of clk_apb 3: input with the posedge of clk_160 4 input with the negedge of clk_160 5: input with the spi_clk high edge 6: input with the spi_clk low edge*/
uint32_t reserved18 : 14; /*reserved*/
};
uint32_t val;
} spi_smem_din_num;
union {
struct {
uint32_t spi_smem_dout0_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout1_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout2_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout3_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout4_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout5_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout6_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout7_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_douts_mode: 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t reserved9: 23; /*reserved*/
uint32_t spi_smem_dout0_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout1_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout2_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout3_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout4_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout5_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout6_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_dout7_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t spi_smem_douts_mode : 1; /*the output signals are delayed by system clock cycles 0: output without delayed 1: output with the posedge of clk_apb 2 output with the negedge of clk_apb 3: output with the posedge of clk_160 4 output with the negedge of clk_160 5: output with the spi_clk high edge 6: output with the spi_clk low edge*/
uint32_t reserved9 : 23; /*reserved*/
};
uint32_t val;
} spi_smem_dout_mode;
uint32_t reserved_cc;
union {
struct {
uint32_t spi_smem_cs_setup: 1; /*For spi0 spi cs is enable when spi is in prepare phase. 1: enable 0: disable.*/
uint32_t spi_smem_cs_hold: 1; /*For spi0 spi cs keep low when spi is in done phase. 1: enable 0: disable.*/
uint32_t spi_smem_cs_setup_time: 5; /*For spi0 (cycles-1) of prepare phase by spi clock this bits are combined with spi_mem_cs_setup bit.*/
uint32_t spi_smem_cs_hold_time: 5; /*For spi0 spi cs signal is delayed to inactive by spi clock this bits are combined with spi_mem_cs_hold bit.*/
uint32_t spi_smem_ecc_cs_hold_time: 3; /*SPI_SMEM_CS_HOLD_TIME + SPI_SMEM_ECC_CS_HOLD_TIME is the MSPI CS hold cycles in ECC mode when accessed external RAM.*/
uint32_t spi_smem_ecc_skip_page_corner: 1; /*1: MSPI skips page corner when accesses external RAM. 0: Not skip page corner when accesses external RAM.*/
uint32_t spi_smem_ecc_16to18_byte_en: 1; /*Set this bit to enable MSPI ECC 16 bytes data with 2 ECC bytes mode when accesses external RAM.*/
uint32_t reserved17: 8; /*reserved*/
uint32_t spi_smem_cs_hold_delay: 6; /*These bits are used to set the minimum CS high time tSHSL between SPI burst transfer when accesses to external RAM. tSHSL is (SPI_SMEM_CS_HOLD_DELAY[5:0] + 1) MSPI core clock cycles.*/
uint32_t reserved31: 1; /*reserved*/
uint32_t spi_smem_cs_setup : 1; /*For spi0 spi cs is enable when spi is in prepare phase. 1: enable 0: disable.*/
uint32_t spi_smem_cs_hold : 1; /*For spi0 spi cs keep low when spi is in done phase. 1: enable 0: disable.*/
uint32_t spi_smem_cs_setup_time : 5; /*For spi0 (cycles-1) of prepare phase by spi clock this bits are combined with spi_mem_cs_setup bit.*/
uint32_t spi_smem_cs_hold_time : 5; /*For spi0 spi cs signal is delayed to inactive by spi clock this bits are combined with spi_mem_cs_hold bit.*/
uint32_t spi_smem_ecc_cs_hold_time : 3; /*SPI_SMEM_CS_HOLD_TIME + SPI_SMEM_ECC_CS_HOLD_TIME is the MSPI CS hold cycles in ECC mode when accessed external RAM.*/
uint32_t reserved15 : 17;
};
uint32_t val;
} spi_smem_ac;
union {
struct {
uint32_t spi_fmem_ddr_en: 1; /*1: in ddr mode 0 in sdr mode*/
uint32_t spi_fmem_var_dummy: 1; /*Set the bit to enable variable dummy cycle in spi ddr mode.*/
uint32_t spi_fmem_ddr_rdat_swp: 1; /*Set the bit to reorder rx data of the word in spi ddr mode.*/
uint32_t spi_fmem_ddr_wdat_swp: 1; /*Set the bit to reorder tx data of the word in spi ddr mode.*/
uint32_t spi_fmem_ddr_cmd_dis: 1; /*the bit is used to disable dual edge in command phase when ddr mode.*/
uint32_t spi_fmem_outminbytelen: 7; /*It is the minimum output data length in the panda device.*/
uint32_t spi_fmem_tx_ddr_msk_en: 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR write mode when accesses to flash.*/
uint32_t spi_fmem_rx_ddr_msk_en: 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR read mode when accesses to flash.*/
uint32_t spi_fmem_usr_ddr_dqs_thd: 7; /*The delay number of data strobe which from memory based on SPI clock.*/
uint32_t spi_fmem_ddr_dqs_loop: 1; /*the data strobe is generated by SPI.*/
uint32_t spi_fmem_ddr_dqs_loop_mode: 2; /*the bits are combined with the bit spi_fmem_ddr_fdqs_loop which used to select data strobe generating mode in ddr mode.*/
uint32_t spi_fmem_clk_diff_en: 1; /*Set this bit to enable the differential SPI_CLK#.*/
uint32_t spi_fmem_hyperbus_mode: 1; /*Set this bit to enable the SPI HyperBus mode.*/
uint32_t spi_fmem_dqs_ca_in: 1; /*Set this bit to enable the input of SPI_DQS signal in SPI phases of CMD and ADDR.*/
uint32_t spi_fmem_hyperbus_dummy_2x: 1; /*Set this bit to enable the vary dummy function in SPI HyperBus mode when SPI0 accesses flash or SPI1 accesses flash or sram.*/
uint32_t spi_fmem_clk_diff_inv: 1; /*Set this bit to invert SPI_DIFF when accesses to flash. .*/
uint32_t spi_fmem_octa_ram_addr: 1; /*Set this bit to enable octa_ram address out when accesses to flash which means ADDR_OUT[31:0] = {spi_usr_addr_value[25:4] 6'd0 spi_usr_addr_value[3:1] 1'b0}.*/
uint32_t spi_fmem_hyperbus_ca: 1; /*Set this bit to enable HyperRAM address out when accesses to flash which means ADDR_OUT[31:0] = {spi_usr_addr_value[19:4] 13'd0 spi_usr_addr_value[3:1]}.*/
uint32_t reserved31: 1; /*reserved*/
uint32_t spi_fmem_ddr_en : 1; /*1: in ddr mode 0 in sdr mode*/
uint32_t spi_fmem_var_dummy : 1; /*Set the bit to enable variable dummy cycle in spi ddr mode.*/
uint32_t spi_fmem_ddr_rdat_swp : 1; /*Set the bit to reorder rx data of the word in spi ddr mode.*/
uint32_t spi_fmem_ddr_wdat_swp : 1; /*Set the bit to reorder tx data of the word in spi ddr mode.*/
uint32_t spi_fmem_ddr_cmd_dis : 1; /*the bit is used to disable dual edge in command phase when ddr mode.*/
uint32_t spi_fmem_outminbytelen : 7; /*It is the minimum output data length in the panda device.*/
uint32_t spi_fmem_tx_ddr_msk_en : 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR write mode when accesses to flash.*/
uint32_t spi_fmem_rx_ddr_msk_en : 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR read mode when accesses to flash.*/
uint32_t spi_fmem_usr_ddr_dqs_thd : 7; /*The delay number of data strobe which from memory based on SPI clock.*/
uint32_t spi_fmem_ddr_dqs_loop : 1; /*the data strobe is generated by SPI.*/
uint32_t spi_fmem_ddr_dqs_loop_mode : 2; /*the bits are combined with the bit spi_fmem_ddr_fdqs_loop which used to select data strobe generating mode in ddr mode.*/
uint32_t spi_fmem_clk_diff_en : 1; /*Set this bit to enable the differential SPI_CLK#.*/
uint32_t spi_fmem_hyperbus_mode : 1; /*Set this bit to enable the SPI HyperBus mode.*/
uint32_t spi_fmem_dqs_ca_in : 1; /*Set this bit to enable the input of SPI_DQS signal in SPI phases of CMD and ADDR.*/
uint32_t spi_fmem_hyperbus_dummy_2x : 1; /*Set this bit to enable the vary dummy function in SPI HyperBus mode when SPI0 accesses flash or SPI1 accesses flash or sram.*/
uint32_t spi_fmem_clk_diff_inv : 1; /*Set this bit to invert SPI_DIFF when accesses to flash. .*/
uint32_t spi_fmem_octa_ram_addr : 1; /*Set this bit to enable octa_ram address out when accesses to flash which means ADDR_OUT[31:0] = {spi_usr_addr_value[25:4] 6'd0 spi_usr_addr_value[3:1] 1'b0}.*/
uint32_t spi_fmem_hyperbus_ca : 1; /*Set this bit to enable HyperRAM address out when accesses to flash which means ADDR_OUT[31:0] = {spi_usr_addr_value[19:4] 13'd0 spi_usr_addr_value[3:1]}.*/
uint32_t reserved31 : 1; /*reserved*/
};
uint32_t val;
} ddr;
union {
struct {
uint32_t spi_smem_ddr_en: 1; /*1: in ddr mode 0 in sdr mode*/
uint32_t spi_smem_var_dummy: 1; /*Set the bit to enable variable dummy cycle in spi ddr mode.*/
uint32_t spi_smem_ddr_rdat_swp: 1; /*Set the bit to reorder rx data of the word in spi ddr mode.*/
uint32_t spi_smem_ddr_wdat_swp: 1; /*Set the bit to reorder tx data of the word in spi ddr mode.*/
uint32_t spi_smem_ddr_cmd_dis: 1; /*the bit is used to disable dual edge in command phase when ddr mode.*/
uint32_t spi_smem_outminbytelen: 7; /*It is the minimum output data length in the ddr psram.*/
uint32_t spi_smem_tx_ddr_msk_en: 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR write mode when accesses to external RAM.*/
uint32_t spi_smem_rx_ddr_msk_en: 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR read mode when accesses to external RAM.*/
uint32_t spi_smem_usr_ddr_dqs_thd: 7; /*The delay number of data strobe which from memory based on SPI clock.*/
uint32_t spi_smem_ddr_dqs_loop: 1; /*the data strobe is generated by SPI.*/
uint32_t spi_smem_ddr_dqs_loop_mode: 2; /*the bits are combined with the bit spi_smem_ddr_fdqs_loop which used to select data strobe generating mode in ddr mode.*/
uint32_t spi_smem_clk_diff_en: 1; /*Set this bit to enable the differential SPI_CLK#.*/
uint32_t spi_smem_hyperbus_mode: 1; /*Set this bit to enable the SPI HyperBus mode.*/
uint32_t spi_smem_dqs_ca_in: 1; /*Set this bit to enable the input of SPI_DQS signal in SPI phases of CMD and ADDR.*/
uint32_t spi_smem_hyperbus_dummy_2x: 1; /*Set this bit to enable the vary dummy function in SPI HyperBus mode when SPI0 accesses flash or SPI1 accesses flash or sram.*/
uint32_t spi_smem_clk_diff_inv: 1; /*Set this bit to invert SPI_DIFF when accesses to external RAM. .*/
uint32_t spi_smem_octa_ram_addr: 1; /*Set this bit to enable octa_ram address out when accesses to external RAM which means ADDR_OUT[31:0] = {spi_usr_addr_value[25:4] 6'd0 spi_usr_addr_value[3:1] 1'b0}.*/
uint32_t spi_smem_hyperbus_ca: 1; /*Set this bit to enable HyperRAM address out when accesses to external RAM which means ADDR_OUT[31:0] = {spi_usr_addr_value[19:4] 13'd0 spi_usr_addr_value[3:1]}.*/
uint32_t reserved31: 1; /*reserved*/
uint32_t spi_smem_ddr_en : 1; /*1: in ddr mode 0 in sdr mode*/
uint32_t spi_smem_var_dummy : 1; /*Set the bit to enable variable dummy cycle in spi ddr mode.*/
uint32_t spi_smem_ddr_rdat_swp : 1; /*Set the bit to reorder rx data of the word in spi ddr mode.*/
uint32_t spi_smem_ddr_wdat_swp : 1; /*Set the bit to reorder tx data of the word in spi ddr mode.*/
uint32_t spi_smem_ddr_cmd_dis : 1; /*the bit is used to disable dual edge in command phase when ddr mode.*/
uint32_t spi_smem_outminbytelen : 7; /*It is the minimum output data length in the ddr psram.*/
uint32_t spi_smem_tx_ddr_msk_en : 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR write mode when accesses to external RAM.*/
uint32_t spi_smem_rx_ddr_msk_en : 1; /*Set this bit to mask the first or the last byte in MSPI ECC DDR read mode when accesses to external RAM.*/
uint32_t spi_smem_usr_ddr_dqs_thd : 7; /*The delay number of data strobe which from memory based on SPI clock.*/
uint32_t spi_smem_ddr_dqs_loop : 1; /*the data strobe is generated by SPI.*/
uint32_t spi_smem_ddr_dqs_loop_mode : 2; /*the bits are combined with the bit spi_smem_ddr_fdqs_loop which used to select data strobe generating mode in ddr mode.*/
uint32_t spi_smem_clk_diff_en : 1; /*Set this bit to enable the differential SPI_CLK#.*/
uint32_t spi_smem_hyperbus_mode : 1; /*Set this bit to enable the SPI HyperBus mode.*/
uint32_t spi_smem_dqs_ca_in : 1; /*Set this bit to enable the input of SPI_DQS signal in SPI phases of CMD and ADDR.*/
uint32_t spi_smem_hyperbus_dummy_2x : 1; /*Set this bit to enable the vary dummy function in SPI HyperBus mode when SPI0 accesses flash or SPI1 accesses flash or sram.*/
uint32_t spi_smem_clk_diff_inv : 1; /*Set this bit to invert SPI_DIFF when accesses to external RAM. .*/
uint32_t spi_smem_octa_ram_addr : 1; /*Set this bit to enable octa_ram address out when accesses to external RAM which means ADDR_OUT[31:0] = {spi_usr_addr_value[25:4] 6'd0 spi_usr_addr_value[3:1] 1'b0}.*/
uint32_t spi_smem_hyperbus_ca : 1; /*Set this bit to enable HyperRAM address out when accesses to external RAM which means ADDR_OUT[31:0] = {spi_usr_addr_value[19:4] 13'd0 spi_usr_addr_value[3:1]}.*/
uint32_t reserved31 : 1; /*reserved*/
};
uint32_t val;
} spi_smem_ddr;
union {
struct {
uint32_t clk_en: 1; /*Register clock gate enable signal. 1: Enable. 0: Disable.*/
uint32_t reserved1: 31; /*reserved*/
uint32_t clk_en : 1; /*Register clock gate enable signal. 1: Enable. 0: Disable.*/
uint32_t reserved1 : 31; /*reserved*/
};
uint32_t val;
} clock_gate;
union {
struct {
uint32_t spi01_clk_sel: 2; /*When the digital system clock selects PLL clock and the frequency of PLL clock is 480MHz the value of reg_spi01_clk_sel: 0: SPI0/1 module clock (clk) is 80MHz. 1: SPI0/1 module clock (clk) is 120MHz. 2: SPI0/1 module clock (clk) 160MHz. 3: Not used. When the digital system clock selects PLL clock and the frequency of PLL clock is 320MHz the value of reg_spi01_clk_sel: 0: SPI0/1 module clock (clk) is 80MHz. 1: SPI0/1 module clock (clk) is 80MHz. 2: SPI0/1 module clock (clk) 160MHz. 3: Not used.*/
uint32_t reserved2: 30; /*reserved*/
uint32_t spi01_clk_sel : 2; /*When the digital system clock selects PLL clock and the frequency of PLL clock is 480MHz the value of reg_spi01_clk_sel: 0: SPI0/1 module clock (clk) is 80MHz. 1: SPI0/1 module clock (clk) is 120MHz. 2: SPI0/1 module clock (clk) 160MHz. 3: Not used. When the digital system clock selects PLL clock and the frequency of PLL clock is 320MHz the value of reg_spi01_clk_sel: 0: SPI0/1 module clock (clk) is 80MHz. 1: SPI0/1 module clock (clk) is 80MHz. 2: SPI0/1 module clock (clk) 160MHz. 3: Not used.*/
uint32_t reserved2 : 30; /*reserved*/
};
uint32_t val;
} core_clk_sel;
@ -631,16 +687,14 @@ typedef volatile struct {
uint32_t reserved_3f8;
union {
struct {
uint32_t date: 28; /*SPI register version.*/
uint32_t reserved28: 4; /*reserved*/
uint32_t date : 28; /*SPI register version.*/
uint32_t reserved28 : 4; /*reserved*/
};
uint32_t val;
} date;
} spi_mem_dev_t;
extern spi_mem_dev_t SPIMEM0;
extern spi_mem_dev_t SPIMEM1;
#ifdef __cplusplus
}
#endif

View File

@ -463,5 +463,3 @@ extern syscon_dev_t SYSCON;
#ifdef __cplusplus
}
#endif
#endif /* _SOC_SYSCON_STRUCT_H_ */

View File

@ -17,5 +17,6 @@
#define SOC_SYSTIMER_COUNTER_NUM (2) // Number of counter units
#define SOC_SYSTIMER_ALARM_NUM (3) // Number of alarm units
#define SOC_SYSTIMER_BIT_WIDTH_LO (26) // Bit width of systimer low part
#define SOC_SYSTIMER_BIT_WIDTH_HI (26) // Bit width of systimer high part
#define SOC_SYSTIMER_BIT_WIDTH_LO (32) // Bit width of systimer low part
#define SOC_SYSTIMER_BIT_WIDTH_HI (20) // Bit width of systimer high part
#define SOC_SYSTIMER_INT_LEVEL (1) // Systimer peripheral uses level interrupt

View File

@ -19,6 +19,25 @@ extern "C" {
#include "soc.h"
/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */
#define TIMG_WDT_WKEY_VALUE 0x50D83AA1
/* Possible values for TIMG_WDT_STGx */
#define TIMG_WDT_STG_SEL_OFF 0
#define TIMG_WDT_STG_SEL_INT 1
#define TIMG_WDT_STG_SEL_RESET_CPU 2
#define TIMG_WDT_STG_SEL_RESET_SYSTEM 3
/* Possible values for TIMG_WDT_CPU_RESET_LENGTH and TIMG_WDT_SYS_RESET_LENGTH */
#define TIMG_WDT_RESET_LENGTH_100_NS 0
#define TIMG_WDT_RESET_LENGTH_200_NS 1
#define TIMG_WDT_RESET_LENGTH_300_NS 2
#define TIMG_WDT_RESET_LENGTH_400_NS 3
#define TIMG_WDT_RESET_LENGTH_500_NS 4
#define TIMG_WDT_RESET_LENGTH_800_NS 5
#define TIMG_WDT_RESET_LENGTH_1600_NS 6
#define TIMG_WDT_RESET_LENGTH_3200_NS 7
#define TIMG_T0CONFIG_REG(i) (REG_TIMG_BASE(i) + 0x0000)
/* TIMG_T0_EN : R/W ;bitpos:[31] ;default: 1'h0 ; */
/*description: */

View File

@ -0,0 +1,28 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
//Chip specific TWAI related macros
//Any even number from 2 to 32768
#define TWAI_BRP_IS_VALID(brp) ((brp) >= 2 && (brp) <= 32768 && ((brp) & 0x1) == 0)
#define TWAI_BRP_MAX 32768
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,208 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/* ---------------------------- Register Layout ------------------------------ */
/* The TWAI peripheral's registers are 8bits, however the ESP32 can only access
* peripheral registers every 32bits. Therefore each TWAI register is mapped to
* the least significant byte of every 32bits.
*/
typedef volatile struct twai_dev_s {
//Configuration and Control Registers
union {
struct {
uint32_t rm: 1; /* MOD.0 Reset Mode */
uint32_t lom: 1; /* MOD.1 Listen Only Mode */
uint32_t stm: 1; /* MOD.2 Self Test Mode */
uint32_t afm: 1; /* MOD.3 Acceptance Filter Mode */
uint32_t reserved28: 28; /* Internal Reserved. MOD.4 Sleep Mode not supported */
};
uint32_t val;
} mode_reg; /* Address 0 */
union {
struct {
uint32_t tr: 1; /* CMR.0 Transmission Request */
uint32_t at: 1; /* CMR.1 Abort Transmission */
uint32_t rrb: 1; /* CMR.2 Release Receive Buffer */
uint32_t cdo: 1; /* CMR.3 Clear Data Overrun */
uint32_t srr: 1; /* CMR.4 Self Reception Request */
uint32_t reserved27: 27; /* Internal Reserved */
};
uint32_t val;
} command_reg; /* Address 1 */
union {
struct {
uint32_t rbs: 1; /* SR.0 Receive Buffer Status */
uint32_t dos: 1; /* SR.1 Data Overrun Status */
uint32_t tbs: 1; /* SR.2 Transmit Buffer Status */
uint32_t tcs: 1; /* SR.3 Transmission Complete Status */
uint32_t rs: 1; /* SR.4 Receive Status */
uint32_t ts: 1; /* SR.5 Transmit Status */
uint32_t es: 1; /* SR.6 Error Status */
uint32_t bs: 1; /* SR.7 Bus Status */
uint32_t ms: 1; /* SR.8 Miss Status */
uint32_t reserved24: 23; /* Internal Reserved */
};
uint32_t val;
} status_reg; /* Address 2 */
union {
struct {
uint32_t ri: 1; /* IR.0 Receive Interrupt */
uint32_t ti: 1; /* IR.1 Transmit Interrupt */
uint32_t ei: 1; /* IR.2 Error Interrupt */
uint32_t reserved2: 2; /* Internal Reserved (Data Overrun interrupt and Wake-up not supported) */
uint32_t epi: 1; /* IR.5 Error Passive Interrupt */
uint32_t ali: 1; /* IR.6 Arbitration Lost Interrupt */
uint32_t bei: 1; /* IR.7 Bus Error Interrupt */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} interrupt_reg; /* Address 3 */
union {
struct {
uint32_t rie: 1; /* IER.0 Receive Interrupt Enable */
uint32_t tie: 1; /* IER.1 Transmit Interrupt Enable */
uint32_t eie: 1; /* IER.2 Error Interrupt Enable */
uint32_t reserved2: 2; /* Internal Reserved (Data Overrun interrupt and Wake-up not supported) */
uint32_t epie: 1; /* IER.5 Error Passive Interrupt Enable */
uint32_t alie: 1; /* IER.6 Arbitration Lost Interrupt Enable */
uint32_t beie: 1; /* IER.7 Bus Error Interrupt Enable */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} interrupt_enable_reg; /* Address 4 */
uint32_t reserved_05; /* Address 5 */
union {
struct {
uint32_t brp: 14; /* BTR0[13:0] Baud Rate Prescaler */
uint32_t sjw: 2; /* BTR0[15:14] Synchronization Jump Width*/
uint32_t reserved16: 16; /* Internal Reserved */
};
uint32_t val;
} bus_timing_0_reg; /* Address 6 */
union {
struct {
uint32_t tseg1: 4; /* BTR1[3:0] Timing Segment 1 */
uint32_t tseg2: 3; /* BTR1[6:4] Timing Segment 2 */
uint32_t sam: 1; /* BTR1.7 Sampling*/
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} bus_timing_1_reg; /* Address 7 */
uint32_t reserved_08; /* Address 8 (Output control not supported) */
uint32_t reserved_09; /* Address 9 (Test Register not supported) */
uint32_t reserved_10; /* Address 10 */
//Capture and Counter Registers
union {
struct {
uint32_t alc: 5; /* ALC[4:0] Arbitration lost capture */
uint32_t reserved27: 27; /* Internal Reserved */
};
uint32_t val;
} arbitration_lost_captue_reg; /* Address 11 */
union {
struct {
uint32_t seg: 5; /* ECC[4:0] Error Code Segment 0 to 5 */
uint32_t dir: 1; /* ECC.5 Error Direction (TX/RX) */
uint32_t errc: 2; /* ECC[7:6] Error Code */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} error_code_capture_reg; /* Address 12 */
union {
struct {
uint32_t ewl: 8; /* EWL[7:0] Error Warning Limit */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} error_warning_limit_reg; /* EWLR[7:0] Error Warning Limit: Address 13 */
union {
struct {
uint32_t rxerr: 8; /* RXERR[7:0] Receive Error Counter */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} rx_error_counter_reg; /* Address 12 */
union {
struct {
uint32_t txerr: 8; /* TXERR[7:0] Receive Error Counter */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} tx_error_counter_reg; /* Address 15 */
//Shared Registers (TX Buff/RX Buff/Acc Filter)
union {
struct {
union {
struct {
uint32_t byte: 8; /* ACRx[7:0] Acceptance Code */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} acr[4];
union {
struct {
uint32_t byte: 8; /* AMRx[7:0] Acceptance Mask */
uint32_t reserved24: 24; /* Internal Reserved */
};
uint32_t val;
} amr[4];
uint32_t reserved32[5];
} acceptance_filter;
union {
struct {
uint32_t byte: 8;
uint32_t reserved24: 24;
};
uint32_t val;
} tx_rx_buffer[13];
}; /* Address 16-28 TX/RX Buffer and Acc Filter*/;
//Misc Registers
union {
struct {
uint32_t rmc: 7; /* RMC[6:0] RX Message Counter */
uint32_t reserved25: 25; /* Internal Reserved */
};
uint32_t val;
} rx_message_counter_reg; /* Address 29 */
uint32_t reserved_30; /* Address 30 (RX Buffer Start Address not supported) */
union {
struct {
uint32_t cd: 8; /* CDR[7:0] CLKOUT frequency selector based of fOSC */
uint32_t co: 1; /* CDR.8 CLKOUT enable/disable */
uint32_t reserved24: 23; /* Internal Reserved */
};
uint32_t val;
} clock_divider_reg; /* Address 31 */
} twai_dev_t;
_Static_assert(sizeof(twai_dev_t) == 128, "TWAI registers should be 32 * 4 bytes");
extern twai_dev_t TWAI;
#ifdef __cplusplus
}
#endif

View File

@ -22,8 +22,7 @@ extern "C" {
typedef volatile struct {
union {
struct {
uint8_t rw_byte;
uint8_t reserved[3];
uint32_t rw_byte;
};
uint32_t val;
} ahb_fifo;

View File

@ -26,9 +26,9 @@ const sdmmc_slot_info_t sdmmc_slot_info[2] = {
.d5_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D5,
.d6_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D6,
.d7_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D7,
.card_detect = HOST_CARD_DETECT_N_1_IDX,
.write_protect = HOST_CARD_WRITE_PRT_1_IDX,
.card_int = HOST_CARD_INT_N_1_IDX,
.card_detect = SDHOST_CARD_DETECT_N_1_IDX,
.write_protect = SDHOST_CARD_WRITE_PRT_1_IDX,
.card_int = SDHOST_CARD_INT_N_1_IDX,
.width = 8
},
{
@ -42,9 +42,9 @@ const sdmmc_slot_info_t sdmmc_slot_info[2] = {
.d5_gpio = -1,
.d6_gpio = -1,
.d7_gpio = -1,
.card_detect = HOST_CARD_DETECT_N_2_IDX,
.write_protect = HOST_CARD_WRITE_PRT_2_IDX,
.card_int = HOST_CARD_INT_N_2_IDX,
.card_detect = SDHOST_CARD_DETECT_N_2_IDX,
.write_protect = SDHOST_CARD_WRITE_PRT_2_IDX,
.card_int = SDHOST_CARD_INT_N_2_IDX,
.width = 4
}
};

View File

@ -20,7 +20,7 @@
*/
const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
{
.spiclk_out = SPICLK_OUT_MUX_IDX,
.spiclk_out = SPICLK_OUT_IDX,
.spiclk_in = 0,/* SPI clock is not an input signal*/
.spid_out = SPID_OUT_IDX,
.spiq_out = SPIQ_OUT_IDX,
@ -44,7 +44,7 @@ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
.hw = (spi_dev_t *) &SPIMEM1,
.func = SPI_FUNC_NUM,
}, {
.spiclk_out = FSPICLK_OUT_MUX_IDX,
.spiclk_out = FSPICLK_OUT_IDX,
.spiclk_in = FSPICLK_IN_IDX,
.spid_out = FSPID_OUT_IDX,
.spiq_out = FSPIQ_OUT_IDX,
@ -68,7 +68,7 @@ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
.hw = &GPSPI2,
.func = FSPI_FUNC_NUM,
}, {
.spiclk_out = SPI3_CLK_OUT_MUX_IDX,
.spiclk_out = SPI3_CLK_OUT_IDX,
.spiclk_in = SPI3_CLK_IN_IDX,
.spid_out = SPI3_D_OUT_IDX,
.spiq_out = SPI3_Q_OUT_IDX,

View File

@ -14,6 +14,7 @@
#pragma once
#include <stdint.h>
#include "sdkconfig.h"
#include "soc/soc.h"
#include "soc/periph_defs.h"
@ -22,8 +23,7 @@
#include "soc/spi_reg.h"
#include "soc/spi_struct.h"
#include "soc/gpio_sig_map.h"
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32S2
#if SOC_MEMSPI_IS_INDEPENDENT
#include "soc/spi_mem_struct.h"
#include "soc/spi_mem_reg.h"
#endif

View File

@ -107,12 +107,13 @@ void systimer_hal_counter_value_advance(systimer_counter_id_t counter_id, int64_
void systimer_hal_enable_counter(systimer_counter_id_t counter_id)
{
systimer_ll_enable_clock();
(void)counter_id;
}
void systimer_hal_init(void)
{
assert(rtc_clk_xtal_freq_get() == 40 && "update the step for xtal to support other XTAL:APB frequency ratios");
systimer_ll_enable_clock();
/* Configure the counter:
* - increment by 1 when running from PLL (80 ticks per microsecond),
* - increment by 2 when running from XTAL (40 ticks per microsecond).
@ -138,3 +139,10 @@ void systimer_hal_select_alarm_mode(systimer_alarm_id_t alarm_id, systimer_alarm
break;
}
}
void systimer_hal_connect_alarm_counter(systimer_alarm_id_t alarm_id, systimer_counter_id_t counter_id)
{
// esp32s2 only has one counter, so there's no need to connect alarm unit to counter
(void)alarm_id;
(void)counter_id;
}

View File

@ -0,0 +1,21 @@
set(srcs "brownout_hal.c"
"rtc_clk_init.c"
"rtc_clk.c"
"rtc_init.c"
"rtc_pm.c"
"rtc_sleep.c"
"rtc_time.c"
"soc_memory_layout.c"
"systimer_hal.c"
"touch_sensor_hal.c")
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
target_include_directories(${COMPONENT_LIB} PUBLIC . include)
target_include_directories(${COMPONENT_LIB} PRIVATE ../hal)
if(NOT CMAKE_BUILD_EARLY_EXPANSION)
set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/rtc_clk.c" PROPERTIES
COMPILE_FLAGS "-fno-jump-tables -fno-tree-switch-conversion")
endif()

View File

@ -0,0 +1,45 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "hal/brownout_hal.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/rtc_cntl_reg.h"
#include "i2c_rtc_clk.h"
#include "i2c_brownout.h"
void brownout_hal_config(const brownout_hal_config_t *cfg)
{
I2C_WRITEREG_MASK_RTC(I2C_BOD, I2C_BOD_THRESHOLD, cfg->threshold);
typeof(RTCCNTL.brown_out) brown_out_reg = {
.int_wait = 0x002,
.close_flash_ena = cfg->flash_power_down,
.pd_rf_ena = cfg->rf_power_down,
.rst_wait = 0x3ff,
.rst_ena = cfg->reset_enabled,
.ena = cfg->enabled,
};
RTCCNTL.brown_out = brown_out_reg;
}
void brownout_hal_intr_enable(bool enable)
{
RTCCNTL.int_ena.rtc_brown_out = enable;
}
void brownout_hal_intr_clear(void)
{
RTCCNTL.int_clr.rtc_brown_out = 1;
}

View File

@ -0,0 +1,30 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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

View File

@ -0,0 +1,68 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
/**
* @file i2c_dig_reg.h
* @brief Register definitions for digital to get rtc voltage & digital voltage by setting rtc_dbias_Wak & dig_dbias_wak or by analog self-calibration.
*
*/
#define I2C_DIG_REG 0x6D
#define I2C_DIG_REG_HOSTID 1
#define I2C_DIG_REG_EXT_RTC_DREG 4
#define I2C_DIG_REG_EXT_RTC_DREG_MSB 4
#define I2C_DIG_REG_EXT_RTC_DREG_LSB 0
#define I2C_DIG_REG_ENX_RTC_DREG 4
#define I2C_DIG_REG_ENX_RTC_DREG_MSB 7
#define I2C_DIG_REG_ENX_RTC_DREG_LSB 7
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP 5
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB 4
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB 0
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP 5
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP_MSB 7
#define I2C_DIG_REG_ENX_RTC_DREG_SLEEP_LSB 7
#define I2C_DIG_REG_EXT_DIG_DREG 6
#define I2C_DIG_REG_EXT_DIG_DREG_MSB 4
#define I2C_DIG_REG_EXT_DIG_DREG_LSB 0
#define I2C_DIG_REG_ENX_DIG_DREG 6
#define I2C_DIG_REG_ENX_DIG_DREG_MSB 7
#define I2C_DIG_REG_ENX_DIG_DREG_LSB 7
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP 7
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB 4
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB 0
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP 7
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP_MSB 7
#define I2C_DIG_REG_ENX_DIG_DREG_SLEEP_LSB 7
#define I2C_DIG_REG_OR_EN_CONT_CAL 9
#define I2C_DIG_REG_OR_EN_CONT_CAL_MSB 7
#define I2C_DIG_REG_OR_EN_CONT_CAL_LSB 7
#define I2C_DIG_REG_XPD_RTC_REG 13
#define I2C_DIG_REG_XPD_RTC_REG_MSB 2
#define I2C_DIG_REG_XPD_RTC_REG_LSB 2
#define I2C_DIG_REG_XPD_DIG_REG 13
#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
#define I2C_DIG_REG_XPD_DIG_REG_LSB 3

View File

@ -0,0 +1,49 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "i2c_bbpll.h"
#include "i2c_dig_reg.h"
/* Analog function control register */
#define ANA_CONFIG_REG 0x6000E044
#define ANA_CONFIG_S (8)
#define ANA_CONFIG_M (0x3FF)
/* Clear to enable APLL */
#define I2C_APLL_M (BIT(14))
/* Clear to enable BBPLL */
#define I2C_BBPLL_M (BIT(17))
/* ROM functions which read/write internal control bus */
uint8_t rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add);
uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb);
void rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data);
void rom_i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data);
/* Convenience macros for the above functions, these use register definitions
* from i2c_bbpll.h/i2c_dig_reg.h/i2c_ulp.h header files.
*/
#define I2C_WRITEREG_MASK_RTC(block, reg_add, indata) \
rom_i2c_writeReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata)
#define I2C_READREG_MASK_RTC(block, reg_add) \
rom_i2c_readReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB)
#define I2C_WRITEREG_RTC(block, reg_add, indata) \
rom_i2c_writeReg(block, block##_HOSTID, reg_add, indata)
#define I2C_READREG_RTC(block, reg_add) \
rom_i2c_readReg(block, block##_HOSTID, reg_add)

View File

@ -0,0 +1,262 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The HAL layer for ADC (esp32s3 specific part)
#pragma once
#include "hal/adc_ll.h"
#include "hal/adc_types.h"
#include_next "hal/adc_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
/**
* Digital controller initialization.
*/
void adc_hal_digi_init(void);
/**
* Digital controller deinitialization.
*/
void adc_hal_digi_deinit(void);
/**
* Setting the digital controller.
*
* @param cfg Pointer to digital controller paramter.
*/
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg);
/**
* ADC Digital controller output data invert or not.
*
* @param adc_n ADC unit.
* @param inv_en data invert or not.
*/
#define adc_hal_digi_output_invert(adc_n, inv_en) adc_ll_digi_output_invert(adc_n, inv_en)
/**
* Sets the number of interval clock cycles for the digital controller to trigger the measurement.
*
* @note The trigger interval should not be less than the sampling time of the SAR ADC.
* @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095.
*/
#define adc_hal_digi_set_trigger_interval(cycle) adc_ll_digi_set_trigger_interval(cycle)
/**
* Enable digital controller to trigger the measurement.
*/
void adc_hal_digi_enable(void);
/**
* Disable digital controller to trigger the measurement.
*/
void adc_hal_digi_disable(void);
/**
* Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
* Enable clock and select clock source for ADC digital controller.
* Expression: controller_clk = APLL/APB * (div_num + div_b / div_a).
*
* @param clk Refer to `adc_digi_clk_t`.
*/
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk);
/**
* Reset adc digital controller filter.
*
* @param adc_n ADC unit.
*/
#define adc_hal_digi_filter_reset(adc_n) adc_ll_digi_filter_reset(adc_n)
/**
* Set adc digital controller filter factor.
*
* @param adc_n ADC unit.
* @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
*/
#define adc_hal_digi_filter_set_factor(adc_n, factor) adc_ll_digi_filter_set_factor(adc_n, factor)
/**
* Get adc digital controller filter factor.
*
* @param adc_n ADC unit.
* @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
*/
#define adc_hal_digi_filter_get_factor(adc_n, factor) adc_ll_digi_filter_get_factor(adc_n, factor)
/**
* Enable/disable adc digital controller filter.
* Filtering the ADC data to obtain smooth data at higher sampling rates.
*
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
*/
#define adc_hal_digi_filter_enable(adc_n, enable) adc_ll_digi_filter_enable(adc_n, enable)
/**
* Get the filtered data of adc digital controller filter.
* The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
*
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @return Filtered data.
*/
#define adc_hal_digi_filter_read_data(adc_n) adc_ll_digi_filter_read_data(adc_n)
/**
* Config monitor of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @param config Refer to `adc_digi_monitor_t`.
*/
void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config);
/**
* Enable/disable monitor of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
*/
#define adc_hal_digi_monitor_enable(adc_n, enable) adc_ll_digi_monitor_enable(adc_n, enable)
/**
* Enable interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
#define adc_hal_digi_intr_enable(adc_n, intr) adc_ll_digi_intr_enable(adc_n, intr)
/**
* Disable interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
#define adc_hal_digi_intr_disable(adc_n, intr) adc_ll_digi_intr_disable(adc_n, intr)
/**
* Clear interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
#define adc_hal_digi_intr_clear(adc_n, intr) adc_ll_digi_intr_clear(adc_n, intr)
/**
* Get interrupt status mask of adc digital controller.
*
* @param adc_n ADC unit.
* @return
* - intr Interrupt bitmask.
*/
#define adc_hal_digi_get_intr_status(adc_n) adc_ll_digi_get_intr_status(adc_n)
/**
* 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.
*/
#define adc_hal_digi_dma_set_eof_num(num) adc_ll_digi_dma_set_eof_num(num)
/**
* Enable output data to DMA from adc digital controller.
*/
#define adc_hal_digi_dma_enable() adc_ll_digi_dma_enable()
/**
* Disable output data to DMA from adc digital controller.
*/
#define adc_hal_digi_dma_disable() adc_ll_digi_dma_disable()
/**
* Reset adc digital controller.
*/
#define adc_hal_digi_reset() adc_ll_digi_reset()
/*---------------------------------------------------------------
RTC controller setting
---------------------------------------------------------------*/
/**
* Reset RTC controller FSM.
*/
#define adc_hal_rtc_reset() adc_ll_rtc_reset()
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* Config ADC2 module 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 ADC2 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 > RTC > Digital;
*
* @param config Refer to `adc_arbiter_t`.
*/
void adc_hal_arbiter_config(adc_arbiter_t *config);
/*---------------------------------------------------------------
ADC calibration setting
---------------------------------------------------------------*/
/**
* Calibrate the ADC according to the parameters.
*
* @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.
* @param force_cal true: Do not use the results that have already been verified, and perform the verification again. It will take a long time.
* false: Use the result of the last calibration.
*
* @return
* - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
*/
uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal);
/**
* Set the calibration result (initial data) to ADC.
*
* @note Different ADC units and different attenuation options use different calibration data (initial data).
*
* @param adc_n ADC index number.
*/
#define adc_hal_set_calibration_param(adc_n, param) adc_ll_set_calibration_param(adc_n, param);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,231 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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"
static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
{
switch (periph) {
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_UART2_MODULE:
return SYSTEM_UART2_CLK_EN;
case PERIPH_USB_MODULE:
return SYSTEM_USB_CLK_EN;
case PERIPH_I2C0_MODULE:
return SYSTEM_I2C_EXT0_CLK_EN;
case PERIPH_I2C1_MODULE:
return SYSTEM_I2C_EXT1_CLK_EN;
case PERIPH_I2S0_MODULE:
return SYSTEM_I2S0_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_PWM0_MODULE:
return SYSTEM_PWM0_CLK_EN;
case PERIPH_PWM1_MODULE:
return SYSTEM_PWM1_CLK_EN;
case PERIPH_PWM2_MODULE:
return SYSTEM_PWM2_CLK_EN;
case PERIPH_PWM3_MODULE:
return SYSTEM_PWM3_CLK_EN;
case PERIPH_UHCI0_MODULE:
return SYSTEM_UHCI0_CLK_EN;
case PERIPH_UHCI1_MODULE:
return SYSTEM_UHCI1_CLK_EN;
case PERIPH_PCNT_MODULE:
return SYSTEM_PCNT_CLK_EN;
case PERIPH_SPI_MODULE:
return SYSTEM_SPI01_CLK_EN;
case PERIPH_FSPI_MODULE:
return SYSTEM_SPI2_CLK_EN;
case PERIPH_HSPI_MODULE:
return SYSTEM_SPI3_CLK_EN;
case PERIPH_VSPI_MODULE:
return SYSTEM_SPI4_CLK_EN;
case PERIPH_SPI2_DMA_MODULE:
return SYSTEM_SPI2_DMA_CLK_EN;
case PERIPH_SPI3_DMA_MODULE:
return SYSTEM_SPI3_DMA_CLK_EN;
case PERIPH_SDMMC_MODULE:
return SYSTEM_SDIO_HOST_CLK_EN;
case PERIPH_TWAI_MODULE:
return SYSTEM_TWAI_CLK_EN;
case PERIPH_RNG_MODULE:
return SYSTEM_WIFI_CLK_RNG_EN;
case PERIPH_WIFI_MODULE:
return SYSTEM_WIFI_CLK_WIFI_EN_M;
case PERIPH_BT_MODULE:
return SYSTEM_WIFI_CLK_BT_EN_M;
case PERIPH_WIFI_BT_COMMON_MODULE:
return SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M;
case PERIPH_BT_BASEBAND_MODULE:
return SYSTEM_BT_BASEBAND_EN;
case PERIPH_BT_LC_MODULE:
return SYSTEM_BT_LC_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_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_UART2_MODULE:
return SYSTEM_UART2_RST;
case PERIPH_USB_MODULE:
return SYSTEM_USB_RST;
case PERIPH_I2C0_MODULE:
return SYSTEM_I2C_EXT0_RST;
case PERIPH_I2C1_MODULE:
return SYSTEM_I2C_EXT1_RST;
case PERIPH_I2S0_MODULE:
return SYSTEM_I2S0_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_PWM0_MODULE:
return SYSTEM_PWM0_RST;
case PERIPH_PWM1_MODULE:
return SYSTEM_PWM1_RST;
case PERIPH_PWM2_MODULE:
return SYSTEM_PWM2_RST;
case PERIPH_PWM3_MODULE:
return SYSTEM_PWM3_RST;
case PERIPH_UHCI0_MODULE:
return SYSTEM_UHCI0_RST;
case PERIPH_UHCI1_MODULE:
return SYSTEM_UHCI1_RST;
case PERIPH_PCNT_MODULE:
return SYSTEM_PCNT_RST;
case PERIPH_SPI_MODULE:
return SYSTEM_SPI01_RST;
case PERIPH_FSPI_MODULE:
return SYSTEM_SPI2_RST;
case PERIPH_HSPI_MODULE:
return SYSTEM_SPI3_RST;
case PERIPH_VSPI_MODULE:
return SYSTEM_SPI4_RST;
case PERIPH_SPI2_DMA_MODULE:
return SYSTEM_SPI2_DMA_RST;
case PERIPH_SPI3_DMA_MODULE:
return SYSTEM_SPI3_DMA_RST;
case PERIPH_SDMMC_MODULE:
return SYSTEM_SDIO_HOST_RST;
case PERIPH_TWAI_MODULE:
return SYSTEM_TWAI_RST;
default:
return 0;
}
}
static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
{
switch (periph) {
case PERIPH_RNG_MODULE:
case PERIPH_WIFI_MODULE:
case PERIPH_BT_MODULE:
case PERIPH_WIFI_BT_COMMON_MODULE:
case PERIPH_BT_BASEBAND_MODULE:
case PERIPH_BT_LC_MODULE:
return SYSTEM_WIFI_CLK_EN_REG ;
case PERIPH_UART2_MODULE:
case PERIPH_SDMMC_MODULE:
case PERIPH_SPI_SHARED_DMA_MODULE:
return SYSTEM_PERIP_CLK_EN1_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_RNG_MODULE:
case PERIPH_WIFI_MODULE:
case PERIPH_BT_MODULE:
case PERIPH_WIFI_BT_COMMON_MODULE:
case PERIPH_BT_BASEBAND_MODULE:
case PERIPH_BT_LC_MODULE:
return SYSTEM_CORE_RST_EN_REG;
case PERIPH_UART2_MODULE:
case PERIPH_SDMMC_MODULE:
case PERIPH_SPI_SHARED_DMA_MODULE:
return SYSTEM_PERIP_RST_EN1_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

View File

@ -0,0 +1,176 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "soc/cpu_caps.h"
#include "xt_instr_macros.h"
#include "xtensa/config/specreg.h"
#include "xtensa/config/extreg.h"
#include "esp_bit_defs.h"
#include "xtensa/config/core.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline int cpu_ll_get_core_id(void)
{
uint32_t id;
asm volatile (
"rsr.prid %0\n"
"extui %0,%0,13,1"
:"=r"(id));
return (int) id;
}
static inline uint32_t cpu_ll_get_cycle_count(void)
{
uint32_t result;
RSR(CCOUNT, result);
return result;
}
static inline void* cpu_ll_get_sp(void)
{
void *sp;
asm volatile ("mov %0, sp;" : "=r" (sp));
return sp;
}
static inline void cpu_ll_init_hwloop(void)
{
#if XCHAL_ERRATUM_572
uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT;
WSR(MEMCTL, memctl);
#endif // XCHAL_ERRATUM_572
}
static inline void cpu_ll_set_breakpoint(int id, uint32_t pc)
{
uint32_t en;
// Set the break address register to the appropriate PC
if (id) {
WSR(IBREAKA_1, pc);
} else {
WSR(IBREAKA_0, pc);
}
// Enable the breakpoint using the break enable register
RSR(IBREAKENABLE, en);
en |= BIT(id);
WSR(IBREAKENABLE, en);
}
static inline void cpu_ll_clear_breakpoint(int id)
{
uint32_t en = 0;
uint32_t pc = 0;
// Set the break address register to the appropriate PC
if (id) {
WSR(IBREAKA_1, pc);
} else {
WSR(IBREAKA_0, pc);
}
// Enable the breakpoint using the break enable register
RSR(IBREAKENABLE, en);
en &= ~BIT(id);
WSR(IBREAKENABLE, en);
}
static inline uint32_t cpu_ll_ptr_to_pc(const void* addr)
{
return ((uint32_t) addr);
}
static inline void* cpu_ll_pc_to_ptr(uint32_t pc)
{
return (void*) ((pc & 0x3fffffff) | 0x40000000);
}
static inline void cpu_ll_set_watchpoint(int id,
const void* addr,
size_t size,
bool on_read,
bool on_write)
{
uint32_t dbreakc = 0x3F;
//We support watching 2^n byte values, from 1 to 64. Calculate the mask for that.
for (int x = 0; x < 7; x++) {
if (size == (1 << x)) {
break;
}
dbreakc <<= 1;
}
dbreakc = (dbreakc & 0x3F);
if (on_read) {
dbreakc |= BIT(30);
}
if (on_write) {
dbreakc |= BIT(31);
}
// Write the break address register and the size to control
// register.
if (id) {
WSR(DBREAKA_1, (uint32_t) addr);
WSR(DBREAKC_1, dbreakc);
} else {
WSR(DBREAKA_0, (uint32_t) addr);
WSR(DBREAKC_0, dbreakc);
}
}
static inline void cpu_ll_clear_watchpoint(int id)
{
// Clear both break address register and control register
if (id) {
WSR(DBREAKA_1, 0);
WSR(DBREAKC_1, 0);
} else {
WSR(DBREAKA_0, 0);
WSR(DBREAKC_0, 0);
}
}
static inline bool cpu_ll_is_debugger_attached(void)
{
uint32_t dcr = 0;
uint32_t reg = DSRSET;
RER(reg, dcr);
return (dcr&0x1);
}
static inline void cpu_ll_break(void)
{
__asm__ ("break 0,0");
}
static inline void cpu_ll_set_vecbase(const void* vecbase)
{
asm volatile ("wsr %0, vecbase" :: "r" (vecbase));
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,206 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The ll is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
#pragma once
#include <stdlib.h>
#include "soc/dac_periph.h"
#include "hal/dac_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Power on dac module and start output voltage.
*
* @note Before powering up, make sure the DAC PAD is set to RTC PAD and floating status.
* @param channel DAC channel num.
*/
static inline void dac_ll_power_on(dac_channel_t channel)
{
RTCIO.pad_dac[channel].dac_xpd_force = 1;
RTCIO.pad_dac[channel].xpd_dac = 1;
}
/**
* Power done dac module and stop output voltage.
*
* @param channel DAC channel num.
*/
static inline void dac_ll_power_down(dac_channel_t channel)
{
RTCIO.pad_dac[channel].dac_xpd_force = 0;
RTCIO.pad_dac[channel].xpd_dac = 0;
}
/**
* Output voltage with value (8 bit).
*
* @param channel DAC channel num.
* @param value Output value. Value range: 0 ~ 255.
* The corresponding range of voltage is 0v ~ VDD3P3_RTC.
*/
static inline void dac_ll_update_output_value(dac_channel_t channel, uint8_t value)
{
if (channel == DAC_CHANNEL_1) {
SENS.sar_dac_ctrl2.dac_cw_en1 = 0;
RTCIO.pad_dac[channel].dac = value;
} else if (channel == DAC_CHANNEL_2) {
SENS.sar_dac_ctrl2.dac_cw_en2 = 0;
RTCIO.pad_dac[channel].dac = value;
}
}
/**
* Enable/disable the synchronization operation function of ADC1 and DAC.
*
* @note If enabled(default), ADC RTC controller sampling will cause the DAC channel output voltage.
*
* @param enable Enable or disable adc and dac synchronization function.
*/
static inline void dac_ll_rtc_sync_by_adc(bool enable)
{
// SENS.sar_meas_ctrl2.sar1_dac_xpd_fsm = enable;
}
/************************************/
/* DAC cosine wave generator API's */
/************************************/
/**
* Enable cosine wave generator output.
*/
static inline void dac_ll_cw_generator_enable(void)
{
SENS.sar_dac_ctrl1.sw_tone_en = 1;
}
/**
* Disable cosine wave generator output.
*/
static inline void dac_ll_cw_generator_disable(void)
{
SENS.sar_dac_ctrl1.sw_tone_en = 0;
}
/**
* Enable the cosine wave generator of DAC channel.
*
* @param channel DAC channel num.
* @param enable
*/
static inline void dac_ll_cw_set_channel(dac_channel_t channel, bool enable)
{
if (channel == DAC_CHANNEL_1) {
SENS.sar_dac_ctrl2.dac_cw_en1 = enable;
} else if (channel == DAC_CHANNEL_2) {
SENS.sar_dac_ctrl2.dac_cw_en2 = enable;
}
}
/**
* Set frequency of cosine wave generator output.
*
* @note We know that CLK8M is about 8M, but don't know the actual value. so this freq have limited error.
* @param freq_hz CW generator frequency. Range: 130(130Hz) ~ 55000(100KHz).
*/
static inline void dac_ll_cw_set_freq(uint32_t freq)
{
uint32_t sw_freq = freq * 0xFFFF / RTC_FAST_CLK_FREQ_APPROX;
SENS.sar_dac_ctrl1.sw_fstep = (sw_freq > 0xFFFF) ? 0xFFFF : sw_freq;
}
/**
* Set the amplitude of the cosine wave generator output.
*
* @param channel DAC channel num.
* @param scale The multiple of the amplitude. The max amplitude is VDD3P3_RTC.
*/
static inline void dac_ll_cw_set_scale(dac_channel_t channel, dac_cw_scale_t scale)
{
if (channel == DAC_CHANNEL_1) {
SENS.sar_dac_ctrl2.dac_scale1 = scale;
} else if (channel == DAC_CHANNEL_2) {
SENS.sar_dac_ctrl2.dac_scale2 = scale;
}
}
/**
* Set the phase of the cosine wave generator output.
*
* @param channel DAC channel num.
* @param scale Phase value.
*/
static inline void dac_ll_cw_set_phase(dac_channel_t channel, dac_cw_phase_t phase)
{
if (channel == DAC_CHANNEL_1) {
SENS.sar_dac_ctrl2.dac_inv1 = phase;
} else if (channel == DAC_CHANNEL_2) {
SENS.sar_dac_ctrl2.dac_inv2 = phase;
}
}
/**
* Set the voltage value of the DC component of the cosine wave generator output.
*
* @note The DC offset setting should be after phase setting.
* @note Unreasonable settings can cause the signal to be oversaturated.
* @param channel DAC channel num.
* @param offset DC value. Range: -128 ~ 127.
*/
static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
{
if (channel == DAC_CHANNEL_1) {
if (SENS.sar_dac_ctrl2.dac_inv1 == DAC_CW_PHASE_180) {
offset = 0 - offset;
}
SENS.sar_dac_ctrl2.dac_dc1 = offset ? offset : (-128 - offset);
} else if (channel == DAC_CHANNEL_2) {
if (SENS.sar_dac_ctrl2.dac_inv2 == DAC_CW_PHASE_180) {
offset = 0 - offset;
}
SENS.sar_dac_ctrl2.dac_dc2 = offset ? offset : (-128 - offset);
}
}
/************************************/
/* DAC DMA API's */
/************************************/
/**
* Enable DAC output data from I2S DMA.
* I2S_CLK connect to DAC_CLK, I2S_DATA_OUT connect to DAC_DATA.
*/
static inline void dac_ll_dma_enable(void)
{
SENS.sar_dac_ctrl1.dac_dig_force = 1;
}
/**
* Disable DAC output data from I2S DMA.
*/
static inline void dac_ll_dma_disable(void)
{
SENS.sar_dac_ctrl1.dac_dig_force = 0;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,422 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32-S3 GPIO register operations
#pragma once
#include "soc/soc.h"
#include "soc/gpio_periph.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "hal/gpio_types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Get GPIO hardware instance with giving gpio num
#define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL)
/**
* @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, gpio_num_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, gpio_num_t gpio_num)
{
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, gpio_num_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, gpio_num_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, gpio_num_t gpio_num, gpio_int_type_t intr_type)
{
hw->pin[gpio_num].int_type = intr_type;
}
/**
* @brief Get GPIO interrupt status
*
* @param hw Peripheral GPIO hardware instance address.
* @param core_id interrupt core id
* @param status interrupt status
*/
static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
{
*status = hw->pcpu_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
*/
static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
{
*status = hw->pcpu_int1.intr;
}
/**
* @brief Clear GPIO interrupt status
*
* @param hw Peripheral GPIO hardware instance address.
* @param mask interrupt status clear mask
*/
static inline void gpio_ll_clear_intr_status(gpio_dev_t *hw, uint32_t mask)
{
hw->status_w1tc = mask;
}
/**
* @brief Clear GPIO interrupt status high
*
* @param hw Peripheral GPIO hardware instance address.
* @param mask interrupt status high clear mask
*/
static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask)
{
hw->status1_w1tc.intr_st = 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);
*/
static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, gpio_num_t gpio_num)
{
if (core_id == 0) {
GPIO.pin[gpio_num].int_ena = GPIO_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);
*/
static inline void gpio_ll_intr_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
hw->pin[gpio_num].int_ena = 0; //disable GPIO intr
}
/**
* @brief Disable input mode on GPIO.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
*/
static inline void gpio_ll_input_disable(gpio_dev_t *hw, gpio_num_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, gpio_num_t gpio_num)
{
PIN_INPUT_ENABLE(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, gpio_num_t gpio_num)
{
if (gpio_num < 32) {
hw->enable_w1tc = (0x1 << gpio_num);
} else {
hw->enable1_w1tc.data = (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 void gpio_ll_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
if (gpio_num < 32) {
hw->enable_w1ts = (0x1 << gpio_num);
} else {
hw->enable1_w1ts.data = (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 void gpio_ll_od_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
hw->pin[gpio_num].pad_driver = 0;
}
/**
* @brief Enable open-drain mode on GPIO.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
*/
static inline void gpio_ll_od_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
hw->pin[gpio_num].pad_driver = 1;
}
/**
* @brief GPIO set output level
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number. If you want to set the output level of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
* @param level Output level. 0: low ; 1: high
*/
static inline void gpio_ll_set_level(gpio_dev_t *hw, gpio_num_t gpio_num, uint32_t level)
{
if (level) {
if (gpio_num < 32) {
hw->out_w1ts = (1 << gpio_num);
} else {
hw->out1_w1ts.data = (1 << (gpio_num - 32));
}
} else {
if (gpio_num < 32) {
hw->out_w1tc = (1 << gpio_num);
} else {
hw->out1_w1tc.data = (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, gpio_num_t gpio_num)
{
if (gpio_num < 32) {
return (hw->in >> gpio_num) & 0x1;
} else {
return (hw->in1.data >> (gpio_num - 32)) & 0x1;
}
}
/**
* @brief Enable GPIO 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_wakeup_enable(gpio_dev_t *hw, gpio_num_t gpio_num, gpio_int_type_t intr_type)
{
hw->pin[gpio_num].int_type = intr_type;
hw->pin[gpio_num].wakeup_enable = 0x1;
}
/**
* @brief Disable GPIO wake-up function.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
*/
static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
hw->pin[gpio_num].wakeup_enable = 0;
}
/**
* @brief Set GPIO pad drive capability
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number, only support output GPIOs
* @param strength Drive capability of the pad
*/
static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, gpio_num_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, gpio_num_t gpio_num, gpio_drive_cap_t *strength)
{
*strength = 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)
{
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, gpio_num_t gpio_num)
{
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, gpio_num_t gpio_num)
{
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``.
*/
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(GPIO_PIN_MUX_REG[gpio]);
}
/**
* @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].oen_sel = 0;
hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv;
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], func);
}
static inline void gpio_ll_force_hold_all(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_FORCE_HOLD);
}
static inline void gpio_ll_force_unhold_all(gpio_dev_t *hw)
{
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);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,363 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* 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 "hal/spi_types.h"
#include "hal/spi_flash_types.h"
#include <sys/param.h> // For MIN/MAX
#include <stdbool.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define gpspi_flash_ll_get_hw(host_id) (((host_id)==SPI2_HOST ? &GPSPI2 \
: ((host_id)==SPI3_HOST ? &GPSPI3 \
: ({abort();(spi_dev_t*)0;}))))
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : (\
((dev) == (void*)&GPSPI3) ? SPI3_HOST : (\
-1 \
)) )
typedef typeof(GPSPI2.clock) gpspi_flash_ll_clock_reg_t;
//Supported clock register values
#define GPSPI_FLASH_LL_CLKREG_VAL_5MHZ ((gpspi_flash_ll_clock_reg_t){.val=0x0000F1CF}) ///< Clock set to 5 MHz
#define GPSPI_FLASH_LL_CLKREG_VAL_10MHZ ((gpspi_flash_ll_clock_reg_t){.val=0x000070C7}) ///< Clock set to 10 MHz
#define GPSPI_FLASH_LL_CLKREG_VAL_20MHZ ((gpspi_flash_ll_clock_reg_t){.val=0x00003043}) ///< Clock set to 20 MHz
#define GPSPI_FLASH_LL_CLKREG_VAL_26MHZ ((gpspi_flash_ll_clock_reg_t){.val=0x00002002}) ///< Clock set to 26 MHz
#define GPSPI_FLASH_LL_CLKREG_VAL_40MHZ ((gpspi_flash_ll_clock_reg_t){.val=0x00001001}) ///< Clock set to 40 MHz
#define GPSPI_FLASH_LL_CLKREG_VAL_80MHZ ((gpspi_flash_ll_clock_reg_t){.val=0x80000000}) ///< Clock set to 80 MHz
/*------------------------------------------------------------------------------
* 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;
}
/**
* 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.val == 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.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 gpspi_flash_ll_host_idle(const spi_dev_t *dev)
{
return false;
}
/**
* 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);
// ctrl.val |= SPI_FAST_RD_MODE_M;
switch (read_mode) {
case SPI_FLASH_FASTRD:
//the default option
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;
// case SPI_FLASH_SLOWRD:
// ctrl.fast_rd_mode = 0;
// break;
default:
abort();
}
dev->ctrl = ctrl;
dev->user = user;
}
/**
* Set clock frequency to work at.
*
* @param dev Beginning address of the peripheral registers.
* @param clock_val pointer to the clock value to set
*/
static inline void gpspi_flash_ll_set_clock(spi_dev_t *dev, gpspi_flash_ll_clock_reg_t *clock_val)
{
dev->clock = *clock_val;
}
/**
* Set the input length, in bits.
*
* @param dev Beginning address of the peripheral registers.
* @param bitlen Length of input, in bits.
*/
static inline void gpspi_flash_ll_set_miso_bitlen(spi_dev_t *dev, uint32_t bitlen)
{
dev->user.usr_miso = bitlen > 0;
}
/**
* 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;
}
/**
* Set the command with fixed length (8 bits).
*
* @param dev Beginning address of the peripheral registers.
* @param command Command to send
*/
static inline void gpspi_flash_ll_set_command8(spi_dev_t *dev, uint8_t command)
{
dev->user.usr_command = 1;
typeof(dev->user2) user2 = {
.usr_command_value = command,
.usr_command_bitlen = (8 - 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)
{
dev->addr = (addr << (32 - bitlen));
}
/**
* 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;
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;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,860 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for I2C register operations
#pragma once
#include "soc/i2c_periph.h"
#include "hal/i2c_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief I2C hardware cmd register filed.
*/
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_hw_cmd_t;
/**
* @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 Data structure for calculating I2C bus timing.
*/
typedef struct {
uint16_t scl_low; /*!< I2C scl low period */
uint16_t scl_high; /*!< I2C scl hight period */
uint16_t sda_hold; /*!< I2C scl low period */
uint16_t sda_sample; /*!< I2C sda sample time */
uint16_t setup; /*!< I2C start and stop condition setup period */
uint16_t hold; /*!< I2C start and stop condition hold period */
uint16_t tout; /*!< I2C bus timeout period */
} i2c_clk_cal_t;
// Get the I2C hardware instance
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == 0) ? &I2C0 : &I2C1)
// Get the I2C hardware FIFO address
#define I2C_LL_GET_FIFO_ADDR(i2c_num) (I2C_DATA_APB_REG(i2c_num))
// I2C master TX interrupt bitmap
#define I2C_LL_MASTER_TX_INT (I2C_ACK_ERR_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_EMPTY_INT_ENA_M)
// I2C slave RX interrupt bitmap
#define I2C_LL_SLAVE_RX_INT (I2C_RXFIFO_FULL_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M)
//I2C base clock freq 80M
#define I2C_BASE_CLK_FREQ (80000000)
/**
* @brief Calculate I2C bus frequency
*
* @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_clk_cal_t *clk_cal)
{
uint32_t half_cycle = source_clk / bus_freq / 2;
clk_cal->scl_low = half_cycle;
clk_cal->scl_high = half_cycle;
clk_cal->sda_hold = half_cycle / 2;
clk_cal->sda_sample = clk_cal->scl_high / 2;
clk_cal->setup = half_cycle;
clk_cal->hold = half_cycle;
clk_cal->tout = half_cycle * 20; //default we set the timeout value to 10 bus cycles.
}
/**
* @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_clk_cal_t *bus_cfg)
{
//scl period
hw->scl_low_period.period = bus_cfg->scl_low;
hw->scl_high_period.period = bus_cfg->scl_high;
//sda sample
hw->sda_hold.time = bus_cfg->sda_hold;
hw->sda_sample.time = bus_cfg->sda_sample;
//setup
hw->scl_rstart_setup.time = bus_cfg->setup;
hw->scl_stop_setup.time = bus_cfg->setup;
//hold
hw->scl_start_hold.time = bus_cfg->hold;
hw->scl_stop_hold.time = bus_cfg->hold;
hw->timeout.tout = bus_cfg->tout;
}
/**
* @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 APB cycle)
* @param low_period The I2C SCL low period (in APB cycle)
*
* @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;
hw->scl_high_period.period = hight_period;
}
/**
* @brief Clear I2C interrupt status
*
* @param hw Beginning address of the peripheral registers
* @param mask Interrupt mask needs to be cleared
*
* @return None
*/
static inline void i2c_ll_clr_intsts_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
*/
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
*/
static inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
{
return 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 (in APB cycle)
*
* @return None
*/
static inline void i2c_ll_set_tout(i2c_dev_t *hw, int tout)
{
hw->timeout.tout = 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_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 APB cycle)
* @param start_hold The start condition hold period (in APB 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;
}
/**
* @brief Configure I2C stop timing
*
* @param hw Beginning address of the peripheral registers
* @param stop_setup The stop condition setup period (in APB cycle)
* @param stop_hold The stop condition hold period (in APB 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 APB cycle)
* @param sda_hold The SDA hold time (in APB 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_empty_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_full_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->status_reg.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
*/
static inline uint32_t i2c_ll_get_rxfifo_cnt(i2c_dev_t *hw)
{
return hw->status_reg.rx_fifo_cnt;
}
/**
* @brief Get I2C txFIFO writable length
*
* @param hw Beginning address of the peripheral registers
*
* @return TxFIFO writable length
*/
static inline uint32_t i2c_ll_get_txfifo_len(i2c_dev_t *hw)
{
return SOC_I2C_FIFO_LEN - hw->status_reg.tx_fifo_cnt;
}
/**
* @brief Get I2C timeout configuration
*
* @param hw Beginning address of the peripheral registers
*
* @return The I2C timeout value
*/
static inline uint32_t i2c_ll_get_tout(i2c_dev_t *hw)
{
return hw->timeout.tout;
}
/**
* @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;
}
/**
* @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;
*low_period = hw->scl_low_period.period;
}
/**
* @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.
*/
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
{
uint32_t fifo_addr = (hw == &I2C0) ? 0x6001301c : 0x6002701c;
for(int i = 0; i < len; i++) {
WRITE_PERI_REG(fifo_addr, 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
*/
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] = 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->scl_filter_cfg.thres = filter_num;
hw->sda_filter_cfg.thres = filter_num;
hw->scl_filter_cfg.en = 1;
hw->sda_filter_cfg.en = 1;
} else {
hw->scl_filter_cfg.en = 0;
hw->sda_filter_cfg.en = 0;
}
}
/**
* @brief Get I2C hardware filter configuration
*
* @param hw Beginning address of the peripheral registers
*
* @return The hardware filter configuration
*/
static inline uint8_t i2c_ll_get_filter(i2c_dev_t *hw)
{
return hw->sda_filter_cfg.thres;
}
/**
* @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 = ~0;
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 = ~0;
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
*/
static inline void i2c_ll_master_disable_rx_it(i2c_dev_t *hw)
{
hw->int_ena.val &= (~I2C_LL_MASTER_RX_INT);
}
/**
* @brief Clear I2C master TX interrupt status register
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_clr_tx_it(i2c_dev_t *hw)
{
hw->int_clr.val = I2C_LL_MASTER_TX_INT;
}
/**
* @brief Clear I2C master RX interrupt status register
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_master_clr_rx_it(i2c_dev_t *hw)
{
hw->int_clr.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
*/
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);
}
/**
* @brief Clear I2C slave TX interrupt status register
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_slave_clr_tx_it(i2c_dev_t *hw)
{
hw->int_clr.val = I2C_LL_SLAVE_TX_INT;
}
/**
* @brief Clear I2C slave RX interrupt status register.
*
* @param hw Beginning address of the peripheral registers
*
* @return None
*/
static inline void i2c_ll_slave_clr_rx_it(i2c_dev_t *hw)
{
hw->int_clr.val = I2C_LL_SLAVE_RX_INT;
}
/**
* @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)
{
;//ESP32 do not support
}
/**
* @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)
{
;//ESP32 do not support
}
/**
* @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_sclk_t src_clk)
{
;//Not support on ESP32
}
/**
* @brief Get I2C master interrupt event
*
* @param hw Beginning address of the peripheral registers
* @param event Pointer to accept the interrupt event
*
* @return None
*/
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.ack_err) {
*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
*/
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_empty) {
*event = I2C_INTR_EVENT_TXFIFO_EMPTY;
} else if (int_sts.trans_complete) {
*event = I2C_INTR_EVENT_TRANS_DONE;
} else if (int_sts.rx_fifo_full) {
*event = I2C_INTR_EVENT_RXFIFO_FULL;
} else {
*event = I2C_INTR_EVENT_ERR;
}
}
/**
* @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.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;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,850 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32-S3 I2S register operations
#pragma once
#include <stdbool.h>
#include "soc/i2s_periph.h"
#include "hal/i2s_types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Get I2S hardware instance with giving i2s num
#define I2S_LL_GET_HW(num) (((num) == 0) ? (&I2S0) : NULL)
#define I2S_INTR_IN_SUC_EOF BIT(9)
#define I2S_INTR_OUT_EOF BIT(12)
#define I2S_INTR_IN_DSCR_ERR BIT(13)
#define I2S_INTR_OUT_DSCR_ERR BIT(14)
#define I2S_INTR_MAX (0xFFFFFFFF)
/**
* @brief Reset rx fifo
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_reset_rx_fifo(i2s_dev_t *hw)
{
hw->rx_conf.rx_fifo_reset = 1;
hw->rx_conf.rx_fifo_reset = 0;
}
/**
* @brief Reset tx fifo
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_reset_tx_fifo(i2s_dev_t *hw)
{
hw->tx_conf.tx_fifo_reset = 1;
hw->tx_conf.tx_fifo_reset = 0;
}
/**
* @brief Enable rx interrupt
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_enable_rx_intr(i2s_dev_t *hw)
{
}
/**
* @brief Disable rx interrupt
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_disable_rx_intr(i2s_dev_t *hw)
{
}
/**
* @brief Disable tx interrupt
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_disable_tx_intr(i2s_dev_t *hw)
{
}
/**
* @brief Enable tx interrupt
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_enable_tx_intr(i2s_dev_t *hw)
{
}
/**
* @brief Reset dma in
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_reset_dma_in(i2s_dev_t *hw)
{
}
/**
* @brief Reset dma out
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_reset_dma_out(i2s_dev_t *hw)
{
}
/**
* @brief Reset tx
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_reset_tx(i2s_dev_t *hw)
{
}
/**
* @brief Reset rx
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_reset_rx(i2s_dev_t *hw)
{
}
/**
* @brief Start out link
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_start_out_link(i2s_dev_t *hw)
{
}
/**
* @brief Start tx
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_start_tx(i2s_dev_t *hw)
{
}
/**
* @brief Start in link
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_start_in_link(i2s_dev_t *hw)
{
}
/**
* @brief Start rx
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_start_rx(i2s_dev_t *hw)
{
}
/**
* @brief Stop out link
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_stop_out_link(i2s_dev_t *hw)
{
}
/**
* @brief Stop tx
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_stop_tx(i2s_dev_t *hw)
{
}
/**
* @brief Stop in link
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_stop_in_link(i2s_dev_t *hw)
{
}
/**
* @brief Stop rx
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_stop_rx(i2s_dev_t *hw)
{
}
/**
* @brief Enable dma
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_enable_dma(i2s_dev_t *hw)
{
}
/**
* @brief Get I2S interrupt status
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get interrupt status
*/
static inline void i2s_ll_get_intr_status(i2s_dev_t *hw, uint32_t *val)
{
*val = hw->int_st.val;
}
/**
* @brief Clear I2S interrupt status
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to clear interrupt status
*/
static inline void i2s_ll_clear_intr_status(i2s_dev_t *hw, uint32_t val)
{
hw->int_clr.val = val;
}
/**
* @brief Get I2S out eof des address
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get out eof des address
*/
static inline void i2s_ll_get_out_eof_des_addr(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Get I2S in eof des address
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get in eof des address
*/
static inline void i2s_ll_get_in_eof_des_addr(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Get I2S tx fifo mode
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get tx fifo mode
*/
static inline void i2s_ll_get_tx_fifo_mod(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Set I2S tx fifo mode
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx fifo mode
*/
static inline void i2s_ll_set_tx_fifo_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Get I2S rx fifo mode
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get rx fifo mode
*/
static inline void i2s_ll_get_rx_fifo_mod(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Set I2S rx fifo mode
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx fifo mode
*/
static inline void i2s_ll_set_rx_fifo_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx chan mode
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx chan mode
*/
static inline void i2s_ll_set_tx_chan_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx chan mode
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx chan mode
*/
static inline void i2s_ll_set_rx_chan_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S out link address
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set out link address
*/
static inline void i2s_ll_set_out_link_addr(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S in link address
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set in link address
*/
static inline void i2s_ll_set_in_link_addr(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx eof num
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx eof num
*/
static inline void i2s_ll_set_rx_eof_num(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Get I2S tx pdm fp
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get tx pdm fp
*/
static inline void i2s_ll_get_tx_pdm_fp(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Get I2S tx pdm fs
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get tx pdm fs
*/
static inline void i2s_ll_get_tx_pdm_fs(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Set I2S tx pdm fp
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx pdm fp
*/
static inline void i2s_ll_set_tx_pdm_fp(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx pdm fs
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx pdm fs
*/
static inline void i2s_ll_set_tx_pdm_fs(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Get I2S rx sinc dsr 16 en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get rx sinc dsr 16 en
*/
static inline void i2s_ll_get_rx_sinc_dsr_16_en(i2s_dev_t *hw, bool *val)
{
}
/**
* @brief Set I2S clkm div num
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set clkm div num
*/
static inline void i2s_ll_set_clkm_div_num(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S clkm div b
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set clkm div b
*/
static inline void i2s_ll_set_clkm_div_b(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S clkm div a
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set clkm div a
*/
static inline void i2s_ll_set_clkm_div_a(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx bck div num
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx bck div num
*/
static inline void i2s_ll_set_tx_bck_div_num(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx bck div num
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx bck div num
*/
static inline void i2s_ll_set_rx_bck_div_num(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S clk sel
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set clk sel
*/
static inline void i2s_ll_set_clk_sel(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx bits mod
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx bits mod
*/
static inline void i2s_ll_set_tx_bits_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx bits mod
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx bits mod
*/
static inline void i2s_ll_set_rx_bits_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx sinc dsr 16 en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx sinc dsr 16 en
*/
static inline void i2s_ll_set_rx_sinc_dsr_16_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S dscr en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set dscr en
*/
static inline void i2s_ll_set_dscr_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S lcd en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set lcd en
*/
static inline void i2s_ll_set_lcd_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S camera en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set camera en
*/
static inline void i2s_ll_set_camera_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S pcm2pdm conv en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set pcm2pdm conv en
*/
static inline void i2s_ll_set_pcm2pdm_conv_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S pdm2pcm conv en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set pdm2pcm conv en
*/
static inline void i2s_ll_set_pdm2pcm_conv_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S rx pdm en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx pdm en
*/
static inline void i2s_ll_set_rx_pdm_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S tx pdm en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx pdm en
*/
static inline void i2s_ll_set_tx_pdm_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S tx msb shift
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx msb shift
*/
static inline void i2s_ll_set_tx_msb_shift(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx msb shift
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx msb shift
*/
static inline void i2s_ll_set_rx_msb_shift(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx short sync
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx short sync
*/
static inline void i2s_ll_set_tx_short_sync(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx short sync
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx short sync
*/
static inline void i2s_ll_set_rx_short_sync(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx fifo mod force en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx fifo mod force en
*/
static inline void i2s_ll_set_tx_fifo_mod_force_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S rx fifo mod force en
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx fifo mod force en
*/
static inline void i2s_ll_set_rx_fifo_mod_force_en(i2s_dev_t *hw, bool val)
{
}
/**
* @brief Set I2S tx right first
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx right first
*/
static inline void i2s_ll_set_tx_right_first(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx right first
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx right first
*/
static inline void i2s_ll_set_rx_right_first(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx slave mod
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx slave mod
*/
static inline void i2s_ll_set_tx_slave_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx slave mod
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx slave mod
*/
static inline void i2s_ll_set_rx_slave_mod(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Get I2S tx msb right
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get tx msb right
*/
static inline void i2s_ll_get_tx_msb_right(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Get I2S rx msb right
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to get rx msb right
*/
static inline void i2s_ll_get_rx_msb_right(i2s_dev_t *hw, uint32_t *val)
{
}
/**
* @brief Set I2S tx msb right
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx msb right
*/
static inline void i2s_ll_set_tx_msb_right(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx msb right
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx msb right
*/
static inline void i2s_ll_set_rx_msb_right(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx mono
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx mono
*/
static inline void i2s_ll_set_tx_mono(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S rx mono
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set rx mono
*/
static inline void i2s_ll_set_rx_mono(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S tx sinc osr2
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set tx sinc osr2
*/
static inline void i2s_ll_set_tx_sinc_osr2(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S sig loopback
*
* @param hw Peripheral I2S hardware instance address.
* @param val value to set sig loopback
*/
static inline void i2s_ll_set_sig_loopback(i2s_dev_t *hw, uint32_t val)
{
}
/**
* @brief Set I2S TX to philip standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_tx_format_philip(i2s_dev_t *hw)
{
}
/**
* @brief Set I2S RX to philip standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_rx_format_philip(i2s_dev_t *hw)
{
}
/**
* @brief Set I2S TX to MSB Alignment Standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_tx_format_msb_align(i2s_dev_t *hw)
{
}
/**
* @brief Set I2S RX to MSB Alignment Standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_rx_format_msb_align(i2s_dev_t *hw)
{
}
/**
* @brief Set I2S TX to PCM short standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_tx_pcm_short(i2s_dev_t *hw)
{
}
/**
* @brief Set I2S RX to PCM short standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_rx_pcm_short(i2s_dev_t *hw)
{
}
/**
* @brief Set I2S TX to PCM long standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_tx_pcm_long(i2s_dev_t *hw)
{
}
/**
* @brief Set I2S RX to PCM long standard
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_set_rx_pcm_long(i2s_dev_t *hw)
{
}
/**
* @brief Configure I2S TX pdm
*
* @param sample_rate The sample rate to be set.
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_tx_pdm_cfg(i2s_dev_t *hw, uint32_t sample_rate)
{
}
/**
* @brief Configure I2S TX pdm
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_rx_pdm_cfg(i2s_dev_t *hw)
{
}
/**
* @brief Enable I2S build in ADC mode
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_build_in_adc_ena(i2s_dev_t *hw)
{
}
/**
* @brief Enable I2S build in DAC mode
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_build_in_dac_ena(i2s_dev_t *hw)
{
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,518 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 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"
#ifdef __cplusplus
extern "C" {
#endif
#define LEDC_LL_GET_HW() &LEDC
/**
* @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_RTC8M) {
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_RTC8M;
} else if (clk_sel_val == 3) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
}
}
/**
* @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 Set 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 Timer clock source
*
* @return None
*/
static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src)
{
if (clk_src == LEDC_REF_TICK) {
//REF_TICK can only be used when APB is selected.
hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 1;
hw->conf.apb_clk_sel = 1;
} else {
hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 0;
}
}
/**
* @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)
{
if (hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 1) {
*clk_src = LEDC_REF_TICK;
} else {
*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

View File

@ -0,0 +1,735 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32 MCPWM register operations
#pragma once
#include <soc/mcpwm_periph.h>
#include "soc/mcpwm_periph.h"
#include "hal/mcpwm_types.h"
#include "soc/mcpwm_caps.h"
#include "hal/hal_defs.h"
#include "esp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Get the address of peripheral registers
#define MCPWM_LL_GET_HW(ID) (((ID)==0)? &MCPWM0: &MCPWM1)
/********************* Global *******************/
/**
* Initialize common registers.
*
* @param mcpwm Address of the MCPWM peripheral registers.
*/
static inline void mcpwm_ll_init(mcpwm_dev_t *mcpwm)
{
mcpwm->update_cfg.global_up_en = 1;
mcpwm->update_cfg.global_force_up = 1;
mcpwm->update_cfg.global_force_up = 0;
}
/**
* Set the prescale of the PWM main clock to the input clock.
*
* Input clock is 160MHz, PWM main clock cycle = 6.25ns*(prescale + 1).
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param prescale Prescale factor, 0-255.
*/
static inline void mcpwm_ll_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale)
{
mcpwm->clk_cfg.prescale = prescale;
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP0, MCPWM_CAP0_INT_RAW);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP1, MCPWM_CAP1_INT_RAW);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP2, MCPWM_CAP2_INT_RAW);
/**
* Get raw interrupt status.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @return The triggered interrupts, ORed by active interrupts.
*/
static inline mcpwm_intr_t mcpwm_ll_get_intr(mcpwm_dev_t *mcpwm)
{
return mcpwm->int_raw.val;
}
/**
* Clear the interrupts.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param intr Bitwise ORed interrupts to clear.
*/
static inline void mcpwm_ll_clear_intr(mcpwm_dev_t* mcpwm, mcpwm_intr_t intr)
{
mcpwm->int_clr.val = intr;
}
/********************* Timer *******************/
/**
* Set the prescale of the Timer_x clock to the PWM main clock.
*
* Timer clock frequency = PWM main clock frequency/(prescale + 1).
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to set the prescale, 0-2.
* @param prescale Prescale factor, 0-255.
*/
static inline void mcpwm_ll_timer_set_prescale(mcpwm_dev_t* mcpwm, int timer, uint32_t prescale)
{
mcpwm->timer[timer].period.prescale = prescale;
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_UP_COUNTER, 1);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_DOWN_COUNTER, 2);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_UP_DOWN_COUNTER, 3);
/**
* Set the counting mode for the PWM timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to change counting mode, 0-2.
* @param mode Counting mode to use.
*/
static inline void mcpwm_ll_timer_set_count_mode(mcpwm_dev_t *mcpwm, int timer, mcpwm_counter_type_t mode)
{
mcpwm->timer[timer].mode.mode = mode;
}
/**
* Start a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to start, 0-2.
*/
static inline void mcpwm_ll_timer_start(mcpwm_dev_t *mcpwm, int timer)
{
mcpwm->timer[timer].mode.start = 2;
}
/**
* Stop a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to stop, 0-2.
*/
static inline void mcpwm_ll_timer_stop(mcpwm_dev_t *mcpwm, int timer)
{
mcpwm->timer[timer].mode.start = 0;
}
/**
* Set the overflow period of a timer.
*
* The overflow rate will be Frequency of timer / period.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to set period, 0-2.
* @param period Total timer count of each period, 0-65535.
*/
static inline void mcpwm_ll_timer_set_period(mcpwm_dev_t *mcpwm, int timer, uint32_t period)
{
mcpwm->timer[timer].period.period = period;
mcpwm->timer[timer].period.upmethod = 0;
}
/**
* Get the period setting of a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to get the period, 0-2.
* @return Period setting value.
*/
static inline uint32_t mcpwm_ll_timer_get_period(mcpwm_dev_t *mcpwm, int timer)
{
return mcpwm->timer[timer].period.period;
}
/********************* Sync *******************/
/**
* Enable the synchronization feature for a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer Timer to set, 0-2.
* @param enable true to enable, otherwise false.
*/
static inline void mcpwm_ll_sync_enable(mcpwm_dev_t *mcpwm, int timer, bool enable)
{
if (enable) {
mcpwm->timer[timer].sync.out_sel = 0;
mcpwm->timer[timer].sync.in_en = 1;
} else {
mcpwm->timer[timer].sync.in_en = 0;
}
}
/**
* Set the phase (counter value) to reload when the sync signal triggers.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer Timer to set, 0-2.
* @param reload_val The reloaded value.
*/
static inline void mcpwm_ll_sync_set_phase(mcpwm_dev_t *mcpwm, int timer, uint32_t reload_val)
{
mcpwm->timer[timer].sync.timer_phase = reload_val;
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC0, 4);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC1, 5);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC2, 6);
/**
* Set the sync signal source for a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to set, 0-2.
* @param sync_sig The synchronization signal to use.
*/
static inline void mcpwm_ll_sync_set_input(mcpwm_dev_t *mcpwm, int timer, mcpwm_sync_signal_t sync_sig)
{
if (timer == 0) {
mcpwm->timer_synci_cfg.t0_in_sel = sync_sig;
} else if (timer == 1) {
mcpwm->timer_synci_cfg.t1_in_sel = sync_sig;
} else { //MCPWM_TIMER_2
mcpwm->timer_synci_cfg.t2_in_sel = sync_sig;
}
}
/********************* Comparator *******************/
/**
* Select a timer for the specified operator to use.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to choose timer, 0-2.
* @param timer The timer to use, 0-2.
*/
static inline void mcpwm_ll_operator_select_timer(mcpwm_dev_t *mcpwm, int op, int timer)
{
if (op == 0) {
mcpwm->timer_sel.operator0_sel = timer;
} else if (op == 1) {
mcpwm->timer_sel.operator1_sel = timer;
} else {
mcpwm->timer_sel.operator2_sel = timer;
}
}
/**
* Set the update method of the compare value of a timer
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op Operator to set, 0-2.
*/
static inline void mcpwm_ll_operator_set_compare_upmethod(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].cmpr_cfg.a_upmethod = BIT(0);
mcpwm->channel[op].cmpr_cfg.b_upmethod = BIT(0);
}
/**
* Get one of the compare value of a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to get, 0-2.
* @param cmp_n Comparer id to get, 0-1.
* @return The set compare value.
*/
static inline uint32_t mcpwm_ll_operator_get_compare(mcpwm_dev_t *mcpwm, int op, int cmp_n)
{
return (mcpwm->channel[op].cmpr_value[cmp_n].cmpr_val);
}
/**
* Set one of the compare value of a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param cmp_n The comparer to set value, 0-1.
* @param compare The compare value, 0-65535.
*/
static inline void mcpwm_ll_operator_set_compare(mcpwm_dev_t *mcpwm, int op, int cmp_n, uint32_t compare)
{
mcpwm->channel[op].cmpr_value[cmp_n].cmpr_val = compare;
}
/********************* Generator *******************/
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_NO_CHANGE, 0);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_FORCE_LOW, 1);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_FORCE_HIGH, 2);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_TOGGLE, 3);
/**
* Set the action will be taken by a operator when its timer counts to zero.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set action, 0-2.
* @param gen One generator of the operator to take the action, 0-1.
* @param action Action to take.
*/
static inline void mcpwm_ll_gen_set_zero_action(mcpwm_dev_t *mcpwm, int op, int gen, mcpwm_output_action_t action)
{
mcpwm->channel[op].generator[gen].utez = action;
mcpwm->channel[op].generator[gen].dtez = action;
}
/**
* Set the action will be taken by a operator when its timer counts to the period value.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set action, 0-2.
* @param gen One generator of the operator to take the action, 0-1.
* @param action Action to take.
*/
static inline void mcpwm_ll_gen_set_period_action(mcpwm_dev_t *mcpwm, int op, int gen, mcpwm_output_action_t action)
{
mcpwm->channel[op].generator[gen].utep = action;
mcpwm->channel[op].generator[gen].dtep = action;
}
/**
* Set the action will be taken by a operator when its timer counts to the compare value.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set action, 0-2.
* @param gen One generator of the operator to take the action, 0-1.
* @param cmp_n The comparer to use.
* @param up_action The action to take when the counter is counting up.
* @param down_action The action to take when the counter is counting down.
*/
static inline void mcpwm_ll_gen_set_cmp_action(mcpwm_dev_t *mcpwm, int op, int gen,
int cmp_n, mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
{
if (cmp_n == 0) {
mcpwm->channel[op].generator[gen].utea = up_action;
mcpwm->channel[op].generator[gen].dtea = down_action;
} else {
mcpwm->channel[op].generator[gen].uteb = up_action;
mcpwm->channel[op].generator[gen].dteb = down_action;
}
}
/********************* Fault *******************/
/**
* Enable the fault detection feature for an input signal.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param fault_sig One of the signals to select, 0-2.
* @param level The active level of the fault-detection signal.
*/
static inline void mcpwm_ll_fault_enable(mcpwm_dev_t *mcpwm, int fault_sig, bool level)
{
if (fault_sig == 0) {
mcpwm->fault_detect.f0_en = 1;
mcpwm->fault_detect.f0_pole = level;
} else if (fault_sig == 1) {
mcpwm->fault_detect.f1_en = 1;
mcpwm->fault_detect.f1_pole = level;
} else { //MCPWM_SELECT_F2
mcpwm->fault_detect.f2_en = 1;
mcpwm->fault_detect.f2_pole = level;
}
}
/**
* Disable the fault detection of an input signal.
* @param mcpwm Address of the MCPWM peripheral registers.
* @param fault_sig The signal to disable, 0-2.
*/
static inline void mcpwm_ll_fault_disable(mcpwm_dev_t *mcpwm, int fault_sig)
{
if (fault_sig == 0) {
mcpwm->fault_detect.f0_en = 0;
} else if (fault_sig == 1) {
mcpwm->fault_detect.f1_en = 0;
} else { //MCPWM_SELECT_F2
mcpwm->fault_detect.f2_en = 0;
}
}
/**
* Clear the oneshot fault status of an operator.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to clear, 0-2.
*/
static inline void mcpwm_ll_fault_clear_ost(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].tz_cfg1.clr_ost = 1;
mcpwm->channel[op].tz_cfg1.clr_ost = 0;
}
/**
* Use the oneshot mode to handle the fault when it occurs
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param signal The fault signal to set, 0-2.
* @param enable true to enable oneshot, otherwise false.
*/
static inline void mcpwm_ll_fault_oneshot_enable_signal(mcpwm_dev_t *mcpwm, int op, int signal, bool enable)
{
if (signal == 0) {
mcpwm->channel[op].tz_cfg0.f0_ost = enable;
} else if (signal == 1) {
mcpwm->channel[op].tz_cfg0.f1_ost = enable;
} else { //MCPWM_SELECT_F2
mcpwm->channel[op].tz_cfg0.f2_ost = enable;
}
}
/**
* @brief Get the oneshot enabled status of the operator
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to check, 0-2.
* @param signal The fault signal to get, 0-2.
*/
static inline bool mcpwm_ll_fault_oneshot_signal_enabled(mcpwm_dev_t *mcpwm, int op, int signal)
{
if (signal == 0) {
return mcpwm->channel[op].tz_cfg0.f0_ost;
} else if (signal == 1) {
return mcpwm->channel[op].tz_cfg0.f1_ost;
} else { //MCPWM_SELECT_F2
return mcpwm->channel[op].tz_cfg0.f2_ost;
}
}
/**
* Use the CBC (cycle-by-cycle) mode to handle the fault when it occurs.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param signal The fault signal to set, 0-2.
* @param enable true to enable cbc mode, otherwise false.
*/
static inline void mcpwm_ll_fault_cbc_enable_signal(mcpwm_dev_t *mcpwm, int op, int signal, bool enable)
{
if (signal == 0) {
mcpwm->channel[op].tz_cfg0.f0_cbc = enable;
} else if (signal == 1) {
mcpwm->channel[op].tz_cfg0.f1_cbc = enable;
} else { //MCPWM_SELECT_F2
mcpwm->channel[op].tz_cfg0.f2_cbc = enable;
}
}
/**
* Set the action that will be taken when the fault is handled by oneshot.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param gen The generator to take the action, 0-1.
* @param up_action Action to take when fault happens when counting up.
* @param down_action Action to take when fault happens when counting down.
*/
static inline void mcpwm_ll_fault_set_oneshot_action(mcpwm_dev_t *mcpwm, int op, int gen,
mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
{
if (gen == 0) {
mcpwm->channel[op].tz_cfg0.a_ost_u = up_action;
mcpwm->channel[op].tz_cfg0.a_ost_d = down_action;
} else {
mcpwm->channel[op].tz_cfg0.b_ost_u = up_action;
mcpwm->channel[op].tz_cfg0.b_ost_d = down_action;
}
}
/**
* Set the action that will be taken when the fault is handled cycle by cycle.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param gen The generator to take the action, 0-1.
* @param up_action Action to take when fault happens when counting up.
* @param down_action Action to take when fault happens when counting down.
*/
static inline void mcpwm_ll_fault_set_cyc_action(mcpwm_dev_t *mcpwm, int op, int gen,
mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
{
mcpwm->channel[op].tz_cfg1.cbcpulse = BIT(0); //immediately
if (gen == 0) {
mcpwm->channel[op].tz_cfg0.a_cbc_u = up_action;
mcpwm->channel[op].tz_cfg0.a_cbc_d = down_action;
} else {
mcpwm->channel[op].tz_cfg0.b_cbc_u = up_action;
mcpwm->channel[op].tz_cfg0.b_cbc_d = down_action;
}
}
/********************* Dead Zone (deadtime) *******************/
/**
* Initialize the dead zone feature.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to initialize, 0-2.
*/
static inline void mcpwm_ll_deadtime_init(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].db_cfg.fed_upmethod = BIT(0);
mcpwm->channel[op].db_cfg.red_upmethod = BIT(0);
mcpwm->channel[op].db_cfg.clk_sel = 0;
}
/**
* Set the output dead zone mode applying to the outputs of a timer.
*
* If the desired internal connection is not provided, you can write your own inside this function.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param mode Dead zone mode to use.
*/
static inline void mcpwm_ll_set_deadtime_mode(mcpwm_dev_t *mcpwm,
int op, mcpwm_deadtime_type_t mode)
{
#define MCPWM_LL_DEADTIME_REG_MASK (MCPWM_DT0_DEB_MODE_M | MCPWM_DT0_A_OUTSWAP_M | MCPWM_DT0_B_OUTSWAP_M | \
MCPWM_DT0_RED_INSEL_M | MCPWM_DT0_FED_INSEL_M | MCPWM_DT0_RED_OUTINVERT_M | MCPWM_DT0_FED_OUTINVERT_M | \
MCPWM_DT0_A_OUTBYPASS_M | MCPWM_DT0_B_OUTBYPASS_M)
static uint32_t deadtime_mode_settings[MCPWM_DEADTIME_TYPE_MAX] = {
[MCPWM_BYPASS_RED] = 0b010010000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_BYPASS_FED] = 0b100000000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_HIGH_MODE] = 0b000010000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_LOW_MODE] = 0b001110000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE] = 0b001010000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_LOW_COMPLIMENT_MODE] = 0b000101000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_RED_FED_FROM_PWMXA] = 0b000000011 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_RED_FED_FROM_PWMXB] = 0b000001011 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_DEADTIME_BYPASS] = 0b110000000 << MCPWM_DT0_DEB_MODE_S,
};
mcpwm->channel[op].db_cfg.val =
(mcpwm->channel[op].db_cfg.val & (~MCPWM_LL_DEADTIME_REG_MASK)) | deadtime_mode_settings[mode];
#undef MCPWM_LL_DEADTIME_REG_MASK
}
/**
* Set the delay of the falling edge on the output.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param fed Falling delay, by PWM main clock.
*/
static inline void mcpwm_ll_deadtime_set_falling_delay(mcpwm_dev_t *mcpwm, int op, uint32_t fed)
{
mcpwm->channel[op].db_fed_cfg.fed = fed;
}
/**
* Set the delay of the rising edge on the output.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param fed Rising delay, by PWM main clock.
*/
static inline void mcpwm_ll_deadtime_set_rising_delay(mcpwm_dev_t *mcpwm, int op, uint32_t red)
{
mcpwm->channel[op].db_red_cfg.red = red;
}
/**
* Disable (bypass) the dead zone feature.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
*/
static inline void mcpwm_ll_deadtime_bypass(mcpwm_dev_t *mcpwm, int op)
{
mcpwm_ll_set_deadtime_mode(mcpwm, op, MCPWM_DEADTIME_BYPASS);
}
/********************* Carrier *******************/
/**
* Initialize the carrier feature.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
*/
static inline void mcpwm_ll_carrier_init(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].carrier_cfg.in_invert = 0;
}
/**
* Enable the carrier feature for a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param enable true to enable, otherwise false.
*/
static inline void mcpwm_ll_carrier_enable(mcpwm_dev_t *mcpwm, int op, bool enable)
{
mcpwm->channel[op].carrier_cfg.en = enable;
}
/**
* Set the prescale of the carrier timer.
*
* The carrier period will be Frequency of PWM main clock/(carrier_period+1).
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param carrier_period The prescale of the carrier clock, 0-15.
*/
static inline void mcpwm_ll_carrier_set_prescale(mcpwm_dev_t *mcpwm, int op, uint8_t carrier_period)
{
mcpwm->channel[op].carrier_cfg.prescale = carrier_period;
}
/**
* Set the duty rate of the carrier.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param carrier_duty Duty rate will be (carrier_duty/8)*100%. 0-7.
*/
static inline void mcpwm_ll_carrier_set_duty(mcpwm_dev_t *mcpwm, int op, uint8_t carrier_duty)
{
mcpwm->channel[op].carrier_cfg.duty = carrier_duty;
}
/**
* Invert output of the carrier.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param invert true to invert, otherwise false.
*/
static inline void mcpwm_ll_carrier_out_invert(mcpwm_dev_t *mcpwm, int op, bool invert)
{
mcpwm->channel[op].carrier_cfg.out_invert = invert;
}
/**
* Set the oneshot pulse width of the carrier.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param pulse_width The width of the oneshot pulse, by carrier period. 0 to disable the oneshot pulse.
*/
static inline void mcpwm_ll_carrier_set_oneshot_width(mcpwm_dev_t *mcpwm, int op, uint8_t pulse_width)
{
mcpwm->channel[op].carrier_cfg.oshtwth = pulse_width;
}
/********************* Capture *******************/
/**
* Enable the capture feature for a signal
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig Signal to enable, 0-2.
* @param enable true to enable, otherwise false.
*/
static inline void mcpwm_ll_capture_enable(mcpwm_dev_t *mcpwm, int cap_sig, int enable)
{
if (enable) {
mcpwm->cap_timer_cfg.timer_en = 1;
mcpwm->cap_cfg_ch[cap_sig].en = 1;
} else {
mcpwm->cap_cfg_ch[cap_sig].en = 0;
}
}
/**
* Get the captured value.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig Of which signal to get the captured value.
* @return The captured value
*/
static inline uint32_t mcpwm_ll_get_capture_val(mcpwm_dev_t *mcpwm, int cap_sig)
{
return mcpwm->cap_val_ch[cap_sig];
}
/**
* Get the set capture edge.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig Which signal the edge capture is applied.
* @return Capture signal edge: 1 - positive edge, 2 - negtive edge
*/
static inline mcpwm_capture_on_edge_t mcpwm_ll_get_captured_edge(mcpwm_dev_t *mcpwm, int cap_sig)
{
bool edge;
if (cap_sig == 0) {
edge = mcpwm->cap_status.cap0_edge;
} else if (cap_sig == 1) {
edge = mcpwm->cap_status.cap0_edge;
} else { //2
edge = mcpwm->cap_status.cap0_edge;
}
return (edge? MCPWM_NEG_EDGE: MCPWM_POS_EDGE);
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_NEG_EDGE, BIT(0));
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_POS_EDGE, BIT(1));
/**
* Select the edge to capture.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig The signal to capture, 0-2.
* @param cap_edge The edge to capture, bitwise.
*/
static inline void mcpwm_ll_capture_select_edge(mcpwm_dev_t *mcpwm, int cap_sig,
mcpwm_capture_on_edge_t cap_edge)
{
mcpwm->cap_cfg_ch[cap_sig].mode = cap_edge;
}
/**
* Set the prescale of the input signal to capture.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig The prescaled signal to capture, 0-2.
* @param prescale Prescal value, 0 to disable.
*/
static inline void mcpwm_ll_capture_set_prescale(mcpwm_dev_t *mcpwm, int cap_sig, uint32_t prescale)
{
mcpwm->cap_cfg_ch[cap_sig].prescale = prescale;
}
/**
* Utility function, get the `mcpwm_intr_t` interrupt enum of a specific capture signal.
*
* @param bit x for CAPx.
* @return the corresponding `mcpwm_intr_t`.
*/
static inline mcpwm_intr_t mcpwm_ll_get_cap_intr_def(int bit)
{
return BIT(bit+MCPWM_CAP0_INT_RAW_S);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,654 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// not implemented for esp32s3 yet
#if 0
/**
* === IRAM0 ====
*/
#define IRAM0_TOTAL_UNI_BLOCKS 4
#define IRAM0_UNI_BLOCK_0 0
#define IRAM0_UNI_BLOCK_1 1
#define IRAM0_UNI_BLOCK_2 2
#define IRAM0_UNI_BLOCK_3 3
#define IRAM0_SPL_BLOCK_BASE 0x40000000
//unified management (SRAM blocks 0-3)
#define IRAM0_UNI_BLOCK_0_LOW 0x40020000
#define IRAM0_UNI_BLOCK_0_HIGH 0x40021FFF
#define IRAM0_UNI_BLOCK_1_LOW 0x40022000
#define IRAM0_UNI_BLOCK_1_HIGH 0x40023FFF
#define IRAM0_UNI_BLOCK_2_LOW 0x40024000
#define IRAM0_UNI_BLOCK_2_HIGH 0x40025FFF
#define IRAM0_UNI_BLOCK_3_LOW 0x40026000
#define IRAM0_UNI_BLOCK_3_HIGH 0x40027FFF
//split management (SRAM blocks 4-21)
#define IRAM0_SPL_BLOCK_LOW 0x40028000 //block 4 low
#define IRAM0_SPL_BLOCK_HIGH 0x4006FFFF //block 21 high
#define IRAM0_SPLTADDR_MIN 0x40030000 //block 6 low - minimum splitting address
//IRAM0 interrupt status bitmasks
#define IRAM0_INTR_ST_FAULTADDR_M 0x003FFFFC //(bits 21:6 in the reg, as well as in real address)
#define IRAM0_INTR_ST_FAULTADDR_HI 0x40000000 //(high nonsignificant bits 31:22 of the faulting address - constant)
#define IRAM0_INTR_ST_OP_TYPE_BIT BIT(1) //instruction: 0, data: 1
#define IRAM0_INTR_ST_OP_RW_BIT BIT(0) //read: 0, write: 1
static inline uint32_t esp_memprot_iram0_get_intr_source_num(void)
{
return ETS_PMS_PRO_IRAM0_ILG_INTR_SOURCE;
}
static inline void esp_memprot_iram0_intr_ena(bool enable)
{
if ( enable ) {
DPORT_SET_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_EN );
} else {
DPORT_CLEAR_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_EN );
}
}
static inline uint32_t esp_memprot_iram0_get_ena_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_4_REG);
}
static inline uint32_t esp_memprot_iram0_get_fault_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_5_REG);
}
static inline void esp_memprot_iram0_get_fault_status(uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype)
{
uint32_t status_bits = esp_memprot_iram0_get_fault_reg();
uint32_t fault_addr = (status_bits & IRAM0_INTR_ST_FAULTADDR_M);
*faulting_address = (uint32_t *)(fault_addr | IRAM0_INTR_ST_FAULTADDR_HI);
*op_type = (uint32_t)status_bits & IRAM0_INTR_ST_OP_RW_BIT;
*op_subtype = (uint32_t)status_bits & IRAM0_INTR_ST_OP_TYPE_BIT;
}
static inline bool esp_memprot_iram0_is_assoc_intr(void)
{
return DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_INTR) > 0;
}
static inline void esp_memprot_iram0_clear_intr(void)
{
DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_CLR);
}
static inline uint32_t esp_memprot_iram0_get_intr_ena_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_EN);
}
static inline uint32_t esp_memprot_iram0_get_intr_on_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_INTR);
}
static inline uint32_t esp_memprot_iram0_get_intr_clr_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_CLR);
}
//resets automatically on CPU restart
static inline void esp_memprot_iram0_set_lock(void)
{
DPORT_WRITE_PERI_REG( DPORT_PMS_PRO_IRAM0_0_REG, DPORT_PMS_PRO_IRAM0_LOCK);
}
static inline uint32_t esp_memprot_iram0_get_lock_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_0_REG);
}
static inline uint32_t esp_memprot_iram0_get_lock_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_IRAM0_0_REG, DPORT_PMS_PRO_IRAM0_LOCK);
}
//block 0-3
static inline void esp_memprot_iram0_set_uni_block_perm(uint32_t block, bool write_perm, bool read_perm, bool exec_perm)
{
assert(block < IRAM0_TOTAL_UNI_BLOCKS);
uint32_t write_bit, read_bit, exec_bit;
switch ( block ) {
case IRAM0_UNI_BLOCK_0:
write_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_W;
read_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_R;
exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_F;
break;
case IRAM0_UNI_BLOCK_1:
write_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_W;
read_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_R;
exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_F;
break;
case IRAM0_UNI_BLOCK_2:
write_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_W;
read_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_R;
exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_F;
break;
case IRAM0_UNI_BLOCK_3:
write_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_W;
read_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_R;
exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_F;
break;
default:
abort();
}
if ( write_perm ) {
DPORT_SET_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_1_REG, write_bit );
} else {
DPORT_CLEAR_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_1_REG, write_bit );
}
if ( read_perm ) {
DPORT_SET_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_1_REG, read_bit );
} else {
DPORT_CLEAR_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_1_REG, read_bit );
}
if ( exec_perm ) {
DPORT_SET_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_1_REG, exec_bit );
} else {
DPORT_CLEAR_PERI_REG_MASK( DPORT_PMS_PRO_IRAM0_1_REG, exec_bit );
}
}
static inline uint32_t esp_memprot_iram0_get_uni_block_read_bit(uint32_t block)
{
assert(block < IRAM0_TOTAL_UNI_BLOCKS);
switch ( block ) {
case IRAM0_UNI_BLOCK_0:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_0_R );
case IRAM0_UNI_BLOCK_1:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_1_R );
case IRAM0_UNI_BLOCK_2:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_2_R );
case IRAM0_UNI_BLOCK_3:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_3_R );
default:
abort();
}
}
static inline uint32_t esp_memprot_iram0_get_uni_block_write_bit(uint32_t block)
{
assert(block < IRAM0_TOTAL_UNI_BLOCKS);
switch ( block ) {
case IRAM0_UNI_BLOCK_0:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_0_W );
case IRAM0_UNI_BLOCK_1:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_1_W );
case IRAM0_UNI_BLOCK_2:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_2_W );
case IRAM0_UNI_BLOCK_3:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_3_W );
default:
abort();
}
}
static inline uint32_t esp_memprot_iram0_get_uni_block_exec_bit(uint32_t block)
{
assert(block < IRAM0_TOTAL_UNI_BLOCKS);
switch ( block ) {
case IRAM0_UNI_BLOCK_0:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_0_F );
case IRAM0_UNI_BLOCK_1:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_1_F );
case IRAM0_UNI_BLOCK_2:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_2_F );
case IRAM0_UNI_BLOCK_3:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_1_REG, DPORT_PMS_PRO_IRAM0_SRAM_3_F );
default:
abort();
}
}
static inline void esp_memprot_iram0_get_uni_block_sgnf_bits(uint32_t block, uint32_t *write_bit, uint32_t *read_bit, uint32_t *exec_bit)
{
assert(block < IRAM0_TOTAL_UNI_BLOCKS);
switch ( block ) {
case IRAM0_UNI_BLOCK_0:
*write_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_W;
*read_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_R;
*exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_0_F;
break;
case IRAM0_UNI_BLOCK_1:
*write_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_W;
*read_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_R;
*exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_1_F;
break;
case IRAM0_UNI_BLOCK_2:
*write_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_W;
*read_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_R;
*exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_2_F;
break;
case IRAM0_UNI_BLOCK_3:
*write_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_W;
*read_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_R;
*exec_bit = DPORT_PMS_PRO_IRAM0_SRAM_3_F;
break;
default:
abort();
}
}
static inline uint32_t esp_memprot_iram0_get_perm_uni_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_1_REG);
}
static inline uint32_t esp_memprot_iram0_get_perm_split_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_IRAM0_2_REG);
}
static inline void esp_memprot_iram0_set_prot(uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx)
{
uint32_t addr = (uint32_t)split_addr;
assert( addr <= IRAM0_SPL_BLOCK_HIGH );
//find possible split.address in low region blocks
int uni_blocks_low = -1;
if ( addr >= IRAM0_UNI_BLOCK_0_LOW ) {
uni_blocks_low++;
}
if ( addr >= IRAM0_UNI_BLOCK_1_LOW ) {
uni_blocks_low++;
}
if ( addr >= IRAM0_UNI_BLOCK_2_LOW ) {
uni_blocks_low++;
}
if ( addr >= IRAM0_UNI_BLOCK_3_LOW ) {
uni_blocks_low++;
}
//unified mgmt settings per block (bits W/R/X: [11:9] bl3, [8:6] bl2, [5:3] bl1, [2:0] bl0)
uint32_t write_bit, read_bit, exec_bit;
uint32_t uni_block_perm = 0;
for ( size_t x = 0; x < IRAM0_TOTAL_UNI_BLOCKS; x++ ) {
esp_memprot_iram0_get_uni_block_sgnf_bits(x, &write_bit, &read_bit, &exec_bit);
if ( x <= uni_blocks_low ) {
if (lw) {
uni_block_perm |= write_bit;
}
if (lr) {
uni_block_perm |= read_bit;
}
if (lx) {
uni_block_perm |= exec_bit;
}
} else {
if (hw) {
uni_block_perm |= write_bit;
}
if (hr) {
uni_block_perm |= read_bit;
}
if (hx) {
uni_block_perm |= exec_bit;
}
}
}
//if splt.ddr not set yet, do required normalization to make the addr writeble into splt.mgmt cfg register
uint32_t reg_split_addr = 0;
if ( addr >= IRAM0_SPL_BLOCK_LOW ) {
//split Address must be WORD aligned
reg_split_addr = addr >> 2;
assert(addr == (reg_split_addr << 2));
//use only 17 signf.bits as the cropped parts are constant for whole section (bits [16:0])
reg_split_addr = (reg_split_addr << DPORT_PMS_PRO_IRAM0_SRAM_4_SPLTADDR_S) & DPORT_PMS_PRO_IRAM0_SRAM_4_SPLTADDR_M;
}
//prepare high & low permission mask (bits: [22:20] high range, [19:17] low range)
uint32_t permission_mask = 0;
if ( lw ) {
permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_L_W;
}
if ( lr ) {
permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_L_R;
}
if ( lx ) {
permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_L_F;
}
if ( hw ) {
permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_H_W;
}
if ( hr ) {
permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_H_R;
}
if ( hx ) {
permission_mask |= DPORT_PMS_PRO_IRAM0_SRAM_4_H_F;
}
//write both cfg. registers
DPORT_WRITE_PERI_REG( DPORT_PMS_PRO_IRAM0_1_REG, uni_block_perm );
DPORT_WRITE_PERI_REG( DPORT_PMS_PRO_IRAM0_2_REG, reg_split_addr | permission_mask );
}
static inline void esp_memprot_iram0_get_split_sgnf_bits(bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx)
{
*lw = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_W );
*lr = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_R );
*lx = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_L_F );
*hw = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_W );
*hr = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_R );
*hx = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_IRAM0_2_REG, DPORT_PMS_PRO_IRAM0_SRAM_4_H_F );
}
/**
* === DRAM0 ====
*/
#define DRAM0_TOTAL_UNI_BLOCKS 4
#define DRAM0_UNI_BLOCK_0 0
#define DRAM0_UNI_BLOCK_1 1
#define DRAM0_UNI_BLOCK_2 2
#define DRAM0_UNI_BLOCK_3 3
#define DRAM0_SPL_BLOCK_BASE 0x3FFB0000
//unified management (SRAM blocks 0-3)
#define DRAM0_UNI_BLOCK_0_LOW 0x3FFB0000
#define DRAM0_UNI_BLOCK_0_HIGH 0x3FFB1FFF
#define DRAM0_UNI_BLOCK_1_LOW 0x3FFB2000
#define DRAM0_UNI_BLOCK_1_HIGH 0x3FFB3FFF
#define DRAM0_UNI_BLOCK_2_LOW 0x3FFB4000
#define DRAM0_UNI_BLOCK_2_HIGH 0x3FFB5FFF
#define DRAM0_UNI_BLOCK_3_LOW 0x3FFB6000
#define DRAM0_UNI_BLOCK_3_HIGH 0x3FFB7FFF
//split management (SRAM blocks 4-21)
#define DRAM0_SPL_BLOCK_LOW 0x3FFB8000 //block 4 low
#define DRAM0_SPL_BLOCK_HIGH 0x3FFFFFFF //block 21 high
#define DRAM0_SPLTADDR_MIN 0x3FFC0000 //block 6 low - minimum splitting address
//DRAM0 interrupt status bitmasks
#define DRAM0_INTR_ST_FAULTADDR_M 0x03FFFFC0 //(bits 25:6 in the reg)
#define DRAM0_INTR_ST_FAULTADDR_S 0x4 //(bits 21:2 of real address)
#define DRAM0_INTR_ST_FAULTADDR_HI 0x3FF00000 //(high nonsignificant bits 31:22 of the faulting address - constant)
#define DRAM0_INTR_ST_OP_RW_BIT BIT(4) //read: 0, write: 1
#define DRAM0_INTR_ST_OP_ATOMIC_BIT BIT(5) //non-atomic: 0, atomic: 1
static inline uint32_t esp_memprot_dram0_get_intr_source_num(void)
{
return ETS_PMS_PRO_DRAM0_ILG_INTR_SOURCE;
}
static inline void esp_memprot_dram0_intr_ena(bool enable)
{
if ( enable ) {
DPORT_SET_PERI_REG_MASK( DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_EN );
} else {
DPORT_CLEAR_PERI_REG_MASK( DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_EN );
}
}
static inline bool esp_memprot_dram0_is_assoc_intr(void)
{
return DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_INTR) > 0;
}
static inline void esp_memprot_dram0_clear_intr(void)
{
DPORT_SET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_CLR);
}
static inline uint32_t esp_memprot_dram0_get_intr_ena_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_EN);
}
static inline uint32_t esp_memprot_dram0_get_intr_on_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_INTR);
}
static inline uint32_t esp_memprot_dram0_get_intr_clr_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_CLR);
}
static inline uint32_t esp_memprot_dram0_get_lock_bit(void)
{
return DPORT_REG_GET_FIELD(DPORT_PMS_PRO_DRAM0_0_REG, DPORT_PMS_PRO_DRAM0_LOCK);
}
static inline void esp_memprot_dram0_get_uni_block_sgnf_bits(uint32_t block, uint32_t *write_bit, uint32_t *read_bit)
{
assert(block < DRAM0_TOTAL_UNI_BLOCKS);
switch ( block ) {
case DRAM0_UNI_BLOCK_0:
*write_bit = DPORT_PMS_PRO_DRAM0_SRAM_0_W;
*read_bit = DPORT_PMS_PRO_DRAM0_SRAM_0_R;
break;
case DRAM0_UNI_BLOCK_1:
*write_bit = DPORT_PMS_PRO_DRAM0_SRAM_1_W;
*read_bit = DPORT_PMS_PRO_DRAM0_SRAM_1_R;
break;
case DRAM0_UNI_BLOCK_2:
*write_bit = DPORT_PMS_PRO_DRAM0_SRAM_2_W;
*read_bit = DPORT_PMS_PRO_DRAM0_SRAM_2_R;
break;
case DRAM0_UNI_BLOCK_3:
*write_bit = DPORT_PMS_PRO_DRAM0_SRAM_3_W;
*read_bit = DPORT_PMS_PRO_DRAM0_SRAM_3_R;
break;
default:
abort();
}
}
static inline void esp_memprot_dram0_set_uni_block_perm(uint32_t block, bool write_perm, bool read_perm)
{
assert(block < DRAM0_TOTAL_UNI_BLOCKS);
uint32_t write_bit, read_bit;
esp_memprot_dram0_get_uni_block_sgnf_bits(block, &write_bit, &read_bit);
if ( write_perm ) {
DPORT_SET_PERI_REG_MASK( DPORT_PMS_PRO_DRAM0_1_REG, write_bit );
} else {
DPORT_CLEAR_PERI_REG_MASK( DPORT_PMS_PRO_DRAM0_1_REG, write_bit );
}
if ( read_perm ) {
DPORT_SET_PERI_REG_MASK( DPORT_PMS_PRO_DRAM0_1_REG, read_bit );
} else {
DPORT_CLEAR_PERI_REG_MASK( DPORT_PMS_PRO_DRAM0_1_REG, read_bit );
}
}
static inline uint32_t esp_memprot_dram0_get_uni_block_read_bit(uint32_t block)
{
assert(block < DRAM0_TOTAL_UNI_BLOCKS);
switch ( block ) {
case DRAM0_UNI_BLOCK_0:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_0_R );
case DRAM0_UNI_BLOCK_1:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_1_R );
case DRAM0_UNI_BLOCK_2:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_2_R );
case DRAM0_UNI_BLOCK_3:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_3_R );
default:
abort();
}
}
static inline uint32_t esp_memprot_dram0_get_uni_block_write_bit(uint32_t block)
{
assert(block < DRAM0_TOTAL_UNI_BLOCKS);
switch ( block ) {
case DRAM0_UNI_BLOCK_0:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_0_W );
case DRAM0_UNI_BLOCK_1:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_1_W );
case DRAM0_UNI_BLOCK_2:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_2_W );
case DRAM0_UNI_BLOCK_3:
return DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_3_W );
default:
abort();
}
}
static inline uint32_t esp_memprot_dram0_get_lock_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_0_REG);
}
//lock resets automatically on CPU restart
static inline void esp_memprot_dram0_set_lock(void)
{
DPORT_WRITE_PERI_REG( DPORT_PMS_PRO_DRAM0_0_REG, DPORT_PMS_PRO_DRAM0_LOCK);
}
static inline uint32_t esp_memprot_dram0_get_perm_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_1_REG);
}
static inline uint32_t esp_memprot_dram0_get_ena_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_3_REG);
}
static inline uint32_t esp_memprot_dram0_get_fault_reg(void)
{
return DPORT_READ_PERI_REG(DPORT_PMS_PRO_DRAM0_4_REG);
}
static inline void esp_memprot_dram0_get_fault_status(uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype)
{
uint32_t status_bits = esp_memprot_dram0_get_fault_reg();
uint32_t fault_addr = (status_bits & DRAM0_INTR_ST_FAULTADDR_M) >> DRAM0_INTR_ST_FAULTADDR_S;
*faulting_address = (uint32_t *)(fault_addr | DRAM0_INTR_ST_FAULTADDR_HI);
*op_type = (uint32_t)status_bits & DRAM0_INTR_ST_OP_RW_BIT;
*op_subtype = (uint32_t)status_bits & DRAM0_INTR_ST_OP_ATOMIC_BIT;
}
static inline void esp_memprot_dram0_set_prot(uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr)
{
uint32_t addr = (uint32_t)split_addr;
//low boundary check provided by LD script. see comment in esp_memprot_iram0_set_prot()
assert( addr <= DRAM0_SPL_BLOCK_HIGH );
//set low region
int uni_blocks_low = -1;
if ( addr >= DRAM0_UNI_BLOCK_0_LOW ) {
uni_blocks_low++;
}
if ( addr >= DRAM0_UNI_BLOCK_1_LOW ) {
uni_blocks_low++;
}
if ( addr >= DRAM0_UNI_BLOCK_2_LOW ) {
uni_blocks_low++;
}
if ( addr >= DRAM0_UNI_BLOCK_3_LOW ) {
uni_blocks_low++;
}
//set unified mgmt region
uint32_t write_bit, read_bit, uni_block_perm = 0;
for ( size_t x = 0; x < DRAM0_TOTAL_UNI_BLOCKS; x++ ) {
esp_memprot_dram0_get_uni_block_sgnf_bits(x, &write_bit, &read_bit);
if ( x <= uni_blocks_low ) {
if (lw) {
uni_block_perm |= write_bit;
}
if (lr) {
uni_block_perm |= read_bit;
}
} else {
if (hw) {
uni_block_perm |= write_bit;
}
if (hr) {
uni_block_perm |= read_bit;
}
}
}
//check split address is WORD aligned
uint32_t reg_split_addr = addr >> 2;
assert(addr == (reg_split_addr << 2));
//shift aligned split address to proper bit offset
reg_split_addr = (reg_split_addr << DPORT_PMS_PRO_DRAM0_SRAM_4_SPLTADDR_S) & DPORT_PMS_PRO_DRAM0_SRAM_4_SPLTADDR_M;
//prepare high & low permission mask
uint32_t permission_mask = 0;
if (lw) {
permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_L_W;
}
if (lr) {
permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_L_R;
}
if (hw) {
permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_H_W;
}
if (hr) {
permission_mask |= DPORT_PMS_PRO_DRAM0_SRAM_4_H_R;
}
//write configuration to DPORT_PMS_PRO_DRAM0_1_REG
DPORT_WRITE_PERI_REG(DPORT_PMS_PRO_DRAM0_1_REG, reg_split_addr | permission_mask | uni_block_perm);
}
static inline void esp_memprot_dram0_get_split_sgnf_bits(bool *lw, bool *lr, bool *hw, bool *hr)
{
*lw = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_L_W );
*lr = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_L_R );
*hw = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_H_W );
*hr = DPORT_REG_GET_FIELD( DPORT_PMS_PRO_DRAM0_1_REG, DPORT_PMS_PRO_DRAM0_SRAM_4_H_R );
}
#endif
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,62 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "soc/mpu_caps.h"
#include "xt_instr_macros.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t mpu_ll_id_to_addr(int id)
{
// vpn - id
// 0x00000000 = 0
// 0x20000000 = 1
// 0x40000000 = 2
// 0x60000000 = 3
// 0x80000000 = 4
// 0xa0000000 = 5
// 0xc0000000 = 6
// 0xe0000000 = 7
return id * SOC_MPU_MIN_REGION_SIZE;
}
static inline void mpu_ll_set_region_rw(uint32_t addr)
{
WDTLB(0x0, addr); // cached, no allocate
}
static inline void mpu_ll_set_region_rwx(uint32_t addr)
{
WDTLB(0x2, addr); // bypass cache
}
static inline void mpu_ll_set_region_x(uint32_t addr)
{
WITLB(0x3, addr); // cached
}
static inline void mpu_ll_set_region_illegal(uint32_t addr)
{
WITLB(0xF, addr);
WDTLB(0xF, addr);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,263 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 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 "hal/wdt_types.h"
#include "esp_attr.h"
//Type check wdt_stage_action_t
_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");
_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");
_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");
_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
_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");
_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");
_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");
_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");
_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");
_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");
_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");
_Static_assert(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
/**
* @brief Enable the MWDT
*
* @param hw Start address of the peripheral registers.
*/
FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
{
hw->wdt_config0.en = 1;
}
/**
* @brief Disable the MWDT
*
* @param hw Start address of the peripheral registers.
* @note This function does not disable the flashboot mode. Therefore, given that
* the MWDT is disabled using this function, a timeout can still occur
* if the flashboot mode is simultaneously enabled.
*/
FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
{
hw->wdt_config0.en = 0;
}
/**
* Check if the MWDT is enabled
*
* @param hw Start address of the peripheral registers.
* @return True if the MWDT is enabled, false otherwise
*/
FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
{
return (hw->wdt_config0.en) ? true : false;
}
/**
* @brief Configure a particular stage of the MWDT
*
* @param hw Start address of the peripheral registers.
* @param stage Which stage to configure
* @param timeout Number of timer ticks for the stage to timeout
* @param behavior What action to take when the stage times out
*/
FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior)
{
switch (stage) {
case WDT_STAGE0:
hw->wdt_config0.stg0 = behavior;
hw->wdt_config2 = timeout;
break;
case WDT_STAGE1:
hw->wdt_config0.stg1 = behavior;
hw->wdt_config3 = timeout;
break;
case WDT_STAGE2:
hw->wdt_config0.stg2 = behavior;
hw->wdt_config4 = timeout;
break;
case WDT_STAGE3:
hw->wdt_config0.stg3 = behavior;
hw->wdt_config5 = timeout;
break;
default:
break;
}
}
/**
* @brief Disable a particular stage of the MWDT
*
* @param hw Start address of the peripheral registers.
* @param stage Which stage to disable
*/
FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
{
switch (stage) {
case WDT_STAGE0:
hw->wdt_config0.stg0 = WDT_STAGE_ACTION_OFF;
break;
case WDT_STAGE1:
hw->wdt_config0.stg1 = WDT_STAGE_ACTION_OFF;
break;
case WDT_STAGE2:
hw->wdt_config0.stg2 = WDT_STAGE_ACTION_OFF;
break;
case WDT_STAGE3:
hw->wdt_config0.stg3 = WDT_STAGE_ACTION_OFF;
break;
default:
break;
}
}
/**
* @brief Enable or disable MWDT edge interrupt
*
* @param hw Start address of the peripheral registers.
* @param enable Whether to enable edge interrupt
*/
FORCE_INLINE_ATTR void mwdt_ll_set_edge_intr(timg_dev_t *hw, bool enable)
{
}
/**
* @brief Enable or disable MWDT level interrupt
*
* @param hw Start address of the peripheral registers.
* @param enable Whether to enable level interrupt
*/
FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable)
{
hw->int_ena.wdt = enable;
}
/**
* @brief Set the length of the CPU reset action
*
* @param hw Start address of the peripheral registers.
* @param length Length of CPU reset signal
*/
FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{
hw->wdt_config0.cpu_reset_length = length;
}
/**
* @brief Set the length of the system reset action
*
* @param hw Start address of the peripheral registers.
* @param length Length of system reset signal
*/
FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{
hw->wdt_config0.sys_reset_length = length;
}
/**
* @brief Enable/Disable the MWDT flashboot mode.
*
* @param hw Beginning address of the peripheral registers.
* @param enable True to enable WDT flashboot mode, false to disable WDT flashboot mode.
*
* @note Flashboot mode is independent and can trigger a WDT timeout event if the
* WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled
* on flashboot, and should be disabled by software when flashbooting completes.
*/
FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
{
hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0;
}
/**
* @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)
{
hw->wdt_config1.clk_prescale = prescaler;
}
/**
* @brief Feed the MWDT
*
* Resets the current timer count and current stage.
*
* @param hw Start address of the peripheral registers.
*/
FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
{
hw->wdt_feed = 1;
}
/**
* @brief Enable write protection of the MWDT registers
*
* Locking the MWDT will prevent any of the MWDT's registers from being modified
*
* @param hw Start address of the peripheral registers.
*/
FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
{
hw->wdt_wprotect = 0;
}
/**
* @brief Disable write protection of the MWDT registers
*
* @param hw Start address of the peripheral registers.
*/
FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
{
hw->wdt_wprotect = TIMG_WDT_WKEY_VALUE;
}
/**
* @brief Clear the MWDT interrupt status.
*
* @param hw Start address of the peripheral registers.
*/
FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
{
hw->int_clr.wdt = 1;
}
/**
* @brief Set the interrupt enable bit for the MWDT interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param enable Whether to enable the MWDT interrupt
*/
FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
{
hw->int_ena.wdt = (enable) ? 1 : 0;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,301 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32-S3 PCNT register operations
#pragma once
#include "soc/pcnt_periph.h"
#include "hal/pcnt_types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Get PCNT hardware instance with giving pcnt num
#define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL)
/**
* @brief Set PCNT counter mode
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param channel PCNT channel number
* @param pos_mode Counter mode when detecting positive edge
* @param neg_mode Counter mode when detecting negative edge
* @param hctrl_mode Counter mode when control signal is high level
* @param lctrl_mode Counter mode when control signal is low level
*/
static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
{
typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0;
if (channel == 0) {
conf0_reg.ch0_pos_mode = pos_mode;
conf0_reg.ch0_neg_mode = neg_mode;
conf0_reg.ch0_hctrl_mode = hctrl_mode;
conf0_reg.ch0_lctrl_mode = lctrl_mode;
} else {
conf0_reg.ch1_pos_mode = pos_mode;
conf0_reg.ch1_neg_mode = neg_mode;
conf0_reg.ch1_hctrl_mode = hctrl_mode;
conf0_reg.ch1_lctrl_mode = lctrl_mode;
}
hw->conf_unit[unit].conf0 = conf0_reg;
}
/**
* @brief Get pulse counter value
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit Pulse Counter unit number
* @param count Pointer to accept counter value
*/
static inline void pcnt_ll_get_counter_value(pcnt_dev_t *hw, pcnt_unit_t unit, int16_t *count)
{
*count = (int16_t) hw->cnt_unit[unit].cnt_val;
}
/**
* @brief Pause PCNT counter of PCNT unit
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
*/
static inline void pcnt_ll_counter_pause(pcnt_dev_t *hw, pcnt_unit_t unit)
{
hw->ctrl.val |= BIT(PCNT_CNT_PAUSE_U0_S + (unit * 2));
}
/**
* @brief Resume counting for PCNT counter
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number, select from pcnt_unit_t
*/
static inline void pcnt_ll_counter_resume(pcnt_dev_t *hw, pcnt_unit_t unit)
{
hw->ctrl.val &= (~(BIT(PCNT_CNT_PAUSE_U0_S + (unit * 2))));
}
/**
* @brief Clear and reset PCNT counter value to zero
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number, select from pcnt_unit_t
*/
static inline void pcnt_ll_counter_clear(pcnt_dev_t *hw, pcnt_unit_t unit)
{
uint32_t reset_bit = BIT(PCNT_PULSE_CNT_RST_U0_S + (unit * 2));
hw->ctrl.val |= reset_bit;
hw->ctrl.val &= ~reset_bit;
}
/**
* @brief Enable PCNT interrupt for PCNT unit
* @note
* Each Pulse counter unit has five watch point events that share the same interrupt.
* Configure events with pcnt_event_enable() and pcnt_event_disable()
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
*/
static inline void pcnt_ll_intr_enable(pcnt_dev_t *hw, pcnt_unit_t unit)
{
hw->int_ena.val |= BIT(PCNT_CNT_THR_EVENT_U0_INT_ENA_S + unit);
}
/**
* @brief Disable PCNT interrupt for PCNT unit
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
*/
static inline void pcnt_ll_intr_disable(pcnt_dev_t *hw, pcnt_unit_t unit)
{
hw->int_ena.val &= (~(BIT(PCNT_CNT_THR_EVENT_U0_INT_ENA_S + unit)));
}
/**
* @brief Get PCNT interrupt status
*
* @param hw Peripheral PCNT hardware instance address.
* @param status Pointer to accept value
*/
static inline void pcnt_ll_get_intr_status(pcnt_dev_t *hw, uint32_t *status)
{
*status = hw->int_st.val;
}
/**
* @brief Clear PCNT interrupt status
*
* @param hw Peripheral PCNT hardware instance address.
* @param status value to clear interrupt status
*/
static inline void pcnt_ll_clear_intr_status(pcnt_dev_t *hw, uint32_t status)
{
hw->int_clr.val = status;
}
/**
* @brief Enable PCNT event of PCNT unit
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param evt_type Watch point event type.
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
*/
static inline void pcnt_ll_event_enable(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_evt_type_t evt_type)
{
if (evt_type == PCNT_EVT_L_LIM) {
hw->conf_unit[unit].conf0.thr_l_lim_en = 1;
} else if (evt_type == PCNT_EVT_H_LIM) {
hw->conf_unit[unit].conf0.thr_h_lim_en = 1;
} else if (evt_type == PCNT_EVT_THRES_0) {
hw->conf_unit[unit].conf0.thr_thres0_en = 1;
} else if (evt_type == PCNT_EVT_THRES_1) {
hw->conf_unit[unit].conf0.thr_thres1_en = 1;
} else if (evt_type == PCNT_EVT_ZERO) {
hw->conf_unit[unit].conf0.thr_zero_en = 1;
}
}
/**
* @brief Disable PCNT event of PCNT unit
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param evt_type Watch point event type.
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
*/
static inline void pcnt_ll_event_disable(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_evt_type_t evt_type)
{
if (evt_type == PCNT_EVT_L_LIM) {
hw->conf_unit[unit].conf0.thr_l_lim_en = 0;
} else if (evt_type == PCNT_EVT_H_LIM) {
hw->conf_unit[unit].conf0.thr_h_lim_en = 0;
} else if (evt_type == PCNT_EVT_THRES_0) {
hw->conf_unit[unit].conf0.thr_thres0_en = 0;
} else if (evt_type == PCNT_EVT_THRES_1) {
hw->conf_unit[unit].conf0.thr_thres1_en = 0;
} else if (evt_type == PCNT_EVT_ZERO) {
hw->conf_unit[unit].conf0.thr_zero_en = 0;
}
}
/**
* @brief Set PCNT event value of PCNT unit
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param evt_type Watch point event type.
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
*
* @param value Counter value for PCNT event
*/
static inline void pcnt_ll_set_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t value)
{
if (evt_type == PCNT_EVT_L_LIM) {
hw->conf_unit[unit].conf2.cnt_l_lim = value;
} else if (evt_type == PCNT_EVT_H_LIM) {
hw->conf_unit[unit].conf2.cnt_h_lim = value;
} else if (evt_type == PCNT_EVT_THRES_0) {
hw->conf_unit[unit].conf1.cnt_thres0 = value;
} else if (evt_type == PCNT_EVT_THRES_1) {
hw->conf_unit[unit].conf1.cnt_thres1 = value;
}
}
/**
* @brief Get PCNT event value of PCNT unit
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param evt_type Watch point event type.
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
* @param value Pointer to accept counter value for PCNT event
*/
static inline void pcnt_ll_get_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t *value)
{
if (evt_type == PCNT_EVT_L_LIM) {
*value = (int16_t) hw->conf_unit[unit].conf2.cnt_l_lim;
} else if (evt_type == PCNT_EVT_H_LIM) {
*value = (int16_t) hw->conf_unit[unit].conf2.cnt_h_lim;
} else if (evt_type == PCNT_EVT_THRES_0) {
*value = (int16_t) hw->conf_unit[unit].conf1.cnt_thres0;
} else if (evt_type == PCNT_EVT_THRES_1) {
*value = (int16_t) hw->conf_unit[unit].conf1.cnt_thres1;
} else {
*value = 0;
}
}
/**
* @brief Set PCNT filter value
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param filter_val PCNT signal filter value, counter in APB_CLK cycles.
* Any pulses lasting shorter than this will be ignored when the filter is enabled.
* @note
* filter_val is a 10-bit value, so the maximum filter_val should be limited to 1023.
*/
static inline void pcnt_ll_set_filter_value(pcnt_dev_t *hw, pcnt_unit_t unit, uint16_t filter_val)
{
hw->conf_unit[unit].conf0.filter_thres = filter_val;
}
/**
* @brief Get PCNT filter value
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param filter_val Pointer to accept PCNT filter value.
*/
static inline void pcnt_ll_get_filter_value(pcnt_dev_t *hw, pcnt_unit_t unit, uint16_t *filter_val)
{
*filter_val = hw->conf_unit[unit].conf0.filter_thres;
}
/**
* @brief Enable PCNT input filter
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
*/
static inline void pcnt_ll_filter_enable(pcnt_dev_t *hw, pcnt_unit_t unit)
{
hw->conf_unit[unit].conf0.filter_en = 1;
}
/**
* @brief Disable PCNT input filter
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
*/
static inline void pcnt_ll_filter_disable(pcnt_dev_t *hw, pcnt_unit_t unit)
{
hw->conf_unit[unit].conf0.filter_en = 0;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,373 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "soc/rmt_struct.h"
#include "soc/rmt_caps.h"
#define RMT_LL_HW_BASE (&RMT)
#define RMT_LL_MEM_BASE (&RMTMEM)
static inline void rmt_ll_enable_drive_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
}
static inline void rmt_ll_reset_counter_clock_div(rmt_dev_t *dev, uint32_t channel)
{
dev->ref_cnt_rst.val |= (1 << channel);
dev->ref_cnt_rst.val &= ~(1 << channel);
}
static inline void rmt_ll_reset_tx_pointer(rmt_dev_t *dev, uint32_t channel)
{
}
static inline void rmt_ll_reset_rx_pointer(rmt_dev_t *dev, uint32_t channel)
{
}
static inline void rmt_ll_start_tx(rmt_dev_t *dev, uint32_t channel)
{
}
static inline void rmt_ll_stop_tx(rmt_dev_t *dev, uint32_t channel)
{
}
static inline void rmt_ll_enable_rx(rmt_dev_t *dev, uint32_t channel, bool enable)
{
}
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;
}
static inline bool rmt_ll_is_mem_power_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);
}
static inline void rmt_ll_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num)
{
}
static inline uint32_t rmt_ll_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return 0;
}
static inline void rmt_ll_set_counter_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)
{
}
static inline uint32_t rmt_ll_get_counter_clock_div(rmt_dev_t *dev, uint32_t channel)
{
return 256;
}
static inline void rmt_ll_enable_tx_pingpong(rmt_dev_t *dev, bool enable)
{
}
static inline void rmt_ll_enable_mem_access(rmt_dev_t *dev, bool enable)
{
dev->sys_conf.fifo_mask = enable;
}
static inline void rmt_ll_set_rx_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
{
}
static inline uint32_t rmt_ll_get_rx_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return 0;
}
static inline void rmt_ll_set_mem_owner(rmt_dev_t *dev, uint32_t channel, uint8_t owner)
{
}
static inline uint32_t rmt_ll_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return 0;
}
static inline void rmt_ll_enable_tx_loop(rmt_dev_t *dev, uint32_t channel, bool enable)
{
}
static inline bool rmt_ll_is_tx_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return false;
}
static inline void rmt_ll_set_tx_loop_count(rmt_dev_t *dev, uint32_t channel, uint32_t count)
{
dev->tx_lim_ch[channel].tx_loop_num = count;
}
static inline void rmt_ll_reset_tx_loop(rmt_dev_t *dev, uint32_t channel)
{
dev->tx_lim_ch[channel].loop_count_reset = 1;
dev->tx_lim_ch[channel].loop_count_reset = 0;
}
static inline void rmt_ll_enable_tx_loop_count(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->tx_lim_ch[channel].tx_loop_cnt_en = enable;
}
static inline void rmt_ll_enable_tx_sync(rmt_dev_t *dev, bool enable)
{
dev->tx_sim.en = enable;
}
static inline void rmt_ll_add_channel_to_group(rmt_dev_t *dev, uint32_t channel)
{
dev->tx_sim.val |= 1 << channel;
}
static inline uint32_t rmt_ll_remove_channel_from_group(rmt_dev_t *dev, uint32_t channel)
{
dev->tx_sim.val &= ~(1 << channel);
return dev->tx_sim.val & 0x0F;
}
static inline void rmt_ll_enable_rx_filter(rmt_dev_t *dev, uint32_t channel, bool enable)
{
}
static inline void rmt_ll_set_rx_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
{
}
static inline void rmt_ll_set_counter_clock_src(rmt_dev_t *dev, uint32_t channel, uint8_t src)
{
}
static inline uint32_t rmt_ll_get_counter_clock_src(rmt_dev_t *dev, uint32_t channel)
{
return 0;
}
static inline void rmt_ll_enable_tx_idle(rmt_dev_t *dev, uint32_t channel, bool enable)
{
}
static inline bool rmt_ll_is_tx_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return false;
}
static inline void rmt_ll_set_tx_idle_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
{
}
static inline uint32_t rmt_ll_get_tx_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return 0;
}
static inline uint32_t rmt_ll_get_channel_status(rmt_dev_t *dev, uint32_t channel)
{
return dev->status_ch[channel].val;
}
static inline void rmt_ll_set_tx_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
{
dev->tx_lim_ch[channel].limit = limit;
}
static inline void rmt_ll_set_rx_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
{
}
static inline uint32_t rmt_ll_get_rx_limit(rmt_dev_t *dev, uint32_t channel)
{
return 0;
}
static inline void rmt_ll_enable_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->int_ena.val &= ~(1 << (channel * 3));
dev->int_ena.val |= (enable << (channel * 3));
}
static inline void rmt_ll_enable_rx_end_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->int_ena.val &= ~(1 << (channel * 3 + 1));
dev->int_ena.val |= (enable << (channel * 3 + 1));
}
static inline void rmt_ll_enable_err_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->int_ena.val &= ~(1 << (channel * 3 + 2));
dev->int_ena.val |= (enable << (channel * 3 + 2));
}
static inline void rmt_ll_enable_tx_thres_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->int_ena.val &= ~(1 << (channel + 12));
dev->int_ena.val |= (enable << (channel + 12));
}
static inline void rmt_ll_enable_tx_loop_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->int_ena.val &= ~(1 << (channel + 16));
dev->int_ena.val |= (enable << (channel + 16));
}
static inline void rmt_ll_enable_rx_thres_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->int_ena.val &= ~(1 << (channel + 20));
dev->int_ena.val |= (enable << (channel + 20));
}
static inline void rmt_ll_clear_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel)
{
dev->int_clr.val = (1 << (channel * 3));
}
static inline void rmt_ll_clear_rx_end_interrupt(rmt_dev_t *dev, uint32_t channel)
{
dev->int_clr.val = (1 << (channel * 3 + 1));
}
static inline void rmt_ll_clear_err_interrupt(rmt_dev_t *dev, uint32_t channel)
{
dev->int_clr.val = (1 << (channel * 3 + 2));
}
static inline void rmt_ll_clear_tx_thres_interrupt(rmt_dev_t *dev, uint32_t channel)
{
dev->int_clr.val = (1 << (channel + 12));
}
static inline void rmt_ll_clear_tx_loop_interrupt(rmt_dev_t *dev, uint32_t channel)
{
dev->int_clr.val = (1 << (channel + 16));
}
static inline void rmt_ll_clear_rx_thres_interrupt(rmt_dev_t *dev, uint32_t channel)
{
dev->int_clr.val = (1 << (channel + 20));
}
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x01) >> 0) | ((status & 0x08) >> 2) | ((status & 0x40) >> 4) | ((status & 0x200) >> 6);
}
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x02) >> 1) | ((status & 0x10) >> 3) | ((status & 0x80) >> 5) | ((status & 0x400) >> 7);
}
static inline uint32_t rmt_ll_get_err_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return ((status & 0x04) >> 2) | ((status & 0x20) >> 4) | ((status & 0x100) >> 6) | ((status & 0x800) >> 8);
}
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return (status & 0xF000) >> 12;
}
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return (status & 0xF0000) >> 16;
}
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
uint32_t status = dev->int_st.val;
return (status & 0xF00000) >> 20;
}
static inline void rmt_ll_set_tx_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks)
{
dev->carrier_duty_ch[channel].high = high_ticks;
dev->carrier_duty_ch[channel].low = low_ticks;
}
static inline void rmt_ll_set_rx_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks)
{
}
static inline void rmt_ll_get_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t *high_ticks, uint32_t *low_ticks)
{
*high_ticks = dev->carrier_duty_ch[channel].high;
*low_ticks = dev->carrier_duty_ch[channel].low;
}
static inline void rmt_ll_enable_carrier(rmt_dev_t *dev, uint32_t channel, bool enable)
{
}
static inline void rmt_ll_set_carrier_on_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
{
}
// set true, enable carrier in all RMT state (idle, reading, sending)
// set false, enable carrier only in sending state (i.e. there're effective data in RAM to be sent)
static inline void rmt_ll_tx_set_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
{
}
static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const rmt_item32_t *data, uint32_t length, uint32_t off)
{
length = (off + length) > SOC_RMT_CHANNEL_MEM_WORDS ? (SOC_RMT_CHANNEL_MEM_WORDS - off) : length;
for (uint32_t i = 0; i < length; i++) {
mem->chan[channel].data32[i + off].val = data[i].val;
}
}
static inline void rmt_ll_enable_rx_pingpong(rmt_dev_t *dev, uint32_t channel, bool enable)
{
}
/************************************************************************************************
* Following Low Level APIs only used for backward compatible, will be deprecated in the future!
***********************************************************************************************/
static inline void rmt_ll_set_intr_enable_mask(uint32_t mask)
{
RMT.int_ena.val |= mask;
}
static inline void rmt_ll_clr_intr_enable_mask(uint32_t mask)
{
RMT.int_ena.val &= (~mask);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,357 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The ll is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
#pragma once
#include <stdlib.h>
#include "soc/rtc_io_periph.h"
#include "hal/rtc_io_types.h"
#include "hal/gpio_types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
RTCIO_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */
RTCIO_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
} rtcio_ll_func_t;
typedef enum {
RTCIO_WAKEUP_DISABLE = 0, /*!< Disable GPIO interrupt */
RTCIO_WAKEUP_LOW_LEVEL = 0x4, /*!< GPIO interrupt type : input low level trigger */
RTCIO_WAKEUP_HIGH_LEVEL = 0x5, /*!< GPIO interrupt type : input high level trigger */
} rtcio_ll_wake_type_t;
typedef enum {
RTCIO_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */
RTCIO_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */
} rtcio_ll_out_mode_t;
/**
* @brief Select the rtcio function.
*
* @note The RTC function must be selected before the pad analog function is enabled.
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param func Select pin function.
*/
static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
{
if (func == RTCIO_FUNC_RTC) {
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
//0:RTC FUNCTION 1,2,3:Reserved
SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, SOC_PIN_FUNC_RTC_IO, rtc_io_desc[rtcio_num].func);
} else if (func == RTCIO_FUNC_DIGITAL) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
}
}
/**
* Enable rtcio output.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
RTCIO.enable_w1ts.w1ts = (1U << rtcio_num);
}
/**
* Disable rtcio output.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
RTCIO.enable_w1tc.w1tc = (1U << rtcio_num);
}
/**
* Set RTCIO output level.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param level 0: output low; ~0: output high.
*/
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
RTCIO.out_w1ts.w1ts = (1U << rtcio_num);
} else {
RTCIO.out_w1tc.w1tc = (1U << rtcio_num);
}
}
/**
* Enable rtcio input.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_input_enable(int rtcio_num)
{
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].ie);
}
/**
* Disable rtcio input.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_input_disable(int rtcio_num)
{
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].ie);
}
/**
* Get RTCIO input level.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @return 0: input low; ~0: input high.
*/
static inline uint32_t rtcio_ll_get_level(int rtcio_num)
{
return (uint32_t)(RTCIO.in_val.in >> rtcio_num) & 0x1;
}
/**
* @brief Set RTC GPIO pad drive capability
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param strength Drive capability of the pad. Range: 0 ~ 3.
*/
static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength)
{
if (rtc_io_desc[rtcio_num].drv_v) {
SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, strength, rtc_io_desc[rtcio_num].drv_s);
}
}
/**
* @brief Get RTC GPIO pad drive capability.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @return Drive capability of the pad. Range: 0 ~ 3.
*/
static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num)
{
return GET_PERI_REG_BITS2(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, rtc_io_desc[rtcio_num].drv_s);
}
/**
* @brief Set RTC GPIO pad output mode.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @return mode Output mode.
*/
static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode)
{
RTCIO.pin[rtcio_num].pad_driver = mode;
}
/**
* RTC GPIO pullup enable.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_pullup_enable(int rtcio_num)
{
if (rtc_io_desc[rtcio_num].pullup) {
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup);
}
}
/**
* RTC GPIO pullup disable.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_pullup_disable(int rtcio_num)
{
if (rtc_io_desc[rtcio_num].pullup) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup);
}
}
/**
* RTC GPIO pulldown enable.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_pulldown_enable(int rtcio_num)
{
if (rtc_io_desc[rtcio_num].pulldown) {
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown);
}
}
/**
* RTC GPIO pulldown disable.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_pulldown_disable(int rtcio_num)
{
if (rtc_io_desc[rtcio_num].pulldown) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown);
}
}
/**
* Enable force hold function for RTC IO pad.
*
* Enabling HOLD function will cause the pad to lock current status, such as,
* input/output enable, input/output value, function, drive strength values.
* This function is useful when going into light or deep sleep mode to prevent
* the pin configuration from changing.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_force_hold_enable(int rtcio_num)
{
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, rtc_io_desc[rtcio_num].hold_force);
}
/**
* Disable hold function on an RTC IO pad
*
* @note If disable the pad hold, the status of pad maybe changed in sleep mode.
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_force_hold_disable(int rtcio_num)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, rtc_io_desc[rtcio_num].hold_force);
}
/**
* Enable force hold function for RTC IO pad.
*
* Enabling HOLD function will cause the pad to lock current status, such as,
* input/output enable, input/output value, function, drive strength values.
* This function is useful when going into light or deep sleep mode to prevent
* the pin configuration from changing.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_force_hold_all(void)
{
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
}
/**
* Disable hold function on an RTC IO pad
*
* @note If disable the pad hold, the status of pad maybe changed in sleep mode.
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_force_unhold_all(void)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
}
/**
* Enable wakeup function and set wakeup type from light sleep status for rtcio.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param type Wakeup on high level or low level.
*/
static inline void rtcio_ll_wakeup_enable(int rtcio_num, rtcio_ll_wake_type_t type)
{
RTCIO.pin[rtcio_num].wakeup_enable = 0x1;
RTCIO.pin[rtcio_num].int_type = type;
}
/**
* Disable wakeup function from light sleep status for rtcio.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_wakeup_disable(int rtcio_num)
{
RTCIO.pin[rtcio_num].wakeup_enable = 0;
RTCIO.pin[rtcio_num].int_type = RTCIO_WAKEUP_DISABLE;
}
/**
* Enable rtc io output in deep sleep.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_enable_output_in_sleep(gpio_num_t gpio_num)
{
if (rtc_io_desc[gpio_num].slpoe) {
SET_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpoe);
}
}
/**
* Disable rtc io output in deep sleep.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_in_sleep_disable_output(gpio_num_t gpio_num)
{
if (rtc_io_desc[gpio_num].slpoe) {
CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpoe);
}
}
/**
* Enable rtc io input in deep sleep.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_in_sleep_enable_input(gpio_num_t gpio_num)
{
SET_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpie);
}
/**
* Disable rtc io input in deep sleep.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_in_sleep_disable_input(gpio_num_t gpio_num)
{
CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpie);
}
/**
* Enable rtc io keep another setting in deep sleep.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_enable_sleep_setting(gpio_num_t gpio_num)
{
SET_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpsel);
}
/**
* Disable rtc io keep another setting in deep sleep. (Default)
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num)
{
CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpsel);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,310 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdbool.h>
#include "hal/wdt_types.h"
#include "soc/rtc_cntl_periph.h"
#include "soc/efuse_reg.h"
#include "esp_attr.h"
//Type check wdt_stage_action_t
_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");
_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");
_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");
_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");
_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
_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");
_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");
_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");
_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");
_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");
_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");
_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");
_Static_assert(WDT_RESET_SIG_LENGTH_3_2us == RTC_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
/**
* @brief Enable the RWDT
*
* @param hw Start address of the peripheral registers.
*/
FORCE_INLINE_ATTR void 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;
hw->wdt_config1 = timeout_ticks >> 1;
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)
{
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

View File

@ -0,0 +1,73 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32 SIGMADELTA register operations
#pragma once
#include <stdbool.h>
#include "soc/sigmadelta_periph.h"
#include "hal/sigmadelta_types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Get SIGMADELTA hardware instance with giving sigmadelta num
#define SIGMADELTA_LL_GET_HW(num) (((num) == 0) ? (&SIGMADELTA) : NULL)
/**
* @brief Set Sigma-delta enable
*
* @param hw Peripheral SIGMADELTA hardware instance address.
* @param en Sigma-delta enable value
*/
static inline void sigmadelta_ll_set_en(gpio_sd_dev_t *hw, bool en)
{
// The clk enable register does not exist on ESP32.
}
/**
* @brief Set Sigma-delta channel duty.
*
* @param hw Peripheral SIGMADELTA hardware instance address.
* @param channel Sigma-delta channel number
* @param duty Sigma-delta duty 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.
*/
static inline void sigmadelta_ll_set_duty(gpio_sd_dev_t *hw, sigmadelta_channel_t channel, int8_t duty)
{
hw->channel[channel].duty = duty;
}
/**
* @brief Set Sigma-delta channel's clock pre-scale value.
*
* @param hw Peripheral SIGMADELTA hardware instance address.
* @param channel Sigma-delta channel number
* @param val The divider of source clock, ranges from 0 to 255
*/
static inline void sigmadelta_ll_set_prescale(gpio_sd_dev_t *hw, sigmadelta_channel_t channel, uint8_t prescale)
{
hw->channel[channel].prescale = prescale;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,53 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline void soc_ll_stall_core(int core)
{
const int rtc_cntl_c1_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_M, RTC_CNTL_SW_STALL_APPCPU_C1_M};
const int rtc_cntl_c1_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_S, RTC_CNTL_SW_STALL_APPCPU_C1_S};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_M, RTC_CNTL_SW_STALL_APPCPU_C0_M};
const int rtc_cntl_c0_s[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_S, RTC_CNTL_SW_STALL_APPCPU_C0_S};
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m[core]);
SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21 << rtc_cntl_c1_s[core]);
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m[core]);
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2 << rtc_cntl_c0_s[core]);
}
static inline void soc_ll_unstall_core(int core)
{
const int rtc_cntl_c1_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C1_M, RTC_CNTL_SW_STALL_APPCPU_C1_M};
const int rtc_cntl_c0_m[SOC_CPU_CORES_NUM] = {RTC_CNTL_SW_STALL_PROCPU_C0_M, RTC_CNTL_SW_STALL_APPCPU_C0_M};
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, rtc_cntl_c1_m[core]);
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, rtc_cntl_c0_m[core]);
}
static inline void soc_ll_reset_core(int core)
{
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
core == 0 ? RTC_CNTL_SW_PROCPU_RST_M : RTC_CNTL_SW_APPCPU_RST_M);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,105 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* 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
// For esp32s2, spimem is equivalent to traditional spi peripherals found
// in esp32. Let the spi flash clock reg definitions reflect this.
#define SPI_FLASH_LL_CLKREG_VAL_5MHZ {.spimem=SPIMEM_FLASH_LL_CLKREG_VAL_5MHZ}
#define SPI_FLASH_LL_CLKREG_VAL_10MHZ {.spimem=SPIMEM_FLASH_LL_CLKREG_VAL_10MHZ}
#define SPI_FLASH_LL_CLKREG_VAL_20MHZ {.spimem=SPIMEM_FLASH_LL_CLKREG_VAL_20MHZ}
#define SPI_FLASH_LL_CLKREG_VAL_26MHZ {.spimem=SPIMEM_FLASH_LL_CLKREG_VAL_26MHZ}
#define SPI_FLASH_LL_CLKREG_VAL_40MHZ {.spimem=SPIMEM_FLASH_LL_CLKREG_VAL_40MHZ}
#define SPI_FLASH_LL_CLKREG_VAL_80MHZ {.spimem=SPIMEM_FLASH_LL_CLKREG_VAL_80MHZ}
#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_command8(dev, cmd) gpspi_flash_ll_set_command8((spi_dev_t*)dev, cmd)
#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)
#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_command8(dev, cmd) spimem_flash_ll_set_command8((spi_mem_dev_t*)dev, cmd)
#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_address((spi_mem_dev_t*)dev, addr)
#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)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,791 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32-S3 SPI register operations
#pragma once
#include <stdlib.h> //for abs()
#include <string.h>
#include "hal/hal_defs.h"
#include "esp_types.h"
#include "soc/spi_periph.h"
#include "esp32s3/rom/lldesc.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Registers to reset during initialization. Don't use in app.
#define SPI_LL_RST_MASK (SPI_DMA_AFIFO_RST | SPI_BUF_AFIFO_RST | SPI_RX_AFIFO_RST)
/// Interrupt not used. Don't use in app.
#define SPI_LL_UNUSED_INT_MASK (SPI_TRANS_DONE_INT_ENA | SPI_SLV_WR_DMA_DONE_INT_ENA | SPI_SLV_RD_DMA_DONE_INT_ENA | SPI_SLV_WR_BUF_DONE_INT_ENA | SPI_SLV_RD_BUF_DONE_INT_ENA)
/// Swap the bit order to its correct place to send
#define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)data<<(32-len))
#define SPI_LL_GET_HW(ID) ((ID)==0? ({abort();NULL;}):((ID)==1? &GPSPI2 : &GPSPI3))
/**
* The data structure holding calculated clock configuration. Since the
* calculation needs long time, it should be calculated during initialization and
* stored somewhere to be quickly used.
*/
typedef uint32_t spi_ll_clock_val_t;
/** IO modes supported by the master. */
typedef enum {
SPI_LL_IO_MODE_NORMAL = 0, ///< 1-bit mode for all phases
SPI_LL_IO_MODE_DIO, ///< 2-bit mode for address and data phases, 1-bit mode for command phase
SPI_LL_IO_MODE_DUAL, ///< 2-bit mode for data phases only, 1-bit mode for command and address phases
SPI_LL_IO_MODE_QIO, ///< 4-bit mode for address and data phases, 1-bit mode for command phase
SPI_LL_IO_MODE_QUAD, ///< 4-bit mode for data phases only, 1-bit mode for command and address phases
} spi_ll_io_mode_t;
/// Interrupt type for different working pattern
typedef enum {
SPI_LL_INT_TYPE_NORMAL = 0, ///< Typical pattern, only wait for trans done
SPI_LL_INT_TYPE_SEG = 1, ///< Wait for DMA signals
} spi_ll_slave_intr_type;
/*------------------------------------------------------------------------------
* Control
*----------------------------------------------------------------------------*/
/**
* Initialize SPI peripheral (master).
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_master_init(spi_dev_t *hw)
{
//Reset DMA
hw->dma_conf.val |= SPI_LL_RST_MASK;
hw->dma_conf.val &= ~SPI_LL_RST_MASK;
//use all 64 bytes of the buffer
hw->user.usr_miso_highpart = 0;
hw->user.usr_mosi_highpart = 0;
//Disable unneeded ints
hw->slave.val &= ~SPI_LL_UNUSED_INT_MASK;
}
/**
* Initialize SPI peripheral (slave).
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_slave_init(spi_dev_t *hw)
{
//Configure slave
hw->clock.val = 0;
hw->user.val = 0;
hw->ctrl.val = 0;
hw->user.doutdin = 1; //we only support full duplex
hw->user.sio = 0;
hw->slave.slave_mode = 1;
hw->dma_conf.val &= ~SPI_LL_RST_MASK;
//use all 64 bytes of the buffer
hw->user.usr_miso_highpart = 0;
hw->user.usr_mosi_highpart = 0;
//Disable unneeded ints
hw->slave.val &= ~SPI_LL_UNUSED_INT_MASK;
hw->dma_int_ena.val = 0;
}
/**
* Reset TX and RX DMAs.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_reset_dma(spi_dev_t *hw)
{
}
/**
* Start RX DMA.
*
* @param hw Beginning address of the peripheral registers.
* @param addr Address of the beginning DMA descriptor.
*/
static inline void spi_ll_rxdma_start(spi_dev_t *hw, lldesc_t *addr)
{
}
/**
* Start TX DMA.
*
* @param hw Beginning address of the peripheral registers.
* @param addr Address of the beginning DMA descriptor.
*/
static inline void spi_ll_txdma_start(spi_dev_t *hw, lldesc_t *addr)
{
}
/**
* Write to SPI buffer.
*
* @param hw Beginning address of the peripheral registers.
* @param buffer_to_send Data address to copy to the buffer.
* @param bitlen Length to copy, in bits.
*/
static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_send, size_t bitlen)
{
for (int x = 0; x < bitlen; x += 32) {
//Use memcpy to get around alignment issues for txdata
uint32_t word;
memcpy(&word, &buffer_to_send[x / 8], 4);
hw->data_buf[(x / 32)] = word;
}
}
/**
* Read from SPI buffer.
*
* @param hw Beginning address of the peripheral registers.
* @param buffer_to_rcv Address to copy buffer data to.
* @param bitlen Length to copy, in bits.
*/
static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, size_t bitlen)
{
for (int x = 0; x < bitlen; x += 32) {
//Do a memcpy to get around possible alignment issues in rx_buffer
uint32_t word = hw->data_buf[x / 32];
int len = bitlen - x;
if (len > 32) {
len = 32;
}
memcpy(&buffer_to_rcv[x / 8], &word, (len + 7) / 8);
}
}
/**
* Check whether user-defined transaction is done.
*
* @param hw Beginning address of the peripheral registers.
*
* @return true if transaction is done, otherwise false.
*/
static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
{
return false;
}
/**
* Trigger start of user-defined transaction.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_user_start(spi_dev_t *hw)
{
hw->cmd.usr = 1;
}
/**
* Get current running command bit-mask. (Preview)
*
* @param hw Beginning address of the peripheral registers.
*
* @return Bitmask of running command, see ``SPI_CMD_REG``. 0 if no in-flight command.
*/
static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
{
return hw->cmd.val;
}
/**
* Disable the trans_done interrupt.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_disable_int(spi_dev_t *hw)
{
}
/**
* Clear the trans_done interrupt.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_clear_int_stat(spi_dev_t *hw)
{
hw->dma_int_clr.val = UINT32_MAX;
}
/**
* Set the trans_done interrupt.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_set_int_stat(spi_dev_t *hw)
{
}
/**
* Enable the trans_done interrupt.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_enable_int(spi_dev_t *hw)
{
}
/**
* Set different interrupt types for the slave.
*
* @param hw Beginning address of the peripheral registers.
* @param int_type Interrupt type
*/
static inline void spi_ll_slave_set_int_type(spi_dev_t *hw, spi_ll_slave_intr_type int_type)
{
}
/*------------------------------------------------------------------------------
* Configs: mode
*----------------------------------------------------------------------------*/
/**
* Enable/disable the postive-cs feature.
*
* @param hw Beginning address of the peripheral registers.
* @param cs One of the CS (0-2) to enable/disable the feature.
* @param pos_cs true to enable the feature, otherwise disable (default).
*/
static inline void spi_ll_master_set_pos_cs(spi_dev_t *hw, int cs, uint32_t pos_cs)
{
if (pos_cs) {
hw->misc.master_cs_pol |= (1 << cs);
} else {
hw->misc.master_cs_pol &= (1 << cs);
}
}
/**
* Enable/disable the LSBFIRST feature for TX data.
*
* @param hw Beginning address of the peripheral registers.
* @param lsbfirst true if LSB of TX data to be sent first, otherwise MSB is sent first (default).
*/
static inline void spi_ll_set_tx_lsbfirst(spi_dev_t *hw, bool lsbfirst)
{
hw->ctrl.wr_bit_order = lsbfirst;
}
/**
* Enable/disable the LSBFIRST feature for RX data.
*
* @param hw Beginning address of the peripheral registers.
* @param lsbfirst true if first bit received as LSB, otherwise as MSB (default).
*/
static inline void spi_ll_set_rx_lsbfirst(spi_dev_t *hw, bool lsbfirst)
{
hw->ctrl.rd_bit_order = lsbfirst;
}
/**
* Set SPI mode for the peripheral as master.
*
* @param hw Beginning address of the peripheral registers.
* @param mode SPI mode to work at, 0-3.
*/
static inline void spi_ll_master_set_mode(spi_dev_t *hw, uint8_t mode)
{
//Configure polarity
if (mode == 0) {
hw->misc.ck_idle_edge = 0;
hw->user.ck_out_edge = 0;
} else if (mode == 1) {
hw->misc.ck_idle_edge = 0;
hw->user.ck_out_edge = 1;
} else if (mode == 2) {
hw->misc.ck_idle_edge = 1;
hw->user.ck_out_edge = 1;
} else if (mode == 3) {
hw->misc.ck_idle_edge = 1;
hw->user.ck_out_edge = 0;
}
}
/**
* Set SPI mode for the peripheral as slave.
*
* @param hw Beginning address of the peripheral registers.
* @param mode SPI mode to work at, 0-3.
*/
static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma_used)
{
}
/**
* Set SPI to work in full duplex or half duplex mode.
*
* @param hw Beginning address of the peripheral registers.
* @param half_duplex true to work in half duplex mode, otherwise in full duplex mode.
*/
static inline void spi_ll_set_half_duplex(spi_dev_t *hw, bool half_duplex)
{
hw->user.doutdin = !half_duplex;
}
/**
* Set SPI to work in SIO mode or not.
*
* SIO is a mode which MOSI and MISO share a line. The device MUST work in half-duplexmode.
*
* @param hw Beginning address of the peripheral registers.
* @param sio_mode true to work in SIO mode, otherwise false.
*/
static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode)
{
hw->user.sio = sio_mode;
}
/**
* Configure the io mode for the master to work at.
*
* @param hw Beginning address of the peripheral registers.
* @param io_mode IO mode to work at, see ``spi_ll_io_mode_t``.
*/
static inline void spi_ll_master_set_io_mode(spi_dev_t *hw, spi_ll_io_mode_t io_mode)
{
if (io_mode == SPI_LL_IO_MODE_DIO || io_mode == SPI_LL_IO_MODE_DUAL) {
hw->ctrl.fcmd_dual = (io_mode == SPI_LL_IO_MODE_DIO) ? 1 : 0;
hw->ctrl.faddr_dual = (io_mode == SPI_LL_IO_MODE_DIO) ? 1 : 0;
hw->ctrl.fread_dual = 1;
hw->user.fwrite_dual = 1;
hw->ctrl.fcmd_quad = 0;
hw->ctrl.faddr_quad = 0;
hw->ctrl.fread_quad = 0;
hw->user.fwrite_quad = 0;
} else if (io_mode == SPI_LL_IO_MODE_QIO || io_mode == SPI_LL_IO_MODE_QUAD) {
hw->ctrl.fcmd_quad = (io_mode == SPI_LL_IO_MODE_QIO) ? 1 : 0;
hw->ctrl.faddr_quad = (io_mode == SPI_LL_IO_MODE_QIO) ? 1 : 0;
hw->ctrl.fread_quad = 1;
hw->user.fwrite_quad = 1;
hw->ctrl.fcmd_dual = 0;
hw->ctrl.faddr_dual = 0;
hw->ctrl.fread_dual = 0;
hw->user.fwrite_dual = 0;
} else {
hw->ctrl.fcmd_dual = 0;
hw->ctrl.faddr_dual = 0;
hw->ctrl.fread_dual = 0;
hw->user.fwrite_dual = 0;
hw->ctrl.fcmd_quad = 0;
hw->ctrl.faddr_quad = 0;
hw->ctrl.fread_quad = 0;
hw->user.fwrite_quad = 0;
}
}
/**
* Select one of the CS to use in current transaction.
*
* @param hw Beginning address of the peripheral registers.
* @param cs_id The cs to use, 0-2, otherwise none of them is used.
*/
static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
{
hw->misc.cs0_dis = (cs_id == 0) ? 0 : 1;
hw->misc.cs1_dis = (cs_id == 1) ? 0 : 1;
hw->misc.cs2_dis = (cs_id == 2) ? 0 : 1;
}
/*------------------------------------------------------------------------------
* Configs: parameters
*----------------------------------------------------------------------------*/
/**
* Set the clock for master by stored value.
*
* @param hw Beginning address of the peripheral registers.
* @param val stored clock configuration calculated before (by ``spi_ll_cal_clock``).
*/
static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, spi_ll_clock_val_t *val)
{
hw->clock.val = *(uint32_t *)val;
}
/**
* Get the frequency of given dividers. Don't use in app.
*
* @param fapb APB clock of the system.
* @param pre Pre devider.
* @param n main divider.
*
* @return Frequency of given dividers.
*/
static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
{
return (fapb / (pre * n));
}
/**
* Calculate the nearest frequency avaliable for master.
*
* @param fapb APB clock of the system.
* @param hz Frequncy desired.
* @param duty_cycle Duty cycle desired.
* @param out_reg Output address to store the calculated clock configurations for the return frequency.
*
* @return Actual (nearest) frequency.
*/
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
{
typeof(GPSPI2.clock) reg;
int eff_clk;
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
if (hz > ((fapb / 4) * 3)) {
//Using Fapb directly will give us the best result here.
reg.clkcnt_l = 0;
reg.clkcnt_h = 0;
reg.clkcnt_n = 0;
reg.clkdiv_pre = 0;
reg.clk_equ_sysclk = 1;
eff_clk = fapb;
} else {
//For best duty cycle resolution, we want n to be as close to 32 as possible, but
//we also need a pre/n combo that gets us as close as possible to the intended freq.
//To do this, we bruteforce n and calculate the best pre to go along with that.
//If there's a choice between pre/n combos that give the same result, use the one
//with the higher n.
int pre, n, h, l;
int bestn = -1;
int bestpre = -1;
int besterr = 0;
int errval;
for (n = 2; n <= 64; n++) { //Start at 2: we need to be able to set h/l so we have at least one high and one low pulse.
//Effectively, this does pre=round((fapb/n)/hz).
pre = ((fapb / n) + (hz / 2)) / hz;
if (pre <= 0) {
pre = 1;
}
if (pre > 8192) {
pre = 8192;
}
errval = abs(spi_ll_freq_for_pre_n(fapb, pre, n) - hz);
if (bestn == -1 || errval <= besterr) {
besterr = errval;
bestn = n;
bestpre = pre;
}
}
n = bestn;
pre = bestpre;
l = n;
//This effectively does round((duty_cycle*n)/256)
h = (duty_cycle * n + 127) / 256;
if (h <= 0) {
h = 1;
}
reg.clk_equ_sysclk = 0;
reg.clkcnt_n = n - 1;
reg.clkdiv_pre = pre - 1;
reg.clkcnt_h = h - 1;
reg.clkcnt_l = l - 1;
eff_clk = spi_ll_freq_for_pre_n(fapb, pre, n);
}
if (out_reg != NULL) {
*(uint32_t *)out_reg = reg.val;
}
return eff_clk;
}
/**
* Calculate and set clock for SPI master according to desired parameters.
*
* This takes long, suggest to calculate the configuration during
* initialization by ``spi_ll_master_cal_clock`` and store the result, then
* configure the clock by stored value when used by
* ``spi_ll_msater_set_clock_by_reg``.
*
* @param hw Beginning address of the peripheral registers.
* @param fapb APB clock of the system.
* @param hz Frequncy desired.
* @param duty_cycle Duty cycle desired.
*
* @return Actual frequency that is used.
*/
static inline int spi_ll_master_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle)
{
spi_ll_clock_val_t reg_val;
int freq = spi_ll_master_cal_clock(fapb, hz, duty_cycle, &reg_val);
spi_ll_master_set_clock_by_reg(hw, &reg_val);
return freq;
}
/**
* Set the mosi delay after the output edge to the signal. (Preview)
*
* The delay mode/num is a Espressif conception, may change in the new chips.
*
* @param hw Beginning address of the peripheral registers.
* @param delay_mode Delay mode, see TRM.
* @param delay_num APB clocks to delay.
*/
static inline void spi_ll_set_mosi_delay(spi_dev_t *hw, int delay_mode, int delay_num)
{
}
/**
* Set the miso delay applied to the input signal before the internal peripheral. (Preview)
*
* The delay mode/num is a Espressif conception, may change in the new chips.
*
* @param hw Beginning address of the peripheral registers.
* @param delay_mode Delay mode, see TRM.
* @param delay_num APB clocks to delay.
*/
static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int delay_num)
{
}
/**
* Set dummy clocks to output before RX phase (master), or clocks to skip
* before the data phase and after the address phase (slave).
*
* Note this phase is also used to compensate RX timing in half duplex mode.
*
* @param hw Beginning address of the peripheral registers.
* @param dummy_n Dummy cycles used. 0 to disable the dummy phase.
*/
static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n)
{
hw->user.usr_dummy = dummy_n ? 1 : 0;
hw->user1.usr_dummy_cyclelen = dummy_n - 1;
}
/**
* Set the delay of SPI clocks before the CS inactive edge after the last SPI clock.
*
* @param hw Beginning address of the peripheral registers.
* @param hold Delay of SPI clocks after the last clock, 0 to disable the hold phase.
*/
static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold)
{
hw->user.cs_hold = hold ? 1 : 0;
}
/**
* Set the delay of SPI clocks before the first SPI clock after the CS active edge.
*
* Note ESP32 doesn't support to use this feature when command/address phases
* are used in full duplex mode.
*
* @param hw Beginning address of the peripheral registers.
* @param setup Delay of SPI clocks after the CS active edge, 0 to disable the setup phase.
*/
static inline void spi_ll_master_set_cs_setup(spi_dev_t *hw, uint8_t setup)
{
}
/**
* Enable/disable the segment transfer feature for the slave.
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable.
*/
static inline void spi_ll_slave_set_seg_en(spi_dev_t *hw, bool en)
{
hw->dma_conf.dma_seg_trans_en = en;
}
/*------------------------------------------------------------------------------
* Configs: data
*----------------------------------------------------------------------------*/
/**
* Set the input length (master).
*
* @param hw Beginning address of the peripheral registers.
* @param bitlen input length, in bits.
*/
static inline void spi_ll_set_miso_bitlen(spi_dev_t *hw, size_t bitlen)
{
}
/**
* Set the output length (master).
*
* @param hw Beginning address of the peripheral registers.
* @param bitlen output length, in bits.
*/
static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen)
{
}
/**
* Set the maximum input length (slave).
*
* @param hw Beginning address of the peripheral registers.
* @param bitlen input length, in bits.
*/
static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen)
{
spi_ll_set_miso_bitlen(hw, bitlen);
}
/**
* Set the maximum output length (slave).
*
* @param hw Beginning address of the peripheral registers.
* @param bitlen output length, in bits.
*/
static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen)
{
spi_ll_set_miso_bitlen(hw, bitlen);
}
/**
* Set the length of command phase.
*
* When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit
* command phases takes 4 cycles in 4-bit mode.
*
* @param hw Beginning address of the peripheral registers.
* @param bitlen Length of command phase, in bits. 0 to disable the command phase.
*/
static inline void spi_ll_set_command_bitlen(spi_dev_t *hw, int bitlen)
{
hw->user2.usr_command_bitlen = bitlen - 1;
hw->user.usr_command = bitlen ? 1 : 0;
}
/**
* Set the length of address phase.
*
* When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit
* address phases takes 4 cycles in 4-bit mode.
*
* @param hw Beginning address of the peripheral registers.
* @param bitlen Length of address phase, in bits. 0 to disable the address phase.
*/
static inline void spi_ll_set_addr_bitlen(spi_dev_t *hw, int bitlen)
{
hw->user1.usr_addr_bitlen = bitlen - 1;
hw->user.usr_addr = bitlen ? 1 : 0;
}
/**
* Set the address value in an intuitive way.
*
* The length and lsbfirst is required to shift and swap the address to the right place.
*
* @param hw Beginning address of the peripheral registers.
* @param address Address to set
* @param addrlen Length of the address phase
* @param lsbfirst whether the LSB first feature is enabled.
*/
static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen, uint32_t lsbfirst)
{
if (lsbfirst) {
/* The output address start from the LSB of the highest byte, i.e.
* addr[24] -> addr[31]
* ...
* addr[0] -> addr[7]
* So swap the byte order to let the LSB sent first.
*/
addr = HAL_SWAP32(addr);
//otherwise only addr register is sent
hw->addr = addr;
} else {
// shift the address to MSB of addr register.
// output address will be sent from MSB to LSB of addr register
hw->addr = addr << (32 - addrlen);
}
}
/**
* Set the command value in an intuitive way.
*
* The length and lsbfirst is required to shift and swap the command to the right place.
*
* @param hw Beginning command of the peripheral registers.
* @param command Command to set
* @param addrlen Length of the command phase
* @param lsbfirst whether the LSB first feature is enabled.
*/
static inline void spi_ll_set_command(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst)
{
if (lsbfirst) {
// The output command start from bit0 to bit 15, kept as is.
hw->user2.usr_command_value = cmd;
} else {
/* Output command will be sent from bit 7 to 0 of command_value, and
* then bit 15 to 8 of the same register field. Shift and swap to send
* more straightly.
*/
hw->user2.usr_command_value = HAL_SPI_SWAP_DATA_TX(cmd, cmdlen);
}
}
/**
* Enable/disable the RX data phase.
*
* @param hw Beginning address of the peripheral registers.
* @param enable true if RX phase exist, otherwise false.
*/
static inline void spi_ll_enable_miso(spi_dev_t *hw, int enable)
{
hw->user.usr_miso = enable;
}
/**
* Enable/disable the TX data phase.
*
* @param hw Beginning address of the peripheral registers.
* @param enable true if TX phase exist, otherwise false.
*/
static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable)
{
hw->user.usr_mosi = enable;
}
/**
* Reset the slave peripheral before next transaction.
*
* @param hw Beginning address of the peripheral registers.
*/
static inline void spi_ll_slave_reset(spi_dev_t *hw)
{
}
/**
* Get the received bit length of the slave.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Received bits of the slave.
*/
static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
{
return 0;
}
#undef SPI_LL_RST_MASK
#undef SPI_LL_UNUSED_INT_MASK
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,388 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* 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 "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) spimem_flash_ll_clock_reg_t;
//Supported clock register values
#define SPIMEM_FLASH_LL_CLKREG_VAL_5MHZ ((spimem_flash_ll_clock_reg_t){.val=0x000F070F}) ///< Clock set to 5 MHz
#define SPIMEM_FLASH_LL_CLKREG_VAL_10MHZ ((spimem_flash_ll_clock_reg_t){.val=0x00070307}) ///< Clock set to 10 MHz
#define SPIMEM_FLASH_LL_CLKREG_VAL_20MHZ ((spimem_flash_ll_clock_reg_t){.val=0x00030103}) ///< Clock set to 20 MHz
#define SPIMEM_FLASH_LL_CLKREG_VAL_26MHZ ((spimem_flash_ll_clock_reg_t){.val=0x00020002}) ///< Clock set to 26 MHz
#define SPIMEM_FLASH_LL_CLKREG_VAL_40MHZ ((spimem_flash_ll_clock_reg_t){.val=0x00010001}) ///< Clock set to 40 MHz
#define SPIMEM_FLASH_LL_CLKREG_VAL_80MHZ ((spimem_flash_ll_clock_reg_t){.val=0x80000000}) ///< Clock set to 80 MHz
/*------------------------------------------------------------------------------
* 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;
}
/**
* 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.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 = *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 with fixed length (8 bits).
*
* @param dev Beginning address of the peripheral registers.
* @param command Command to send
*/
static inline void spimem_flash_ll_set_command8(spi_mem_dev_t *dev, uint8_t command)
{
dev->user.usr_command = 1;
typeof(dev->user2) user2 = {
.usr_command_value = command,
.usr_command_bitlen = (8 - 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 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;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,140 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc.h"
#include "soc/sys_timer_reg.h"
// All these functions get invoked either from ISR or HAL that linked to IRAM.
// Always inline these functions even no gcc optimization is applied.
/*******************counter*************************/
__attribute__((always_inline)) static inline void systimer_ll_enable_clock(void)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_CONF_REG, SYS_TIMER_CLK_EN);
}
__attribute__((always_inline)) static inline void systimer_ll_enable_counter(uint32_t counter_id)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_CONF_REG, 1 << (30 - counter_id));
}
__attribute__((always_inline)) static inline void systimer_ll_apply_counter_value(uint32_t counter_id)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_UNIT0_OP_REG + 4 * counter_id, 1 << 31);
}
__attribute__((always_inline)) static inline void systimer_ll_load_counter_value(uint32_t counter_id, uint64_t value)
{
REG_WRITE(SYS_TIMER_SYSTIMER_UNIT0_LOAD_LO_REG + 8 * counter_id, value & 0xFFFFFFFF);
REG_WRITE(SYS_TIMER_SYSTIMER_UNIT0_LOAD_HI_REG, value >> 32);
}
__attribute__((always_inline)) static inline void systimer_ll_counter_snapshot(uint32_t counter_id)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_UNIT0_OP_REG + 4 * counter_id, 1 << 30);
}
__attribute__((always_inline)) static inline bool systimer_ll_is_counter_value_valid(uint32_t counter_id)
{
return REG_GET_BIT(SYS_TIMER_SYSTIMER_UNIT0_OP_REG + 4 * counter_id, 1 << 29);
}
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_low(uint32_t counter_id)
{
return REG_READ(SYS_TIMER_SYSTIMER_UNIT0_VALUE_LO_REG + 8 * counter_id);
}
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_high(uint32_t counter_id)
{
return REG_READ(SYS_TIMER_SYSTIMER_UNIT0_VALUE_HI_REG + 8 * counter_id);
}
/*******************alarm*************************/
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_value(uint32_t alarm_id, uint64_t value)
{
REG_WRITE(SYS_TIMER_SYSTIMER_TARGET0_LO_REG + alarm_id * 8, value & 0xFFFFFFFF);
REG_WRITE(SYS_TIMER_SYSTIMER_TARGET0_HI_REG + alarm_id * 8, value >> 32);
REG_WRITE(SYS_TIMER_SYSTIMER_COMP0_LOAD_REG + alarm_id * 4, SYS_TIMER_TIMER_COMP0_LOAD);
}
__attribute__((always_inline)) static inline uint64_t systimer_ll_get_alarm_value(uint32_t alarm_id)
{
return ((uint64_t) REG_READ(SYS_TIMER_SYSTIMER_TARGET0_HI_REG + alarm_id * 8) << 32) \
| REG_READ(SYS_TIMER_SYSTIMER_TARGET0_LO_REG + alarm_id * 8);
}
__attribute__((always_inline)) static inline void systimer_ll_disable_alarm(uint32_t alarm_id)
{
REG_CLR_BIT(SYS_TIMER_SYSTIMER_CONF_REG, 1 << (24 - alarm_id));
}
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm(uint32_t alarm_id)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_CONF_REG, 1 << (24 - alarm_id));
}
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_oneshot(uint32_t alarm_id)
{
REG_CLR_BIT(SYS_TIMER_SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, SYS_TIMER_TARGET0_PERIOD_MODE_M);
}
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_period(uint32_t alarm_id)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, SYS_TIMER_TARGET0_PERIOD_MODE_M);
}
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(uint32_t alarm_id, uint32_t period)
{
REG_SET_FIELD(SYS_TIMER_SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, SYS_TIMER_TARGET0_PERIOD, period);
}
__attribute__((always_inline)) static inline void systimer_ll_connect_alarm_counter(uint32_t alarm_id, uint32_t counter_id)
{
REG_SET_FIELD(SYS_TIMER_SYSTIMER_TARGET0_CONF_REG + 4 * alarm_id, SYS_TIMER_TARGET0_TIMER_UNIT_SEL, counter_id);
}
/*******************interrupt*************************/
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_int(uint32_t alarm_id)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_INT_ENA_REG, 1 << alarm_id);
}
__attribute__((always_inline)) static inline void systimer_ll_disable_alarm_int(uint32_t alarm_id)
{
REG_CLR_BIT(SYS_TIMER_SYSTIMER_INT_ENA_REG, 1 << alarm_id);
}
__attribute__((always_inline)) static inline bool systimer_ll_is_alarm_int_fired(uint32_t alarm_id)
{
return REG_GET_BIT(SYS_TIMER_SYSTIMER_INT_RAW_REG, 1 << alarm_id);
}
__attribute__((always_inline)) static inline void systimer_ll_clear_alarm_int(uint32_t alarm_id)
{
REG_SET_BIT(SYS_TIMER_SYSTIMER_INT_CLR_REG, 1 << alarm_id);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,440 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include "hal/timer_types.h"
#include "soc/timer_periph.h"
_Static_assert(TIMER_INTR_T0 == TIMG_T0_INT_CLR, "Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t");
_Static_assert(TIMER_INTR_T1 == TIMG_T1_INT_CLR, "Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t");
_Static_assert(TIMER_INTR_WDT == TIMG_WDT_INT_CLR, "Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t");
typedef struct {
timg_dev_t *dev;
timer_idx_t idx;
} timer_ll_context_t;
// Get timer group instance with giving group number
#define TIMER_LL_GET_HW(num) ((num == 0) ? (&TIMERG0) : (&TIMERG1))
/**
* @brief Set timer clock prescale value
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param divider Prescale value
*
* @return None
*/
static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint16_t divider)
{
int timer_en = hw->hw_timer[timer_num].config.enable;
hw->hw_timer[timer_num].config.enable = 0;
hw->hw_timer[timer_num].config.divider = divider;
hw->hw_timer[timer_num].config.enable = timer_en;
}
/**
* @brief Get timer clock prescale value
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param divider Pointer to accept the prescale value
*
* @return None
*/
static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider)
{
uint32_t d = hw->hw_timer[timer_num].config.divider;
if (d == 0) {
d = 65536;
}
*divider = d;
}
/**
* @brief Load counter value into time-base counter
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param load_val Counter value
*
* @return None
*/
static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val)
{
hw->hw_timer[timer_num].load_high.load_hi = (uint32_t) (load_val >> 32);
hw->hw_timer[timer_num].load_low = (uint32_t) load_val;
hw->hw_timer[timer_num].reload = 1;
}
/**
* @brief Get counter value from time-base counter
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param timer_val Pointer to accept the counter value
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val)
{
hw->hw_timer[timer_num].update.update = 1;
*timer_val = ((uint64_t) hw->hw_timer[timer_num].cnt_high.hi << 32) | (hw->hw_timer[timer_num].cnt_low);
}
/**
* @brief Set counter mode, include increment mode and decrement mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param increase_en True to increment mode, fasle to decrement mode
*
* @return None
*/
static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en)
{
hw->hw_timer[timer_num].config.increase = increase_en;
}
/**
* @brief Get counter mode, include increment mode and decrement mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Increment mode
* - false Decrement mode
*/
static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.increase;
}
/**
* @brief Set counter status, enable or disable counter.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param counter_en True to enable counter, false to disable counter
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en)
{
hw->hw_timer[timer_num].config.enable = counter_en;
}
/**
* @brief Get counter status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable counter
* - false Disable conuter
*/
static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.enable;
}
/**
* @brief Set auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
*
* @return None
*/
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en)
{
hw->hw_timer[timer_num].config.autoreload = auto_reload_en;
}
/**
* @brief Get auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.autoreload;
}
/**
* @brief Set the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Counter value to trigger the alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value)
{
hw->hw_timer[timer_num].alarm_high.alarm_hi = (uint32_t) (alarm_value >> 32);
hw->hw_timer[timer_num].alarm_low = (uint32_t) alarm_value;
}
/**
* @brief Get the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Pointer to accept the counter value to trigger the alarm
*
* @return None
*/
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value)
{
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarm_high.alarm_hi << 32) | (hw->hw_timer[timer_num].alarm_low);
}
/**
* @brief Set the alarm status, enable or disable the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_en True to enable alarm, false to disable alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en)
{
hw->hw_timer[timer_num].config.alarm_en = alarm_en;
}
/**
* @brief Get the alarm status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable alarm
* - false Disable alarm
*/
static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.alarm_en;
}
/**
* @brief Enable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
hw->int_ena.val |= BIT(timer_num);
}
/**
* @brief Disable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num)
{
hw->int_ena.val &= (~BIT(timer_num));
}
/**
* @brief Disable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num)
{
hw->int_clr.val |= BIT(timer_num);
}
/**
* @brief Get interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param intr_status Interrupt status
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status)
{
*intr_status = hw->int_st.val;
}
/**
* @brief Get interrupt raw status.
*
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
* @param intr_raw_status Interrupt raw status
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status)
{
timg_dev_t *hw = TIMER_LL_GET_HW(group_num);
*intr_raw_status = hw->int_raw.val;
}
/**
* @brief Set the level interrupt status, enable or disable the level interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param level_int_en True to enable level interrupt, false to disable level interrupt
*
* @return None
*/
static inline void timer_ll_set_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool level_int_en)
{
switch (timer_num) {
case 0:
hw->int_ena.t0 = level_int_en;
break;
case 1:
hw->int_ena.t1 = level_int_en;
break;
default:
break;
}
}
/**
* @brief Get the level interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable level interrupt
* - false Disable level interrupt
*/
static inline bool timer_ll_get_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
bool enable = false;
switch (timer_num) {
case 0:
enable = hw->int_ena.t0;
break;
case 1:
enable = hw->int_ena.t1;
break;
default:
break;
}
return enable;
}
/**
* @brief Set the edge interrupt status, enable or disable the edge interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param edge_int_en True to enable edge interrupt, false to disable edge interrupt
*
* @return None
*/
static inline void timer_ll_set_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool edge_int_en)
{
}
/**
* @brief Get the edge interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return false;
}
/**
* @brief Get interrupt status register address.
*
* @param hw Beginning address of the peripheral registers.
*
* @return uint32_t Interrupt status register address
*/
static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw)
{
return (uint32_t) & (hw->int_st.val);
}
static inline uint32_t timer_ll_get_intr_mask_bit(timg_dev_t *hw, timer_idx_t timer_num)
{
return (1U << timer_num);
}
/**
* @brief Set clock source.
*
* @param hal Context of the HAL layer
* @param use_xtal_en True to use XTAL clock, flase to use APB clock
*
* @return None
*/
static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num, bool use_xtal_en)
{
hw->hw_timer[timer_num].config.use_xtal = use_xtal_en;
}
/**
* @brief Get clock source.
*
* @param hal Context of the HAL layer
*
* @return
* - true Use XTAL clock
* - false Use APB clock
*/
static inline bool timer_ll_get_use_xtal(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.use_xtal;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,613 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The HAL layer for touch sensor (esp32s2 specific part)
#pragma once
#include "hal/touch_sensor_ll.h"
#include "hal/touch_sensor_types.h"
#include_next "hal/touch_sensor_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Reset the whole of touch module.
*
* @note Call this funtion after `touch_pad_fsm_stop`,
*/
#define touch_hal_reset() touch_ll_reset()
/**
* Set touch sensor measurement time.
*
* @param meas_time The duration of the touch sensor measurement.
* t_meas = meas_time / (8MHz), the maximum measure time is 0xffff / 8M = 8.19 ms.
*/
#define touch_hal_set_meas_times(meas_time) touch_ll_set_meas_times(meas_time)
/**
* Get touch sensor times of charge and discharge.
*
* @param meas_times Pointer to accept times count of charge and discharge.
*/
#define touch_hal_get_measure_times(meas_time) touch_ll_get_measure_times(meas_time)
/**
* Set connection type of touch channel in idle status.
* When a channel is in measurement mode, other initialized channels are in idle mode.
* The touch channel is generally adjacent to the trace, so the connection state of the idle channel
* affects the stability and sensitivity of the test channel.
* The `CONN_HIGHZ`(high resistance) setting increases the sensitivity of touch channels.
* The `CONN_GND`(grounding) setting increases the stability of touch channels.
*
* @param type Select idle channel connect to high resistance state or ground.
*/
#define touch_hal_set_idle_channel_connect(type) touch_ll_set_idle_channel_connect(type)
/**
* Set connection type of touch channel in idle status.
* When a channel is in measurement mode, other initialized channels are in idle mode.
* The touch channel is generally adjacent to the trace, so the connection state of the idle channel
* affects the stability and sensitivity of the test channel.
* The `CONN_HIGHZ`(high resistance) setting increases the sensitivity of touch channels.
* The `CONN_GND`(grounding) setting increases the stability of touch channels.
*
* @param type Select idle channel connect to high resistance state or ground.
*/
#define touch_hal_get_idle_channel_connect(type) touch_ll_get_idle_channel_connect(type)
/**
* Get the current measure channel. Touch sensor measurement is cyclic scan mode.
*
* @return
* - touch channel number
*/
#define touch_hal_get_current_meas_channel() touch_ll_get_current_meas_channel()
/**
* Enable touch sensor interrupt by bitmask.
*
* @param type interrupt type
*/
#define touch_hal_intr_enable(int_mask) touch_ll_intr_enable(int_mask)
/**
* Disable touch sensor interrupt by bitmask.
*
* @param type interrupt type
*/
#define touch_hal_intr_disable(int_mask) touch_ll_intr_disable(int_mask)
/**
* Clear touch sensor interrupt by bitmask.
*
* @param int_mask Pad mask to clear interrupts
*/
#define touch_hal_intr_clear(int_mask) touch_ll_intr_clear(int_mask)
/**
* Get the bitmask of touch sensor interrupt status.
*
* @return type interrupt type
*/
#define touch_hal_read_intr_status_mask() touch_ll_read_intr_status_mask()
/**
* Enable the timeout check for all touch sensor channels measurements.
* When the touch reading of a touch channel exceeds the measurement threshold,
* If enable: a timeout interrupt will be generated and it will go to the next channel measurement.
* If disable: the FSM is always on the channel, until the measurement of this channel is over.
*
* @note Set the timeout threshold correctly before enabling it.
*/
#define touch_hal_timeout_enable() touch_ll_timeout_enable()
/**
* Disable the timeout check for all touch sensor channels measurements.
* When the touch reading of a touch channel exceeds the measurement threshold,
* If enable: a timeout interrupt will be generated and it will go to the next channel measurement.
* If disable: the FSM is always on the channel, until the measurement of this channel is over.
*
* @note Set the timeout threshold correctly before enabling it.
*/
#define touch_hal_timeout_disable() touch_ll_timeout_disable()
/**
* Set timeout threshold for all touch sensor channels measurements.
* Compared with touch readings.
*
* @param threshold Set to the maximum time measured on one channel.
*/
#define touch_hal_timeout_set_threshold(threshold) touch_ll_timeout_set_threshold(threshold)
/**
* Get timeout threshold for all touch sensor channels measurements.
* Compared with touch readings.
*
* @param threshold Point to timeout threshold.
*/
#define touch_hal_timeout_get_threshold(threshold) touch_ll_timeout_get_threshold(threshold)
/**
* Touch timer trigger measurement and always wait measurement done.
* Force done for touch timer ensures that the timer always can get the measurement done signal.
*/
#define touch_hal_timer_force_done() touch_ll_timer_force_done()
/************************ Filter register setting ************************/
/**
* Set parameter of touch sensor filter and detection algorithm.
* For more details on the detection algorithm, please refer to the application documentation.
*
* @param filter_info select filter type and threshold of detection algorithm
*/
void touch_hal_filter_set_config(const touch_filter_config_t *filter_info);
/**
* Get parameter of touch sensor filter and detection algorithm.
* For more details on the detection algorithm, please refer to the application documentation.
*
* @param filter_info select filter type and threshold of detection algorithm
*/
void touch_hal_filter_get_config(touch_filter_config_t *filter_info);
/**
* Get smoothed data that obtained by filtering the raw data.
*
* @param touch_num touch pad index
* @param smooth_data pointer to smoothed data
*/
#define touch_hal_filter_read_smooth(touch_num, smooth_data) touch_ll_filter_read_smooth(touch_num, smooth_data)
/**
* Get benchmark value of touch sensor.
*
* @note After initialization, the benchmark value is the maximum during the first measurement period.
* @param touch_num touch pad index
* @param touch_value pointer to accept touch sensor value
*/
#define touch_hal_read_benchmark(touch_num, benchmark) touch_ll_read_benchmark(touch_num, benchmark)
/**
* Force reset benchmark to raw data of touch sensor.
*
* @param touch_num touch pad index
* - TOUCH_PAD_MAX Reset basaline of all channels.
*/
#define touch_hal_reset_benchmark(touch_num) touch_ll_reset_benchmark(touch_num)
/**
* Set filter mode. The input of the filter is the raw value of touch reading,
* and the output of the filter is involved in the judgment of the touch state.
*
* @param mode Filter mode type. Refer to ``touch_filter_mode_t``.
*/
#define touch_hal_filter_set_filter_mode(mode) touch_ll_filter_set_filter_mode(mode)
/**
* Get filter mode. The input of the filter is the raw value of touch reading,
* and the output of the filter is involved in the judgment of the touch state.
*
* @param mode Filter mode type. Refer to ``touch_filter_mode_t``.
*/
#define touch_hal_filter_get_filter_mode(mode) touch_ll_filter_get_filter_mode(mode)
/**
* Set debounce count, such as `n`. If the measured values continue to exceed
* the threshold for `n` times, it is determined that the touch sensor state changes.
*
* @param dbc_cnt Debounce count value.
*/
#define touch_hal_filter_set_debounce(dbc_cnt) touch_ll_filter_set_debounce(dbc_cnt)
/**
* Get debounce count.
*
* @param dbc_cnt Debounce count value.
*/
#define touch_hal_filter_get_debounce(dbc_cnt) touch_ll_filter_get_debounce(dbc_cnt)
/**
* Set noise threshold coefficient. Higher = More noise resistance.
* The actual noise should be less than (noise coefficient * touch threshold).
* Range: 0 ~ 3. The coefficient is 0: 4/8; 1: 3/8; 2: 2/8; 3: 1;
*
* @param hys_thr Noise threshold coefficient.
*/
#define touch_hal_filter_set_noise_thres(noise_thr) touch_ll_filter_set_noise_thres(noise_thr)
/**
* Get noise threshold coefficient. Higher = More noise resistance.
* The actual noise should be less than (noise coefficient * touch threshold).
* Range: 0 ~ 3. The coefficient is 0: 4/8; 1: 3/8; 2: 2/8; 3: 1;
*
* @param noise_thr Noise threshold coefficient.
*/
#define touch_hal_filter_get_noise_thres(noise_thr) touch_ll_filter_get_noise_thres(noise_thr)
/**
* Set the cumulative number of benchmark reset processes. such as `n`. If the measured values continue to exceed
* the negative noise threshold for `n` times, the benchmark reset to raw data.
* Range: 0 ~ 15
*
* @param reset_cnt The cumulative number of benchmark reset processes.
*/
#define touch_hal_filter_set_benchmark_reset(reset_cnt) touch_ll_filter_set_benchmark_reset(reset_cnt)
/**
* Get the cumulative number of benchmark reset processes. such as `n`. If the measured values continue to exceed
* the negative noise threshold for `n` times, the benchmark reset to raw data.
* Range: 0 ~ 15
*
* @param reset_cnt The cumulative number of benchmark reset processes.
*/
#define touch_hal_filter_get_benchmark_reset(reset_cnt) touch_ll_filter_get_benchmark_reset(reset_cnt)
/**
* Set jitter filter step size.
* If filter mode is jitter, should set filter step for jitter.
* Range: 0 ~ 15
*
* @param step The step size of the data change.
*/
#define touch_hal_filter_set_jitter_step(step) touch_ll_filter_set_jitter_step(step)
/**
* Get jitter filter step size.
* If filter mode is jitter, should set filter step for jitter.
* Range: 0 ~ 15
*
* @param step The step size of the data change.
*/
#define touch_hal_filter_get_jitter_step(step) touch_ll_filter_get_jitter_step(step)
/**
* Enable touch sensor filter and detection algorithm.
* For more details on the detection algorithm, please refer to the application documentation.
*/
#define touch_hal_filter_enable() touch_ll_filter_enable()
/**
* Disable touch sensor filter and detection algorithm.
* For more details on the detection algorithm, please refer to the application documentation.
*/
#define touch_hal_filter_disable() touch_ll_filter_disable()
/************************ Denoise register setting ************************/
/**
* set parameter of denoise pad (TOUCH_PAD_NUM0).
* T0 is an internal channel that does not have a corresponding external GPIO.
* T0 will work simultaneously with the measured channel Tn. Finally, the actual
* measured value of Tn is the value after subtracting lower bits of T0.
* This denoise function filters out interference introduced on all channels,
* such as noise introduced by the power supply and external EMI.
*
* @param denoise parameter of denoise
*/
void touch_hal_denoise_set_config(const touch_pad_denoise_t *denoise);
/**
* @brief get parameter of denoise pad (TOUCH_PAD_NUM0).
*
* @param denoise Pointer to parameter of denoise
*/
void touch_hal_denoise_get_config(touch_pad_denoise_t *denoise);
/**
* Enable denoise function.
* T0 is an internal channel that does not have a corresponding external GPIO.
* T0 will work simultaneously with the measured channel Tn. Finally, the actual
* measured value of Tn is the value after subtracting lower bits of T0.
* This denoise function filters out interference introduced on all channels,
* such as noise introduced by the power supply and external EMI.
*/
void touch_hal_denoise_enable(void);
/**
* Enable denoise function.
* T0 is an internal channel that does not have a corresponding external GPIO.
* T0 will work simultaneously with the measured channel Tn. Finally, the actual
* measured value of Tn is the value after subtracting lower bits of T0.
* This denoise function filters out interference introduced on all channels,
* such as noise introduced by the power supply and external EMI.
*/
#define touch_hal_denoise_disable() touch_ll_denoise_disable()
/**
* Set internal reference capacitance of denoise channel.
* Select the appropriate internal reference capacitance value so that
* the reading of denoise channel is closest to the reading of the channel being measured.
*
* @param cap_level Capacitance level.
*/
#define touch_hal_denoise_set_cap_level(cap_level) touch_ll_denoise_set_cap_level(cap_level)
/**
* Get internal reference capacitance of denoise channel.
* Select the appropriate internal reference capacitance value so that
* the reading of denoise channel is closest to the reading of the channel being measured.
*
* @param cap_level Capacitance level.
*/
#define touch_hal_denoise_get_cap_level(cap_level) touch_ll_denoise_get_cap_level(cap_level)
/**
* Set denoise range of denoise channel.
* Determined by measuring the noise amplitude of the denoise channel.
*
* @param grade Denoise range of denoise channel.
*/
#define touch_hal_denoise_set_grade(grade) touch_ll_denoise_set_grade(grade)
/**
* Set denoise range of denoise channel.
* Determined by measuring the noise amplitude of the denoise channel.
*
* @param grade Denoise range of denoise channel.
*/
#define touch_hal_denoise_get_grade(grade) touch_ll_denoise_get_grade(grade)
/**
* Read denoise measure value (TOUCH_PAD_NUM0).
*
* @param denoise value of denoise.
*/
#define touch_hal_denoise_read_data(data) touch_ll_denoise_read_data(data)
/************************ Waterproof register setting ************************/
/**
* Set touch channel use for guard pad.
*
* @param pad_num Touch sensor channel number.
*/
#define touch_hal_waterproof_set_guard_pad(pad_num) touch_ll_waterproof_set_guard_pad(pad_num)
/**
* Get touch channel use for guard pad.
*
* @param pad_num Touch sensor channel number.
*/
#define touch_hal_waterproof_get_guard_pad(pad_num) touch_ll_waterproof_get_guard_pad(pad_num)
/**
* Set max equivalent capacitance for sheild channel.
* The equivalent capacitance of the shielded channel can be calculated
* from the reading of denoise channel.
*
* @param pad_num Touch sensor channel number.
*/
#define touch_hal_waterproof_set_sheild_driver(driver_level) touch_ll_waterproof_set_sheild_driver(driver_level)
/**
* Get max equivalent capacitance for sheild channel.
* The equivalent capacitance of the shielded channel can be calculated
* from the reading of denoise channel.
*
* @param pad_num Touch sensor channel number.
*/
#define touch_hal_waterproof_get_sheild_driver(driver_level) touch_ll_waterproof_get_sheild_driver(driver_level)
/**
* Set parameter of waterproof function.
*
* The waterproof function includes a shielded channel (TOUCH_PAD_NUM14) and a guard channel.
* Guard pad is used to detect the large area of water covering the touch panel.
* Shield pad is used to shield the influence of water droplets covering the touch panel.
* It is generally designed as a grid and is placed around the touch buttons.
*
* @param waterproof parameter of waterproof
*/
void touch_hal_waterproof_set_config(const touch_pad_waterproof_t *waterproof);
/**
* Get parameter of waterproof function.
*
* @param waterproof parameter of waterproof.
*/
void touch_hal_waterproof_get_config(touch_pad_waterproof_t *waterproof);
/**
* Enable parameter of waterproof function.
* Should be called after function ``touch_hal_waterproof_set_config``.
*/
void touch_hal_waterproof_enable(void);
/**
* Disable parameter of waterproof function.
*/
#define touch_hal_waterproof_disable() touch_ll_waterproof_disable()
/************************ Proximity register setting ************************/
/**
* Enable/disable proximity function of touch channels.
* The proximity sensor measurement is the accumulation of touch channel measurements.
*
* @note Supports up to three touch channels configured as proximity sensors.
* @param touch_num touch pad index
* @param enabled true: enable the proximity function; false: disable the proximity function
* @return
* - true: Configured correctly.
* - false: Configured error.
*/
bool touch_hal_enable_proximity(touch_pad_t touch_num, bool enabled);
/**
* Set touch channel number for proximity pad.
* If disable the proximity pad, point this pad to `TOUCH_PAD_NUM0`
*
* @param prox_pad The array of three proximity pads.
*/
#define touch_hal_proximity_set_channel_num(prox_pad) touch_ll_proximity_set_channel_num(prox_pad)
/**
* Get touch channel number for proximity pad.
* If disable the proximity pad, point this pad to `TOUCH_PAD_NUM0`
*
* @param prox_pad The array of three proximity pads.
*/
#define touch_hal_proximity_get_channel_num(prox_pad) touch_ll_proximity_get_channel_num(prox_pad)
/**
* Set cumulative measurement times for proximity pad.
*
* @param times The cumulative number of measurement cycles.
*/
#define touch_hal_proximity_set_meas_times(times) touch_ll_proximity_set_meas_times(times)
/**
* Get cumulative measurement times for proximity pad.
*
* @param times The cumulative number of measurement cycles.
*/
#define touch_hal_proximity_get_meas_times(times) touch_ll_proximity_get_meas_times(times)
/**
* Read current cumulative measurement times for proximity pad.
*
* @param times The cumulative number of measurement cycles.
*/
#define touch_hal_proximity_read_meas_cnt(touch_num, cnt) touch_ll_proximity_read_meas_cnt(touch_num, cnt)
/**
* Check if the touch sensor channel is the proximity pad.
*
* @param touch_num The touch sensor channel number.
*/
#define touch_hal_proximity_pad_check(touch_num) touch_ll_proximity_pad_check(touch_num)
/************** sleep pad setting ***********************/
/**
* Get parameter of touch sensor sleep channel.
* The touch sensor can works in sleep mode to wake up sleep.
* After the sleep channel is configured, users should query the channel reading using a specific function.
*
* @param slp_config Point to touch sleep pad config.
*/
void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config);
/**
* Set parameter of touch sensor sleep channel.
* The touch sensor can works in sleep mode to wake up sleep.
* After the sleep channel is configured, users should query the channel reading using a specific function.
*
* @note ESP32S2 only support one channel to be set sleep channel.
*
* @param pad_num touch sleep pad number.
* @param enable Enable/disable sleep pad function.
*/
void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable);
/**
* Set touch channel number for sleep pad.
*
* @note Only one touch sensor channel is supported in deep sleep mode.
* @param touch_num Touch sensor channel number.
*/
#define touch_hal_sleep_set_channel_num(touch_num) touch_ll_sleep_set_channel_num(touch_num)
/**
* Get touch channel number for sleep pad.
*
* @note Only one touch sensor channel is supported in deep sleep mode.
* @param touch_num Touch sensor channel number.
*/
#define touch_hal_sleep_get_channel_num(touch_num) touch_ll_sleep_get_channel_num(touch_num)
/**
* Set the trigger threshold of touch sensor in deep sleep.
* The threshold determines the sensitivity of the touch sensor.
* The threshold is the original value of the trigger state minus the benchmark value.
*
* @note The threshold at sleep is the same as the threshold before sleep.
*/
#define touch_hal_sleep_set_threshold(touch_thres) touch_ll_sleep_set_threshold(touch_thres)
/**
* Get the trigger threshold of touch sensor in deep sleep.
* The threshold determines the sensitivity of the touch sensor.
* The threshold is the original value of the trigger state minus the benchmark value.
*
* @note The threshold at sleep is the same as the threshold before sleep.
*/
#define touch_hal_sleep_get_threshold(touch_thres) touch_ll_sleep_get_threshold(touch_thres)
/**
* Enable proximity function for sleep pad.
*/
#define touch_hal_sleep_enable_approach() touch_ll_sleep_enable_approach()
/**
* Disable proximity function for sleep pad.
*/
#define touch_hal_sleep_disable_approach() touch_ll_sleep_disable_approach()
/**
* Read benchmark of touch sensor for sleep pad.
*
* @param benchmark Pointer to accept touch sensor benchmark value.
*/
#define touch_hal_sleep_read_benchmark(benchmark) touch_ll_sleep_read_benchmark(benchmark)
/**
* Read smooth data of touch sensor for sleep pad.
*/
#define touch_hal_sleep_read_smooth(smooth_data) touch_ll_sleep_read_smooth(smooth_data)
/**
* Read raw data of touch sensor for sleep pad.
*/
#define touch_hal_sleep_read_data(raw_data) touch_ll_sleep_read_data(raw_data)
/**
* Reset benchmark of touch sensor for sleep pad.
*/
#define touch_hal_sleep_reset_benchmark() touch_ll_sleep_reset_benchmark()
/**
* Read debounce of touch sensor for sleep pad.
*
* @param debounce Pointer to accept touch sensor debounce value.
*/
#define touch_hal_sleep_read_debounce(debounce) touch_ll_sleep_read_debounce(debounce)
/**
* Read proximity count of touch sensor for sleep pad.
* @param proximity_cnt Pointer to accept touch sensor proximity count value.
*/
#define touch_hal_sleep_read_proximity_cnt(approach_cnt) touch_ll_sleep_read_proximity_cnt(approach_cnt)
/**
* Get the touch pad which caused wakeup from deep sleep.
*
* @param pad_num pointer to touch pad which caused wakeup.
*/
#define touch_hal_get_wakeup_status(pad_num) touch_ll_get_wakeup_status(pad_num)
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,703 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* 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 TWAI
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "hal/twai_types.h"
#include "soc/twai_periph.h"
/* ------------------------- Defines and Typedefs --------------------------- */
#define TWAI_LL_STATUS_RBS (0x1 << 0)
#define TWAI_LL_STATUS_DOS (0x1 << 1)
#define TWAI_LL_STATUS_TBS (0x1 << 2)
#define TWAI_LL_STATUS_TCS (0x1 << 3)
#define TWAI_LL_STATUS_RS (0x1 << 4)
#define TWAI_LL_STATUS_TS (0x1 << 5)
#define TWAI_LL_STATUS_ES (0x1 << 6)
#define TWAI_LL_STATUS_BS (0x1 << 7)
#define TWAI_LL_INTR_RI (0x1 << 0)
#define TWAI_LL_INTR_TI (0x1 << 1)
#define TWAI_LL_INTR_EI (0x1 << 2)
//Data overrun interrupt not supported in SW due to HW peculiarities
#define TWAI_LL_INTR_EPI (0x1 << 5)
#define TWAI_LL_INTR_ALI (0x1 << 6)
#define TWAI_LL_INTR_BEI (0x1 << 7)
/*
* The following frame structure has an NEARLY identical bit field layout to
* each byte of the TX buffer. This allows for formatting and parsing frames to
* be done outside of time critical regions (i.e., ISRs). All the ISR needs to
* do is to copy byte by byte to/from the TX/RX buffer. The two reserved bits in
* TX buffer are used in the frame structure to store the self_reception and
* single_shot flags which in turn indicate the type of transmission to execute.
*/
typedef union {
struct {
struct {
uint8_t dlc: 4; //Data length code (0 to 8) of the frame
uint8_t self_reception: 1; //This frame should be transmitted using self reception command
uint8_t single_shot: 1; //This frame should be transmitted using single shot command
uint8_t rtr: 1; //This frame is a remote transmission request
uint8_t frame_format: 1; //Format of the frame (1 = extended, 0 = standard)
};
union {
struct {
uint8_t id[2]; //11 bit standard frame identifier
uint8_t data[8]; //Data bytes (0 to 8)
uint8_t reserved8[2];
} standard;
struct {
uint8_t id[4]; //29 bit extended frame identifier
uint8_t data[8]; //Data bytes (0 to 8)
} extended;
};
};
uint8_t bytes[13];
} __attribute__((packed)) twai_ll_frame_buffer_t;
_Static_assert(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type should be 13 bytes");
/* ---------------------------- Mode Register ------------------------------- */
/**
* @brief Enter reset mode
*
* When in reset mode, the TWAI controller is effectively disconnected from the
* TWAI bus and will not participate in any bus activates. Reset mode is required
* in order to write the majority of configuration registers.
*
* @param hw Start address of the TWAI registers
* @return true if reset mode was entered successfully
*
* @note Reset mode is automatically entered on BUS OFF condition
*/
static inline bool twai_ll_enter_reset_mode(twai_dev_t *hw)
{
hw->mode_reg.rm = 1;
return hw->mode_reg.rm;
}
/**
* @brief Exit reset mode
*
* When not in reset mode, the TWAI controller will take part in bus activities
* (e.g., send/receive/acknowledge messages and error frames) depending on the
* operating mode.
*
* @param hw Start address of the TWAI registers
* @return true if reset mode was exit successfully
*
* @note Reset mode must be exit to initiate BUS OFF recovery
*/
static inline bool twai_ll_exit_reset_mode(twai_dev_t *hw)
{
hw->mode_reg.rm = 0;
return !(hw->mode_reg.rm);
}
/**
* @brief Check if in reset mode
* @param hw Start address of the TWAI registers
* @return true if in reset mode
*/
static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw)
{
return hw->mode_reg.rm;
}
/**
* @brief Set operating mode of TWAI controller
*
* @param hw Start address of the TWAI registers
* @param mode Operating mode
*
* @note Must be called in reset mode
*/
static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode)
{
if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode
hw->mode_reg.lom = 0;
hw->mode_reg.stm = 0;
} else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack)
hw->mode_reg.lom = 0;
hw->mode_reg.stm = 1;
} else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode
hw->mode_reg.lom = 1;
hw->mode_reg.stm = 0;
}
}
/* --------------------------- Command Register ----------------------------- */
/**
* @brief Set TX command
*
* Setting the TX command will cause the TWAI controller to attempt to transmit
* the frame stored in the TX buffer. The TX buffer will be occupied (i.e.,
* locked) until TX completes.
*
* @param hw Start address of the TWAI registers
*
* @note Transmit commands should be called last (i.e., after handling buffer
* release and clear data overrun) in order to prevent the other commands
* overwriting this latched TX bit with 0.
*/
static inline void twai_ll_set_cmd_tx(twai_dev_t *hw)
{
hw->command_reg.tr = 1;
}
/**
* @brief Set single shot TX command
*
* Similar to setting TX command, but the TWAI controller will not automatically
* retry transmission upon an error (e.g., due to an acknowledgement error).
*
* @param hw Start address of the TWAI registers
*
* @note Transmit commands should be called last (i.e., after handling buffer
* release and clear data overrun) in order to prevent the other commands
* overwriting this latched TX bit with 0.
*/
static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw)
{
hw->command_reg.val = 0x03; //Writing to TR and AT simultaneously
}
/**
* @brief Aborts TX
*
* Frames awaiting TX will be aborted. Frames already being TX are not aborted.
* Transmission Complete Status bit is automatically set to 1.
* Similar to setting TX command, but the TWAI controller will not automatically
* retry transmission upon an error (e.g., due to acknowledge error).
*
* @param hw Start address of the TWAI registers
*
* @note Transmit commands should be called last (i.e., after handling buffer
* release and clear data overrun) in order to prevent the other commands
* overwriting this latched TX bit with 0.
*/
static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw)
{
hw->command_reg.at = 1;
}
/**
* @brief Release RX buffer
*
* Rotates RX buffer to the next frame in the RX FIFO.
*
* @param hw Start address of the TWAI registers
*/
static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw)
{
hw->command_reg.rrb = 1;
}
/**
* @brief Clear data overrun
*
* Clears the data overrun status bit
*
* @param hw Start address of the TWAI registers
*/
static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw)
{
hw->command_reg.cdo = 1;
}
/**
* @brief Set self reception single shot command
*
* Similar to setting TX command, but the TWAI controller also simultaneously
* receive the transmitted frame and is generally used for self testing
* purposes. The TWAI controller will not ACK the received message, so consider
* using the NO_ACK operating mode.
*
* @param hw Start address of the TWAI registers
*
* @note Transmit commands should be called last (i.e., after handling buffer
* release and clear data overrun) in order to prevent the other commands
* overwriting this latched TX bit with 0.
*/
static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw)
{
hw->command_reg.srr = 1;
}
/**
* @brief Set self reception request command
*
* Similar to setting the self reception request, but the TWAI controller will
* not automatically retry transmission upon an error (e.g., due to and
* acknowledgement error).
*
* @param hw Start address of the TWAI registers
*
* @note Transmit commands should be called last (i.e., after handling buffer
* release and clear data overrun) in order to prevent the other commands
* overwriting this latched TX bit with 0.
*/
static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw)
{
hw->command_reg.val = 0x12;
}
/* --------------------------- Status Register ------------------------------ */
/**
* @brief Get all status bits
*
* @param hw Start address of the TWAI registers
* @return Status bits
*/
static inline uint32_t twai_ll_get_status(twai_dev_t *hw)
{
return hw->status_reg.val;
}
/**
* @brief Check if RX FIFO overrun status bit is set
*
* @param hw Start address of the TWAI registers
* @return Overrun status bit
*/
static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw)
{
return hw->status_reg.dos;
}
/**
* @brief Check if previously TX was successful
*
* @param hw Start address of the TWAI registers
* @return Whether previous TX was successful
*/
static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw)
{
return hw->status_reg.tcs;
}
//Todo: Add stand alone status bit check functions when necessary
/* -------------------------- Interrupt Register ---------------------------- */
/**
* @brief Get currently set interrupts
*
* Reading the interrupt registers will automatically clear all interrupts
* except for the Receive Interrupt.
*
* @param hw Start address of the TWAI registers
* @return Bit mask of set interrupts
*/
static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw)
{
return hw->interrupt_reg.val;
}
/* ----------------------- Interrupt Enable Register ------------------------ */
/**
* @brief Set which interrupts are enabled
*
* @param hw Start address of the TWAI registers
* @param Bit mask of interrupts to enable
*
* @note Must be called in reset mode
*/
static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask)
{
#ifdef TWAI_BRP_DIV_SUPPORTED
//ESP32 Rev 2 has brp div. Need to mask when setting
hw->interrupt_enable_reg.val = (hw->interrupt_enable_reg.val & 0x10) | intr_mask;
#else
hw->interrupt_enable_reg.val = intr_mask;
#endif
}
/* ------------------------ Bus Timing Registers --------------------------- */
/**
* @brief Set bus timing
*
* @param hw Start address of the TWAI registers
* @param brp Baud Rate Prescaler
* @param sjw Synchronization Jump Width
* @param tseg1 Timing Segment 1
* @param tseg2 Timing Segment 2
* @param triple_sampling Triple Sampling enable/disable
*
* @note Must be called in reset mode
* @note ESP32 rev 2 or later can support a x2 brp by setting a brp_div bit,
* allowing the brp to go from a maximum of 128 to 256.
*/
static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2, bool triple_sampling)
{
#ifdef TWAI_BRP_DIV_SUPPORTED
if (brp > TWAI_BRP_DIV_THRESH) {
//Need to set brp_div bit
hw->interrupt_enable_reg.brp_div = 1;
brp /= 2;
}
#endif
hw->bus_timing_0_reg.brp = (brp / 2) - 1;
hw->bus_timing_0_reg.sjw = sjw - 1;
hw->bus_timing_1_reg.tseg1 = tseg1 - 1;
hw->bus_timing_1_reg.tseg2 = tseg2 - 1;
hw->bus_timing_1_reg.sam = triple_sampling;
}
/* ----------------------------- ALC Register ------------------------------- */
/**
* @brief Clear Arbitration Lost Capture Register
*
* Reading the ALC register rearms the Arbitration Lost Interrupt
*
* @param hw Start address of the TWAI registers
*/
static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw)
{
(void)hw->arbitration_lost_captue_reg.val;
//Todo: Decode ALC register
}
/* ----------------------------- ECC Register ------------------------------- */
/**
* @brief Clear Error Code Capture register
*
* Reading the ECC register rearms the Bus Error Interrupt
*
* @param hw Start address of the TWAI registers
*/
static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw)
{
(void)hw->error_code_capture_reg.val;
//Todo: Decode error code capture
}
/* ----------------------------- EWL Register ------------------------------- */
/**
* @brief Set Error Warning Limit
*
* @param hw Start address of the TWAI registers
* @param ewl Error Warning Limit
*
* @note Must be called in reset mode
*/
static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl)
{
hw->error_warning_limit_reg.ewl = ewl;
}
/**
* @brief Get Error Warning Limit
*
* @param hw Start address of the TWAI registers
* @return Error Warning Limit
*/
static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw)
{
return hw->error_warning_limit_reg.val;
}
/* ------------------------ RX Error Count Register ------------------------- */
/**
* @brief Get RX Error Counter
*
* @param hw Start address of the TWAI registers
* @return REC value
*
* @note REC is not frozen in reset mode. Listen only mode will freeze it. A BUS
* OFF condition automatically sets the REC to 0.
*/
static inline uint32_t twai_ll_get_rec(twai_dev_t *hw)
{
return hw->rx_error_counter_reg.val;
}
/**
* @brief Set RX Error Counter
*
* @param hw Start address of the TWAI registers
* @param rec REC value
*
* @note Must be called in reset mode
*/
static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec)
{
hw->rx_error_counter_reg.rxerr = rec;
}
/* ------------------------ TX Error Count Register ------------------------- */
/**
* @brief Get TX Error Counter
*
* @param hw Start address of the TWAI registers
* @return TEC value
*
* @note A BUS OFF condition will automatically set this to 128
*/
static inline uint32_t twai_ll_get_tec(twai_dev_t *hw)
{
return hw->tx_error_counter_reg.val;
}
/**
* @brief Set TX Error Counter
*
* @param hw Start address of the TWAI registers
* @param tec TEC value
*
* @note Must be called in reset mode
*/
static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec)
{
hw->tx_error_counter_reg.txerr = tec;
}
/* ---------------------- Acceptance Filter Registers ----------------------- */
/**
* @brief Set Acceptance Filter
* @param hw Start address of the TWAI registers
* @param code Acceptance Code
* @param mask Acceptance Mask
* @param single_filter Whether to enable single filter mode
*
* @note Must be called in reset mode
*/
static inline void twai_ll_set_acc_filter(twai_dev_t* hw, uint32_t code, uint32_t mask, bool single_filter)
{
uint32_t code_swapped = __builtin_bswap32(code);
uint32_t mask_swapped = __builtin_bswap32(mask);
for (int i = 0; i < 4; i++) {
hw->acceptance_filter.acr[i].byte = ((code_swapped >> (i * 8)) & 0xFF);
hw->acceptance_filter.amr[i].byte = ((mask_swapped >> (i * 8)) & 0xFF);
}
hw->mode_reg.afm = single_filter;
}
/* ------------------------- TX/RX Buffer Registers ------------------------- */
/**
* @brief Copy a formatted TWAI frame into TX buffer for transmission
*
* @param hw Start address of the TWAI registers
* @param tx_frame Pointer to formatted frame
*
* @note Call twai_ll_format_frame_buffer() to format a frame
*/
static inline void twai_ll_set_tx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *tx_frame)
{
//Copy formatted frame into TX buffer
for (int i = 0; i < 13; i++) {
hw->tx_rx_buffer[i].val = tx_frame->bytes[i];
}
}
/**
* @brief Copy a received frame from the RX buffer for parsing
*
* @param hw Start address of the TWAI registers
* @param rx_frame Pointer to store formatted frame
*
* @note Call twai_ll_prase_frame_buffer() to parse the formatted frame
*/
static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *rx_frame)
{
//Copy RX buffer registers into frame
for (int i = 0; i < 13; i++) {
rx_frame->bytes[i] = hw->tx_rx_buffer[i].byte;
}
}
/**
* @brief Format contents of a TWAI frame into layout of TX Buffer
*
* This function encodes a message into a frame structure. The frame structure
* has an identical layout to the TX buffer, allowing the frame structure to be
* directly copied into TX buffer.
*
* @param[in] 11bit or 29bit ID
* @param[in] dlc Data length code
* @param[in] data Pointer to an 8 byte array containing data. NULL if no data
* @param[in] format Type of TWAI frame
* @param[in] single_shot Frame will not be retransmitted on failure
* @param[in] self_rx Frame will also be simultaneously received
* @param[out] tx_frame Pointer to store formatted frame
*/
static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const uint8_t *data,
uint32_t flags, twai_ll_frame_buffer_t *tx_frame)
{
bool is_extd = flags & TWAI_MSG_FLAG_EXTD;
bool is_rtr = flags & TWAI_MSG_FLAG_RTR;
//Set frame information
tx_frame->dlc = dlc;
tx_frame->frame_format = is_extd;
tx_frame->rtr = is_rtr;
tx_frame->self_reception = (flags & TWAI_MSG_FLAG_SELF) ? 1 : 0;
tx_frame->single_shot = (flags & TWAI_MSG_FLAG_SS) ? 1 : 0;
//Set ID. The ID registers are big endian and left aligned, therefore a bswap will be required
if (is_extd) {
uint32_t id_temp = __builtin_bswap32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i))
for (int i = 0; i < 4; i++) {
tx_frame->extended.id[i] = (id_temp >> (8 * i)) & 0xFF;
}
} else {
uint32_t id_temp = __builtin_bswap16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i))
for (int i = 0; i < 2; i++) {
tx_frame->standard.id[i] = (id_temp >> (8 * i)) & 0xFF;
}
}
uint8_t *data_buffer = (is_extd) ? tx_frame->extended.data : tx_frame->standard.data;
if (!is_rtr) { //Only copy data if the frame is a data frame (i.e not RTR)
for (int i = 0; (i < dlc) && (i < TWAI_FRAME_MAX_DLC); i++) {
data_buffer[i] = data[i];
}
}
}
/**
* @brief Parse formatted TWAI frame (RX Buffer Layout) into its constituent contents
*
* @param[in] rx_frame Pointer to formatted frame
* @param[out] id 11 or 29bit ID
* @param[out] dlc Data length code
* @param[out] data Data. Left over bytes set to 0.
* @param[out] format Type of TWAI frame
*/
static inline void twai_ll_prase_frame_buffer(twai_ll_frame_buffer_t *rx_frame, uint32_t *id, uint8_t *dlc,
uint8_t *data, uint32_t *flags)
{
//Copy frame information
*dlc = rx_frame->dlc;
uint32_t flags_temp = 0;
flags_temp |= (rx_frame->frame_format) ? TWAI_MSG_FLAG_EXTD : 0;
flags_temp |= (rx_frame->rtr) ? TWAI_MSG_FLAG_RTR : 0;
flags_temp |= (rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_MSG_FLAG_DLC_NON_COMP : 0;
*flags = flags_temp;
//Copy ID. The ID registers are big endian and left aligned, therefore a bswap will be required
if (rx_frame->frame_format) {
uint32_t id_temp = 0;
for (int i = 0; i < 4; i++) {
id_temp |= rx_frame->extended.id[i] << (8 * i);
}
id_temp = __builtin_bswap32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3)
*id = id_temp & TWAI_EXTD_ID_MASK;
} else {
uint32_t id_temp = 0;
for (int i = 0; i < 2; i++) {
id_temp |= rx_frame->standard.id[i] << (8 * i);
}
id_temp = __builtin_bswap16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5)
*id = id_temp & TWAI_STD_ID_MASK;
}
uint8_t *data_buffer = (rx_frame->frame_format) ? rx_frame->extended.data : rx_frame->standard.data;
//Only copy data if the frame is a data frame (i.e. not a remote frame)
int data_length = (rx_frame->rtr) ? 0 : ((rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_FRAME_MAX_DLC : rx_frame->dlc);
for (int i = 0; i < data_length; i++) {
data[i] = data_buffer[i];
}
//Set remaining bytes of data to 0
for (int i = data_length; i < TWAI_FRAME_MAX_DLC; i++) {
data[i] = 0;
}
}
/* ----------------------- RX Message Count Register ------------------------ */
/**
* @brief Get RX Message Counter
*
* @param hw Start address of the TWAI registers
* @return RX Message Counter
*/
static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw)
{
return hw->rx_message_counter_reg.val;
}
/* ------------------------- Clock Divider Register ------------------------- */
/**
* @brief Set CLKOUT Divider and enable/disable
*
* Configure CLKOUT. CLKOUT is a pre-scaled version of APB CLK. Divider can be
* 1, or any even number from 2 to 14. Set the divider to 0 to disable CLKOUT.
*
* @param hw Start address of the TWAI registers
* @param divider Divider for CLKOUT. Set to 0 to disable CLKOUT
*/
static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider)
{
if (divider >= 2 && divider <= 14) {
hw->clock_divider_reg.co = 0;
hw->clock_divider_reg.cd = (divider / 2) - 1;
} else if (divider == 1) {
//Setting the divider reg to max value (7) means a divider of 1
hw->clock_divider_reg.co = 0;
hw->clock_divider_reg.cd = 7;
} else {
hw->clock_divider_reg.co = 1;
hw->clock_divider_reg.cd = 0;
}
}
/**
* @brief Set register address mapping to extended mode
*
* Extended mode register address mapping consists of more registers and extra
* features.
*
* @param hw Start address of the TWAI registers
*
* @note Must be called before setting any configuration
* @note Must be called in reset mode
*/
static inline void twai_ll_enable_extended_reg_layout(twai_dev_t *hw)
{
hw->clock_divider_reg.cd = 1;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,803 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for UART register operations.
// Note that most of the register operations in this layer are non-atomic operations.
#pragma once
#include "hal/uart_types.h"
#include "soc/uart_periph.h"
#ifdef __cplusplus
extern "C" {
#endif
// The default fifo depth
#define UART_LL_FIFO_DEF_LEN (UART_FIFO_LEN)
// Get UART hardware instance with giving uart num
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1))
// Define UART interrupts
typedef enum {
UART_INTR_RXFIFO_FULL = (0x1 << 0),
UART_INTR_TXFIFO_EMPTY = (0x1 << 1),
UART_INTR_PARITY_ERR = (0x1 << 2),
UART_INTR_FRAM_ERR = (0x1 << 3),
UART_INTR_RXFIFO_OVF = (0x1 << 4),
UART_INTR_DSR_CHG = (0x1 << 5),
UART_INTR_CTS_CHG = (0x1 << 6),
UART_INTR_BRK_DET = (0x1 << 7),
UART_INTR_RXFIFO_TOUT = (0x1 << 8),
UART_INTR_SW_XON = (0x1 << 9),
UART_INTR_SW_XOFF = (0x1 << 10),
UART_INTR_GLITCH_DET = (0x1 << 11),
UART_INTR_TX_BRK_DONE = (0x1 << 12),
UART_INTR_TX_BRK_IDLE = (0x1 << 13),
UART_INTR_TX_DONE = (0x1 << 14),
UART_INTR_RS485_PARITY_ERR = (0x1 << 15),
UART_INTR_RS485_FRM_ERR = (0x1 << 16),
UART_INTR_RS485_CLASH = (0x1 << 17),
UART_INTR_CMD_CHAR_DET = (0x1 << 18),
} uart_intr_t;
/**
* @brief Configure the baud-rate.
*
* @param hw Beginning address of the peripheral registers.
* @param baud The baud rate to be set. When the source clock is APB, the max baud rate is `UART_LL_BITRATE_MAX`
* @param source_clk The UART source clock. The source clock can be APB clock or REF_TICK.
* If the source clock is REF_TICK, the UART can still work when the APB changes.
*
* @return None
*/
static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud)
{
uint32_t sclk_freq = (source_clk == UART_SCLK_APB) ? APB_CLK_FREQ : REF_CLK_FREQ;
uint32_t clk_div = ((sclk_freq) << 4) / baud;
// The baud rate configuration register is divided into
// an integer part and a fractional part.
hw->clk_div.div_int = clk_div >> 4;
hw->clk_div.div_frag = clk_div & 0xf;
}
/**
* @brief Get the current baud-rate.
*
* @param hw Beginning address of the peripheral registers.
*
* @return The current baudrate
*/
static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw)
{
uint32_t src_clk = APB_CLK_FREQ;
typeof(hw->clk_div) div_reg = hw->clk_div;
return ((src_clk << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag);
}
/**
* @brief Enable the UART interrupt based on the given mask.
*
* @param hw Beginning address of the peripheral registers.
* @param mask The bitmap of the interrupts need to be enabled.
*
* @return None
*/
static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask)
{
hw->int_ena.val |= mask;
}
/**
* @brief Disable the UART interrupt based on the given mask.
*
* @param hw Beginning address of the peripheral registers.
* @param mask The bitmap of the interrupts need to be disabled.
*
* @return None
*/
static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask)
{
hw->int_ena.val &= (~mask);
}
/**
* @brief Get the UART interrupt status.
*
* @param hw Beginning address of the peripheral registers.
*
* @return The UART interrupt status.
*/
static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw)
{
return hw->int_st.val;
}
/**
* @brief Clear the UART interrupt status based on the given mask.
*
* @param hw Beginning address of the peripheral registers.
* @param mask The bitmap of the interrupts need to be cleared.
*
* @return None
*/
static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
{
hw->int_clr.val = mask;
}
/**
* @brief Get status of enabled interrupt.
*
* @param hw Beginning address of the peripheral registers.
*
* @return interrupt enable value
*/
static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
{
return hw->int_ena.val;
}
/**
* @brief Read the UART rxfifo.
*
* @param hw Beginning address of the peripheral registers.
* @param buf The data buffer. The buffer size should be large than 128 byts.
* @param rd_len The data length needs to be read.
*
* @return None.
*/
static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len)
{
//Get the UART fifo addr, ESP32-S2 have 2 UART
uint32_t fifo_addr = (hw == &UART0) ? UART_FIFO_AHB_REG(0) : UART_FIFO_AHB_REG(1);
for (int i = 0; i < rd_len; i++) {
buf[i] = READ_PERI_REG(fifo_addr);
}
}
/**
* @brief Write byte to the UART txfifo.
*
* @param hw Beginning address of the peripheral registers.
* @param buf The data buffer.
* @param wr_len The data length needs to be writen.
*
* @return None
*/
static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len)
{
//Get the UART fifo addr, ESP32-S2 have 2 UART
uint32_t fifo_addr = (hw == &UART0) ? UART_FIFO_AHB_REG(0) : UART_FIFO_AHB_REG(1);
for (int i = 0; i < wr_len; i++) {
WRITE_PERI_REG(fifo_addr, buf[i]);
}
}
/**
* @brief Reset the UART hw rxfifo.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None
*/
static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
{
hw->conf0.rxfifo_rst = 1;
hw->conf0.rxfifo_rst = 0;
}
/**
* @brief Reset the UART hw txfifo.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None
*/
static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
{
hw->conf0.txfifo_rst = 1;
hw->conf0.txfifo_rst = 0;
}
/**
* @brief Get the length of readable data in UART rxfifo.
*
* @param hw Beginning address of the peripheral registers.
*
* @return The readable data length in rxfifo.
*/
static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
{
return hw->status.rxfifo_cnt;
}
/**
* @brief Get the writable data length of UART txfifo.
*
* @param hw Beginning address of the peripheral registers.
*
* @return The data length of txfifo can be written.
*/
static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
{
return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt;
}
/**
* @brief Configure the UART stop bit.
*
* @param hw Beginning address of the peripheral registers.
* @param stop_bit The stop bit number to be set.
*
* @return None.
*/
static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit)
{
hw->conf0.stop_bit_num = stop_bit;
}
/**
* @brief Get the configuration of the UART stop bit.
*
* @param hw Beginning address of the peripheral registers.
* @param stop_bit The pointer to accept the stop bit configuration
*
* @return None.
*/
static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit)
{
*stop_bit = hw->conf0.stop_bit_num;
}
/**
* @brief Configure the UART parity check mode.
*
* @param hw Beginning address of the peripheral registers.
* @param parity_mode The parity check mode to be set.
*
* @return None.
*/
static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode)
{
if (parity_mode != UART_PARITY_DISABLE) {
hw->conf0.parity = parity_mode & 0x1;
}
hw->conf0.parity_en = (parity_mode >> 1) & 0x1;
}
/**
* @brief Get the UART parity check mode configuration.
*
* @param hw Beginning address of the peripheral registers.
* @param parity_mode The pointer to accept the parity check mode configuration.
*
* @return None.
*/
static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode)
{
if (hw->conf0.parity_en) {
*parity_mode = 0X2 | hw->conf0.parity;
} else {
*parity_mode = UART_PARITY_DISABLE;
}
}
/**
* @brief Set the UART rxfifo full threshold value. When the data in rxfifo is more than the threshold value,
* it will produce rxfifo_full_int_raw interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param full_thrhd The full threshold value of the rxfifo. `full_thrhd` should be less than `UART_LL_FIFO_DEF_LEN`.
*
* @return None.
*/
static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd)
{
hw->conf1.rxfifo_full_thrhd = full_thrhd;
}
/**
* @brief Set the txfifo empty threshold. when the data length in txfifo is less than threshold value,
* it will produce txfifo_empty_int_raw interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param empty_thrhd The empty threshold of txfifo.
*
* @return None.
*/
static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd)
{
hw->conf1.txfifo_empty_thrhd = empty_thrhd;
}
/**
* @brief Set the UART rx-idle threshold value. when receiver takes more time than rx_idle_thrhd to receive a byte data,
* it will produce frame end signal for uhci to stop receiving data.
*
* @param hw Beginning address of the peripheral registers.
* @param rx_idle_thr The rx-idle threshold to be set.
*
* @return None.
*/
static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr)
{
hw->idle_conf.rx_idle_thrhd = rx_idle_thr;
}
/**
* @brief Configure the duration time between transfers.
*
* @param hw Beginning address of the peripheral registers.
* @param idle_num the duration time between transfers.
*
* @return None.
*/
static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num)
{
hw->idle_conf.tx_idle_num = idle_num;
}
/**
* @brief Configure the transmiter to send break chars.
*
* @param hw Beginning address of the peripheral registers.
* @param break_num The number of the break chars need to be send.
*
* @return None.
*/
static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
{
if (break_num > 0) {
hw->txbrk_conf.tx_brk_num = break_num;
hw->conf0.txd_brk = 1;
} else {
hw->conf0.txd_brk = 0;
}
}
/**
* @brief Configure the UART hardware flow control.
*
* @param hw Beginning address of the peripheral registers.
* @param flow_ctrl The hw flow control configuration.
* @param rx_thrs The rx flow control signal will be active if the data length in rxfifo is more than this value.
*
* @return None.
*/
static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs)
{
//only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set.
if (flow_ctrl & UART_HW_FLOWCTRL_RTS) {
hw->mem_conf.rx_flow_thrhd = rx_thrs;
hw->conf1.rx_flow_en = 1;
} else {
hw->conf1.rx_flow_en = 0;
}
if (flow_ctrl & UART_HW_FLOWCTRL_CTS) {
hw->conf0.tx_flow_en = 1;
} else {
hw->conf0.tx_flow_en = 0;
}
}
/**
* @brief Configure the hardware flow control.
*
* @param hw Beginning address of the peripheral registers.
* @param flow_ctrl A pointer to accept the hw flow control configuration.
*
* @return None.
*/
static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl)
{
*flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
if (hw->conf1.rx_flow_en) {
*flow_ctrl |= UART_HW_FLOWCTRL_RTS;
}
if (hw->conf0.tx_flow_en) {
*flow_ctrl |= UART_HW_FLOWCTRL_CTS;
}
}
/**
* @brief Configure the software flow control.
*
* @param hw Beginning address of the peripheral registers.
* @param flow_ctrl The UART sofware flow control settings.
* @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false.
*
* @return None.
*/
static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en)
{
if (sw_flow_ctrl_en) {
hw->flow_conf.xonoff_del = 1;
hw->flow_conf.sw_flow_con_en = 1;
hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd;
hw->swfc_conf0.xoff_threshold = flow_ctrl->xoff_thrd;
hw->swfc_conf1.xon_char = flow_ctrl->xon_char;
hw->swfc_conf0.xoff_char = flow_ctrl->xoff_char;
} else {
hw->flow_conf.sw_flow_con_en = 0;
hw->flow_conf.xonoff_del = 0;
}
}
/**
* @brief Configure the AT cmd char. When the receiver receives a continuous AT cmd char, it will produce at_cmd_char_det interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param cmd_char The AT cmd char configuration.The configuration member is:
* - cmd_char The AT cmd character
* - char_num The number of received AT cmd char must be equal to or greater than this value
* - gap_tout The interval between each AT cmd char, when the duration is less than this value, it will not take this data as AT cmd char
* - pre_idle The idle time before the first AT cmd char, when the duration is less than this value, it will not take the previous data as the last AT cmd char
* - post_idle The idle time after the last AT cmd char, when the duration is less than this value, it will not take this data as the first AT cmd char
*
* @return None.
*/
static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char)
{
hw->at_cmd_char.data = cmd_char->cmd_char;
hw->at_cmd_char.char_num = cmd_char->char_num;
hw->at_cmd_postcnt.post_idle_num = cmd_char->post_idle;
hw->at_cmd_precnt.pre_idle_num = cmd_char->pre_idle;
hw->at_cmd_gaptout.rx_gap_tout = cmd_char->gap_tout;
}
/**
* @brief Set the UART data bit mode.
*
* @param hw Beginning address of the peripheral registers.
* @param data_bit The data bit mode to be set.
*
* @return None.
*/
static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit)
{
hw->conf0.bit_num = data_bit;
}
/**
* @brief Get the UART source clock.
*
* @param hw Beginning address of the peripheral registers.
* @param source_clk The pointer to accept the UART source clock configuration.
*
* @return None.
*/
static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk)
{
*source_clk = UART_SCLK_APB;
}
/**
* @brief Set the rts active level.
*
* @param hw Beginning address of the peripheral registers.
* @param level The rts active level, 0 or 1.
*
* @return None.
*/
static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
{
hw->conf0.sw_rts = level & 0x1;
}
/**
* @brief Set the dtr active level.
*
* @param hw Beginning address of the peripheral registers.
* @param level The dtr active level, 0 or 1.
*
* @return None.
*/
static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
{
hw->conf0.sw_dtr = level & 0x1;
}
/**
* @brief Set the UART wakeup threshold.
*
* @param hw Beginning address of the peripheral registers.
* @param wakeup_thrd The wakeup threshold value to be set. When the input rx edge changes more than this value,
* the UART will active from light sleeping mode.
*
* @return None.
*/
static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
hw->sleep_conf.active_threshold = wakeup_thrd - SOC_UART_MIN_WAKEUP_THRESH;
}
/**
* @brief Configure the UART work in normal mode.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
{
hw->rs485_conf.en = 0;
hw->rs485_conf.tx_rx_en = 0;
hw->rs485_conf.rx_busy_tx_en = 0;
hw->conf0.irda_en = 0;
}
/**
* @brief Configure the UART work in rs485_app_ctrl mode.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
{
// Application software control, remove echo
hw->rs485_conf.rx_busy_tx_en = 1;
hw->conf0.irda_en = 0;
hw->conf0.sw_rts = 0;
hw->conf0.irda_en = 0;
hw->rs485_conf.en = 1;
}
/**
* @brief Configure the UART work in rs485_half_duplex mode.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
{
// Enable receiver, sw_rts = 1 generates low level on RTS pin
hw->conf0.sw_rts = 1;
// Must be set to 0 to automatically remove echo
hw->rs485_conf.tx_rx_en = 0;
// This is to void collision
hw->rs485_conf.rx_busy_tx_en = 1;
hw->conf0.irda_en = 0;
hw->rs485_conf.en = 1;
}
/**
* @brief Configure the UART work in collision_detect mode.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
{
hw->conf0.irda_en = 0;
// Transmitters output signal loop back to the receivers input signal
hw->rs485_conf.tx_rx_en = 1 ;
// Transmitter should send data when the receiver is busy
hw->rs485_conf.rx_busy_tx_en = 1;
hw->conf0.sw_rts = 0;
hw->rs485_conf.en = 1;
}
/**
* @brief Configure the UART work in irda mode.
*
* @param hw Beginning address of the peripheral registers.
*
* @return None.
*/
static inline void uart_ll_set_mode_irda(uart_dev_t *hw)
{
hw->rs485_conf.en = 0;
hw->rs485_conf.tx_rx_en = 0;
hw->rs485_conf.rx_busy_tx_en = 0;
hw->conf0.sw_rts = 0;
hw->conf0.irda_en = 1;
}
/**
* @brief Set uart mode.
*
* @param hw Beginning address of the peripheral registers.
* @param mode The UART mode to be set.
*
* @return None.
*/
static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
{
switch (mode) {
default:
case UART_MODE_UART:
uart_ll_set_mode_normal(hw);
break;
case UART_MODE_RS485_COLLISION_DETECT:
uart_ll_set_mode_collision_detect(hw);
break;
case UART_MODE_RS485_APP_CTRL:
uart_ll_set_mode_rs485_app_ctrl(hw);
break;
case UART_MODE_RS485_HALF_DUPLEX:
uart_ll_set_mode_rs485_half_duplex(hw);
break;
case UART_MODE_IRDA:
uart_ll_set_mode_irda(hw);
break;
}
}
/**
* @brief Get the UART AT cmd char configuration.
*
* @param hw Beginning address of the peripheral registers.
* @param cmd_char The Pointer to accept value of UART AT cmd char.
* @param char_num Pointer to accept the repeat number of UART AT cmd char.
*
* @return None.
*/
static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num)
{
*cmd_char = hw->at_cmd_char.data;
*char_num = hw->at_cmd_char.char_num;
}
/**
* @brief Get the UART wakeup threshold value.
*
* @param hw Beginning address of the peripheral registers.
*
* @return The UART wakeup threshold value.
*/
static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
{
return hw->sleep_conf.active_threshold + SOC_UART_MIN_WAKEUP_THRESH;
}
/**
* @brief Get the UART data bit configuration.
*
* @param hw Beginning address of the peripheral registers.
* @param data_bit The pointer to accept the UART data bit configuration.
*
* @return The bit mode.
*/
static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit)
{
*data_bit = hw->conf0.bit_num;
}
/**
* @brief Check if the UART sending state machine is in the IDLE state.
*
* @param hw Beginning address of the peripheral registers.
*
* @return True if the state machine is in the IDLE state, otherwise false is returned.
*/
static inline bool uart_ll_is_tx_idle(uart_dev_t *hw)
{
return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0));
}
/**
* @brief Check if the UART rts flow control is enabled.
*
* @param hw Beginning address of the peripheral registers.
*
* @return True if hw rts flow control is enabled, otherwise false is returned.
*/
static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw)
{
return hw->conf1.rx_flow_en;
}
/**
* @brief Check if the UART cts flow control is enabled.
*
* @param hw Beginning address of the peripheral registers.
*
* @return True if hw cts flow control is enabled, otherwise false is returned.
*/
static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw)
{
return hw->conf0.tx_flow_en;
}
/**
* @brief Configure TX signal loop back to RX module, just for the testing purposes
*
* @param hw Beginning address of the peripheral registers.
* @param loop_back_en Set ture to enable the loop back function, else set it false.
*
* @return None
*/
static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
{
hw->conf0.loopback = loop_back_en;
}
/**
* @brief Inverse the UART signal with the given mask.
*
* @param hw Beginning address of the peripheral registers.
* @param inv_mask The UART signal bitmap needs to be inversed.
* Use the ORred mask of `uart_signal_inv_t`;
*
* @return None.
*/
static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
{
typeof(hw->conf0) conf0_reg = hw->conf0;
conf0_reg.irda_tx_inv |= (inv_mask & UART_SIGNAL_IRDA_TX_INV) ? 1 : 0;
conf0_reg.irda_rx_inv |= (inv_mask & UART_SIGNAL_IRDA_RX_INV) ? 1 : 0;
conf0_reg.rxd_inv |= (inv_mask & UART_SIGNAL_RXD_INV) ? 1 : 0;
conf0_reg.cts_inv |= (inv_mask & UART_SIGNAL_CTS_INV) ? 1 : 0;
conf0_reg.dsr_inv |= (inv_mask & UART_SIGNAL_DSR_INV) ? 1 : 0;
conf0_reg.txd_inv |= (inv_mask & UART_SIGNAL_TXD_INV) ? 1 : 0;
conf0_reg.rts_inv |= (inv_mask & UART_SIGNAL_RTS_INV) ? 1 : 0;
conf0_reg.dtr_inv |= (inv_mask & UART_SIGNAL_DTR_INV) ? 1 : 0;
hw->conf0.val = conf0_reg.val;
}
/**
* @brief Configure the timeout value for receiver receiving a byte, and enable rx timeout function.
*
* @param hw Beginning address of the peripheral registers.
* @param tout_thrd The timeout value as UART bit time. The rx timeout function will be disabled if `tout_thrd == 0`.
*
* @return None.
*/
static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd)
{
uint16_t tout_val = tout_thrd;
if(tout_thrd > 0) {
hw->mem_conf.rx_tout_thrhd = tout_val;
hw->conf1.rx_tout_en = 1;
} else {
hw->conf1.rx_tout_en = 0;
}
}
/**
* @brief Get the timeout value for receiver receiving a byte.
*
* @param hw Beginning address of the peripheral registers.
*
* @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0.
*/
static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
{
uint16_t tout_thrd = 0;
if(hw->conf1.rx_tout_en > 0) {
tout_thrd = hw->mem_conf.rx_tout_thrhd;
}
return tout_thrd;
}
/**
* @brief Get UART maximum timeout threshold.
*
* @param hw Beginning address of the peripheral registers.
*
* @return maximum timeout threshold.
*/
static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
{
return UART_RX_TOUT_THRHD_V;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,560 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "esp32s3/rom/ets_sys.h"
#include "esp32s3/rom/rtc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "soc/dport_reg.h"
#include "soc/efuse_reg.h"
#include "soc/syscon_reg.h"
#include "soc/system_reg.h"
#include "i2c_rtc_clk.h"
#include "soc_log.h"
#include "rtc_clk_common.h"
#include "sdkconfig.h"
#include "xtensa/core-macros.h"
static const char *TAG = "rtc_clk";
#define RTC_PLL_FREQ_320M 320
#define RTC_PLL_FREQ_480M 480
// Current PLL frequency, in MHZ (320 or 480). Zero if PLL is not enabled.
static int s_cur_pll_freq = RTC_PLL_FREQ_480M;
static void rtc_clk_cpu_freq_to_8m(void);
void rtc_clk_32k_enable_internal(x32k_config_t cfg)
{
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);
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
}
void rtc_clk_32k_enable(bool enable)
{
if (enable) {
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
rtc_clk_32k_enable_internal(cfg);
} else {
SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
}
}
void rtc_clk_32k_enable_external(void)
{
SET_PERI_REG_MASK(RTC_IO_XTAL_32P_PAD_REG, RTC_IO_X32P_MUX_SEL);
SET_PERI_REG_MASK(RTC_IO_XTAL_32N_PAD_REG, RTC_IO_X32N_MUX_SEL);
/* TODO: external 32k source may need different settings */
x32k_config_t cfg = X32K_CONFIG_DEFAULT();
rtc_clk_32k_enable_internal(cfg);
}
void rtc_clk_32k_bootstrap(uint32_t cycle)
{
/* No special bootstrapping needed for ESP32-S3, '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)
{
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;
bool disabled = xtal_xpd_sw && !xtal_xpd_st;
return !disabled;
}
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
{
if (clk_8m_en) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
/* no need to wait once enabled by software */
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CK8M_ENABLE_WAIT_DEFAULT);
esp_rom_delay_us(DELAY_8M_ENABLE);
} else {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M);
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_DEFAULT);
}
/* d256 should be independent configured with 8M
* Maybe we can split this function into 8m and dmd256
*/
if (d256_en) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
} else {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV);
}
}
bool rtc_clk_8m_enabled(void)
{
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M) == 0;
}
bool rtc_clk_8md256_enabled(void)
{
return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
}
void rtc_clk_set_xtal_wait(void)
{
/*
the `xtal_wait` time need 1ms, so we need calibrate slow clk period,
and `RTC_CNTL_XTL_BUF_WAIT` depend on it.
*/
rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
if (slow_clk_freq == (rtc_slow_freq_x32k)) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_freq == rtc_slow_freq_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 2000);
uint32_t xtal_wait_1ms = 100;
if (slow_clk_period) {
xtal_wait_1ms = (1000 << RTC_CLK_CAL_FRACT) / slow_clk_period;
}
REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, xtal_wait_1ms);
}
void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
{
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
/* Why we need to connect this clock to digital?
* Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead?
*/
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
(slow_freq == RTC_SLOW_FREQ_32K_XTAL) ? 1 : 0);
/* The clk_8m_d256 will be closed when rtc_state in SLEEP,
so if the slow_clk is 8md256, clk_8m must be force power on
*/
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU, (slow_freq == RTC_SLOW_FREQ_8MD256) ? 1 : 0);
rtc_clk_set_xtal_wait();
esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
}
rtc_slow_freq_t rtc_clk_slow_freq_get(void)
{
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
}
uint32_t rtc_clk_slow_freq_get_hz(void)
{
switch (rtc_clk_slow_freq_get()) {
case RTC_SLOW_FREQ_RTC: return RTC_SLOW_CLK_FREQ_90K;
case RTC_SLOW_FREQ_32K_XTAL: return RTC_SLOW_CLK_FREQ_32K;
case RTC_SLOW_FREQ_8MD256: return RTC_SLOW_CLK_FREQ_8MD256;
}
return 0;
}
void rtc_clk_fast_freq_set(rtc_fast_freq_t fast_freq)
{
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
}
rtc_fast_freq_t rtc_clk_fast_freq_get(void)
{
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_FAST_CLK_RTC_SEL);
}
static void rtc_clk_bbpll_disable(void)
{
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
s_cur_pll_freq = 0;
}
static void rtc_clk_bbpll_enable(void)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
}
void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
{
uint8_t div_ref;
uint8_t div7_0;
uint8_t dr1;
uint8_t dr3;
uint8_t dchgp;
uint8_t dcur;
uint8_t dbias;
if (pll_freq == RTC_PLL_FREQ_480M) {
/* Set this register to let the digital part know 480M PLL is used */
SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
/* Configure 480M PLL */
switch (xtal_freq) {
case RTC_XTAL_FREQ_40M:
div_ref = 0;
div7_0 = 8;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
case RTC_XTAL_FREQ_32M:
div_ref = 1;
div7_0 = 26;
dr1 = 1;
dr3 = 1;
dchgp = 4;
dcur = 0;
dbias = 2;
break;
default:
div_ref = 0;
div7_0 = 8;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
}
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
} else {
/* Clear this register to let the digital part know 320M PLL is used */
CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
/* Configure 320M PLL */
switch (xtal_freq) {
case RTC_XTAL_FREQ_40M:
div_ref = 0;
div7_0 = 4;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
case RTC_XTAL_FREQ_32M:
div_ref = 1;
div7_0 = 6;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
default:
div_ref = 0;
div7_0 = 4;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
}
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
}
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
// Enable calibration by software
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_IR_CAL_ENX_CAP, 1);
for (int ext_cap = 0; ext_cap < 16; ext_cap++) {
uint8_t cal_result;
I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, ext_cap);
cal_result = I2C_READREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OR_CAL_CAP);
if (cal_result == 0) {
break;
}
if (ext_cap == 15) {
SOC_LOGE(TAG, "BBPLL SOFTWARE CAL FAIL");
}
}
s_cur_pll_freq = pll_freq;
}
/**
* 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 dbias = DIG_DBIAS_80M_160M;
int per_conf = DPORT_CPUPERIOD_SEL_80;
if (cpu_freq_mhz == 80) {
/* nothing to do */
} else if (cpu_freq_mhz == 160) {
per_conf = DPORT_CPUPERIOD_SEL_160;
} else if (cpu_freq_mhz == 240) {
dbias = DIG_DBIAS_240M;
per_conf = DPORT_CPUPERIOD_SEL_240;
} else {
SOC_LOGE(TAG, "invalid frequency");
}
REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
ets_update_cpu_frequency(cpu_freq_mhz);
}
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
{
uint32_t source_freq_mhz;
rtc_cpu_freq_src_t source;
uint32_t divider;
uint32_t real_freq_mhz;
uint32_t xtal_freq = (uint32_t) rtc_clk_xtal_freq_get();
if (freq_mhz <= xtal_freq) {
divider = xtal_freq / freq_mhz;
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
if (real_freq_mhz != freq_mhz) {
// no suitable divider
return false;
}
source_freq_mhz = xtal_freq;
source = RTC_CPU_FREQ_SRC_XTAL;
} else if (freq_mhz == 80) {
real_freq_mhz = freq_mhz;
source = RTC_CPU_FREQ_SRC_PLL;
source_freq_mhz = RTC_PLL_FREQ_480M;
divider = 6;
} else if (freq_mhz == 160) {
real_freq_mhz = freq_mhz;
source = RTC_CPU_FREQ_SRC_PLL;
source_freq_mhz = RTC_PLL_FREQ_480M;
divider = 3;
} else if (freq_mhz == 240) {
real_freq_mhz = freq_mhz;
source = RTC_CPU_FREQ_SRC_PLL;
source_freq_mhz = RTC_PLL_FREQ_480M;
divider = 2;
} else {
// unsupported frequency
return false;
}
*out_config = (rtc_cpu_freq_config_t) {
.source = source,
.div = divider,
.source_freq_mhz = source_freq_mhz,
.freq_mhz = real_freq_mhz
};
return true;
}
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
{
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
if (soc_clk_sel != DPORT_SOC_CLK_SEL_XTAL) {
rtc_clk_cpu_freq_to_xtal(xtal_freq, 1);
}
if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
rtc_clk_bbpll_disable();
}
if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
if (config->div > 1) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
}
} else if (config->source == RTC_CPU_FREQ_SRC_PLL) {
rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
} else if (config->source == RTC_CPU_FREQ_SRC_8M) {
rtc_clk_cpu_freq_to_8m();
}
}
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
{
rtc_cpu_freq_src_t source;
uint32_t source_freq_mhz;
uint32_t div;
uint32_t freq_mhz;
uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
switch (soc_clk_sel) {
case DPORT_SOC_CLK_SEL_XTAL: {
source = RTC_CPU_FREQ_SRC_XTAL;
div = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
source_freq_mhz = (uint32_t) rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
}
break;
case DPORT_SOC_CLK_SEL_PLL: {
source = RTC_CPU_FREQ_SRC_PLL;
uint32_t cpuperiod_sel = DPORT_REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL);
uint32_t pllfreq_sel = DPORT_REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
source_freq_mhz = (pllfreq_sel) ? RTC_PLL_FREQ_480M : RTC_PLL_FREQ_320M;
if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) {
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 6 : 4;
freq_mhz = 80;
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160) {
div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 3 : 2;
div = 3;
freq_mhz = 160;
} else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_240) {
div = 2;
freq_mhz = 240;
} else {
SOC_LOGE(TAG, "unsupported frequency configuration");
return;
}
break;
}
case DPORT_SOC_CLK_SEL_8M:
source = RTC_CPU_FREQ_SRC_8M;
source_freq_mhz = 8;
div = 1;
freq_mhz = source_freq_mhz;
break;
default:
SOC_LOGE(TAG, "unsupported frequency configuration");
return;
}
*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 == RTC_CPU_FREQ_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
} else if (config->source == RTC_CPU_FREQ_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)
{
int freq_mhz = (int) rtc_clk_xtal_freq_get();
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
rtc_clk_bbpll_disable();
}
/**
* Switch to XTAL frequency. Does not disable the PLL.
*/
void rtc_clk_cpu_freq_to_xtal(int freq, int div)
{
ets_update_cpu_frequency(freq);
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
/* no need to adjust the REF_TICK */
/* switch clock source */
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
rtc_clk_apb_freq_update(freq * MHZ);
/* lower the voltage */
if (freq <= 2) {
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_2M);
} else {
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
}
}
static void rtc_clk_cpu_freq_to_8m(void)
{
ets_update_cpu_frequency(8);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
rtc_clk_apb_freq_update(RTC_FAST_CLK_FREQ_8M);
}
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
{
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if (!clk_val_is_valid(xtal_freq_reg)) {
SOC_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value: 0x%08x", xtal_freq_reg);
return RTC_XTAL_FREQ_40M;
}
return reg_val_to_clk_val(xtal_freq_reg);
}
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
{
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, clk_val_to_reg_val(xtal_freq));
}
void rtc_clk_apb_freq_update(uint32_t apb_freq)
{
WRITE_PERI_REG(RTC_APB_FREQ_REG, clk_val_to_reg_val(apb_freq >> 12));
}
uint32_t rtc_clk_apb_freq_get(void)
{
uint32_t freq_hz = reg_val_to_clk_val(READ_PERI_REG(RTC_APB_FREQ_REG)) << 12;
// round to the nearest MHz
freq_hz += MHZ / 2;
uint32_t remainder = freq_hz % MHZ;
return freq_hz - remainder;
}
void rtc_clk_divider_set(uint32_t div)
{
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, div);
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
}
void rtc_clk_8m_divider_set(uint32_t div)
{
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, div);
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL_VLD);
}
/* 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")));

View File

@ -0,0 +1,58 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#define MHZ (1000000)
#define DPORT_CPUPERIOD_SEL_80 0
#define DPORT_CPUPERIOD_SEL_160 1
#define DPORT_CPUPERIOD_SEL_240 2
#define DPORT_SOC_CLK_SEL_XTAL 0
#define DPORT_SOC_CLK_SEL_PLL 1
#define DPORT_SOC_CLK_SEL_8M 2
#define RTC_FAST_CLK_FREQ_8M 8500000
#ifdef __cplusplus
extern "C" {
#endif
void rtc_clk_cpu_freq_to_xtal(int freq, int div);
/* Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are stored as two copies in
* lower and upper 16-bit halves. These are the routines to work with such a
* representation.
*/
static inline bool clk_val_is_valid(uint32_t val)
{
return (val & 0xffff) == ((val >> 16) & 0xffff) &&
val != 0 &&
val != UINT32_MAX;
}
static inline uint32_t reg_val_to_clk_val(uint32_t val)
{
return val & UINT16_MAX;
}
static inline uint32_t clk_val_to_reg_val(uint32_t val)
{
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,84 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include "esp_rom_uart.h"
#include "esp32s3/rom/rtc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
#include "i2c_rtc_clk.h"
#include "soc_log.h"
#include "xtensa/core-macros.h"
#include "rtc_clk_common.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 90k 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 90k 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.
*/
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
/* Configure 90k 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);
/* Enable the internal bus used to configure PLLs */
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M | I2C_BBPLL_M);
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(xtal_freq * MHZ);
/* Set CPU frequency */
rtc_clk_cpu_freq_get_config(&old_config);
uint32_t freq_before = old_config.freq_mhz;
bool res = rtc_clk_cpu_freq_mhz_to_config(cfg.cpu_freq_mhz, &new_config);
if (!res) {
SOC_LOGE(TAG, "invalid CPU frequency value");
abort();
}
rtc_clk_cpu_freq_set_config(&new_config);
/* Re-calculate the ccount to make time calculation correct. */
XTHAL_SET_CCOUNT( (uint64_t)XTHAL_GET_CCOUNT() * cfg.cpu_freq_mhz / freq_before );
/* Slow & fast clocks setup */
if (cfg.slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
rtc_clk_32k_enable(true);
}
if (cfg.fast_freq == RTC_FAST_FREQ_8M) {
bool need_8md256 = cfg.slow_freq == RTC_SLOW_FREQ_8MD256;
rtc_clk_8m_enable(true, need_8md256);
}
rtc_clk_fast_freq_set(cfg.fast_freq);
rtc_clk_slow_freq_set(cfg.slow_freq);
}

View File

@ -0,0 +1,226 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/dport_reg.h"
#include "soc/gpio_reg.h"
#include "soc/spi_mem_reg.h"
#include "soc/extmem_reg.h"
#include "i2c_rtc_clk.h"
#include "i2c_ulp.h"
#define RTC_CNTL_MEM_FORCE_PU (RTC_CNTL_SLOWMEM_FORCE_PU | RTC_CNTL_FASTMEM_FORCE_PU)
#define RTC_CNTL_MEM_FORCE_NOISO (RTC_CNTL_SLOWMEM_FORCE_NOISO | RTC_CNTL_FASTMEM_FORCE_NOISO)
void rtc_init(rtc_config_t cfg)
{
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU);
rtc_clk_set_xtal_wait();
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);
/* Moved from rtc sleep to rtc init to save sleep function running time */
// set shortest possible sleep time limit
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
// set wifi timer
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);
// set rtc peri timer
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_POWERUP_TIMER, rtc_init_cfg.rtc_powerup_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_WAIT_TIMER, rtc_init_cfg.rtc_wait_cycles);
// set digital wrap timer
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);
// set rtc memory timer
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_RTCMEM_POWERUP_TIMER, rtc_init_cfg.rtc_mem_powerup_cycles);
REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_RTCMEM_WAIT_TIMER, rtc_init_cfg.rtc_mem_wait_cycles);
/* Reset RTC bias to default value (needed if waking up from deep sleep) */
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, RTC_CNTL_DBIAS_1V10);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, RTC_CNTL_DBIAS_1V10);
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 rom clock force on
REG_SET_FIELD(SYSTEM_ROM_CTRL_0_REG, SYSTEM_ROM_IRAM0_CLKGATE_FORCE_ON, 0);
//clear sram clock force on
REG_SET_FIELD(SYSTEM_SRAM_CTRL_0_REG, SYSTEM_SRAM_CLKGATE_FORCE_ON, 0);
//clear tag clock force on
CLEAR_PERI_REG_MASK(EXTMEM_DCACHE_TAG_POWER_CTRL_REG, EXTMEM_DCACHE_TAG_MEM_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);
}
// CLEAR APLL close
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);
//cancel bbpll force pu if setting no force power up
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);
}
//cancel RTC REG force PU
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PU);
//combine two rtc memory options
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_NOISO);
if (cfg.rtc_dboost_fpd) {
SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PD);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PD);
}
//cancel digital pu force
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_PU);
/* 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_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(0);
rtc_sleep_pd(pd_cfg);
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_WIFI_FORCE_PU);
// ROM_RAM power domain is removed
// CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_ROM_RAM_FORCE_PU);
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_ROM_RAM_FORCE_NOISO);
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FORCE_NOISO);
//cancel digital PADS force no iso
if (cfg.cpu_waiti_clk_gate) {
SET_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);
}
if (cfg.cali_ocode) {
/*
Bangap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration(must close PLL).
Method:
1. read current cpu config, save in old_config;
2. switch cpu to xtal because PLL will be closed when o-code calibration;
3. begin o-code calibration;
4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
5. set cpu to old-config.
*/
rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
if (slow_clk_freq == (rtc_slow_freq_x32k)) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_freq == rtc_slow_freq_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
uint64_t max_delay_time_us = 10000;
uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
uint64_t cycle0 = rtc_time_get();
uint64_t timeout_cycle = cycle0 + max_delay_cycle;
uint64_t cycle1 = 0;
rtc_cpu_freq_config_t old_config;
rtc_clk_cpu_freq_get_config(&old_config);
rtc_clk_cpu_freq_set_xtal();
I2C_WRITEREG_MASK_RTC(I2C_ULP, I2C_ULP_IR_RESETB, 0);
I2C_WRITEREG_MASK_RTC(I2C_ULP, I2C_ULP_IR_RESETB, 1);
bool odone_flag = 0;
bool bg_odone_flag = 0;
while (1) {
odone_flag = I2C_READREG_MASK_RTC(I2C_ULP, I2C_ULP_O_DONE_FLAG);
bg_odone_flag = I2C_READREG_MASK_RTC(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
cycle1 = rtc_time_get();
if (odone_flag && bg_odone_flag) {
break;
}
if (cycle1 >= timeout_cycle) {
break;
}
}
rtc_clk_cpu_freq_set_config(&old_config);
}
}
rtc_vddsdio_config_t rtc_vddsdio_get_config(void)
{
rtc_vddsdio_config_t result;
uint32_t sdio_conf_reg = REG_READ(RTC_CNTL_SDIO_CONF_REG);
result.drefh = (sdio_conf_reg & RTC_CNTL_DREFH_SDIO_M) >> RTC_CNTL_DREFH_SDIO_S;
result.drefm = (sdio_conf_reg & RTC_CNTL_DREFM_SDIO_M) >> RTC_CNTL_DREFM_SDIO_S;
result.drefl = (sdio_conf_reg & RTC_CNTL_DREFL_SDIO_M) >> RTC_CNTL_DREFL_SDIO_S;
if (sdio_conf_reg & RTC_CNTL_SDIO_FORCE) {
// Get configuration from RTC
result.force = 1;
result.enable = (sdio_conf_reg & RTC_CNTL_XPD_SDIO_REG_M) >> RTC_CNTL_XPD_SDIO_REG_S;
result.tieh = (sdio_conf_reg & RTC_CNTL_SDIO_TIEH_M) >> RTC_CNTL_SDIO_TIEH_S;
return result;
} else {
result.force = 0;
}
// Otherwise, VDD_SDIO is controlled by bootstrapping pin
uint32_t strap_reg = REG_READ(GPIO_STRAP_REG);
result.tieh = (strap_reg & BIT(5)) ? RTC_VDDSDIO_TIEH_1_8V : RTC_VDDSDIO_TIEH_3_3V;
result.enable = 1;
return result;
}
void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
{
uint32_t val = 0;
val |= (config.force << RTC_CNTL_SDIO_FORCE_S);
val |= (config.enable << RTC_CNTL_XPD_SDIO_REG_S);
val |= (config.drefh << RTC_CNTL_DREFH_SDIO_S);
val |= (config.drefm << RTC_CNTL_DREFM_SDIO_S);
val |= (config.drefl << RTC_CNTL_DREFL_SDIO_S);
val |= (config.tieh << RTC_CNTL_SDIO_TIEH_S);
val |= RTC_CNTL_SDIO_PD_EN;
REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
}

View File

@ -0,0 +1,67 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <assert.h>
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
typedef enum {
PM_LIGHT_SLEEP = BIT(2), /*!< WiFi PD, memory in light sleep */
} pm_sleep_mode_t;
typedef enum {
PM_SW_NOREJECT = 0,
PM_SW_REJECT = 1
} pm_sw_reject_t;
/* These MAC-related functions are defined in the closed source part of
* RTC library
*/
extern void pm_mac_init(void);
extern int pm_check_mac_idle(void);
extern void pm_mac_deinit(void);
/* This sleep-related function is called from the closed source part of RTC
* library.
*/
pm_sw_reject_t pm_set_sleep_mode(pm_sleep_mode_t sleep_mode, void(*pmac_save_params)(void))
{
(void) pmac_save_params; /* unused */
pm_mac_deinit();
if (pm_check_mac_idle()) {
pm_mac_init();
return PM_SW_REJECT;
}
rtc_sleep_config_t cfg = { 0 };
switch (sleep_mode) {
case PM_LIGHT_SLEEP:
cfg.wifi_pd_en = 1;
cfg.dig_dbias_wak = 4;
cfg.dig_dbias_slp = 0;
cfg.rtc_dbias_wak = 0;
cfg.rtc_dbias_slp = 0;
rtc_sleep_init(cfg);
break;
default:
assert(0 && "unsupported sleep mode");
}
return PM_SW_NOREJECT;
}

View File

@ -0,0 +1,158 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
#include "soc/dport_reg.h"
#include "soc/rtc.h"
#include "soc/i2s_reg.h"
#include "soc/timer_group_reg.h"
#include "soc/bb_reg.h"
#include "soc/nrx_reg.h"
#include "soc/fe_reg.h"
#include "soc/rtc.h"
#include "i2c_rtc_clk.h"
#define RTC_CNTL_MEM_FOLW_CPU (RTC_CNTL_SLOWMEM_FOLW_CPU | RTC_CNTL_FASTMEM_FOLW_CPU)
/**
* Configure whether certain peripherals are powered down in deep sleep
* @param cfg power down flags as rtc_sleep_pd_config_t structure
*/
void rtc_sleep_pd(rtc_sleep_pd_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_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_LPU, cfg.rtc_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_DC_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_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);
}
void rtc_sleep_init(rtc_sleep_config_t cfg)
{
if (cfg.lslp_mem_inf_fpu) {
rtc_sleep_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(1);
rtc_sleep_pd(pd_cfg);
}
if (cfg.rtc_mem_inf_follow_cpu) {
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FOLW_CPU);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FOLW_CPU);
}
if (cfg.rtc_fastmem_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_PD_EN);
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_NOISO);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_PD_EN);
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_PU);
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_NOISO);
}
if (cfg.rtc_slowmem_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_PD_EN);
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_NOISO);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_PD_EN);
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_PU);
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_NOISO);
}
if (cfg.rtc_peri_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PD_EN);
}
if (cfg.wifi_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
}
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, RTC_CNTL_BIASSLP_SLEEP_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, RTC_CNTL_PD_CUR_MONITOR_DEFAULT);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, RTC_CNTL_PD_CUR_SLEEP_DEFAULT);
if (cfg.deep_slp) {
CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT);
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);
} else {
SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT);
}
/* 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);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, cfg.rtc_dbias_wak);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp);
I2C_WRITEREG_MASK_RTC(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, cfg.dig_dbias_wak);
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);
}
void rtc_sleep_set_wakeup_time(uint64_t t)
{
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
}
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) {
;
}
/* 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_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(0);
rtc_sleep_pd(pd_cfg);
}
return reject;
}

View File

@ -0,0 +1,181 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "esp_rom_sys.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/timer_group_reg.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 ESP32S3, choosing RTC_CAL_RTC_MUX results in calibration of
* the 90k 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) {
rtc_slow_freq_t slow_freq = rtc_clk_slow_freq_get();
if (slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_freq == RTC_SLOW_FREQ_8MD256) {
cal_clk = RTC_CAL_8MD256;
}
}
/* Enable requested clock (150k clock is always on) */
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
}
if (cal_clk == RTC_CAL_8MD256) {
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
}
/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
/* 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_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY));
}
}
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 = RTC_SLOW_CLK_FREQ_32K;
} else if (cal_clk == RTC_CAL_8MD256) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_8MD256;
} else {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = RTC_SLOW_CLK_FREQ_90K;
}
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);
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);
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
if (cal_clk == RTC_CAL_8MD256) {
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN);
}
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;
}
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);
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)
{
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;
}
uint64_t rtc_light_slp_time_get(void)
{
uint64_t t_wake = READ_PERI_REG(RTC_CNTL_TIME_LOW0_REG);
t_wake |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH0_REG)) << 32;
uint64_t t_slp = READ_PERI_REG(RTC_CNTL_TIME_LOW1_REG);
t_slp |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH1_REG)) << 32;
return (t_wake - t_slp);
}
uint64_t rtc_deep_slp_time_get(void)
{
uint64_t t_slp = READ_PERI_REG(RTC_CNTL_TIME_LOW1_REG);
t_slp |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME_HIGH1_REG)) << 32;
uint64_t t_wake = rtc_time_get();
return (t_wake - t_slp);
}
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);
}
}

View File

@ -0,0 +1,112 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <sys/param.h>
#include "hal/systimer_hal.h"
#include "hal/systimer_ll.h"
#include "hal/systimer_types.h"
#include "soc/systimer_caps.h"
#define SYSTIMER_TICKS_PER_US (16) // Number of timer ticks per microsecond
uint64_t systimer_hal_get_counter_value(systimer_counter_id_t counter_id)
{
uint32_t lo, lo_start, hi;
/* Set the "update" bit and wait for acknowledgment */
systimer_ll_counter_snapshot(counter_id);
while (!systimer_ll_is_counter_value_valid(counter_id));
/* Read LO, HI, then LO again, check that LO returns the same value.
* This accounts for the case when an interrupt may happen between reading
* HI and LO values, and this function may get called from the ISR.
* In this case, the repeated read will return consistent values.
*/
lo_start = systimer_ll_get_counter_value_low(counter_id);
do {
lo = lo_start;
hi = systimer_ll_get_counter_value_high(counter_id);
lo_start = systimer_ll_get_counter_value_low(counter_id);
} while (lo_start != lo);
systimer_counter_value_t result = {
.lo = lo,
.hi = hi
};
return result.val;
}
uint64_t systimer_hal_get_time(systimer_counter_id_t counter_id)
{
return systimer_hal_get_counter_value(counter_id) / SYSTIMER_TICKS_PER_US;
}
void systimer_hal_set_alarm_value(systimer_alarm_id_t alarm_id, uint64_t timestamp)
{
systimer_counter_value_t alarm = { .val = timestamp * SYSTIMER_TICKS_PER_US};
systimer_ll_disable_alarm(alarm_id);
systimer_ll_set_alarm_value(alarm_id, alarm.val);
systimer_ll_enable_alarm(alarm_id);
}
uint64_t systimer_hal_get_alarm_value(systimer_alarm_id_t alarm_id)
{
return systimer_ll_get_alarm_value(alarm_id);
}
void systimer_hal_enable_alarm_int(systimer_alarm_id_t alarm_id)
{
systimer_ll_enable_alarm_int(alarm_id);
}
void systimer_hal_on_apb_freq_update(uint32_t apb_ticks_per_us)
{
/* Nothing to do here, SYSTIMER clock is independent of APB clock */
(void)apb_ticks_per_us;
}
void systimer_hal_counter_value_advance(systimer_counter_id_t counter_id, int64_t time_us)
{
systimer_counter_value_t new_count = { .val = systimer_hal_get_counter_value(counter_id) + time_us * SYSTIMER_TICKS_PER_US };
systimer_ll_load_counter_value(counter_id, new_count.val);
systimer_ll_apply_counter_value(counter_id);
}
void systimer_hal_enable_counter(systimer_counter_id_t counter_id)
{
systimer_ll_enable_counter(counter_id);
}
void systimer_hal_init(void)
{
systimer_ll_enable_clock();
}
void systimer_hal_select_alarm_mode(systimer_alarm_id_t alarm_id, systimer_alarm_mode_t mode)
{
switch (mode) {
case SYSTIMER_ALARM_MODE_ONESHOT:
systimer_ll_enable_alarm_oneshot(alarm_id);
break;
case SYSTIMER_ALARM_MODE_PERIOD:
systimer_ll_enable_alarm_period(alarm_id);
break;
default:
break;
}
}
void systimer_hal_connect_alarm_counter(systimer_alarm_id_t alarm_id, systimer_counter_id_t counter_id)
{
systimer_ll_connect_alarm_counter(alarm_id, counter_id);
}

View File

@ -0,0 +1,156 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The HAL layer for Touch Sensor (common part)
#include "hal/touch_sensor_hal.h"
#include "hal/touch_sensor_types.h"
void touch_hal_init(void)
{
touch_ll_intr_disable(TOUCH_PAD_INTR_MASK_ALL);
touch_ll_clear_channel_mask(SOC_TOUCH_SENSOR_BIT_MASK_MAX);
touch_ll_clear_trigger_status_mask();
touch_ll_set_meas_times(TOUCH_PAD_MEASURE_CYCLE_DEFAULT);
touch_ll_set_sleep_time(TOUCH_PAD_SLEEP_CYCLE_DEFAULT);
touch_ll_set_voltage_high(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD);
touch_ll_set_voltage_low(TOUCH_PAD_LOW_VOLTAGE_THRESHOLD);
touch_ll_set_voltage_attenuation(TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD);
touch_ll_set_idle_channel_connect(TOUCH_PAD_IDLE_CH_CONNECT_DEFAULT);
/* Clear touch channels to initialize the channel value (benchmark, raw_data).
* Note: Should call it after enable clock gate. */
touch_ll_clkgate(true); // Enable clock gate for touch sensor.
touch_ll_reset_benchmark(TOUCH_PAD_MAX);
touch_ll_sleep_reset_benchmark();
}
void touch_hal_deinit(void)
{
touch_ll_reset_benchmark(TOUCH_PAD_MAX);
touch_ll_sleep_reset_benchmark();
touch_ll_stop_fsm();
touch_ll_clkgate(false);
touch_ll_clear_channel_mask(SOC_TOUCH_SENSOR_BIT_MASK_MAX);
touch_ll_clear_trigger_status_mask();
touch_ll_intr_disable(TOUCH_PAD_INTR_MASK_ALL);
touch_ll_timeout_disable();
touch_ll_waterproof_disable();
touch_ll_denoise_disable();
touch_pad_t prox_pad[SOC_TOUCH_PROXIMITY_CHANNEL_NUM] = {[0 ... (SOC_TOUCH_PROXIMITY_CHANNEL_NUM - 1)] = 0};
touch_ll_proximity_set_channel_num((const touch_pad_t *)prox_pad);
touch_ll_sleep_set_channel_num(0);
touch_ll_sleep_disable_approach();
touch_ll_reset(); // Reset the touch sensor FSM.
}
void touch_hal_filter_set_config(const touch_filter_config_t *filter_info)
{
touch_ll_filter_set_filter_mode(filter_info->mode);
touch_ll_filter_set_debounce(filter_info->debounce_cnt);
touch_ll_filter_set_noise_thres(filter_info->noise_thr);
touch_ll_filter_set_jitter_step(filter_info->jitter_step);
touch_ll_filter_set_smooth_mode(filter_info->smh_lvl);
}
void touch_hal_filter_get_config(touch_filter_config_t *filter_info)
{
touch_ll_filter_get_filter_mode(&filter_info->mode);
touch_ll_filter_get_debounce(&filter_info->debounce_cnt);
touch_ll_filter_get_noise_thres(&filter_info->noise_thr);
touch_ll_filter_get_jitter_step(&filter_info->jitter_step);
touch_ll_filter_get_smooth_mode(&filter_info->smh_lvl);
}
void touch_hal_denoise_set_config(const touch_pad_denoise_t *denoise)
{
touch_ll_denoise_set_cap_level(denoise->cap_level);
touch_ll_denoise_set_grade(denoise->grade);
}
void touch_hal_denoise_get_config(touch_pad_denoise_t *denoise)
{
touch_ll_denoise_get_cap_level(&denoise->cap_level);
touch_ll_denoise_get_grade(&denoise->grade);
}
void touch_hal_denoise_enable(void)
{
touch_ll_clear_channel_mask(1U << SOC_TOUCH_DENOISE_CHANNEL);
touch_ll_denoise_enable();
}
void touch_hal_waterproof_set_config(const touch_pad_waterproof_t *waterproof)
{
touch_ll_waterproof_set_guard_pad(waterproof->guard_ring_pad);
touch_ll_waterproof_set_sheild_driver(waterproof->shield_driver);
}
void touch_hal_waterproof_get_config(touch_pad_waterproof_t *waterproof)
{
touch_ll_waterproof_get_guard_pad(&waterproof->guard_ring_pad);
touch_ll_waterproof_get_sheild_driver(&waterproof->shield_driver);
}
void touch_hal_waterproof_enable(void)
{
touch_ll_clear_channel_mask(1U << SOC_TOUCH_SHIELD_CHANNEL);
touch_ll_waterproof_enable();
}
bool touch_hal_enable_proximity(touch_pad_t touch_num, bool enabled)
{
int i = 0;
touch_pad_t ch_num[SOC_TOUCH_PROXIMITY_CHANNEL_NUM] = {0};
touch_ll_proximity_get_channel_num(ch_num);
if (enabled) {
for (i = 0; i < SOC_TOUCH_PROXIMITY_CHANNEL_NUM; i++) {
if (ch_num[i] == TOUCH_PAD_NUM0 || ch_num[i] >= TOUCH_PAD_MAX || ch_num[i] == touch_num) {
ch_num[i] = touch_num;
break;
}
}
if (i == SOC_TOUCH_PROXIMITY_CHANNEL_NUM) {
return false;
}
} else {
for (i = 0; i < SOC_TOUCH_PROXIMITY_CHANNEL_NUM; i++) {
if (ch_num[i] == touch_num) {
ch_num[i] = TOUCH_PAD_NUM0;
break;
}
}
}
touch_ll_proximity_set_channel_num(ch_num);
return true;
}
void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable)
{
if (enable) {
touch_ll_sleep_set_channel_num(pad_num);
touch_ll_sleep_set_threshold(SOC_TOUCH_PAD_THRESHOLD_MAX);
/* Default change touch dbias to self-dbias to save power.
Measuring the sleep pad threshold after `sleep_channel_set_config`. */
touch_ll_sleep_low_power(true);
touch_ll_sleep_reset_benchmark();
} else {
touch_ll_sleep_set_channel_num(TOUCH_PAD_NUM0);
}
}
void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config)
{
touch_ll_sleep_get_channel_num(&slp_config->touch_num);
slp_config->en_proximity = touch_ll_sleep_get_approach_status();
}

View File

@ -37,7 +37,7 @@ static const spi_flash_hal_clock_config_t spi_flash_clk_cfg_reg[ESP_FLASH_SPEED_
{80e6, SPI_FLASH_LL_CLKREG_VAL_80MHZ},
};
#ifdef CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
static const spi_flash_hal_clock_config_t spi_flash_gpspi_clk_cfg_reg[ESP_FLASH_SPEED_MAX] = {
{5e6, {.gpspi=GPSPI_FLASH_LL_CLKREG_VAL_5MHZ}},
{10e6, {.gpspi=GPSPI_FLASH_LL_CLKREG_VAL_10MHZ}},
@ -75,7 +75,7 @@ esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_
spi_flash_hal_clock_config_t clock_cfg = spi_flash_clk_cfg_reg[cfg->speed];
#ifdef CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
if (cfg->host_id > SPI_HOST) {
clock_cfg = spi_flash_gpspi_clk_cfg_reg[cfg->speed];
}