mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
build and link hello-world for esp32s2beta
This commit is contained in:
parent
61ce868396
commit
84b2f9f14d
@ -15,7 +15,12 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_app_trace_util.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// TIMEOUT /////////////////////////////////////
|
||||
|
@ -3,6 +3,7 @@ set(COMPONENT_SRCS "esp_ota_ops.c"
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
set(COMPONENT_REQUIRES spi_flash partition_table bootloader_support)
|
||||
set(COMPONENT_PRIV_REQUIRES)
|
||||
|
||||
register_component()
|
||||
|
||||
|
@ -39,10 +39,12 @@
|
||||
#include "bootloader_common.h"
|
||||
#include "sys/param.h"
|
||||
#include "esp_system.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
|
||||
typedef struct ota_ops_entry_ {
|
||||
uint32_t handle;
|
||||
|
@ -64,7 +64,7 @@
|
||||
#include "bootloader_utility.h"
|
||||
#include "bootloader_sha.h"
|
||||
|
||||
#ifndef BOOTLOADER_BUILD // TODO: efuse component on esp32s2beta
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// 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 "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/portmacro.h"
|
||||
#include "freertos/task.h"
|
||||
@ -25,6 +25,7 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/can.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
/* ---------------------------- Definitions --------------------------------- */
|
||||
//Internal Macros
|
||||
@ -1004,3 +1005,4 @@ esp_err_t can_clear_receive_queue()
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -212,7 +212,11 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
|
||||
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (gpio_num >= 34 && (mode & GPIO_MODE_DEF_OUTPUT)) {
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (gpio_num >= 46 && (mode & GPIO_MODE_DEF_OUTPUT)) {
|
||||
#endif
|
||||
ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@ -516,7 +520,11 @@ esp_err_t gpio_hold_en(gpio_num_t gpio_num)
|
||||
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
|
||||
r = rtc_gpio_hold_en(gpio_num);
|
||||
} else if (GPIO_HOLD_MASK[gpio_num]) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SET_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
#endif
|
||||
} else {
|
||||
r = ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
@ -530,7 +538,11 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
|
||||
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
|
||||
r = rtc_gpio_hold_dis(gpio_num);
|
||||
} else if (GPIO_HOLD_MASK[gpio_num]) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
#endif
|
||||
} else {
|
||||
r = ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -34,6 +34,9 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_pm.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
static const char* I2S_TAG = "I2S";
|
||||
|
||||
@ -453,12 +456,20 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
|
||||
I2S[i2s_num]->clkm_conf.clkm_div_a = 1;
|
||||
I2S[i2s_num]->sample_rate_conf.tx_bck_div_num = m_scale;
|
||||
I2S[i2s_num]->sample_rate_conf.rx_bck_div_num = m_scale;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
I2S[i2s_num]->clkm_conf.clka_en = 1;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
I2S[i2s_num]->clkm_conf.clk_sel = 1;
|
||||
#endif
|
||||
double fi2s_rate = i2s_apll_get_fi2s(bits, sdm0, sdm1, sdm2, odir);
|
||||
ESP_LOGI(I2S_TAG, "APLL: Req RATE: %d, real rate: %0.3f, BITS: %u, CLKM: %u, BCK_M: %u, MCLK: %0.3f, SCLK: %f, diva: %d, divb: %d",
|
||||
rate, fi2s_rate/bits/channel/m_scale, bits, 1, m_scale, fi2s_rate, fi2s_rate/8, 1, 0);
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
I2S[i2s_num]->clkm_conf.clka_en = 0;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
I2S[i2s_num]->clkm_conf.clk_sel = 2;
|
||||
#endif
|
||||
I2S[i2s_num]->clkm_conf.clkm_div_a = 63;
|
||||
I2S[i2s_num]->clkm_conf.clkm_div_b = clkmDecimals;
|
||||
I2S[i2s_num]->clkm_conf.clkm_div_num = clkmInteger;
|
||||
@ -1378,3 +1389,4 @@ int i2s_pop_sample(i2s_port_t i2s_num, void *sample, TickType_t ticks_to_wait)
|
||||
return bytes_pop;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -76,6 +76,7 @@ extern "C" {
|
||||
#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /*!< Pin 38 selected */
|
||||
#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /*!< Pin 39 selected */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define GPIO_PIN_REG_0 IO_MUX_GPIO0_REG
|
||||
#define GPIO_PIN_REG_1 IO_MUX_GPIO1_REG
|
||||
#define GPIO_PIN_REG_2 IO_MUX_GPIO2_REG
|
||||
@ -111,6 +112,56 @@ extern "C" {
|
||||
#define GPIO_PIN_REG_37 IO_MUX_GPIO37_REG
|
||||
#define GPIO_PIN_REG_38 IO_MUX_GPIO38_REG
|
||||
#define GPIO_PIN_REG_39 IO_MUX_GPIO39_REG
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define GPIO_PIN_REG_0 IO_MUX_GPIO0_REG
|
||||
#define GPIO_PIN_REG_1 IO_MUX_GPIO1_REG
|
||||
#define GPIO_PIN_REG_2 IO_MUX_GPIO2_REG
|
||||
#define GPIO_PIN_REG_3 IO_MUX_GPIO3_REG
|
||||
#define GPIO_PIN_REG_4 IO_MUX_GPIO4_REG
|
||||
#define GPIO_PIN_REG_5 IO_MUX_GPIO5_REG
|
||||
#define GPIO_PIN_REG_6 IO_MUX_GPIO6_REG
|
||||
#define GPIO_PIN_REG_7 IO_MUX_GPIO7_REG
|
||||
#define GPIO_PIN_REG_8 IO_MUX_GPIO8_REG
|
||||
#define GPIO_PIN_REG_9 IO_MUX_GPIO9_REG
|
||||
#define GPIO_PIN_REG_10 IO_MUX_GPIO10_REG
|
||||
#define GPIO_PIN_REG_11 IO_MUX_GPIO11_REG
|
||||
#define GPIO_PIN_REG_12 IO_MUX_GPIO12_REG
|
||||
#define GPIO_PIN_REG_13 IO_MUX_GPIO13_REG
|
||||
#define GPIO_PIN_REG_14 IO_MUX_GPIO14_REG
|
||||
#define GPIO_PIN_REG_15 IO_MUX_GPIO15_REG
|
||||
#define GPIO_PIN_REG_16 IO_MUX_GPIO16_REG
|
||||
#define GPIO_PIN_REG_17 IO_MUX_GPIO17_REG
|
||||
#define GPIO_PIN_REG_18 IO_MUX_GPIO18_REG
|
||||
#define GPIO_PIN_REG_19 IO_MUX_GPIO19_REG
|
||||
#define GPIO_PIN_REG_20 IO_MUX_GPIO20_REG
|
||||
#define GPIO_PIN_REG_21 IO_MUX_GPIO21_REG
|
||||
#define GPIO_PIN_REG_22 IO_MUX_GPIO22_REG
|
||||
#define GPIO_PIN_REG_23 IO_MUX_GPIO23_REG
|
||||
#define GPIO_PIN_REG_24 IO_MUX_GPIO24_REG
|
||||
#define GPIO_PIN_REG_25 IO_MUX_GPIO25_REG
|
||||
#define GPIO_PIN_REG_26 IO_MUX_GPIO26_REG
|
||||
#define GPIO_PIN_REG_27 IO_MUX_GPIO27_REG
|
||||
#define GPIO_PIN_REG_28 IO_MUX_GPIO28_REG
|
||||
#define GPIO_PIN_REG_29 IO_MUX_GPIO29_REG
|
||||
#define GPIO_PIN_REG_30 IO_MUX_GPIO30_REG
|
||||
#define GPIO_PIN_REG_31 IO_MUX_GPIO31_REG
|
||||
#define GPIO_PIN_REG_32 IO_MUX_GPIO32_REG
|
||||
#define GPIO_PIN_REG_33 IO_MUX_GPIO33_REG
|
||||
#define GPIO_PIN_REG_34 IO_MUX_GPIO34_REG
|
||||
#define GPIO_PIN_REG_35 IO_MUX_GPIO35_REG
|
||||
#define GPIO_PIN_REG_36 IO_MUX_GPIO36_REG
|
||||
#define GPIO_PIN_REG_37 IO_MUX_GPIO37_REG
|
||||
#define GPIO_PIN_REG_38 IO_MUX_GPIO38_REG
|
||||
#define GPIO_PIN_REG_39 IO_MUX_GPIO39_REG
|
||||
#define GPIO_PIN_REG_40 IO_MUX_GPIO40_REG
|
||||
#define GPIO_PIN_REG_41 IO_MUX_GPIO41_REG
|
||||
#define GPIO_PIN_REG_42 IO_MUX_GPIO42_REG
|
||||
#define GPIO_PIN_REG_43 IO_MUX_GPIO43_REG
|
||||
#define GPIO_PIN_REG_44 IO_MUX_GPIO44_REG
|
||||
#define GPIO_PIN_REG_45 IO_MUX_GPIO45_REG
|
||||
#define GPIO_PIN_REG_46 IO_MUX_GPIO46_REG
|
||||
#define GPIO_PIN_REG_47 IO_MUX_GPIO47_REG
|
||||
#endif
|
||||
|
||||
#define GPIO_APP_CPU_INTR_ENA (BIT(0))
|
||||
#define GPIO_APP_CPU_NMI_INTR_ENA (BIT(1))
|
||||
@ -127,7 +178,11 @@ extern "C" {
|
||||
/** @endcond */
|
||||
|
||||
#define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && GPIO_PIN_MUX_REG[gpio_num] != 0)) /*!< Check whether it is a valid GPIO number */
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) /*!< Check whether it can be a valid GPIO number of output mode */
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#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 */
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
GPIO_NUM_NC = -1, /*!< Use to signal not connected to S/W */
|
||||
@ -173,7 +228,19 @@ typedef enum {
|
||||
GPIO_NUM_37 = 37, /*!< GPIO37, input mode only */
|
||||
GPIO_NUM_38 = 38, /*!< GPIO38, input mode only */
|
||||
GPIO_NUM_39 = 39, /*!< GPIO39, input mode only */
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
GPIO_NUM_MAX = 40,
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
GPIO_NUM_40 = 40, /*!< GPIO40, input mode only */
|
||||
GPIO_NUM_41 = 41, /*!< GPIO41, input mode only */
|
||||
GPIO_NUM_42 = 42, /*!< GPIO42, input mode only */
|
||||
GPIO_NUM_43 = 43, /*!< GPIO43, input mode only */
|
||||
GPIO_NUM_44 = 44, /*!< GPIO44, input mode only */
|
||||
GPIO_NUM_45 = 45, /*!< GPIO45, input mode only */
|
||||
GPIO_NUM_46 = 46, /*!< GPIO46, input mode only */
|
||||
GPIO_NUM_47 = 47, /*!< GPIO47, input mode only */
|
||||
GPIO_NUM_MAX = 48,
|
||||
#endif
|
||||
/** @endcond */
|
||||
} gpio_num_t;
|
||||
|
||||
|
@ -61,15 +61,52 @@ extern "C"
|
||||
*/
|
||||
#define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len))
|
||||
|
||||
/**
|
||||
* Transform unsigned integer of length <= 32 bits to the format which can be
|
||||
* sent by the SPI driver directly.
|
||||
*
|
||||
* E.g. to send 9 bits of data, you can:
|
||||
*
|
||||
* uint16_t data = SPI_SWAP_DATA_TX(0x145, 9);
|
||||
*
|
||||
* Then points tx_buffer to ``&data``.
|
||||
*
|
||||
* @param data Data to be sent, can be uint8_t, uint16_t or uint32_t. @param
|
||||
* len Length of data to be sent, since the SPI peripheral sends from the MSB,
|
||||
* this helps to shift the data to the MSB.
|
||||
*/
|
||||
#define SPI_SWAP_DATA_TX(data, len) __builtin_bswap32((uint32_t)data<<(32-len))
|
||||
|
||||
/**
|
||||
* Transform received data of length <= 32 bits to the format of an unsigned integer.
|
||||
*
|
||||
* E.g. to transform the data of 15 bits placed in a 4-byte array to integer:
|
||||
*
|
||||
* uint16_t data = SPI_SWAP_DATA_RX(*(uint32_t*)t->rx_data, 15);
|
||||
*
|
||||
* @param data Data to be rearranged, can be uint8_t, uint16_t or uint32_t.
|
||||
* @param len Length of data received, since the SPI peripheral writes from
|
||||
* the MSB, this helps to shift the data to the LSB.
|
||||
*/
|
||||
#define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len))
|
||||
|
||||
/**
|
||||
* @brief Enum with the three SPI peripherals that are software-accessible in it
|
||||
*/
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
typedef enum {
|
||||
SPI_HOST=0, ///< SPI1, SPI
|
||||
HSPI_HOST=1, ///< SPI2, HSPI
|
||||
VSPI_HOST=2 ///< SPI3, VSPI
|
||||
} spi_host_device_t;
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
typedef enum {
|
||||
SPI_HOST=0, ///< SPI1, SPI
|
||||
FSPI_HOST=1, ///< SPI2, FSPI
|
||||
HSPI_HOST=2, ///< SPI3, HSPI
|
||||
VSPI_HOST=3 ///< SPI4, VSPI
|
||||
} spi_host_device_t;
|
||||
#endif
|
||||
/**
|
||||
* @brief This is a configuration structure for a SPI bus.
|
||||
*
|
||||
@ -85,6 +122,9 @@ typedef struct {
|
||||
int sclk_io_num; ///< GPIO pin for Spi CLocK signal, or -1 if not used.
|
||||
int quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal which is used as D2 in 4-bit communication modes, or -1 if not used.
|
||||
int quadhd_io_num; ///< GPIO pin for HD (HolD) signal which is used as D3 in 4-bit communication modes, or -1 if not used.
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
int spicd_io_num; ///< CD GPIO pin for this device, or -1 if not used
|
||||
#endif
|
||||
int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4094 if 0.
|
||||
uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags.
|
||||
int intr_flags; /**< Interrupt flag for the bus to set the priority, and IRAM attribute, see
|
||||
|
@ -25,6 +25,7 @@
|
||||
/** SPI master clock is divided by 80MHz apb clock. Below defines are example frequencies, and are accurate. Be free to specify a random frequency, it will be rounded to closest frequency (to macros below if above 8MHz).
|
||||
* 8MHz
|
||||
*/
|
||||
#if APB_CLK_FREQ==80*1000*1000
|
||||
#define SPI_MASTER_FREQ_8M (APB_CLK_FREQ/10)
|
||||
#define SPI_MASTER_FREQ_9M (APB_CLK_FREQ/9) ///< 8.89MHz
|
||||
#define SPI_MASTER_FREQ_10M (APB_CLK_FREQ/8) ///< 10MHz
|
||||
@ -35,7 +36,14 @@
|
||||
#define SPI_MASTER_FREQ_26M (APB_CLK_FREQ/3) ///< 26.67MHz
|
||||
#define SPI_MASTER_FREQ_40M (APB_CLK_FREQ/2) ///< 40MHz
|
||||
#define SPI_MASTER_FREQ_80M (APB_CLK_FREQ/1) ///< 80MHz
|
||||
|
||||
#elif APB_CLK_FREQ==40*1000*1000
|
||||
#define SPI_MASTER_FREQ_7M (APB_CLK_FREQ/6) ///< 13.33MHz
|
||||
#define SPI_MASTER_FREQ_8M (APB_CLK_FREQ/5) ///< 16MHz
|
||||
#define SPI_MASTER_FREQ_10M (APB_CLK_FREQ/4) ///< 20MHz
|
||||
#define SPI_MASTER_FREQ_13M (APB_CLK_FREQ/3) ///< 26.67MHz
|
||||
#define SPI_MASTER_FREQ_20M (APB_CLK_FREQ/2) ///< 40MHz
|
||||
#define SPI_MASTER_FREQ_40M (APB_CLK_FREQ/1) ///< 80MHz
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
@ -54,6 +62,7 @@ extern "C"
|
||||
* Set this flag to confirm that you're going to work with output only, or read without dummy bits at your own risk.
|
||||
*/
|
||||
#define SPI_DEVICE_NO_DUMMY (1<<6)
|
||||
#define SPI_DEVICE_DDRCLK (1<<7)
|
||||
|
||||
|
||||
typedef struct spi_transaction_t spi_transaction_t;
|
||||
@ -67,8 +76,8 @@ typedef struct {
|
||||
uint8_t address_bits; ///< Default amount of bits in address phase (0-64), used when ``SPI_TRANS_VARIABLE_ADDR`` is not used, otherwise ignored.
|
||||
uint8_t dummy_bits; ///< Amount of dummy bits to insert between address and data phase
|
||||
uint8_t mode; ///< SPI mode (0-3)
|
||||
uint8_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
|
||||
uint8_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions.
|
||||
uint16_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
|
||||
uint16_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions.
|
||||
uint8_t cs_ena_posttrans; ///< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16)
|
||||
int clock_speed_hz; ///< Clock speed, divisors of 80MHz, in Hz. See ``SPI_MASTER_FREQ_*``.
|
||||
int input_delay_ns; /**< Maximum data valid time of slave. The time required between SCLK and MISO
|
||||
@ -110,6 +119,7 @@ typedef struct {
|
||||
#define SPI_TRANS_VARIABLE_CMD (1<<5) ///< Use the ``command_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||
#define SPI_TRANS_VARIABLE_ADDR (1<<6) ///< Use the ``address_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||
#define SPI_TRANS_VARIABLE_DUMMY (1<<7) ///< Use the ``dummy_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||
#define SPI_TRANS_SET_CD (1<<7) ///< Set the CD pin
|
||||
|
||||
/**
|
||||
* This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes.
|
||||
|
@ -278,7 +278,9 @@ esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
|
||||
if (speed_mode == LEDC_HIGH_SPEED_MODE) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_matrix_out(gpio_num, LEDC_HS_SIG_OUT0_IDX + ledc_channel, 0, 0);
|
||||
#endif
|
||||
} else {
|
||||
gpio_matrix_out(gpio_num, LEDC_LS_SIG_OUT0_IDX + ledc_channel, 0, 0);
|
||||
}
|
||||
@ -318,7 +320,9 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t* ledc_conf)
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
|
||||
if (speed_mode == LEDC_HIGH_SPEED_MODE) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_matrix_out(gpio_num, LEDC_HS_SIG_OUT0_IDX + ledc_channel, 0, 0);
|
||||
#endif
|
||||
} else {
|
||||
gpio_matrix_out(gpio_num, LEDC_LS_SIG_OUT0_IDX + ledc_channel, 0, 0);
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "driver/mcpwm.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1};
|
||||
static const char *MCPWM_TAG = "MCPWM";
|
||||
@ -41,7 +44,7 @@ static portMUX_TYPE mcpwm_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
#define MCPWM_DB_ERROR "MCPWM DEADTIME TYPE ERROR"
|
||||
|
||||
#define MCPWM_BASE_CLK (2 * APB_CLK_FREQ) //2*APB_CLK_FREQ 160Mhz
|
||||
#define MCPWM_CLK_PRESCL 15 //MCPWM clock prescale
|
||||
#define MCPWM_CLK_PRESCL 15 //MCPWM clock prescale
|
||||
#define TIMER_CLK_PRESCALE 9 //MCPWM timer prescales
|
||||
#define MCPWM_CLK (MCPWM_BASE_CLK/(MCPWM_CLK_PRESCL +1))
|
||||
#define MCPWM_PIN_IGNORE (-1)
|
||||
@ -727,3 +730,4 @@ esp_err_t mcpwm_isr_register(mcpwm_unit_t mcpwm_num, void (*fn)(void *), void *a
|
||||
ret = esp_intr_alloc((ETS_PWM0_INTR_SOURCE + mcpwm_num), intr_alloc_flags, fn, arg, handle);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
@ -101,11 +101,11 @@ esp_err_t pcnt_set_pin(pcnt_unit_t unit, pcnt_channel_t channel, int pulse_io, i
|
||||
PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(GPIO_IS_VALID_GPIO(pulse_io) || pulse_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(GPIO_IS_VALID_GPIO(ctrl_io) || ctrl_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
|
||||
|
||||
int sig_base = (channel == 0) ? PCNT_SIG_CH0_IN0_IDX : PCNT_SIG_CH1_IN0_IDX;
|
||||
int ctrl_base = (channel == 0) ? PCNT_CTRL_CH0_IN0_IDX : PCNT_CTRL_CH1_IN0_IDX;
|
||||
if (unit > 4) {
|
||||
sig_base += 12; // GPIO matrix assignments have a gap between units 4 & 5
|
||||
if (unit > 4) {
|
||||
sig_base += 12; // GPIO matrix assignments have a gap between units 4 & 5
|
||||
ctrl_base += 12;
|
||||
}
|
||||
int input_sig_index = sig_base + (4 * unit);
|
||||
@ -156,7 +156,11 @@ esp_err_t pcnt_counter_clear(pcnt_unit_t pcnt_unit)
|
||||
{
|
||||
PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_ENTER_CRITICAL(&pcnt_spinlock);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t reset_bit = BIT(PCNT_PLUS_CNT_RST_U0_S + (pcnt_unit * 2));
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
uint32_t reset_bit = BIT(PCNT_PULSE_CNT_RST_U0_S + (pcnt_unit * 2));
|
||||
#endif
|
||||
PCNT.ctrl.val |= reset_bit;
|
||||
PCNT.ctrl.val &= ~reset_bit;
|
||||
PCNT_EXIT_CRITICAL(&pcnt_spinlock);
|
||||
|
@ -16,7 +16,9 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
@ -61,8 +63,13 @@ static uint32_t get_clk_en_mask(periph_module_t periph)
|
||||
return DPORT_UART_CLK_EN;
|
||||
case PERIPH_UART1_MODULE:
|
||||
return DPORT_UART1_CLK_EN;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case PERIPH_UART2_MODULE:
|
||||
return DPORT_UART2_CLK_EN;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
case PERIPH_USB_MODULE:
|
||||
return DPORT_USB_CLK_EN;
|
||||
#endif
|
||||
case PERIPH_I2C0_MODULE:
|
||||
return DPORT_I2C_EXT0_CLK_EN;
|
||||
case PERIPH_I2C1_MODULE:
|
||||
@ -91,12 +98,27 @@ static uint32_t get_clk_en_mask(periph_module_t periph)
|
||||
return DPORT_PCNT_CLK_EN;
|
||||
case PERIPH_SPI_MODULE:
|
||||
return DPORT_SPI01_CLK_EN;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case PERIPH_HSPI_MODULE:
|
||||
return DPORT_SPI2_CLK_EN;
|
||||
case PERIPH_VSPI_MODULE:
|
||||
return DPORT_SPI3_CLK_EN;
|
||||
case PERIPH_SPI_DMA_MODULE:
|
||||
return DPORT_SPI_DMA_CLK_EN;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
case PERIPH_FSPI_MODULE:
|
||||
return DPORT_SPI2_CLK_EN;
|
||||
case PERIPH_HSPI_MODULE:
|
||||
return DPORT_SPI3_CLK_EN;
|
||||
case PERIPH_VSPI_MODULE:
|
||||
return DPORT_SPI4_CLK_EN;
|
||||
case PERIPH_SPI2_DMA_MODULE:
|
||||
return DPORT_SPI2_DMA_CLK_EN;
|
||||
case PERIPH_SPI3_DMA_MODULE:
|
||||
return DPORT_SPI3_DMA_CLK_EN;
|
||||
case PERIPH_SPI_SHARED_DMA_MODULE:
|
||||
return DPORT_SPI_SHARED_DMA_CLK_EN;
|
||||
#endif
|
||||
case PERIPH_SDMMC_MODULE:
|
||||
return DPORT_WIFI_CLK_SDIO_HOST_EN;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
@ -117,12 +139,14 @@ static uint32_t get_clk_en_mask(periph_module_t periph)
|
||||
return DPORT_BT_BASEBAND_EN;
|
||||
case PERIPH_BT_LC_MODULE:
|
||||
return DPORT_BT_LC_EN;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case PERIPH_AES_MODULE:
|
||||
return DPORT_PERI_EN_AES;
|
||||
case PERIPH_SHA_MODULE:
|
||||
return DPORT_PERI_EN_SHA;
|
||||
case PERIPH_RSA_MODULE:
|
||||
return DPORT_PERI_EN_RSA;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -139,8 +163,13 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable)
|
||||
return DPORT_UART_RST;
|
||||
case PERIPH_UART1_MODULE:
|
||||
return DPORT_UART1_RST;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case PERIPH_UART2_MODULE:
|
||||
return DPORT_UART2_RST;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
case PERIPH_USB_MODULE:
|
||||
return DPORT_USB_RST;
|
||||
#endif
|
||||
case PERIPH_I2C0_MODULE:
|
||||
return DPORT_I2C_EXT0_RST;
|
||||
case PERIPH_I2C1_MODULE:
|
||||
@ -169,12 +198,27 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable)
|
||||
return DPORT_PCNT_RST;
|
||||
case PERIPH_SPI_MODULE:
|
||||
return DPORT_SPI01_RST;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case PERIPH_HSPI_MODULE:
|
||||
return DPORT_SPI2_RST;
|
||||
case PERIPH_VSPI_MODULE:
|
||||
return DPORT_SPI3_RST;
|
||||
case PERIPH_SPI_DMA_MODULE:
|
||||
return DPORT_SPI_DMA_RST;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
case PERIPH_FSPI_MODULE:
|
||||
return DPORT_SPI2_RST;
|
||||
case PERIPH_HSPI_MODULE:
|
||||
return DPORT_SPI3_RST;
|
||||
case PERIPH_VSPI_MODULE:
|
||||
return DPORT_SPI4_RST;
|
||||
case PERIPH_SPI2_DMA_MODULE:
|
||||
return DPORT_SPI2_DMA_RST;
|
||||
case PERIPH_SPI3_DMA_MODULE:
|
||||
return DPORT_SPI3_DMA_RST;
|
||||
case PERIPH_SPI_SHARED_DMA_MODULE:
|
||||
return DPORT_SPI_SHARED_DMA_RST;
|
||||
#endif
|
||||
case PERIPH_SDMMC_MODULE:
|
||||
return DPORT_SDIO_HOST_RST;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
@ -183,6 +227,7 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable)
|
||||
return DPORT_CAN_RST;
|
||||
case PERIPH_EMAC_MODULE:
|
||||
return DPORT_EMAC_RST;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case PERIPH_AES_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature & secure boot units, otherwise AES unit is held in reset also.
|
||||
@ -207,6 +252,7 @@ static uint32_t get_rst_en_mask(periph_module_t periph, bool enable)
|
||||
// Don't reset digital signature unit, as this resets AES also
|
||||
return DPORT_PERI_EN_RSA;
|
||||
}
|
||||
#endif
|
||||
case PERIPH_WIFI_MODULE:
|
||||
case PERIPH_BT_MODULE:
|
||||
case PERIPH_WIFI_BT_COMMON_MODULE:
|
||||
@ -240,18 +286,32 @@ static bool is_wifi_clk_peripheral(periph_module_t periph)
|
||||
|
||||
static uint32_t get_clk_en_reg(periph_module_t periph)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) {
|
||||
return DPORT_PERI_CLK_EN_REG;
|
||||
} else {
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if(periph == PERIPH_SPI_SHARED_DMA_MODULE) {
|
||||
return DPORT_PERIP_CLK_EN1_REG;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG : DPORT_PERIP_CLK_EN_REG;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_rst_en_reg(periph_module_t periph)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) {
|
||||
return DPORT_PERI_RST_EN_REG;
|
||||
} else {
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if(periph == PERIPH_SPI_SHARED_DMA_MODULE){
|
||||
return DPORT_PERIP_CLK_EN1_REG;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG : DPORT_PERIP_RST_EN_REG;
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,11 @@ esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool* idle_out_en, rmt_idle_
|
||||
esp_err_t rmt_get_status(rmt_channel_t channel, uint32_t* status)
|
||||
{
|
||||
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
*status = RMT.status_ch[channel];
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
*status = RMT.status_ch[channel].val;
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -15,12 +15,12 @@
|
||||
#include <esp_types.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/sens_periph.h"
|
||||
#include "soc/syscon_periph.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "rtc_io.h"
|
||||
#include "touch_pad.h"
|
||||
#include "adc.h"
|
||||
@ -34,6 +34,12 @@
|
||||
#include "driver/rtc_cntl.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "adc1_i2s_private.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Enable built-in checks in queue.h in debug builds
|
||||
@ -83,14 +89,14 @@ portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
static SemaphoreHandle_t rtc_touch_mux = NULL;
|
||||
/*
|
||||
In ADC2, there're two locks used for different cases:
|
||||
1. lock shared with app and WIFI:
|
||||
when wifi using the ADC2, we assume it will never stop,
|
||||
1. lock shared with app and WIFI:
|
||||
when wifi using the ADC2, we assume it will never stop,
|
||||
so app checks the lock and returns immediately if failed.
|
||||
|
||||
2. lock shared between tasks:
|
||||
when several tasks sharing the ADC2, we want to guarantee
|
||||
2. lock shared between tasks:
|
||||
when several tasks sharing the ADC2, we want to guarantee
|
||||
all the requests will be handled.
|
||||
Since conversions are short (about 31us), app returns the lock very soon,
|
||||
Since conversions are short (about 31us), app returns the lock very soon,
|
||||
we use a spinlock to stand there waiting to do conversions one by one.
|
||||
|
||||
adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
|
||||
@ -373,7 +379,9 @@ void rtc_gpio_force_hold_dis_all()
|
||||
for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) {
|
||||
const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio];
|
||||
if (desc->hold_force != 0) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_CLR_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -432,13 +440,21 @@ inline static touch_pad_t touch_pad_num_wrap(touch_pad_t touch_num)
|
||||
esp_err_t touch_pad_isr_handler_register(void (*fn)(void *), void *arg, int no_use, intr_handle_t *handle_no_use)
|
||||
{
|
||||
RTC_MODULE_CHECK(fn, "Touch_Pad ISR null", ESP_ERR_INVALID_ARG);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
return rtc_isr_register(fn, arg, RTC_CNTL_TOUCH_INT_ST_M);
|
||||
#else
|
||||
return ESP_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t touch_pad_isr_register(intr_handler_t fn, void* arg)
|
||||
{
|
||||
RTC_MODULE_CHECK(fn, "Touch_Pad ISR null", ESP_ERR_INVALID_ARG);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
return rtc_isr_register(fn, arg, RTC_CNTL_TOUCH_INT_ST_M);
|
||||
#else
|
||||
return ESP_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t touch_pad_isr_deregister(intr_handler_t fn, void *arg)
|
||||
@ -566,7 +582,7 @@ esp_err_t touch_pad_set_voltage(touch_high_volt_t refh, touch_low_volt_t refl, t
|
||||
ESP_ERR_INVALID_ARG);
|
||||
RTC_MODULE_CHECK(((atten < TOUCH_HVOLT_ATTEN_MAX) && (refh >= (int )TOUCH_HVOLT_ATTEN_KEEP)), "touch atten error",
|
||||
ESP_ERR_INVALID_ARG);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
if (refh > TOUCH_HVOLT_KEEP) {
|
||||
RTCIO.touch_cfg.drefh = refh;
|
||||
@ -578,11 +594,13 @@ esp_err_t touch_pad_set_voltage(touch_high_volt_t refh, touch_low_volt_t refl, t
|
||||
RTCIO.touch_cfg.drange = atten;
|
||||
}
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t touch_pad_get_voltage(touch_high_volt_t *refh, touch_low_volt_t *refl, touch_volt_atten_t *atten)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
if (refh) {
|
||||
*refh = RTCIO.touch_cfg.drefh;
|
||||
@ -594,6 +612,7 @@ esp_err_t touch_pad_get_voltage(touch_high_volt_t *refh, touch_low_volt_t *refl,
|
||||
*atten = RTCIO.touch_cfg.drange;
|
||||
}
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -601,7 +620,7 @@ esp_err_t touch_pad_set_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t slope,
|
||||
{
|
||||
RTC_MODULE_CHECK((slope < TOUCH_PAD_SLOPE_MAX), "touch slope error", ESP_ERR_INVALID_ARG);
|
||||
RTC_MODULE_CHECK((opt < TOUCH_PAD_TIE_OPT_MAX), "touch opt error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
|
||||
touch_pad_t touch_pad_wrap = touch_pad_num_wrap(touch_num);
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
RTCIO.touch_pad[touch_pad_wrap].tie_opt = opt;
|
||||
@ -613,7 +632,7 @@ esp_err_t touch_pad_set_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t slope,
|
||||
esp_err_t touch_pad_get_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t *slope, touch_tie_opt_t *opt)
|
||||
{
|
||||
RTC_MODULE_CHECK((touch_num < TOUCH_PAD_MAX), "touch IO error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
|
||||
touch_pad_t touch_pad_wrap = touch_pad_num_wrap(touch_num);
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
if(opt) {
|
||||
@ -1152,7 +1171,7 @@ void adc_power_on()
|
||||
#ifndef CONFIG_ADC_FORCE_XPD_FSM
|
||||
//Set the power always on to increase precision.
|
||||
SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
|
||||
#else
|
||||
#else
|
||||
//Use the FSM to turn off the power while not used to save power.
|
||||
if (SENS.sar_meas_wait2.force_xpd_sar & SENS_FORCE_XPD_SAR_SW_M) {
|
||||
SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
|
||||
@ -1266,12 +1285,12 @@ static void adc_set_controller(adc_unit_t unit, adc_controller_t ctrl )
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "adc1 selects invalid controller");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
} else if ( unit == ADC_UNIT_2) {
|
||||
switch( ctrl ) {
|
||||
case ADC_CTRL_RTC:
|
||||
SENS.sar_meas_start2.meas2_start_force = true; //RTC controller controls the ADC,not ulp coprocessor
|
||||
SENS.sar_meas_start2.meas2_start_force = true; //RTC controller controls the ADC,not ulp coprocessor
|
||||
SENS.sar_meas_start2.sar2_en_pad_force = true; //RTC controller controls the data port, not ulp coprocessor
|
||||
SENS.sar_read_ctrl2.sar2_dig_force = false; //RTC controller controls the ADC, not digital controller
|
||||
SENS.sar_read_ctrl2.sar2_pwdet_force = false; //RTC controller controls the ADC, not PWDET
|
||||
@ -1301,7 +1320,7 @@ static void adc_set_controller(adc_unit_t unit, adc_controller_t ctrl )
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "adc2 selects invalid controller");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "invalid adc unit");
|
||||
@ -1321,12 +1340,12 @@ static int adc_convert( adc_unit_t unit, int channel)
|
||||
while (SENS.sar_meas_start1.meas1_done_sar == 0);
|
||||
adc_value = SENS.sar_meas_start1.meas1_data_sar;
|
||||
} else if ( unit == ADC_UNIT_2 ) {
|
||||
SENS.sar_meas_start2.sar2_en_pad = (1 << channel); //only one channel is selected.
|
||||
|
||||
SENS.sar_meas_start2.sar2_en_pad = (1 << channel); //only one channel is selected.
|
||||
|
||||
SENS.sar_meas_start2.meas2_start_sar = 0; //start force 0
|
||||
SENS.sar_meas_start2.meas2_start_sar = 1; //start force 1
|
||||
while (SENS.sar_meas_start2.meas2_done_sar == 0) {}; //read done
|
||||
adc_value = SENS.sar_meas_start2.meas2_data_sar;
|
||||
adc_value = SENS.sar_meas_start2.meas2_data_sar;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "invalid adc unit");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -1479,7 +1498,7 @@ static inline void adc1_fsm_disable()
|
||||
SENS.sar_meas_ctrl.amp_short_ref_gnd_fsm = 0;
|
||||
SENS.sar_meas_wait1.sar_amp_wait1 = 1;
|
||||
SENS.sar_meas_wait1.sar_amp_wait2 = 1;
|
||||
SENS.sar_meas_wait2.sar_amp_wait3 = 1;
|
||||
SENS.sar_meas_wait2.sar_amp_wait3 = 1;
|
||||
}
|
||||
|
||||
esp_err_t adc1_i2s_mode_acquire()
|
||||
@ -1530,7 +1549,7 @@ int adc1_get_raw(adc1_channel_t channel)
|
||||
adc1_adc_mode_acquire();
|
||||
adc_power_on();
|
||||
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
//disable other peripherals
|
||||
adc1_hall_enable(false);
|
||||
adc1_fsm_disable(); //currently the LNA is not open, close it by default
|
||||
@ -1652,7 +1671,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
|
||||
}
|
||||
SENS.sar_atten2 = ( SENS.sar_atten2 & ~(3<<(channel*2)) ) | ((atten&3) << (channel*2));
|
||||
_lock_release( &adc2_wifi_lock );
|
||||
|
||||
|
||||
portEXIT_CRITICAL( &adc2_spinlock );
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -1682,7 +1701,7 @@ static inline void adc2_dac_disable( adc2_channel_t channel)
|
||||
}
|
||||
|
||||
//registers in critical section with adc1:
|
||||
//SENS_SAR_START_FORCE_REG,
|
||||
//SENS_SAR_START_FORCE_REG,
|
||||
esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int* raw_out)
|
||||
{
|
||||
uint16_t adc_value = 0;
|
||||
@ -1692,7 +1711,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int*
|
||||
adc_power_on();
|
||||
|
||||
//avoid collision with other tasks
|
||||
portENTER_CRITICAL(&adc2_spinlock);
|
||||
portENTER_CRITICAL(&adc2_spinlock);
|
||||
//lazy initialization
|
||||
//try the lock, return if failed (wifi using).
|
||||
if ( _lock_try_acquire( &adc2_wifi_lock ) == -1 ) {
|
||||
@ -1895,7 +1914,9 @@ esp_err_t dac_i2s_disable()
|
||||
|
||||
static inline void adc1_hall_enable(bool enable)
|
||||
{
|
||||
RTCIO.hall_sens.xpd_hall = enable;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
RTCIO.hall_sens.xpd_hall = enable;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int hall_sensor_get_value() //hall sensor without LNA
|
||||
@ -1904,14 +1925,15 @@ static int hall_sensor_get_value() //hall sensor without LNA
|
||||
int Sens_Vn0;
|
||||
int Sens_Vp1;
|
||||
int Sens_Vn1;
|
||||
int hall_value;
|
||||
|
||||
int hall_value = 0;
|
||||
|
||||
adc_power_on();
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
portENTER_CRITICAL(&rtc_spinlock);
|
||||
//disable other peripherals
|
||||
adc1_fsm_disable();//currently the LNA is not open, close it by default
|
||||
adc1_hall_enable(true);
|
||||
adc1_fsm_disable();//currently the LNA is not open, close it by default
|
||||
adc1_hall_enable(true);
|
||||
// set controller
|
||||
adc_set_controller( ADC_UNIT_1, ADC_CTRL_RTC );
|
||||
// convert for 4 times with different phase and outputs
|
||||
@ -1923,7 +1945,7 @@ static int hall_sensor_get_value() //hall sensor without LNA
|
||||
Sens_Vn1 = adc_convert( ADC_UNIT_1, ADC1_CHANNEL_3 );
|
||||
portEXIT_CRITICAL(&rtc_spinlock);
|
||||
hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0);
|
||||
|
||||
#endif
|
||||
return hall_value;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "sdmmc_private.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "soc/sdmmc_periph.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define SDMMC_EVENT_QUEUE_LENGTH 32
|
||||
|
||||
|
||||
@ -635,3 +635,4 @@ esp_err_t sdmmc_host_pullup_en(int slot, int width)
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
@ -30,6 +32,9 @@
|
||||
#include "driver/spi_common.h"
|
||||
#include "stdatomic.h"
|
||||
#include "hal/spi_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "cas.h"
|
||||
#endif
|
||||
|
||||
static const char *SPI_TAG = "spi";
|
||||
|
||||
@ -112,7 +117,17 @@ bool spicommon_dma_chan_claim (int dma_chan)
|
||||
spi_dma_chan_enabled |= DMA_CHANNEL_ENABLED(dma_chan);
|
||||
ret = true;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
periph_module_enable( PERIPH_SPI_DMA_MODULE );
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (dma_chan==1) {
|
||||
periph_module_enable(PERIPH_SPI2_DMA_MODULE);
|
||||
} else if (dma_chan==2) {
|
||||
periph_module_enable(PERIPH_SPI3_DMA_MODULE);
|
||||
} else if (dma_chan==3) {
|
||||
periph_module_enable(PERIPH_SPI_SHARED_DMA_MODULE);
|
||||
}
|
||||
#endif
|
||||
portEXIT_CRITICAL(&spi_dma_spinlock);
|
||||
|
||||
return ret;
|
||||
@ -131,10 +146,20 @@ bool spicommon_dma_chan_free(int dma_chan)
|
||||
|
||||
portENTER_CRITICAL(&spi_dma_spinlock);
|
||||
spi_dma_chan_enabled &= ~DMA_CHANNEL_ENABLED(dma_chan);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if ( spi_dma_chan_enabled == 0 ) {
|
||||
//disable the DMA only when all the channels are freed.
|
||||
periph_module_disable( PERIPH_SPI_DMA_MODULE );
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (dma_chan==1) {
|
||||
periph_module_disable(PERIPH_SPI2_DMA_MODULE);
|
||||
} else if (dma_chan==2) {
|
||||
periph_module_disable(PERIPH_SPI3_DMA_MODULE);
|
||||
} else if (dma_chan==3) {
|
||||
periph_module_disable(PERIPH_SPI_SHARED_DMA_MODULE);
|
||||
}
|
||||
#endif
|
||||
portEXIT_CRITICAL(&spi_dma_spinlock);
|
||||
|
||||
return true;
|
||||
@ -234,23 +259,43 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host+1);
|
||||
if (bus_config->mosi_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_iomux_out(bus_config->mosi_io_num, FUNC_SPI, false);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
gpio_iomux_out(bus_config->mosi_io_num, spi_periph_signal[host].func, false);
|
||||
#endif
|
||||
}
|
||||
if (bus_config->miso_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_iomux_out(bus_config->miso_io_num, FUNC_SPI, false);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
gpio_iomux_out(bus_config->miso_io_num, spi_periph_signal[host].func, false);
|
||||
#endif
|
||||
}
|
||||
if (bus_config->quadwp_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_iomux_out(bus_config->quadwp_io_num, FUNC_SPI, false);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
gpio_iomux_out(bus_config->quadwp_io_num, spi_periph_signal[host].func, false);
|
||||
#endif
|
||||
}
|
||||
if (bus_config->quadhd_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_iomux_out(bus_config->quadhd_io_num, FUNC_SPI, false);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
gpio_iomux_out(bus_config->quadhd_io_num, spi_periph_signal[host].func, false);
|
||||
#endif
|
||||
}
|
||||
if (bus_config->sclk_io_num >= 0) {
|
||||
gpio_iomux_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_iomux_out(bus_config->sclk_io_num, FUNC_SPI, false);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
gpio_iomux_out(bus_config->sclk_io_num, spi_periph_signal[host].func, false);
|
||||
#endif
|
||||
}
|
||||
temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
|
||||
} else {
|
||||
@ -264,6 +309,9 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT);
|
||||
}
|
||||
gpio_matrix_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->mosi_io_num]);
|
||||
#endif
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], FUNC_GPIO);
|
||||
}
|
||||
if (bus_config->miso_io_num >= 0) {
|
||||
@ -274,18 +322,27 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT);
|
||||
}
|
||||
gpio_matrix_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in, false);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->miso_io_num]);
|
||||
#endif
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], FUNC_GPIO);
|
||||
}
|
||||
if (bus_config->quadwp_io_num >= 0) {
|
||||
gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_INPUT_OUTPUT);
|
||||
gpio_matrix_out(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_out, false, false);
|
||||
gpio_matrix_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, false);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num]);
|
||||
#endif
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], FUNC_GPIO);
|
||||
}
|
||||
if (bus_config->quadhd_io_num >= 0) {
|
||||
gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_INPUT_OUTPUT);
|
||||
gpio_matrix_out(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_out, false, false);
|
||||
gpio_matrix_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, false);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num]);
|
||||
#endif
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], FUNC_GPIO);
|
||||
}
|
||||
if (bus_config->sclk_io_num >= 0) {
|
||||
@ -296,12 +353,30 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT);
|
||||
}
|
||||
gpio_matrix_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in, false);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->sclk_io_num]);
|
||||
#endif
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], FUNC_GPIO);
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (bus_config->spicd_io_num >= 0) {
|
||||
gpio_set_direction(bus_config->spicd_io_num, GPIO_MODE_INPUT_OUTPUT);
|
||||
gpio_matrix_out(bus_config->spicd_io_num, spi_periph_signal[host].spicd_out, false, false);
|
||||
gpio_matrix_in(bus_config->spicd_io_num, spi_periph_signal[host].spicd_in, false);
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->spicd_io_num]);
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->spicd_io_num], FUNC_GPIO);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//Select DMA channel.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_chan, (host * 2));
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (dma_chan==VSPI_HOST) {
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_SPI_DMA_CHAN_SEL_REG, DPORT_SPI_SHARED_DMA_SEL_M);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags_o) *flags_o = temp_flag;
|
||||
return ESP_OK;
|
||||
@ -354,7 +429,11 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
|
||||
if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) {
|
||||
//The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
|
||||
gpio_iomux_in(cs_io_num, spi_periph_signal[host].spics_in);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
gpio_iomux_out(cs_io_num, FUNC_SPI, false);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
gpio_iomux_out(cs_io_num, spi_periph_signal[host].func, false);
|
||||
#endif
|
||||
} else {
|
||||
//Use GPIO matrix
|
||||
if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) {
|
||||
@ -364,6 +443,9 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
|
||||
gpio_set_direction(cs_io_num, GPIO_MODE_INPUT);
|
||||
}
|
||||
if (cs_num == 0) gpio_matrix_in(cs_io_num, spi_periph_signal[host].spics_in, false);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[cs_io_num]);
|
||||
#endif
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO);
|
||||
}
|
||||
}
|
||||
@ -402,6 +484,7 @@ static int dmaworkaround_waiting_for_chan = 0;
|
||||
|
||||
bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
int otherchan = (dmachan == 1) ? 2 : 1;
|
||||
bool ret;
|
||||
portENTER_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
@ -418,6 +501,9 @@ bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
return ret;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress()
|
||||
@ -427,6 +513,7 @@ bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress()
|
||||
|
||||
void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
portENTER_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
dmaworkaround_channels_busy[dmachan-1] = 0;
|
||||
if (dmaworkaround_waiting_for_chan == dmachan) {
|
||||
@ -438,6 +525,7 @@ void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan)
|
||||
@ -447,4 +535,4 @@ void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan)
|
||||
portEXIT_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -122,7 +122,6 @@ We have two bits to control the interrupt:
|
||||
#include "driver/spi_common.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
@ -139,8 +138,12 @@ We have two bits to control the interrupt:
|
||||
#include "esp_heap_caps.h"
|
||||
#include "stdatomic.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "hal/spi_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "cas.h"
|
||||
#endif
|
||||
|
||||
typedef struct spi_device_t spi_device_t;
|
||||
|
||||
@ -183,6 +186,9 @@ typedef struct {
|
||||
int dma_chan;
|
||||
int max_transfer_sz;
|
||||
spi_bus_config_t bus_cfg;
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
int id;
|
||||
#endif
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_handle_t pm_lock;
|
||||
#endif
|
||||
@ -199,7 +205,7 @@ struct spi_device_t {
|
||||
bool waiting; //the device is waiting for the exclusive control of the bus
|
||||
};
|
||||
|
||||
static spi_host_t *spihost[3];
|
||||
static spi_host_t *spihost[SPI_PERIPH_NUM];
|
||||
|
||||
|
||||
static const char *SPI_TAG = "spi_master";
|
||||
@ -245,6 +251,10 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
|
||||
}
|
||||
memset(spihost[host], 0, sizeof(spi_host_t));
|
||||
memcpy( &spihost[host]->bus_cfg, bus_config, sizeof(spi_bus_config_t));
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
spihost[host]->id = host;
|
||||
#endif
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master",
|
||||
&spihost[host]->pm_lock);
|
||||
@ -259,7 +269,13 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
|
||||
ret = err;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, dma_chan, (host * 2));
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (host==VSPI_HOST) {
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_SPI_SHARED_DMA_SEL_REG, DPORT_SPI_SHARED_DMA_SEL_M, 1, DPORT_SPI_SHARED_DMA_SEL_S);
|
||||
}
|
||||
#endif
|
||||
int dma_desc_ct=0;
|
||||
spihost[host]->dma_chan=dma_chan;
|
||||
if (dma_chan == 0) {
|
||||
@ -1084,4 +1100,4 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_transmit(spi_device_handle_t ha
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -13,13 +13,14 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include <hal/spi_ll.h>
|
||||
#include <hal/spi_slave_hal.h>
|
||||
#include <soc/lldesc.h>
|
||||
#include "driver/spi_common.h"
|
||||
#include "driver/spi_slave.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
@ -34,7 +35,7 @@
|
||||
#include "esp32/rom/lldesc.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
static const char *SPI_TAG = "spi_slave";
|
||||
#define SPI_CHECK(a, str, ret_val) \
|
||||
if (!(a)) { \
|
||||
@ -392,4 +393,4 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
if (do_yield) portYIELD_FROM_ISR();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "driver/timer.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static const char* TIMER_TAG = "timer_group";
|
||||
#define TIMER_CHECK(a, str, ret_val) \
|
||||
@ -47,7 +48,11 @@ esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_val != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
portENTER_CRITICAL_SAFE(&timer_spinlock[group_num]);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TG[group_num]->hw_timer[timer_num].update = 1;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
TG[group_num]->hw_timer[timer_num].update.update = 1;
|
||||
#endif
|
||||
*timer_val = ((uint64_t) TG[group_num]->hw_timer[timer_num].cnt_high << 32)
|
||||
| (TG[group_num]->hw_timer[timer_num].cnt_low);
|
||||
portEXIT_CRITICAL_SAFE(&timer_spinlock[group_num]);
|
||||
@ -171,7 +176,7 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num,
|
||||
esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num,
|
||||
void (*fn)(void*), void * arg, int intr_alloc_flags, timer_isr_handle_t *handle)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
@ -222,7 +227,11 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer
|
||||
//but software reset does not clear interrupt status. This is not safe for application when enable the interrupt of timer_group.
|
||||
//we need to disable the interrupt and clear the interrupt status here.
|
||||
TG[group_num]->int_ena.val &= (~BIT(timer_num));
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TG[group_num]->int_clr_timers.val = BIT(timer_num);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
TG[group_num]->int_clr.val = BIT(timer_num);
|
||||
#endif
|
||||
TG[group_num]->hw_timer[timer_num].config.autoreload = config->auto_reload;
|
||||
TG[group_num]->hw_timer[timer_num].config.divider = (uint16_t) config->divider;
|
||||
TG[group_num]->hw_timer[timer_num].config.enable = config->counter_en;
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "malloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
@ -28,6 +27,12 @@
|
||||
#include "driver/uart.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart_select.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#endif
|
||||
|
||||
#define XOFF (char)0x13
|
||||
#define XON (char)0x11
|
||||
@ -79,7 +84,7 @@ typedef struct {
|
||||
intr_handle_t intr_handle; /*!< UART interrupt handle*/
|
||||
uart_mode_t uart_mode; /*!< UART controller actual mode set by uart_set_mode() */
|
||||
bool coll_det_flg; /*!< UART collision detection flag */
|
||||
|
||||
|
||||
//rx parameters
|
||||
int rx_buffered_len; /*!< UART cached data length */
|
||||
SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/
|
||||
@ -298,9 +303,15 @@ static esp_err_t uart_reset_rx_fifo(uart_port_t uart_num)
|
||||
//See description about UART_TXFIFO_RST and UART_RXFIFO_RST in <<esp32_technical_reference_manual>> v2.6 or later.
|
||||
|
||||
// we read the data out and make `fifo_len == 0 && rd_addr == wr_addr`.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while(UART[uart_num]->status.rxfifo_cnt != 0 || (UART[uart_num]->mem_rx_status.wr_addr != UART[uart_num]->mem_rx_status.rd_addr)) {
|
||||
READ_PERI_REG(UART_FIFO_REG(uart_num));
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
while(UART[uart_num]->status.rxfifo_cnt != 0 || (UART[uart_num]->mem_rx_status.rx_waddr != UART[uart_num]->mem_rx_status.apb_rx_raddr)) {
|
||||
READ_PERI_REG(UART_FIFO_AHB_REG(uart_num));
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -577,12 +588,14 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
||||
rts_sig = U1RTS_OUT_IDX;
|
||||
cts_sig = U1CTS_IN_IDX;
|
||||
break;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case UART_NUM_2:
|
||||
tx_sig = U2TXD_OUT_IDX;
|
||||
rx_sig = U2RXD_IN_IDX;
|
||||
rts_sig = U2RTS_OUT_IDX;
|
||||
cts_sig = U2CTS_IN_IDX;
|
||||
break;
|
||||
#endif
|
||||
case UART_NUM_MAX:
|
||||
default:
|
||||
tx_sig = U0TXD_OUT_IDX;
|
||||
@ -657,7 +670,11 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
|
||||
} else if(uart_num == UART_NUM_1) {
|
||||
periph_module_enable(PERIPH_UART1_MODULE);
|
||||
} else if(uart_num == UART_NUM_2) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
periph_module_enable(PERIPH_UART2_MODULE);
|
||||
#else
|
||||
return ESP_FAIL;
|
||||
#endif
|
||||
}
|
||||
r = uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh);
|
||||
if (r != ESP_OK) return r;
|
||||
@ -861,7 +878,11 @@ static void uart_rx_intr_handler_default(void *param)
|
||||
if (p_uart->rx_buffer_full_flg == false) {
|
||||
//We have to read out all data in RX FIFO to clear the interrupt signal
|
||||
while (buf_idx < rx_fifo_len) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
p_uart->rx_data_buf[buf_idx++] = uart_reg->fifo.rw_byte;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
p_uart->rx_data_buf[buf_idx++] = READ_PERI_REG(UART_FIFO_AHB_REG(uart_num));
|
||||
#endif
|
||||
}
|
||||
uint8_t pat_chr = uart_reg->at_cmd_char.data;
|
||||
int pat_num = uart_reg->at_cmd_char.char_num;
|
||||
@ -997,13 +1018,13 @@ static void uart_rx_intr_handler_default(void *param)
|
||||
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
||||
uart_reset_rx_fifo(uart_num);
|
||||
// Set collision detection flag
|
||||
p_uart_obj[uart_num]->coll_det_flg = true;
|
||||
p_uart_obj[uart_num]->coll_det_flg = true;
|
||||
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
||||
uart_event.type = UART_EVENT_MAX;
|
||||
} else if(uart_intr_status & UART_TX_DONE_INT_ST_M) {
|
||||
uart_disable_intr_mask_from_isr(uart_num, UART_TX_DONE_INT_ENA_M);
|
||||
uart_clear_intr_status(uart_num, UART_TX_DONE_INT_CLR_M);
|
||||
// If RS485 half duplex mode is enable then reset FIFO and
|
||||
// If RS485 half duplex mode is enable then reset FIFO and
|
||||
// reset RTS pin to start receiver driver
|
||||
if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) {
|
||||
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
|
||||
@ -1461,7 +1482,11 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
|
||||
} else if(uart_num == UART_NUM_1) {
|
||||
periph_module_disable(PERIPH_UART1_MODULE);
|
||||
} else if(uart_num == UART_NUM_2) {
|
||||
periph_module_disable(PERIPH_UART2_MODULE);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
periph_module_disable(PERIPH_UART2_MODULE);
|
||||
#else
|
||||
return ESP_FAIL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
@ -1479,11 +1504,11 @@ portMUX_TYPE *uart_get_selectlock()
|
||||
return &uart_selectlock;
|
||||
}
|
||||
// Set UART mode
|
||||
esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode)
|
||||
esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode)
|
||||
{
|
||||
UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_ERR_INVALID_STATE);
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||
if ((mode == UART_MODE_RS485_COLLISION_DETECT) || (mode == UART_MODE_RS485_APP_CTRL)
|
||||
if ((mode == UART_MODE_RS485_COLLISION_DETECT) || (mode == UART_MODE_RS485_APP_CTRL)
|
||||
|| (mode == UART_MODE_RS485_HALF_DUPLEX)) {
|
||||
UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1),
|
||||
"disable hw flowctrl before using RS485 mode", ESP_ERR_INVALID_ARG);
|
||||
@ -1538,13 +1563,13 @@ esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh)
|
||||
esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh)
|
||||
{
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||
UART_CHECK((tout_thresh < 127), "tout_thresh max value is 126", ESP_ERR_INVALID_ARG);
|
||||
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
|
||||
// The tout_thresh = 1, defines TOUT interrupt timeout equal to
|
||||
// transmission time of one symbol (~11 bit) on current baudrate
|
||||
// The tout_thresh = 1, defines TOUT interrupt timeout equal to
|
||||
// transmission time of one symbol (~11 bit) on current baudrate
|
||||
if (tout_thresh > 0) {
|
||||
UART[uart_num]->conf1.rx_tout_thrhd = (tout_thresh & UART_RX_TOUT_THRHD_V);
|
||||
UART[uart_num]->conf1.rx_tout_en = 1;
|
||||
@ -1559,8 +1584,8 @@ esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool* collision_flag)
|
||||
{
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||
UART_CHECK((collision_flag != NULL), "wrong parameter pointer", ESP_ERR_INVALID_ARG);
|
||||
UART_CHECK((UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)
|
||||
|| UART_IS_MODE_SET(uart_num, UART_MODE_RS485_COLLISION_DETECT)),
|
||||
UART_CHECK((UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)
|
||||
|| UART_IS_MODE_SET(uart_num, UART_MODE_RS485_COLLISION_DETECT)),
|
||||
"wrong mode", ESP_ERR_INVALID_ARG);
|
||||
*collision_flag = p_uart_obj[uart_num]->coll_det_flg;
|
||||
return ESP_OK;
|
||||
|
@ -12,8 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESP_EFUSE_MANAGER_H_
|
||||
#define _ESP_EFUSE_MANAGER_H_
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -358,5 +357,3 @@ void esp_efuse_init(uint32_t offset, uint32_t size);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ESP_EFUSE_MANAGER_H_
|
||||
|
@ -46,12 +46,14 @@ elseif(CONFIG_IDF_TARGET_ESP32S2BETA)
|
||||
|
||||
target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_BINARY_DIR}/esp32s2beta_out.ld")
|
||||
|
||||
# Rely on user code to define app_main
|
||||
target_link_libraries(${COMPONENT_LIB} "-u app_main")
|
||||
|
||||
# Process the template file through the linker script generation mechanism, and use the output for linking the
|
||||
# final binary
|
||||
target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_LIST_DIR}/ld/esp32s2beta.project.ld.in" PROCESS)
|
||||
|
||||
target_linker_script(${COMPONENT_LIB} "ld/esp32s2beta.peripherals.ld")
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} gcc)
|
||||
target_link_libraries(${COMPONENT_LIB} "-u call_user_start_cpu0")
|
||||
|
||||
@ -79,6 +81,4 @@ elseif(CONFIG_IDF_TARGET_ESP32S2BETA)
|
||||
cpu_start.c
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
-fno-stack-protector)
|
||||
else()
|
||||
register_config_only_component()
|
||||
endif()
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#include "esp32s2beta/rom/uart.h"
|
||||
#include "esp32s2beta/rom/rtc.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/dport_access.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
@ -22,6 +22,10 @@
|
||||
#include "esp32s2beta/rom/uart.h"
|
||||
#include "esp32s2beta/rom/rtc.h"
|
||||
#include "esp32s2beta/rom/cache.h"
|
||||
#include "esp32s2beta/dport_access.h"
|
||||
#include "esp32s2beta/brownout.h"
|
||||
#include "esp32s2beta/cache_err_int.h"
|
||||
#include "esp32s2beta/spiram.h"
|
||||
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
@ -40,36 +44,33 @@
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
#include "esp_heap_caps_init.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "esp32s2beta/dport_access.h"
|
||||
#include "esp_private/crosscore_int.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "esp_newlib.h"
|
||||
#include "esp32s2beta/brownout.h"
|
||||
#include "esp_int_wdt.h"
|
||||
#include "esp_task.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp32s2beta/cache_err_int.h"
|
||||
#include "esp_coexist_internal.h"
|
||||
#include "esp_debug_helpers.h"
|
||||
#include "esp_core_dump.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp32s2beta/spiram.h"
|
||||
#include "esp_clk_internal.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_private/pm_impl.h"
|
||||
#include "trax.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
|
||||
#define STRINGIFY(s) STRINGIFY2(s)
|
||||
#define STRINGIFY2(s) #s
|
||||
@ -137,7 +138,9 @@ void IRAM_ATTR call_start_cpu0()
|
||||
|| rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET
|
||||
#endif
|
||||
) {
|
||||
esp_panic_wdt_stop();
|
||||
#ifndef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||
rtc_wdt_disable();
|
||||
#endif
|
||||
}
|
||||
|
||||
//Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
|
||||
@ -396,7 +399,6 @@ void start_cpu0_default(void)
|
||||
#endif
|
||||
//esp_cache_err_int_init();
|
||||
esp_crosscore_int_init();
|
||||
esp_ipc_init();
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
esp_dport_access_int_init();
|
||||
#endif
|
||||
@ -459,7 +461,7 @@ void start_cpu1_default(void)
|
||||
}
|
||||
#endif //!CONFIG_FREERTOS_UNICORE
|
||||
|
||||
#ifdef CONFIG_CXX_EXCEPTIONS
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
size_t __cxx_eh_arena_size_get()
|
||||
{
|
||||
return CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE;
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
/**
|
||||
@ -41,7 +42,7 @@ void esp_spiram_init_cache();
|
||||
|
||||
/**
|
||||
* @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and
|
||||
* (in case of a dual-core system) the app CPU is online. This test overwrites the
|
||||
* (in case of a dual-core system) the app CPU is online. This test overwrites the
|
||||
* memory with crap, so do not call after e.g. the heap allocator has stored important
|
||||
* stuff in SPI RAM.
|
||||
*
|
||||
|
@ -1,58 +0,0 @@
|
||||
// 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.
|
||||
#ifndef __ESP_ATTR_H__
|
||||
#define __ESP_ATTR_H__
|
||||
|
||||
#define ROMFN_ATTR
|
||||
|
||||
//Normally, the linker script will put all code and rodata in flash,
|
||||
//and all variables in shared RAM. These macros can be used to redirect
|
||||
//particular functions/variables to other memory regions.
|
||||
|
||||
// Forces code into IRAM instead of flash.
|
||||
#define IRAM_ATTR __attribute__((section(".iram1")))
|
||||
|
||||
// Forces data into DRAM instead of flash
|
||||
#define DRAM_ATTR __attribute__((section(".dram1")))
|
||||
|
||||
// Forces data to be 4 bytes aligned
|
||||
#define WORD_ALIGNED_ATTR __attribute__((aligned(4)))
|
||||
|
||||
// Forces data to be placed to DMA-capable places
|
||||
#define DMA_ATTR WORD_ALIGNED_ATTR DRAM_ATTR
|
||||
|
||||
// Forces a string into DRAM instead of flash
|
||||
// Use as ets_printf(DRAM_STR("Hello world!\n"));
|
||||
#define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;}))
|
||||
|
||||
// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst"
|
||||
#define RTC_IRAM_ATTR __attribute__((section(".rtc.text")))
|
||||
|
||||
// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst"
|
||||
// Any variable marked with this attribute will keep its value
|
||||
// during a deep sleep / wake cycle.
|
||||
#define RTC_DATA_ATTR __attribute__((section(".rtc.data")))
|
||||
|
||||
// Forces read-only data into RTC slow memory. See "docs/deep-sleep-stub.rst"
|
||||
#define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata")))
|
||||
|
||||
// Forces data into noinit section to avoid initialization after restart.
|
||||
#define __NOINIT_ATTR __attribute__((section(".noinit")))
|
||||
|
||||
// Forces data into RTC slow memory of .noinit section.
|
||||
// Any variable marked with this attribute will keep its value
|
||||
// after restart or during a deep sleep / wake cycle.
|
||||
#define RTC_NOINIT_ATTR __attribute__((section(".rtc_noinit")))
|
||||
|
||||
#endif /* __ESP_ATTR_H__ */
|
@ -15,7 +15,7 @@
|
||||
#ifndef __ESP_INTR_H__
|
||||
#define __ESP_INTR_H__
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -80,7 +81,10 @@ extern "C" {
|
||||
// This is used to provide SystemView with positive IRQ IDs, otherwise sheduler events are not shown properly
|
||||
#define ETS_INTERNAL_INTR_SOURCE_OFF (-ETS_INTERNAL_PROFILING_INTR_SOURCE)
|
||||
|
||||
typedef void (*intr_handler_t)(void *arg);
|
||||
#define ESP_INTR_ENABLE(inum) xt_ints_on((1<<inum))
|
||||
#define ESP_INTR_DISABLE(inum) xt_ints_off((1<<inum))
|
||||
|
||||
typedef void (*intr_handler_t)(void *arg);
|
||||
|
||||
|
||||
typedef struct intr_handle_data_t intr_handle_data_t;
|
||||
@ -88,7 +92,7 @@ typedef intr_handle_data_t* intr_handle_t ;
|
||||
|
||||
/**
|
||||
* @brief Mark an interrupt as a shared interrupt
|
||||
*
|
||||
*
|
||||
* This will mark a certain interrupt on the specified CPU as
|
||||
* an interrupt that can be used to hook shared interrupt handlers
|
||||
* to.
|
||||
@ -105,7 +109,7 @@ esp_err_t esp_intr_mark_shared(int intno, int cpu, bool is_in_iram);
|
||||
|
||||
/**
|
||||
* @brief Reserve an interrupt to be used outside of this framework
|
||||
*
|
||||
*
|
||||
* This will mark a certain interrupt on the specified CPU as
|
||||
* reserved, not to be allocated for any reason.
|
||||
*
|
||||
@ -137,7 +141,7 @@ esp_err_t esp_intr_reserve(int intno, int cpu);
|
||||
* choice of interrupts that this routine can choose from. If this value
|
||||
* is 0, it will default to allocating a non-shared interrupt of level
|
||||
* 1, 2 or 3. If this is ESP_INTR_FLAG_SHARED, it will allocate a shared
|
||||
* interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return
|
||||
* interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return
|
||||
* from this function with the interrupt disabled.
|
||||
* @param handler The interrupt handler. Must be NULL when an interrupt of level >3
|
||||
* is requested, because these types of interrupts aren't C-callable.
|
||||
@ -158,7 +162,7 @@ esp_err_t esp_intr_alloc(int source, int flags, intr_handler_t handler, void *ar
|
||||
*
|
||||
*
|
||||
* This essentially does the same as esp_intr_alloc, but allows specifying a register and mask
|
||||
* combo. For shared interrupts, the handler is only called if a read from the specified
|
||||
* combo. For shared interrupts, the handler is only called if a read from the specified
|
||||
* register, ANDed with the mask, returns non-zero. By passing an interrupt status register
|
||||
* address and a fitting mask, this can be used to accelerate interrupt handling in the case
|
||||
* a shared interrupt is triggered; by checking the interrupt statuses first, the code can
|
||||
@ -171,7 +175,7 @@ esp_err_t esp_intr_alloc(int source, int flags, intr_handler_t handler, void *ar
|
||||
* choice of interrupts that this routine can choose from. If this value
|
||||
* is 0, it will default to allocating a non-shared interrupt of level
|
||||
* 1, 2 or 3. If this is ESP_INTR_FLAG_SHARED, it will allocate a shared
|
||||
* interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return
|
||||
* interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return
|
||||
* from this function with the interrupt disabled.
|
||||
* @param intrstatusreg The address of an interrupt status register
|
||||
* @param intrstatusmask A mask. If a read of address intrstatusreg has any of the bits
|
||||
@ -197,9 +201,9 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre
|
||||
* Use an interrupt handle to disable the interrupt and release the resources
|
||||
* associated with it.
|
||||
*
|
||||
* @note
|
||||
* When the handler shares its source with other handlers, the interrupt status
|
||||
* bits it's responsible for should be managed properly before freeing it. see
|
||||
* @note
|
||||
* When the handler shares its source with other handlers, the interrupt status
|
||||
* bits it's responsible for should be managed properly before freeing it. see
|
||||
* ``esp_intr_disable`` for more details.
|
||||
*
|
||||
* @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus
|
||||
@ -213,7 +217,7 @@ esp_err_t esp_intr_free(intr_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Get CPU number an interrupt is tied to
|
||||
*
|
||||
*
|
||||
* @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus
|
||||
*
|
||||
* @return The core number where the interrupt is allocated
|
||||
@ -222,7 +226,7 @@ int esp_intr_get_cpu(intr_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Get the allocated interrupt for a certain handle
|
||||
*
|
||||
*
|
||||
* @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus
|
||||
*
|
||||
* @return The interrupt number
|
||||
@ -231,13 +235,13 @@ int esp_intr_get_intno(intr_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Disable the interrupt associated with the handle
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* @note
|
||||
* 1. For local interrupts (ESP_INTERNAL_* sources), this function has to be called on the
|
||||
* CPU the interrupt is allocated on. Other interrupts have no such restriction.
|
||||
* 2. When several handlers sharing a same interrupt source, interrupt status bits, which are
|
||||
* 2. When several handlers sharing a same interrupt source, interrupt status bits, which are
|
||||
* handled in the handler to be disabled, should be masked before the disabling, or handled
|
||||
* in other enabled interrupts properly. Miss of interrupt status handling will cause infinite
|
||||
* in other enabled interrupts properly. Miss of interrupt status handling will cause infinite
|
||||
* interrupt calls and finally system crash.
|
||||
*
|
||||
* @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus
|
||||
|
@ -24,11 +24,10 @@
|
||||
#include "freertos/task.h"
|
||||
#include <esp_types.h>
|
||||
#include "esp_err.h"
|
||||
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#include "esp_log.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/soc.h"
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -1,253 +0,0 @@
|
||||
/* Default entry point: */
|
||||
ENTRY(call_start_cpu0);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* RTC fast memory holds RTC wake stub code,
|
||||
including from any source file named rtc_wake_stub*.c
|
||||
*/
|
||||
.rtc.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc.literal .rtc.text)
|
||||
*rtc_wake_stub*.o(.literal .text .literal.* .text.*)
|
||||
} > rtc_iram_seg
|
||||
|
||||
/* RTC slow memory holds RTC wake stub
|
||||
data/rodata, including from any source file
|
||||
named rtc_wake_stub*.c
|
||||
*/
|
||||
.rtc.data :
|
||||
{
|
||||
_rtc_data_start = ABSOLUTE(.);
|
||||
*(.rtc.data)
|
||||
*(.rtc.rodata)
|
||||
*rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > rtc_slow_seg
|
||||
|
||||
/* RTC bss, from any source file named rtc_wake_stub*.c */
|
||||
.rtc.bss (NOLOAD) :
|
||||
{
|
||||
_rtc_bss_start = ABSOLUTE(.);
|
||||
*rtc_wake_stub*.o(.bss .bss.*)
|
||||
*rtc_wake_stub*.o(COMMON)
|
||||
_rtc_bss_end = ABSOLUTE(.);
|
||||
} > rtc_slow_seg
|
||||
|
||||
/* This section holds data that should not be initialized at power up
|
||||
and will be retained during deep sleep. The section located in
|
||||
RTC SLOW Memory area. User data marked with RTC_NOINIT_ATTR will be placed
|
||||
into this section. See the file "esp_attr.h" for more information.
|
||||
*/
|
||||
.rtc_noinit (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_noinit_start = ABSOLUTE(.);
|
||||
*(.rtc_noinit .rtc_noinit.*)
|
||||
. = ALIGN(4) ;
|
||||
_rtc_noinit_end = ABSOLUTE(.);
|
||||
} > rtc_slow_seg
|
||||
|
||||
/* Send .iram0 code to iram */
|
||||
.iram0.vectors :
|
||||
{
|
||||
/* Vectors go to IRAM */
|
||||
_init_start = ABSOLUTE(.);
|
||||
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
|
||||
. = 0x0;
|
||||
KEEP(*(.WindowVectors.text));
|
||||
. = 0x180;
|
||||
KEEP(*(.Level2InterruptVector.text));
|
||||
. = 0x1c0;
|
||||
KEEP(*(.Level3InterruptVector.text));
|
||||
. = 0x200;
|
||||
KEEP(*(.Level4InterruptVector.text));
|
||||
. = 0x240;
|
||||
KEEP(*(.Level5InterruptVector.text));
|
||||
. = 0x280;
|
||||
KEEP(*(.DebugExceptionVector.text));
|
||||
. = 0x2c0;
|
||||
KEEP(*(.NMIExceptionVector.text));
|
||||
. = 0x300;
|
||||
KEEP(*(.KernelExceptionVector.text));
|
||||
. = 0x340;
|
||||
KEEP(*(.UserExceptionVector.text));
|
||||
. = 0x3C0;
|
||||
KEEP(*(.DoubleExceptionVector.text));
|
||||
. = 0x400;
|
||||
*(.*Vector.literal)
|
||||
|
||||
*(.UserEnter.literal);
|
||||
*(.UserEnter.text);
|
||||
. = ALIGN (16);
|
||||
*(.entry.text)
|
||||
*(.init.literal)
|
||||
*(.init)
|
||||
_init_end = ABSOLUTE(.);
|
||||
|
||||
/* This goes here, not at top of linker script, so addr2line finds it last,
|
||||
and uses it in preference to the first symbol in IRAM */
|
||||
_iram_start = ABSOLUTE(0);
|
||||
} > iram0_0_seg
|
||||
|
||||
.iram0.text :
|
||||
{
|
||||
/* Code marked as runnning out of IRAM */
|
||||
_iram_text_start = ABSOLUTE(.);
|
||||
*(.iram1 .iram1.*)
|
||||
*libfreertos.a:(.literal .text .literal.* .text.*)
|
||||
*libheap.a:multi_heap.o(.literal .text .literal.* .text.*)
|
||||
*libheap.a:multi_heap_poisoning.o(.literal .text .literal.* .text.*)
|
||||
*libesp32c.a:panic.o(.literal .text .literal.* .text.*)
|
||||
*libesp32c.a:core_dump.o(.literal .text .literal.* .text.*)
|
||||
*libapp_trace.a:(.literal .text .literal.* .text.*)
|
||||
*libxtensa-debug-module.a:eri.o(.literal .text .literal.* .text.*)
|
||||
*librtc.a:(.literal .text .literal.* .text.*)
|
||||
*libsoc.a:(.literal .text .literal.* .text.*)
|
||||
*libhal.a:(.literal .text .literal.* .text.*)
|
||||
*libgcc.a:lib2funcs.o(.literal .text .literal.* .text.*)
|
||||
*libspi_flash.a:spi_flash_rom_patch.o(.literal .text .literal.* .text.*)
|
||||
*libgcov.a:(.literal .text .literal.* .text.*)
|
||||
INCLUDE esp32.spiram.rom-functions-iram.ld
|
||||
_iram_text_end = ABSOLUTE(.);
|
||||
} > iram0_0_seg
|
||||
|
||||
.dram0.data :
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
*(.jcr)
|
||||
*(.dram1 .dram1.*)
|
||||
*libesp32c.a:panic.o(.rodata .rodata.*)
|
||||
*libphy.a:(.rodata .rodata.*)
|
||||
*libsoc.a:rtc_clk.o(.rodata .rodata.*)
|
||||
*libapp_trace.a:(.rodata .rodata.*)
|
||||
*libgcov.a:(.rodata .rodata.*)
|
||||
*libheap.a:multi_heap.o(.rodata .rodata.*)
|
||||
*libheap.a:multi_heap_poisoning.o(.rodata .rodata.*)
|
||||
INCLUDE esp32.spiram.rom-functions-dram.ld
|
||||
_data_end = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
} > dram0_0_seg
|
||||
|
||||
/*This section holds data that should not be initialized at power up.
|
||||
The section located in Internal SRAM memory region. The macro _NOINIT
|
||||
can be used as attribute to place data into this section.
|
||||
See the esp_attr.h file for more information.
|
||||
*/
|
||||
.noinit (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_noinit_start = ABSOLUTE(.);
|
||||
*(.noinit .noinit.*)
|
||||
. = ALIGN(4) ;
|
||||
_noinit_end = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
|
||||
/* Shared RAM */
|
||||
.dram0.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.share.mem)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
/* The heap starts right after end of this section */
|
||||
_heap_start = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
|
||||
.flash.rodata :
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
|
||||
*(.xt_except_table)
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
. = (. + 3) & ~ 3;
|
||||
__eh_frame = ABSOLUTE(.);
|
||||
KEEP(*(.eh_frame))
|
||||
. = (. + 7) & ~ 3;
|
||||
/* C++ constructor and destructor tables, properly ordered: */
|
||||
__init_array_start = ABSOLUTE(.);
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
/* C++ exception handlers table: */
|
||||
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
|
||||
*(.xt_except_desc)
|
||||
*(.gnu.linkonce.h.*)
|
||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
/* Literals are also RO data. */
|
||||
_lit4_start = ABSOLUTE(.);
|
||||
*(*.lit4)
|
||||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
_thread_local_start = ABSOLUTE(.);
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
} >drom0_0_seg
|
||||
|
||||
.flash.text :
|
||||
{
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
|
||||
/* Similar to _iram_start, this symbol goes here so it is
|
||||
resolved by addr2line in preference to the first symbol in
|
||||
the flash.text segment.
|
||||
*/
|
||||
_flash_cache_start = ABSOLUTE(0);
|
||||
} >iram0_2_seg
|
||||
}
|
@ -15,9 +15,9 @@ SECTIONS
|
||||
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
|
||||
_rtc_text_end = ABSOLUTE(.);
|
||||
} > rtc_iram_seg
|
||||
|
||||
|
||||
/*
|
||||
This section is required to skip rtc.text area because rtc_iram_seg and
|
||||
This section is required to skip rtc.text area because rtc_iram_seg and
|
||||
rtc_data_seg are reflect the same address space on different buses.
|
||||
*/
|
||||
.rtc.dummy :
|
||||
@ -28,8 +28,8 @@ SECTIONS
|
||||
_rtc_dummy_end = ABSOLUTE(.);
|
||||
} > rtc_data_seg
|
||||
|
||||
/* This section located in RTC FAST Memory area.
|
||||
It holds data marked with RTC_FAST_ATTR attribute.
|
||||
/* This section located in RTC FAST Memory area.
|
||||
It holds data marked with RTC_FAST_ATTR attribute.
|
||||
See the file "esp_attr.h" for more information.
|
||||
*/
|
||||
.rtc.force_fast :
|
||||
@ -45,7 +45,7 @@ SECTIONS
|
||||
data/rodata, including from any source file
|
||||
named rtc_wake_stub*.c and the data marked with
|
||||
RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
|
||||
The memory location of the data is dependent on
|
||||
The memory location of the data is dependent on
|
||||
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
|
||||
*/
|
||||
.rtc.data :
|
||||
@ -70,11 +70,11 @@ SECTIONS
|
||||
_rtc_bss_end = ABSOLUTE(.);
|
||||
} > rtc_data_location
|
||||
|
||||
/* This section holds data that should not be initialized at power up
|
||||
/* This section holds data that should not be initialized at power up
|
||||
and will be retained during deep sleep.
|
||||
User data marked with RTC_NOINIT_ATTR will be placed
|
||||
into this section. See the file "esp_attr.h" for more information.
|
||||
The memory location of the data is dependent on
|
||||
into this section. See the file "esp_attr.h" for more information.
|
||||
The memory location of the data is dependent on
|
||||
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
|
||||
*/
|
||||
.rtc_noinit (NOLOAD):
|
||||
@ -86,8 +86,8 @@ SECTIONS
|
||||
_rtc_noinit_end = ABSOLUTE(.);
|
||||
} > rtc_data_location
|
||||
|
||||
/* This section located in RTC SLOW Memory area.
|
||||
It holds data marked with RTC_SLOW_ATTR attribute.
|
||||
/* This section located in RTC SLOW Memory area.
|
||||
It holds data marked with RTC_SLOW_ATTR attribute.
|
||||
See the file "esp_attr.h" for more information.
|
||||
*/
|
||||
.rtc.force_slow :
|
||||
@ -100,17 +100,17 @@ SECTIONS
|
||||
} > rtc_slow_seg
|
||||
|
||||
/* Get size of rtc slow data based on rtc_data_location alias */
|
||||
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||
? (_rtc_force_slow_end - _rtc_data_start)
|
||||
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||
? (_rtc_force_slow_end - _rtc_data_start)
|
||||
: (_rtc_force_slow_end - _rtc_force_slow_start);
|
||||
|
||||
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||
? (_rtc_force_fast_end - _rtc_fast_start)
|
||||
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||
? (_rtc_force_fast_end - _rtc_fast_start)
|
||||
: (_rtc_noinit_end - _rtc_fast_start);
|
||||
|
||||
|
||||
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
|
||||
"RTC_SLOW segment data does not fit.")
|
||||
|
||||
|
||||
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
|
||||
"RTC_FAST segment data does not fit.")
|
||||
|
||||
@ -203,7 +203,7 @@ SECTIONS
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_noinit_start = ABSOLUTE(.);
|
||||
*(.noinit .noinit.*)
|
||||
*(.noinit .noinit.*)
|
||||
. = ALIGN(4) ;
|
||||
_noinit_end = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
@ -245,7 +245,7 @@ SECTIONS
|
||||
|
||||
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
|
||||
"DRAM segment data does not fit.")
|
||||
|
||||
|
||||
.flash.rodata :
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "esp_private/pm_impl.h"
|
||||
#include "esp_private/pm_trace.h"
|
||||
#include "esp_private/esp_timer_impl.h"
|
||||
#include "esp32/pm.h"
|
||||
#include "esp32s2beta/pm.h"
|
||||
|
||||
/* CCOMPARE update timeout, in CPU cycles. Any value above ~600 cycles will work
|
||||
* for the purpose of detecting a deadlock.
|
||||
@ -449,6 +449,24 @@ void esp_pm_impl_idle_hook()
|
||||
ESP_PM_TRACE_ENTER(IDLE, core_id);
|
||||
}
|
||||
|
||||
void esp_pm_impl_waiti()
|
||||
{
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
int core_id = xPortGetCoreID();
|
||||
if (s_skipped_light_sleep[core_id]) {
|
||||
asm("waiti 0");
|
||||
/* Interrupt took the CPU out of waiti and s_rtos_lock_handle[core_id]
|
||||
* is now taken. However since we are back to idle task, we can release
|
||||
* the lock so that vApplicationSleep can attempt to enter light sleep.
|
||||
*/
|
||||
esp_pm_impl_idle_hook();
|
||||
s_skipped_light_sleep[core_id] = false;
|
||||
}
|
||||
#else
|
||||
asm("waiti 0");
|
||||
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_pm_impl_isr_hook()
|
||||
{
|
||||
int core_id = xPortGetCoreID();
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "esp32s2beta/rom/cache.h"
|
||||
#include "esp32s2beta/rom/rtc.h"
|
||||
#include "esp32s2beta/rom/uart.h"
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
@ -365,3 +365,4 @@ void esp_chip_info(esp_chip_info_t* out_info)
|
||||
out_info->features = CHIP_FEATURE_WIFI_BGN;
|
||||
|
||||
// FIXME: other features?
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ esp_err_t esp_task_wdt_init(uint32_t timeout, bool panic)
|
||||
twdt_config->panic = panic;
|
||||
|
||||
//Register Interrupt and ISR
|
||||
ESP_ERROR_CHECK(esp_intr_alloc(ETS_TG0_WDT_LEVEL_INTR_SOURCE, 0, task_wdt_isr, NULL, &twdt_config->intr_handle))
|
||||
ESP_ERROR_CHECK(esp_intr_alloc(ETS_TG0_WDT_LEVEL_INTR_SOURCE, 0, task_wdt_isr, NULL, &twdt_config->intr_handle));
|
||||
|
||||
//Configure hardware timer
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
@ -227,7 +227,7 @@ esp_err_t esp_task_wdt_deinit()
|
||||
TIMERG0.wdt_config0.en=0; //Disable timer
|
||||
TIMERG0.wdt_wprotect=0; //Enable write protection
|
||||
|
||||
ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)) //Unregister interrupt
|
||||
ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)); //Unregister interrupt
|
||||
free(twdt_config); //Free twdt_config
|
||||
twdt_config = NULL;
|
||||
portEXIT_CRITICAL(&twdt_spinlock);
|
||||
@ -269,7 +269,7 @@ esp_err_t esp_task_wdt_add(TaskHandle_t handle)
|
||||
//If idle task, register the idle hook callback to appropriate core
|
||||
for(int i = 0; i < portNUM_PROCESSORS; i++){
|
||||
if(handle == xTaskGetIdleTaskHandleForCPU(i)){
|
||||
ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_hook_cb, i))
|
||||
ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_hook_cb, i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
if(IDF_TARGET STREQUAL "esp32s2beta")
|
||||
return()
|
||||
endif()
|
||||
set(COMPONENT_SRCS "esp_adc_cal.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
|
@ -16,9 +16,12 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
// Include SoC-specific definitions. Only ESP32 supported for now.
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/pm.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/pm.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "soc/frc_timer_reg.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -33,6 +32,11 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_private/esp_timer_impl.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
/* We abuse 'timer_arg' field of ETSTimer structure to hold a pointer to esp_timer */
|
||||
#define ESP_TIMER(p_ets_timer) ((esp_timer_handle_t) (p_ets_timer)->timer_arg)
|
||||
|
@ -8,7 +8,7 @@ set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS "private_include")
|
||||
|
||||
set(COMPONENT_REQUIRES log tcpip_adapter)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
if(IDF_TARGET STREQUAL "esp32")
|
||||
set(COMPONENT_PRIV_REQUIRES ethernet)
|
||||
endif()
|
||||
|
||||
|
@ -17,7 +17,9 @@
|
||||
#include "esp_event_legacy.h"
|
||||
#include "esp_wifi_types.h"
|
||||
#include "tcpip_adapter.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp_eth.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The purpose of this file is to provide an "esp_event_send_to_default_loop"
|
||||
@ -87,7 +89,7 @@ esp_err_t esp_event_send_to_default_loop(system_event_t *event)
|
||||
HANDLE_SYS_EVENT_ARG(WIFI, AP_STACONNECTED, sta_connected);
|
||||
HANDLE_SYS_EVENT_ARG(WIFI, AP_STADISCONNECTED, sta_disconnected);
|
||||
HANDLE_SYS_EVENT_ARG(WIFI, AP_PROBEREQRECVED, ap_probereqrecved);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/* Ethernet events */
|
||||
/* Some extra defines to fit the old naming scheme... */
|
||||
#define ETH_EVENT_ETH_START ETHERNET_EVENT_START
|
||||
@ -99,7 +101,7 @@ esp_err_t esp_event_send_to_default_loop(system_event_t *event)
|
||||
HANDLE_SYS_EVENT(ETH, ETH_STOP);
|
||||
HANDLE_SYS_EVENT(ETH, ETH_CONNECTED);
|
||||
HANDLE_SYS_EVENT(ETH, ETH_DISCONNECTED);
|
||||
|
||||
#endif
|
||||
/* IP events */
|
||||
HANDLE_SYS_EVENT_ARG(IP, STA_GOT_IP, got_ip);
|
||||
HANDLE_SYS_EVENT_ARG(IP, ETH_GOT_IP, got_ip);
|
||||
@ -119,9 +121,9 @@ typedef struct {
|
||||
int err;
|
||||
const char *reason;
|
||||
} wifi_reason_t;
|
||||
|
||||
|
||||
static const wifi_reason_t wifi_reason[] =
|
||||
{
|
||||
{
|
||||
{0, "other reason"},
|
||||
{WIFI_REASON_UNSPECIFIED, "unspecified"},
|
||||
{WIFI_REASON_AUTH_EXPIRE, "auth expire"},
|
||||
@ -150,9 +152,9 @@ static const wifi_reason_t wifi_reason[] =
|
||||
{WIFI_REASON_UNSUPP_RSN_IE_VERSION, "unsupported RSN IE version"},
|
||||
{WIFI_REASON_INVALID_RSN_IE_CAP, "invalid RSN IE capability"},
|
||||
{WIFI_REASON_802_1X_AUTH_FAILED, "802.1x auth failed"},
|
||||
{WIFI_REASON_CIPHER_SUITE_REJECTED, "cipher suite rejected"}
|
||||
{WIFI_REASON_CIPHER_SUITE_REJECTED, "cipher suite rejected"}
|
||||
};
|
||||
|
||||
|
||||
static const char* wifi_disconnect_reason_to_str(int err)
|
||||
{
|
||||
for (int i=0; i< sizeof(wifi_reason)/sizeof(wifi_reason[0]); i++){
|
||||
@ -277,6 +279,7 @@ static void esp_system_event_debug(const system_event_t* event)
|
||||
IP6_ADDR_BLOCK8(addr));
|
||||
break;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case SYSTEM_EVENT_ETH_START: {
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_START");
|
||||
break;
|
||||
@ -301,6 +304,7 @@ static void esp_system_event_debug(const system_event_t* event)
|
||||
IP2STR(&got_ip->ip_info.gw));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
ESP_LOGW(TAG, "unexpected system event %d!", event->event_id);
|
||||
break;
|
||||
|
@ -23,7 +23,7 @@ else()
|
||||
|
||||
register_component()
|
||||
|
||||
if (CONFIG_IDF_TARGET_ESP32)
|
||||
if (IDF_TARGET STREQUAL "esp32")
|
||||
set(scripts
|
||||
"esp32/ld/esp32.rom.ld"
|
||||
"esp32/ld/esp32.rom.libgcc.ld"
|
||||
@ -48,14 +48,12 @@ else()
|
||||
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.spiflash.ld")
|
||||
endif()
|
||||
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S2BETA)
|
||||
target_linker_script(${COMPONENT_LIB}
|
||||
"esp32s2beta/ld/esp32s2beta.rom.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.rom.nanofmt.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.rom.spiflash.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.spiram.rom-functions-dram.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.spiram.rom-functions-iram.ld")
|
||||
elseif(IDF_TARGET STREQUAL "esp32s2beta")
|
||||
set(scripts "esp32s2beta/ld/esp32s2beta.rom.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.rom.nanofmt.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.rom.spiflash.ld"
|
||||
"esp32s2beta/ld/esp32s2beta.rom.spiram_incompatible_fns.ld")
|
||||
target_linker_script(${COMPONENT_LIB} "${scripts}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -19,8 +19,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_AES_H_
|
||||
#define _ROM_AES_H_
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@ -61,5 +60,3 @@ void ets_aes_block(const void *input, void *output);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ROM_AES_H_ */
|
||||
|
@ -12,8 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_ETS_SYS_H_
|
||||
#define _ROM_ETS_SYS_H_
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@ -608,5 +607,3 @@ typedef enum {
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ROM_ETS_SYS_H_ */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -174,10 +175,10 @@ void set_rtc_memory_crc(void);
|
||||
/**
|
||||
* @brief Fetch entry from RTC memory and RTC STORE reg
|
||||
*
|
||||
* @param uint32_t * entry_addr : the address to save entry
|
||||
* @param uint32_t * entry_addr : the address to save entry
|
||||
*
|
||||
* @param RESET_REASON reset_reason : reset reason this time
|
||||
*
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void rtc_boot_control(uint32_t * entry_addr, RESET_REASON reset_reason);
|
||||
|
@ -22,7 +22,9 @@ if(NOT CONFIG_ESP32_NO_BLOBS)
|
||||
set(blobs coexist core espnow mesh net80211 phy pp rtc smartconfig wpa2 wpa wps)
|
||||
foreach(blob ${blobs})
|
||||
add_library(${blob} STATIC IMPORTED)
|
||||
set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}/lib${blob}.a)
|
||||
# set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}/lib${blob}.a)
|
||||
# ToDo: add lib_esp32s2beta in esp_wifi component
|
||||
set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_esp32/lib${blob}.a)
|
||||
target_link_libraries(${COMPONENT_LIB} ${blob})
|
||||
|
||||
foreach(_blob ${blobs})
|
||||
|
@ -15,8 +15,12 @@
|
||||
#include "soc/uart_periph.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "esp_core_dump_priv.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#endif
|
||||
|
||||
const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_uart";
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b4c418a5d90c94863b44c8661b9332cf229b08b7
|
||||
Subproject commit cd386661033d25521b1312cf7fa4699ff4719f77
|
@ -50,7 +50,7 @@ if(CONFIG_SECURE_BOOT_ENABLED AND
|
||||
endif()
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
set(ESPTOOLPY_ELF2IMAGE_OPTIONS --elf-sha256-offset 0xb0)
|
||||
# set(ESPTOOLPY_ELF2IMAGE_OPTIONS --elf-sha256-offset 0xb0)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
|
||||
|
@ -1,12 +1,14 @@
|
||||
set(COMPONENT_SRCS "emac_dev.c"
|
||||
"emac_main.c"
|
||||
"eth_phy/phy_common.c"
|
||||
"eth_phy/phy_lan8720.c"
|
||||
"eth_phy/phy_tlk110.c"
|
||||
"eth_phy/phy_ip101.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
if(IDF_TARGET STREQUAL "esp32")
|
||||
set(COMPONENT_SRCS "emac_dev.c"
|
||||
"emac_main.c"
|
||||
"eth_phy/phy_common.c"
|
||||
"eth_phy/phy_lan8720.c"
|
||||
"eth_phy/phy_tlk110.c"
|
||||
"eth_phy/phy_ip101.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES tcpip_adapter esp_event soc)
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES tcpip_adapter esp_event soc)
|
||||
|
||||
register_component()
|
||||
register_component()
|
||||
endif()
|
||||
|
@ -45,10 +45,10 @@
|
||||
#include "port.h"
|
||||
|
||||
/* ----------------------- Modbus includes ----------------------------------*/
|
||||
#include "sdkconfig.h"
|
||||
#include "mb.h"
|
||||
#include "mbport.h"
|
||||
#include "driver/timer.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "port_serial_slave.h"
|
||||
|
||||
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED
|
||||
@ -71,9 +71,17 @@ static void IRAM_ATTR vTimerGroupIsr(void *param)
|
||||
{
|
||||
// Retrieve the interrupt status and the counter value
|
||||
// from the timer that reported the interrupt
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st.val;
|
||||
#endif
|
||||
if (intr_status & BIT(usTimerIndex)) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
MB_TG[usTimerGroupIndex]->int_clr.val |= BIT(usTimerIndex);
|
||||
#endif
|
||||
(void)pxMBPortCBTimerExpired(); // Timer callback function
|
||||
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "mb_m.h"
|
||||
#include "mbport.h"
|
||||
#include "port_serial_master.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks
|
||||
#define MB_TICK_TIME_US (50) // 50uS = one tick for timer
|
||||
@ -69,10 +70,22 @@ static void IRAM_ATTR vTimerGroupIsr(void *param)
|
||||
{
|
||||
// Retrieve the interrupt status and the counter value
|
||||
// from the timer that reported the interrupt
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st.val;
|
||||
#endif
|
||||
if (intr_status & BIT(usTimerIndex)) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
MB_TG[usTimerGroupIndex]->int_clr.val |= BIT(usTimerIndex);
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].update = 1;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].update.update = 1;
|
||||
#endif
|
||||
(void)pxMBMasterPortCBTimerExpired(); // Timer expired callback function
|
||||
// Enable alarm
|
||||
MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN;
|
||||
|
@ -76,7 +76,7 @@
|
||||
/* ESP31 and ESP32 are dualcore processors. */
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
#define portNUM_PROCESSORS 2
|
||||
#else
|
||||
#else
|
||||
#define portNUM_PROCESSORS 1
|
||||
#endif
|
||||
|
||||
@ -117,7 +117,11 @@ int xt_clock_freq(void) __attribute__((deprecated));
|
||||
/* configASSERT behaviour */
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdlib.h> /* for abort() */
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FREERTOS_ASSERT_DISABLE)
|
||||
#define configASSERT(a) /* assertions disabled */
|
||||
@ -155,7 +159,7 @@ int xt_clock_freq(void) __attribute__((deprecated));
|
||||
* memory.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
|
@ -349,12 +349,14 @@ static inline unsigned portENTER_CRITICAL_NESTED() {
|
||||
* ESP32 (portMUX assertions would fail).
|
||||
*/
|
||||
static inline void uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) {
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
__asm__ __volatile__ (
|
||||
"WSR %2,SCOMPARE1 \n"
|
||||
"S32C1I %0, %1, 0 \n"
|
||||
:"=r"(*set)
|
||||
:"r"(addr), "r"(compare), "0"(*set)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +97,6 @@
|
||||
|
||||
#include "xtensa_rtos.h"
|
||||
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "soc/cpu.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
@ -109,6 +108,12 @@
|
||||
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
/* Defined in portasm.h */
|
||||
extern void _frxt_tick_timer_init(void);
|
||||
|
@ -78,8 +78,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
all the API functions to use the MPU wrappers. That should only be done when
|
||||
|
@ -70,13 +70,17 @@
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
all the API functions to use the MPU wrappers. That should only be done when
|
||||
task.h is included from an application file. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
#include "esp_newlib.h"
|
||||
#include "esp_debug_helpers.h"
|
||||
|
||||
|
@ -30,11 +30,16 @@ that are implemented in C.
|
||||
|
||||
|
||||
#ifdef XT_BOARD
|
||||
#include <xtensa/xtbsp.h>
|
||||
#include "xtensa/xtbsp.h"
|
||||
#endif
|
||||
|
||||
#include "xtensa_rtos.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "xtensa_rtos.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#endif
|
||||
|
||||
#ifdef XT_RTOS_TIMER_INT
|
||||
|
||||
|
@ -33,8 +33,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/portable.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_EXCEPTIONS
|
||||
|
||||
|
@ -16,7 +16,12 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <esp32/rom/ets_sys.h>
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/* Because malloc/free can happen inside an ISR context,
|
||||
|
@ -18,7 +18,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include "sdkconfig.h"
|
||||
#include <esp32/rom/ets_sys.h>
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -154,15 +158,15 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, .
|
||||
|
||||
/**
|
||||
* @brief Dump a buffer to the log at specified level.
|
||||
*
|
||||
*
|
||||
* The dump log shows just like the one below:
|
||||
*
|
||||
*
|
||||
* W (195) log_example: 0x3ffb4280 45 53 50 33 32 20 69 73 20 67 72 65 61 74 2c 20 |ESP32 is great, |
|
||||
* W (195) log_example: 0x3ffb4290 77 6f 72 6b 69 6e 67 20 61 6c 6f 6e 67 20 77 69 |working along wi|
|
||||
* W (205) log_example: 0x3ffb42a0 74 68 20 74 68 65 20 49 44 46 2e 00 |th the IDF..|
|
||||
*
|
||||
*
|
||||
* It is highly recommend to use terminals with over 102 text width.
|
||||
*
|
||||
*
|
||||
* @param tag description tag
|
||||
* @param buffer Pointer to the buffer array
|
||||
* @param buff_len length of buffer in bytes
|
||||
@ -287,7 +291,7 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, .
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
/** runtime macro to output logs at a specified level.
|
||||
*
|
||||
*
|
||||
* @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime.
|
||||
* @param level level of the output log.
|
||||
* @param format format of the output log. see ``printf``
|
||||
|
@ -1,3 +1,5 @@
|
||||
idf_build_get_property(idf_target IDF_TARGET)
|
||||
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "port/include" "mbedtls/include")
|
||||
set(COMPONENT_SRCS "mbedtls.c")
|
||||
set(COMPONENT_REQUIRES lwip)
|
||||
@ -79,16 +81,16 @@ set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls})
|
||||
set(mbedtls_targets mbedtls mbedcrypto mbedx509)
|
||||
|
||||
# Add port files to mbedtls targets
|
||||
target_sources(mbedtls PRIVATE "${COMPONENT_DIR}/port/esp_bignum.c"
|
||||
"${COMPONENT_DIR}/port/esp_hardware.c"
|
||||
target_sources(mbedtls PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
|
||||
"${COMPONENT_PATH}/port/esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha1.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha256.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha512.c"
|
||||
"${COMPONENT_DIR}/port/mbedtls_debug.c"
|
||||
"${COMPONENT_DIR}/port/net_sockets.c"
|
||||
"${COMPONENT_DIR}/port/esp32/aes.c"
|
||||
"${COMPONENT_DIR}/port/esp32/sha.c")
|
||||
"${COMPONENT_DIR}/port/${idf_target}/aes.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/sha.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/esp_bignum.c")
|
||||
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_mem.c")
|
||||
|
||||
foreach(target ${mbedtls_targets})
|
||||
@ -101,4 +103,4 @@ target_link_libraries(${COMPONENT_LIB} ${mbedtls_targets})
|
||||
# Catch usage of deprecated mbedTLS functions when building tests
|
||||
if(mbedtls_test IN_LIST BUILD_TEST_COMPONENTS)
|
||||
add_definitions(-DMBEDTLS_DEPRECATED_WARNING)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := port/include mbedtls/include
|
||||
|
||||
COMPONENT_SRCDIRS := mbedtls/library port port/esp32
|
||||
COMPONENT_SRCDIRS := mbedtls/library port port/$(IDF_TARGET)
|
||||
|
||||
COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "mbedtls/aes.h"
|
||||
#include "hwcrypto/aes.h"
|
||||
#include "esp32s2beta/aes.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include <sys/lock.h>
|
||||
|
613
components/mbedtls/port/esp32s2beta/esp_bignum.c
Normal file
613
components/mbedtls/port/esp32s2beta/esp_bignum.c
Normal file
@ -0,0 +1,613 @@
|
||||
/**
|
||||
* \brief Multi-precision integer library, ESP32C hardware accelerated parts
|
||||
*
|
||||
* based on mbedTLS implementation
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "esp32s2beta/rom/bigint.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_intr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/periph_defs.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
static const __attribute__((unused)) char *TAG = "bignum";
|
||||
|
||||
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
|
||||
#define biL (ciL << 3) /* bits in limb */
|
||||
|
||||
#if defined(CONFIG_MBEDTLS_MPI_USE_INTERRUPT)
|
||||
static SemaphoreHandle_t op_complete_sem;
|
||||
|
||||
static IRAM_ATTR void rsa_complete_isr(void *arg)
|
||||
{
|
||||
BaseType_t higher_woken;
|
||||
DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1);
|
||||
xSemaphoreGiveFromISR(op_complete_sem, &higher_woken);
|
||||
if (higher_woken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static void rsa_isr_initialise()
|
||||
{
|
||||
if (op_complete_sem == NULL) {
|
||||
op_complete_sem = xSemaphoreCreateBinary();
|
||||
esp_intr_alloc(ETS_RSA_INTR_SOURCE, 0, rsa_complete_isr, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MBEDTLS_MPI_USE_INTERRUPT */
|
||||
|
||||
static _lock_t mpi_lock;
|
||||
|
||||
void esp_mpi_acquire_hardware( void )
|
||||
{
|
||||
/* newlib locks lazy initialize on ESP-IDF */
|
||||
_lock_acquire(&mpi_lock);
|
||||
|
||||
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_CLK_EN_RSA);
|
||||
/* also clear reset on digital signature & secure boot, otherwise RSA is held in reset */
|
||||
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_RST_EN_RSA
|
||||
| DPORT_RST_EN_DIGITAL_SIGNATURE
|
||||
| DPORT_RST_EN_SECURE_BOOT);
|
||||
|
||||
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_MEM_PD);
|
||||
|
||||
while(DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) {
|
||||
}
|
||||
// Note: from enabling RSA clock to here takes about 1.3us
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
|
||||
rsa_isr_initialise();
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_mpi_release_hardware( void )
|
||||
{
|
||||
DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
|
||||
/* don't reset digital signature unit, as this resets AES also */
|
||||
DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA);
|
||||
DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
|
||||
|
||||
_lock_release(&mpi_lock);
|
||||
}
|
||||
|
||||
|
||||
/* Return the number of words actually used to represent an mpi
|
||||
number.
|
||||
*/
|
||||
static size_t mpi_words(const mbedtls_mpi *mpi)
|
||||
{
|
||||
for (size_t i = mpi->n; i > 0; i--) {
|
||||
if (mpi->p[i - 1] != 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'.
|
||||
|
||||
If num_words is higher than the number of words in the bignum then
|
||||
these additional words will be zeroed in the memory buffer.
|
||||
|
||||
As this function only writes to DPORT memory, no DPORT_STALL_OTHER_CPU_START()
|
||||
is required.
|
||||
*/
|
||||
static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words)
|
||||
{
|
||||
uint32_t *pbase = (uint32_t *)mem_base;
|
||||
uint32_t copy_words = num_words < mpi->n ? num_words : mpi->n;
|
||||
|
||||
/* Copy MPI data to memory block registers */
|
||||
for (int i = 0; i < copy_words; i++) {
|
||||
pbase[i] = mpi->p[i];
|
||||
}
|
||||
|
||||
/* Zero any remaining memory block data */
|
||||
for (int i = copy_words; i < num_words; i++) {
|
||||
pbase[i] = 0;
|
||||
}
|
||||
|
||||
/* Note: not executing memw here, can do it before we start a bignum operation */
|
||||
}
|
||||
|
||||
/* Read mbedTLS MPI bignum back from hardware memory block.
|
||||
|
||||
Reads num_words words from block.
|
||||
|
||||
Can return a failure result if fails to grow the MPI result.
|
||||
|
||||
Cannot be called inside DPORT_STALL_OTHER_CPU_START() (as may allocate memory).
|
||||
*/
|
||||
static inline int mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow(x, num_words) );
|
||||
|
||||
/* Copy data from memory block registers */
|
||||
esp_dport_access_read_buffer(x->p, mem_base, num_words);
|
||||
/* Zero any remaining limbs in the bignum, if the buffer is bigger
|
||||
than num_words */
|
||||
for(size_t i = num_words; i < x->n; i++) {
|
||||
x->p[i] = 0;
|
||||
}
|
||||
|
||||
asm volatile ("memw");
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1,
|
||||
* where B^-1(B-1) mod N=1. Actually, only the least significant part of
|
||||
* N' is needed, hence the definition N0'=N' mod b. We reproduce below the
|
||||
* simple algorithm from an article by Dusse and Kaliski to efficiently
|
||||
* find N0' from N0 and b
|
||||
*/
|
||||
static mbedtls_mpi_uint modular_inverse(const mbedtls_mpi *M)
|
||||
{
|
||||
int i;
|
||||
uint64_t t = 1;
|
||||
uint64_t two_2_i_minus_1 = 2; /* 2^(i-1) */
|
||||
uint64_t two_2_i = 4; /* 2^i */
|
||||
uint64_t N = M->p[0];
|
||||
|
||||
for (i = 2; i <= 32; i++) {
|
||||
if ((mbedtls_mpi_uint) N * t % two_2_i >= two_2_i_minus_1) {
|
||||
t += two_2_i_minus_1;
|
||||
}
|
||||
|
||||
two_2_i_minus_1 <<= 1;
|
||||
two_2_i <<= 1;
|
||||
}
|
||||
|
||||
return (mbedtls_mpi_uint)(UINT32_MAX - t + 1);
|
||||
}
|
||||
|
||||
/* Calculate Rinv = RR^2 mod M, where:
|
||||
*
|
||||
* R = b^n where b = 2^32, n=num_words,
|
||||
* R = 2^N (where N=num_bits)
|
||||
* RR = R^2 = 2^(2*N) (where N=num_bits=num_words*32)
|
||||
*
|
||||
* This calculation is computationally expensive (mbedtls_mpi_mod_mpi)
|
||||
* so caller should cache the result where possible.
|
||||
*
|
||||
* DO NOT call this function while holding esp_mpi_acquire_hardware().
|
||||
*
|
||||
*/
|
||||
static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words)
|
||||
{
|
||||
int ret;
|
||||
size_t num_bits = num_words * 32;
|
||||
mbedtls_mpi RR;
|
||||
mbedtls_mpi_init(&RR);
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&RR, num_bits * 2, 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(Rinv, &RR, M));
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&RR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Begin an RSA operation. op_reg specifies which 'START' register
|
||||
to write to.
|
||||
|
||||
Because the only DPORT operations here are writes,
|
||||
does not need protecting via DPORT_STALL_OTHER_CPU_START();
|
||||
*/
|
||||
static inline void start_op(uint32_t op_reg)
|
||||
{
|
||||
/* Clear interrupt status */
|
||||
DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1);
|
||||
|
||||
/* Note: above REG_WRITE includes a memw, so we know any writes
|
||||
to the memory blocks are also complete. */
|
||||
|
||||
DPORT_REG_WRITE(op_reg, 1);
|
||||
}
|
||||
|
||||
/* Wait for an RSA operation to complete.
|
||||
|
||||
This should NOT be called inside a DPORT_STALL_OTHER_CPU_START(), as it will stall the other CPU for an unacceptably long
|
||||
period (and - depending on config - may require interrupts enabled).
|
||||
*/
|
||||
static inline void wait_op_complete(uint32_t op_reg)
|
||||
{
|
||||
#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
|
||||
if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) {
|
||||
ESP_LOGE(TAG, "Timed out waiting for RSA operation (op_reg 0x%x int_reg 0x%x)",
|
||||
op_reg, DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG));
|
||||
abort(); /* indicates a fundamental problem with driver */
|
||||
}
|
||||
#else
|
||||
while(DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG) != 1)
|
||||
{ }
|
||||
|
||||
/* clear the interrupt */
|
||||
DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Z = (X * Y) mod M
|
||||
|
||||
Not an mbedTLS function
|
||||
*/
|
||||
int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M)
|
||||
{
|
||||
int ret;
|
||||
size_t m_words = mpi_words(M);
|
||||
mbedtls_mpi Rinv;
|
||||
mbedtls_mpi_uint Mprime;
|
||||
|
||||
size_t num_words = MAX(MAX(m_words, mpi_words(X)), mpi_words(Y));
|
||||
|
||||
if (num_words * 32 > 4096) {
|
||||
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
}
|
||||
|
||||
/* Calculate and load the first stage montgomery multiplication */
|
||||
mbedtls_mpi_init(&Rinv);
|
||||
MBEDTLS_MPI_CHK(calculate_rinv(&Rinv, M, m_words));
|
||||
Mprime = modular_inverse(M);
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1));
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, (uint32_t)Mprime);
|
||||
|
||||
/* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */
|
||||
mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, &Rinv, num_words);
|
||||
|
||||
/* Execute first stage montgomery multiplication */
|
||||
start_op(RSA_MOD_MULT_START_REG);
|
||||
|
||||
wait_op_complete(RSA_MOD_MULT_START_REG);
|
||||
|
||||
mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words);
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&Rinv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_MPI_EXP_MOD_ALT)
|
||||
|
||||
/*
|
||||
* Sliding-window exponentiation: Z = X^Y mod M (HAC 14.85)
|
||||
*
|
||||
* _Rinv is optional pre-calculated version of Rinv (via calculate_rinv()).
|
||||
*
|
||||
* (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv)
|
||||
*
|
||||
*/
|
||||
int mbedtls_mpi_exp_mod( mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi* Y, const mbedtls_mpi* M, mbedtls_mpi* _Rinv )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t x_words = mpi_words(X);
|
||||
size_t y_words = mpi_words(Y);
|
||||
size_t m_words = mpi_words(M);
|
||||
size_t num_words;
|
||||
|
||||
mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */
|
||||
mbedtls_mpi *Rinv; /* points to _Rinv (if not NULL) othwerwise &RR_new */
|
||||
mbedtls_mpi_uint Mprime;
|
||||
|
||||
/* "all numbers must be the same length", so choose longest number
|
||||
as cardinal length of operation...
|
||||
*/
|
||||
num_words = MAX(m_words, MAX(x_words, y_words));
|
||||
|
||||
if (num_words * 32 > 4096) {
|
||||
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
}
|
||||
|
||||
/* Determine RR pointer, either _RR for cached value
|
||||
or local RR_new */
|
||||
if (_Rinv == NULL) {
|
||||
mbedtls_mpi_init(&Rinv_new);
|
||||
Rinv = &Rinv_new;
|
||||
} else {
|
||||
Rinv = _Rinv;
|
||||
}
|
||||
if (Rinv->p == NULL) {
|
||||
MBEDTLS_MPI_CHK(calculate_rinv(Rinv, M, num_words));
|
||||
}
|
||||
|
||||
Mprime = modular_inverse(M);
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, num_words - 1);
|
||||
|
||||
/* Load M, X, Rinv, M-prime (M-prime is mod 2^32) */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words);
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime);
|
||||
|
||||
DPORT_REG_WRITE(RSA_CONSTANT_TIME_DISABLE_REG, 1);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 1);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_POS_REG, (y_words * 32) - 1);
|
||||
|
||||
start_op(RSA_MODEXP_START_REG);
|
||||
wait_op_complete(RSA_MODEXP_START_REG);
|
||||
|
||||
DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 0);
|
||||
DPORT_REG_WRITE(RSA_SEARCH_POS_REG, (m_words * 32) - 1);
|
||||
|
||||
ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, m_words);
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
cleanup:
|
||||
if (_Rinv == NULL) {
|
||||
mbedtls_mpi_free(&Rinv_new);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_MPI_EXP_MOD_ALT */
|
||||
|
||||
#if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */
|
||||
|
||||
static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words);
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t Y_bits, size_t words_result);
|
||||
|
||||
/* Z = X * Y */
|
||||
int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t bits_x, bits_y, words_x, words_y, words_mult, words_z;
|
||||
|
||||
/* Count words needed for X & Y in hardware */
|
||||
bits_x = mbedtls_mpi_bitlen(X);
|
||||
bits_y = mbedtls_mpi_bitlen(Y);
|
||||
|
||||
words_x = (bits_x + 7) / 8;
|
||||
words_y = (bits_y + 7) / 8;
|
||||
|
||||
/* Short-circuit eval if either argument is 0 or 1.
|
||||
|
||||
This is needed as the mpi modular division
|
||||
argument will sometimes call in here when one
|
||||
argument is too large for the hardware unit, but the other
|
||||
argument is zero or one.
|
||||
|
||||
This leaks some timing information, although overall there is a
|
||||
lot less timing variation than a software MPI approach.
|
||||
*/
|
||||
if (bits_x == 0 || bits_y == 0) {
|
||||
mbedtls_mpi_lset(Z, 0);
|
||||
return 0;
|
||||
}
|
||||
if (bits_x == 1) {
|
||||
ret = mbedtls_mpi_copy(Z, Y);
|
||||
Z->s *= X->s;
|
||||
return ret;
|
||||
}
|
||||
if (bits_y == 1) {
|
||||
ret = mbedtls_mpi_copy(Z, X);
|
||||
Z->s *= Y->s;
|
||||
return ret;
|
||||
}
|
||||
|
||||
words_mult = (words_x > words_y ? words_x : words_y);
|
||||
|
||||
/* Result Z has to have room for double the larger factor */
|
||||
words_z = words_mult * 2;
|
||||
|
||||
/* If either factor is over 2048 bits, we can't use the standard hardware multiplier
|
||||
(it assumes result is double longest factor, and result is max 4096 bits.)
|
||||
|
||||
However, we can fail over to mod_mult for up to 4096 bits of result (modulo
|
||||
multiplication doesn't have the same restriction, so result is simply the
|
||||
number of bits in X plus number of bits in in Y.)
|
||||
*/
|
||||
if (words_mult * 32 > 2048) {
|
||||
/* Calculate new length of Z */
|
||||
words_z = (bits_x + bits_y + 31) / 32;
|
||||
if (words_z * 32 <= 4096) {
|
||||
/* Note: it's possible to use mpi_mult_mpi_overlong
|
||||
for this case as well, but it's very slightly
|
||||
slower and requires a memory allocation.
|
||||
*/
|
||||
return mpi_mult_mpi_failover_mod_mult(Z, X, Y, words_z);
|
||||
} else {
|
||||
/* Still too long for the hardware unit... */
|
||||
if(bits_y > bits_x) {
|
||||
return mpi_mult_mpi_overlong(Z, X, Y, bits_y, words_z);
|
||||
} else {
|
||||
return mpi_mult_mpi_overlong(Z, Y, X, bits_x, words_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we can use the (faster) multiply hardware unit */
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
/* Copy X (right-extended) & Y (left-extended) to memory block */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, words_mult);
|
||||
mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + words_mult * 4, Y, words_mult);
|
||||
/* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block.
|
||||
This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware().
|
||||
*/
|
||||
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, 0);
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (words_z - 1));
|
||||
start_op(RSA_MULT_START_REG);
|
||||
|
||||
wait_op_complete(RSA_MULT_START_REG);
|
||||
|
||||
/* Read back the result */
|
||||
ret = mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, words_z);
|
||||
|
||||
Z->s = X->s * Y->s;
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Special-case of mbedtls_mpi_mult_mpi(), where we use hardware montgomery mod
|
||||
multiplication to calculate an mbedtls_mpi_mult_mpi result where either
|
||||
A or B are >2048 bits so can't use the standard multiplication method.
|
||||
|
||||
Result (A bits + B bits) must still be less than 4096 bits.
|
||||
|
||||
This case is simpler than the general case modulo multiply of
|
||||
esp_mpi_mul_mpi_mod() because we can control the other arguments:
|
||||
|
||||
* Modulus is chosen with M=(2^num_bits - 1) (ie M=R-1), so output
|
||||
isn't actually modulo anything.
|
||||
* Mprime and Rinv are therefore predictable as follows:
|
||||
Mprime = 1
|
||||
Rinv = 1
|
||||
|
||||
(See RSA Accelerator section in Technical Reference for more about Mprime, Rinv)
|
||||
*/
|
||||
static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Load coefficients to hardware */
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
/* M = 2^num_words - 1, so block is entirely FF */
|
||||
for(int i = 0; i < num_words; i++) {
|
||||
DPORT_REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX);
|
||||
}
|
||||
|
||||
/* Mprime = 1 */
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, 1);
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, num_words -1);
|
||||
|
||||
/* Load X & Y */
|
||||
mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words);
|
||||
mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words);
|
||||
|
||||
/* Rinv = 1 */
|
||||
DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1);
|
||||
for(int i = 1; i < num_words; i++) {
|
||||
DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0);
|
||||
}
|
||||
|
||||
start_op(RSA_MOD_MULT_START_REG);
|
||||
wait_op_complete(RSA_MOD_MULT_START_REG);
|
||||
|
||||
mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, num_words);
|
||||
|
||||
esp_mpi_release_hardware();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Deal with the case when X & Y are too long for the hardware unit, by splitting one operand
|
||||
into two halves.
|
||||
|
||||
Y must be the longer operand
|
||||
|
||||
Slice Y into Yp, Ypp such that:
|
||||
Yp = lower 'b' bits of Y
|
||||
Ypp = upper 'b' bits of Y (right shifted)
|
||||
|
||||
Such that
|
||||
Z = X * Y
|
||||
Z = X * (Yp + Ypp<<b)
|
||||
Z = (X * Yp) + (X * Ypp<<b)
|
||||
|
||||
Note that this function may recurse multiple times, if both X & Y
|
||||
are too long for the hardware multiplication unit.
|
||||
*/
|
||||
static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t bits_y, size_t words_result)
|
||||
{
|
||||
int ret = 0;
|
||||
mbedtls_mpi Ztemp;
|
||||
const size_t limbs_y = (bits_y + biL - 1) / biL;
|
||||
/* Rather than slicing in two on bits we slice on limbs (32 bit words) */
|
||||
const size_t limbs_slice = limbs_y / 2;
|
||||
/* Yp holds lower bits of Y (declared to reuse Y's array contents to save on copying) */
|
||||
const mbedtls_mpi Yp = {
|
||||
.p = Y->p,
|
||||
.n = limbs_slice,
|
||||
.s = Y->s
|
||||
};
|
||||
/* Ypp holds upper bits of Y, right shifted (also reuses Y's array contents) */
|
||||
const mbedtls_mpi Ypp = {
|
||||
.p = Y->p + limbs_slice,
|
||||
.n = limbs_y - limbs_slice,
|
||||
.s = Y->s
|
||||
};
|
||||
mbedtls_mpi_init(&Ztemp);
|
||||
|
||||
/* Grow Z to result size early, avoid interim allocations */
|
||||
mbedtls_mpi_grow(Z, words_result);
|
||||
|
||||
/* Get result Ztemp = Yp * X (need temporary variable Ztemp) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(&Ztemp, X, &Yp) );
|
||||
|
||||
/* Z = Ypp * Y */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(Z, X, &Ypp) );
|
||||
|
||||
/* Z = Z << b */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(Z, limbs_slice * biL) );
|
||||
|
||||
/* Z += Ztemp */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(Z, Z, &Ztemp) );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&Ztemp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_MPI_MUL_MPI_ALT */
|
||||
|
@ -31,8 +31,8 @@
|
||||
#include <byteswap.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "hwcrypto/sha.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp32s2beta/sha.h"
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#define ESP_AES_H
|
||||
|
||||
#include "esp_types.h"
|
||||
#include "rom/aes.h"
|
||||
#include "esp32s2beta/rom/aes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef _ESP_SHA_H_
|
||||
#define _ESP_SHA_H_
|
||||
|
||||
#include "rom/sha.h"
|
||||
#include "esp32s2beta/rom/sha.h"
|
||||
#include "esp_types.h"
|
||||
|
||||
/** @brief Low-level support functions for the hardware SHA engine
|
||||
|
@ -3048,13 +3048,13 @@ void _mdns_disable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protoc
|
||||
/**
|
||||
* @brief Dispatch interface changes based on system events
|
||||
*/
|
||||
static void _mdns_handle_system_event(esp_event_base_t event_base,
|
||||
static void _mdns_handle_system_event(esp_event_base_t event_base,
|
||||
int32_t event_id, tcpip_adapter_if_t interface)
|
||||
{
|
||||
if (!_mdns_server) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
tcpip_adapter_dhcp_status_t dcst;
|
||||
if (event_base == WIFI_EVENT) {
|
||||
switch(event_id) {
|
||||
@ -3079,7 +3079,9 @@ static void _mdns_handle_system_event(esp_event_base_t event_base,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (event_base == ETH_EVENT) {
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
else if (event_base == ETH_EVENT) {
|
||||
switch (event_id) {
|
||||
case ETHERNET_EVENT_CONNECTED:
|
||||
if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &dcst)) {
|
||||
@ -3095,15 +3097,19 @@ static void _mdns_handle_system_event(esp_event_base_t event_base,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (event_base == IP_EVENT) {
|
||||
}
|
||||
#endif
|
||||
else if (event_base == IP_EVENT) {
|
||||
switch (event_id) {
|
||||
case IP_EVENT_STA_GOT_IP:
|
||||
_mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4);
|
||||
_mdns_announce_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6, NULL, 0, true);
|
||||
break;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case IP_EVENT_ETH_GOT_IP:
|
||||
_mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4);
|
||||
break;
|
||||
#endif
|
||||
case IP_EVENT_GOT_IP6:
|
||||
_mdns_enable_pcb(interface, MDNS_IP_PROTOCOL_V6);
|
||||
_mdns_announce_pcb(interface, MDNS_IP_PROTOCOL_V4, NULL, 0, true);
|
||||
@ -3722,7 +3728,7 @@ static void _mdns_execute_action(mdns_action_t * action)
|
||||
|
||||
switch(action->type) {
|
||||
case ACTION_SYSTEM_EVENT:
|
||||
_mdns_handle_system_event(action->data.sys_event.event_base,
|
||||
_mdns_handle_system_event(action->data.sys_event.event_base,
|
||||
action->data.sys_event.event_id, action->data.sys_event.interface);
|
||||
break;
|
||||
case ACTION_HOSTNAME_SET:
|
||||
@ -4117,7 +4123,7 @@ esp_err_t mdns_handle_system_event(void *ctx, system_event_t *event)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
if (!_mdns_server) {
|
||||
@ -4139,7 +4145,7 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
|
||||
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
|
||||
free(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t mdns_init()
|
||||
@ -4168,17 +4174,17 @@ esp_err_t mdns_init()
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto free_lock;
|
||||
}
|
||||
|
||||
if ((err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) {
|
||||
goto free_event_handlers;
|
||||
}
|
||||
if ((err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) {
|
||||
goto free_event_handlers;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if ((err = esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) {
|
||||
goto free_event_handlers;
|
||||
}
|
||||
|
||||
#endif
|
||||
uint8_t i;
|
||||
ip6_addr_t tmp_addr6;
|
||||
tcpip_adapter_ip_info_t if_ip_info;
|
||||
@ -4208,7 +4214,9 @@ free_all_and_disable_pcbs:
|
||||
free_event_handlers:
|
||||
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler);
|
||||
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler);
|
||||
#endif
|
||||
vQueueDelete(_mdns_server->action_queue);
|
||||
free_lock:
|
||||
vSemaphoreDelete(_mdns_server->lock);
|
||||
@ -4256,7 +4264,9 @@ void mdns_free()
|
||||
vSemaphoreDelete(_mdns_server->lock);
|
||||
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler);
|
||||
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler);
|
||||
#endif
|
||||
free(_mdns_server);
|
||||
_mdns_server = NULL;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
/*
|
||||
* MDNS Server Networking -- private include
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "mdns.h"
|
||||
#include "mdns_private.h"
|
||||
@ -21,7 +21,9 @@
|
||||
#include "esp_system.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_event.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp_eth.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -22,20 +22,26 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/lock.h>
|
||||
#include <esp32/rom/rtc.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "esp_timer.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/frc_timer_reg.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/task.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "limits.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "esp32/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#include "esp32s2beta/rom/rtc.h"
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#if defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 )
|
||||
#define WITH_RTC 1
|
||||
|
@ -205,7 +205,7 @@ esp_err_t nvs_set_u32 (nvs_handle_t handle, const char* key, uint32_t value);
|
||||
esp_err_t nvs_set_i64 (nvs_handle_t handle, const char* key, int64_t value);
|
||||
esp_err_t nvs_set_u64 (nvs_handle_t handle, const char* key, uint64_t value);
|
||||
esp_err_t nvs_set_str (nvs_handle_t handle, const char* key, const char* value);
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief set variable length binary value for given key
|
||||
@ -282,7 +282,7 @@ esp_err_t nvs_get_i32 (nvs_handle_t handle, const char* key, int32_t* out_value)
|
||||
esp_err_t nvs_get_u32 (nvs_handle_t handle, const char* key, uint32_t* out_value);
|
||||
esp_err_t nvs_get_i64 (nvs_handle_t handle, const char* key, int64_t* out_value);
|
||||
esp_err_t nvs_get_u64 (nvs_handle_t handle, const char* key, uint64_t* out_value);
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief get value for given key
|
||||
|
@ -11,10 +11,13 @@ endif()
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS include)
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND COMPONENT_SRCS "src/memory_layout_utils.c"
|
||||
"src/lldesc.c src/hal/spi_hal.c"
|
||||
"src/hal/spi_hal_iram.c"
|
||||
"src/lldesc.c"
|
||||
"src/soc_include_legacy_warn.c")
|
||||
|
||||
if(IDF_TARGET STREQUAL "esp32")
|
||||
list(APPEND COMPONENT_SRCS "src/hal/spi_hal.c" "src/hal/spi_hal_iram.c")
|
||||
endif()
|
||||
|
||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
||||
endif()
|
||||
|
||||
|
66
components/soc/esp32s2beta/gpio_periph.c
Normal file
66
components/soc/esp32s2beta/gpio_periph.c
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright 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.
|
||||
|
||||
#include "soc/gpio_periph.h"
|
||||
|
||||
const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
|
||||
IO_MUX_GPIO0_REG,
|
||||
IO_MUX_GPIO1_REG,
|
||||
IO_MUX_GPIO2_REG,
|
||||
IO_MUX_GPIO3_REG,
|
||||
IO_MUX_GPIO4_REG,
|
||||
IO_MUX_GPIO5_REG,
|
||||
IO_MUX_GPIO6_REG,
|
||||
IO_MUX_GPIO7_REG,
|
||||
IO_MUX_GPIO8_REG,
|
||||
IO_MUX_GPIO9_REG,
|
||||
IO_MUX_GPIO10_REG,
|
||||
IO_MUX_GPIO11_REG,
|
||||
IO_MUX_GPIO12_REG,
|
||||
IO_MUX_GPIO13_REG,
|
||||
IO_MUX_GPIO14_REG,
|
||||
IO_MUX_GPIO15_REG,
|
||||
IO_MUX_GPIO16_REG,
|
||||
IO_MUX_GPIO17_REG,
|
||||
IO_MUX_GPIO18_REG,
|
||||
IO_MUX_GPIO19_REG,
|
||||
IO_MUX_GPIO20_REG,
|
||||
IO_MUX_GPIO21_REG,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
IO_MUX_GPIO26_REG,
|
||||
IO_MUX_GPIO27_REG,
|
||||
IO_MUX_GPIO28_REG,
|
||||
IO_MUX_GPIO29_REG,
|
||||
IO_MUX_GPIO30_REG,
|
||||
IO_MUX_GPIO31_REG,
|
||||
IO_MUX_GPIO32_REG,
|
||||
IO_MUX_GPIO33_REG,
|
||||
IO_MUX_GPIO34_REG,
|
||||
IO_MUX_GPIO35_REG,
|
||||
IO_MUX_GPIO36_REG,
|
||||
IO_MUX_GPIO37_REG,
|
||||
IO_MUX_GPIO38_REG,
|
||||
IO_MUX_GPIO39_REG,
|
||||
IO_MUX_GPIO40_REG,
|
||||
IO_MUX_GPIO41_REG,
|
||||
IO_MUX_GPIO42_REG,
|
||||
IO_MUX_GPIO43_REG,
|
||||
IO_MUX_GPIO44_REG,
|
||||
IO_MUX_GPIO45_REG,
|
||||
IO_MUX_GPIO46_REG,
|
||||
0,
|
||||
};
|
@ -23,11 +23,7 @@ typedef enum {
|
||||
PERIPH_LEDC_MODULE = 0,
|
||||
PERIPH_UART0_MODULE,
|
||||
PERIPH_UART1_MODULE,
|
||||
#ifdef CONFIG_CHIP_IS_ESP32
|
||||
PERIPH_UART2_MODULE,
|
||||
#else
|
||||
PERIPH_USB_MODULE,
|
||||
#endif
|
||||
PERIPH_I2C0_MODULE,
|
||||
PERIPH_I2C1_MODULE,
|
||||
PERIPH_I2S0_MODULE,
|
||||
|
34
components/soc/esp32s2beta/include/soc/sdio_slave_pins.h
Normal file
34
components/soc/esp32s2beta/include/soc/sdio_slave_pins.h
Normal file
@ -0,0 +1,34 @@
|
||||
// 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_SDIO_SLAVE_PINS_H_
|
||||
#define _SOC_SDIO_SLAVE_PINS_H_
|
||||
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 12
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 11
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 13
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 14
|
||||
#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 36
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD 35
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0 37
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1 38
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2 33
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3 34
|
||||
#define SDIO_SLAVE_SLOT1_FUNC 3
|
||||
|
||||
#endif /* _SOC_SDIO_SLAVE_PINS_H_ */
|
38
components/soc/esp32s2beta/include/soc/sdmmc_pins.h
Normal file
38
components/soc/esp32s2beta/include/soc/sdmmc_pins.h
Normal file
@ -0,0 +1,38 @@
|
||||
// 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_SDMMC_PINS_H_
|
||||
#define _SOC_SDMMC_PINS_H_
|
||||
|
||||
#define SDMMC_SLOT0_IOMUX_PIN_NUM_CLK 12
|
||||
#define SDMMC_SLOT0_IOMUX_PIN_NUM_CMD 11
|
||||
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D0 13
|
||||
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D1 14
|
||||
#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 36
|
||||
#define SDMMC_SLOT1_IOMUX_PIN_NUM_CMD 35
|
||||
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D0 37
|
||||
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D1 38
|
||||
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D2 33
|
||||
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D3 34
|
||||
#define SDMMC_SLOT1_FUNC 3
|
||||
|
||||
#endif /* _SOC_SDMMC_PINS_H_ */
|
@ -57,6 +57,8 @@
|
||||
|
||||
#define PRO_CPU_NUM (0)
|
||||
|
||||
#define SOC_MAX_CONTIGUOUS_RAM_SIZE 0x400000 ///< Largest span of contiguous memory (DRAM or IRAM) in the address space
|
||||
|
||||
#define DR_REG_SYSTEM_BASE 0x3f4c0000
|
||||
#define DR_REG_SENSITIVE_BASE 0x3f4c1000
|
||||
#define DR_REG_INTERRUPT_BASE 0x3f4c2000
|
||||
@ -123,7 +125,7 @@
|
||||
|
||||
//Registers Operation {{
|
||||
#define ETS_UNCACHED_ADDR(addr) (addr)
|
||||
#define ETS_CACHED_ADDR(addr) (addr)
|
||||
#define ETS_CACHED_ADDR(addr) (addr)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
|
20
components/soc/esp32s2beta/rtc_periph.c
Normal file
20
components/soc/esp32s2beta/rtc_periph.c
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 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.
|
||||
|
||||
#include "soc/rtc_periph.h"
|
||||
|
||||
//Reg,Mux,Fun,IE,Up,Down,Rtc_number
|
||||
const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = {
|
||||
0
|
||||
};
|
@ -13,4 +13,10 @@
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
<<<<<<< a7ae5416fbc96f364c1047b2de9ba426677e258b
|
||||
#include "soc/can_struct.h"
|
||||
=======
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "soc/can_struct.h"
|
||||
#endif
|
||||
>>>>>>> build and link hello-world for esp32s2beta
|
||||
|
@ -10,12 +10,14 @@ else() # not BOOTLOADER_BUILD
|
||||
"flash_mmap.c"
|
||||
"flash_ops.c"
|
||||
"partition.c"
|
||||
"spi_flash_rom_patch.c")
|
||||
"spi_flash_rom_patch.c"
|
||||
"${IDF_TARGET}/flash_ops_${IDF_TARGET}.c")
|
||||
set(COMPONENT_REQUIRES app_update)
|
||||
set(COMPONENT_PRIV_REQUIRES bootloader_support soc)
|
||||
endif()
|
||||
|
||||
set(COMPONENT_ADD_INCLUDEDIRS include)
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS ".")
|
||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
||||
|
||||
register_component()
|
||||
|
@ -20,8 +20,13 @@
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include <esp32/rom/spi_flash.h>
|
||||
#include <esp32/rom/cache.h>
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/spi_flash.h"
|
||||
#include "esp32s2beta/rom/cache.h"
|
||||
#endif
|
||||
#include <soc/soc.h>
|
||||
#include <soc/dport_reg.h>
|
||||
#include "sdkconfig.h"
|
||||
@ -31,6 +36,7 @@
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char* TAG = "spiflash";
|
||||
|
||||
static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state);
|
||||
static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state);
|
||||
@ -62,7 +68,7 @@ void spi_flash_op_unlock()
|
||||
}
|
||||
/*
|
||||
If you're going to modify this, keep in mind that while the flash caches of the pro and app
|
||||
cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine
|
||||
cpu are separate, the psram cache is *not*. If one of the CPUs returns from a flash routine
|
||||
with its cache enabled but the other CPUs cache is not enabled yet, you will have problems
|
||||
when accessing psram from the former CPU.
|
||||
*/
|
||||
@ -133,7 +139,7 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu()
|
||||
}
|
||||
// Kill interrupts that aren't located in IRAM
|
||||
esp_intr_noniram_disable();
|
||||
// This CPU executes this routine, with non-IRAM interrupts and the scheduler
|
||||
// This CPU executes this routine, with non-IRAM interrupts and the scheduler
|
||||
// disabled. The other CPU is spinning in the spi_flash_op_block_func task, also
|
||||
// with non-iram interrupts and the scheduler disabled. None of these CPUs will
|
||||
// touch external RAM or flash this way, so we can safely disable caches.
|
||||
@ -255,13 +261,19 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os()
|
||||
* function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to
|
||||
* Cache_Flush before Cache_Read_Enable, even if cached data was not modified.
|
||||
*/
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static const uint32_t cache_mask = DPORT_APP_CACHE_MASK_OPSDRAM | DPORT_APP_CACHE_MASK_DROM0 |
|
||||
DPORT_APP_CACHE_MASK_DRAM1 | DPORT_APP_CACHE_MASK_IROM0 |
|
||||
DPORT_APP_CACHE_MASK_IRAM1 | DPORT_APP_CACHE_MASK_IRAM0;
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
// static const uint32_t icache_mask = DPORT_PRO_ICACHE_MASK_DROM0 |DPORT_PRO_ICACHE_MASK_IROM0 |
|
||||
// DPORT_PRO_ICACHE_MASK_IRAM1 | DPORT_PRO_ICACHE_MASK_IRAM0;
|
||||
// static const uint32_t dcache_mask = DPORT_PRO_DCACHE_MASK_DRAM1 | DPORT_PRO_DCACHE_MASK_DRAM0 |
|
||||
// DPORT_PRO_DCACHE_MASK_DPORT | DPORT_PRO_DCACHE_MASK_DROM0;
|
||||
#endif
|
||||
static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t ret = 0;
|
||||
if (cpuid == 0) {
|
||||
ret |= DPORT_GET_PERI_REG_BITS2(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, 0);
|
||||
@ -269,33 +281,327 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_st
|
||||
;
|
||||
}
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 0, DPORT_PRO_CACHE_ENABLE_S);
|
||||
} else {
|
||||
}
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
else {
|
||||
ret |= DPORT_GET_PERI_REG_BITS2(DPORT_APP_CACHE_CTRL1_REG, cache_mask, 0);
|
||||
while (DPORT_GET_PERI_REG_BITS2(DPORT_APP_DCACHE_DBUG0_REG, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1) {
|
||||
;
|
||||
}
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 0, DPORT_APP_CACHE_ENABLE_S);
|
||||
}
|
||||
#endif
|
||||
*saved_state = ret;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
*saved_state = Cache_Suspend_ICache();
|
||||
if (!Cache_Drom0_Using_ICache()) {
|
||||
*(saved_state + 1) = Cache_Suspend_DCache();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (cpuid == 0) {
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 1, DPORT_PRO_CACHE_ENABLE_S);
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, saved_state, 0);
|
||||
} else {
|
||||
}
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
else {
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 1, DPORT_APP_CACHE_ENABLE_S);
|
||||
DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL1_REG, cache_mask, saved_state, 0);
|
||||
}
|
||||
#endif
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
Cache_Resume_ICache(saved_state);
|
||||
if (!Cache_Drom0_Using_ICache()) {
|
||||
Cache_Resume_DCache(s_flash_op_cache_state[1]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
IRAM_ATTR bool spi_flash_cache_enabled()
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
bool result = (DPORT_REG_GET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE) != 0);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
bool result = (DPORT_REG_GET_BIT(DPORT_PRO_ICACHE_CTRL_REG, DPORT_PRO_ICACHE_ENABLE) != 0);
|
||||
if (!Cache_Drom0_Using_ICache()) {
|
||||
result = result && (DPORT_REG_GET_BIT(DPORT_PRO_DCACHE_CTRL_REG, DPORT_PRO_DCACHE_ENABLE) != 0);
|
||||
}
|
||||
#endif
|
||||
#if portNUM_PROCESSORS == 2
|
||||
result = result && (DPORT_REG_GET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE) != 0);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
IRAM_ATTR void esp_config_instruction_cache_mode(void)
|
||||
{
|
||||
cache_size_t cache_size;
|
||||
cache_ways_t cache_ways;
|
||||
cache_line_size_t cache_line_size;
|
||||
|
||||
#if CONFIG_INSTRUCTION_CACHE_8KB
|
||||
Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID);
|
||||
cache_size = CACHE_SIZE_8KB;
|
||||
#else
|
||||
Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID);
|
||||
cache_size = CACHE_SIZE_16KB;
|
||||
#endif
|
||||
#if CONFIG_INSTRUCTION_CACHE_4WAYS
|
||||
cache_ways = CACHE_4WAYS_ASSOC;
|
||||
#else
|
||||
cache_ways = CACHE_8WAYS_ASSOC;
|
||||
#endif
|
||||
#if CONFIG_INSTRUCTION_CACHE_LINE_16B
|
||||
cache_line_size = CACHE_LINE_SIZE_16B;
|
||||
#elif CONFIG_INSTRUCTION_CACHE_LINE_32B
|
||||
cache_line_size = CACHE_LINE_SIZE_32B;
|
||||
#else
|
||||
cache_line_size = CACHE_LINE_SIZE_64B;
|
||||
#endif
|
||||
ESP_EARLY_LOGI(TAG, "Instruction cache \t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16,cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 2 : 64));
|
||||
Cache_Suspend_ICache();
|
||||
Cache_Set_ICache_Mode(cache_size, cache_ways, cache_line_size);
|
||||
Cache_Invalidate_ICache_All();
|
||||
Cache_Resume_ICache(0);
|
||||
}
|
||||
|
||||
IRAM_ATTR void esp_config_data_cache_mode(void)
|
||||
{
|
||||
cache_size_t cache_size;
|
||||
cache_ways_t cache_ways;
|
||||
cache_line_size_t cache_line_size;
|
||||
|
||||
#if CONFIG_INSTRUCTION_CACHE_8KB
|
||||
#if CONFIG_DATA_CACHE_8KB
|
||||
Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID);
|
||||
cache_size = CACHE_SIZE_8KB;
|
||||
#else
|
||||
Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_DCACHE_HIGH, CACHE_MEMORY_INVALID);
|
||||
cache_size = CACHE_SIZE_16KB;
|
||||
#endif
|
||||
#else
|
||||
#if CONFIG_DATA_CACHE_8KB
|
||||
Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID);
|
||||
cache_size = CACHE_SIZE_8KB;
|
||||
#else
|
||||
Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_DCACHE_HIGH);
|
||||
cache_size = CACHE_SIZE_16KB;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_DATA_CACHE_4WAYS
|
||||
cache_ways = CACHE_4WAYS_ASSOC;
|
||||
#else
|
||||
cache_ways = CACHE_8WAYS_ASSOC;
|
||||
#endif
|
||||
#if CONFIG_DATA_CACHE_LINE_16B
|
||||
cache_line_size = CACHE_LINE_SIZE_16B;
|
||||
#elif CONFIG_DATA_CACHE_LINE_32B
|
||||
cache_line_size = CACHE_LINE_SIZE_32B;
|
||||
#else
|
||||
cache_line_size = CACHE_LINE_SIZE_64B;
|
||||
#endif
|
||||
ESP_EARLY_LOGI(TAG, "Data cache \t\t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16, cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 2 : 64));
|
||||
Cache_Set_DCache_Mode(cache_size, cache_ways, cache_line_size);
|
||||
Cache_Invalidate_DCache_All();
|
||||
}
|
||||
|
||||
void esp_switch_rodata_to_dcache(void)
|
||||
{
|
||||
REG_CLR_BIT(DPORT_PRO_DCACHE_CTRL1_REG, DPORT_PRO_DCACHE_MASK_DROM0);
|
||||
Cache_Drom0_Source_DCache();
|
||||
MMU_Drom_ICache_Unmap();
|
||||
REG_SET_BIT(DPORT_PRO_ICACHE_CTRL1_REG, DPORT_PRO_ICACHE_MASK_DROM0);
|
||||
ESP_EARLY_LOGI(TAG, "Switch rodata load path to data cache.");
|
||||
}
|
||||
|
||||
static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache, bool dcache)
|
||||
{
|
||||
uint32_t i_autoload, d_autoload;
|
||||
if (icache) {
|
||||
i_autoload = Cache_Suspend_ICache();
|
||||
}
|
||||
if (dcache) {
|
||||
d_autoload = Cache_Suspend_DCache();
|
||||
}
|
||||
REG_SET_BIT(DPORT_PRO_CACHE_WRAP_AROUND_CTRL_REG, DPORT_PRO_CACHE_FLASH_WRAP_AROUND);
|
||||
if (icache) {
|
||||
Cache_Resume_ICache(i_autoload);
|
||||
}
|
||||
if (dcache) {
|
||||
Cache_Resume_DCache(d_autoload);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_SUPPORT
|
||||
static IRAM_ATTR void esp_enable_cache_spiram_wrap(bool icache, bool dcache)
|
||||
{
|
||||
uint32_t i_autoload, d_autoload;
|
||||
if (icache) {
|
||||
i_autoload = Cache_Suspend_ICache();
|
||||
}
|
||||
if (dcache) {
|
||||
d_autoload = Cache_Suspend_DCache();
|
||||
}
|
||||
REG_SET_BIT(DPORT_PRO_CACHE_WRAP_AROUND_CTRL_REG, DPORT_PRO_CACHE_SRAM_RD_WRAP_AROUND);
|
||||
if (icache) {
|
||||
Cache_Resume_ICache(i_autoload);
|
||||
}
|
||||
if (dcache) {
|
||||
Cache_Resume_DCache(d_autoload);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable)
|
||||
{
|
||||
int icache_wrap_size = 0, dcache_wrap_size = 0;
|
||||
int flash_wrap_sizes[2]={-1, -1}, spiram_wrap_sizes[2]={-1, -1};
|
||||
int flash_wrap_size = 0, spiram_wrap_size = 0;
|
||||
int flash_count = 0, spiram_count = 0;
|
||||
int i;
|
||||
bool flash_spiram_wrap_together, flash_support_wrap = true, spiram_support_wrap = true;
|
||||
if (icache_wrap_enable) {
|
||||
#if CONFIG_INSTRUCTION_CACHE_LINE_16B
|
||||
icache_wrap_size = 16;
|
||||
#elif CONFIG_INSTRUCTION_CACHE_LINE_32B
|
||||
icache_wrap_size = 32;
|
||||
#else
|
||||
icache_wrap_size = 64;
|
||||
#endif
|
||||
}
|
||||
if (dcache_wrap_enable) {
|
||||
#if CONFIG_DATA_CACHE_LINE_16B
|
||||
dcache_wrap_size = 16;
|
||||
#elif CONFIG_DATA_CACHE_LINE_32B
|
||||
dcache_wrap_size = 32;
|
||||
#else
|
||||
dcache_wrap_size = 64;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t instruction_use_spiram = 0;
|
||||
uint32_t rodata_use_spiram = 0;
|
||||
#if CONFIG_INSTRUCTION_USE_SPIRAM
|
||||
extern uint32_t esp_spiram_instruction_access_enabled();
|
||||
instruction_use_spiram = esp_spiram_instruction_access_enabled();
|
||||
#endif
|
||||
#if CONFIG_RODATA_USE_SPIRAM
|
||||
extern uint32_t esp_spiram_rodata_access_enabled();
|
||||
rodata_use_spiram = esp_spiram_rodata_access_enabled();
|
||||
#endif
|
||||
|
||||
if (instruction_use_spiram) {
|
||||
spiram_wrap_sizes[0] = icache_wrap_size;
|
||||
} else {
|
||||
flash_wrap_sizes[0] = icache_wrap_size;
|
||||
}
|
||||
if (rodata_use_spiram) {
|
||||
if (Cache_Drom0_Using_ICache()) {
|
||||
spiram_wrap_sizes[0] = icache_wrap_size;
|
||||
} else {
|
||||
spiram_wrap_sizes[1] = dcache_wrap_size;
|
||||
}
|
||||
#ifdef CONFIG_EXT_RODATA_SUPPORT
|
||||
spiram_wrap_sizes[1] = dcache_wrap_size;
|
||||
#endif
|
||||
} else {
|
||||
if (Cache_Drom0_Using_ICache()) {
|
||||
flash_wrap_sizes[0] = icache_wrap_size;
|
||||
} else {
|
||||
flash_wrap_sizes[1] = dcache_wrap_size;
|
||||
}
|
||||
#ifdef CONFIG_EXT_RODATA_SUPPORT
|
||||
flash_wrap_sizes[1] = dcache_wrap_size;
|
||||
#endif
|
||||
}
|
||||
#ifdef CONFIG_SPIRAM_SUPPORT
|
||||
spiram_wrap_sizes[1] = dcache_wrap_size;
|
||||
#endif
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (flash_wrap_sizes[i] != -1) {
|
||||
flash_count++;
|
||||
flash_wrap_size = flash_wrap_sizes[i];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (spiram_wrap_sizes[i] != -1) {
|
||||
spiram_count++;
|
||||
spiram_wrap_size = spiram_wrap_sizes[i];
|
||||
}
|
||||
}
|
||||
if (flash_count + spiram_count <= 2) {
|
||||
flash_spiram_wrap_together = false;
|
||||
} else {
|
||||
flash_spiram_wrap_together = true;
|
||||
}
|
||||
if (flash_count > 1 && flash_wrap_sizes[0] != flash_wrap_sizes[1]) {
|
||||
ESP_EARLY_LOGW(TAG, "Flash wrap with different length %d and %d, abort wrap.", flash_wrap_sizes[0], flash_wrap_sizes[1]);
|
||||
if (spiram_wrap_size == 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (flash_spiram_wrap_together) {
|
||||
ESP_EARLY_LOGE(TAG, "Abort spiram wrap because flash wrap length not fixed.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
if (spiram_count > 1 && spiram_wrap_sizes[0] != spiram_wrap_sizes[1]) {
|
||||
ESP_EARLY_LOGW(TAG, "SPIRAM wrap with different length %d and %d, abort wrap.", spiram_wrap_sizes[0], spiram_wrap_sizes[1]);
|
||||
if (flash_wrap_size == 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (flash_spiram_wrap_together) {
|
||||
ESP_EARLY_LOGW(TAG, "Abort flash wrap because spiram wrap length not fixed.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (flash_spiram_wrap_together && flash_wrap_size != spiram_wrap_size) {
|
||||
ESP_EARLY_LOGW(TAG, "SPIRAM has different wrap length with flash, %d and %d, abort wrap.", spiram_wrap_size, flash_wrap_size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
extern bool spi_flash_support_wrap_size(uint32_t wrap_size);
|
||||
if (!spi_flash_support_wrap_size(flash_wrap_size)) {
|
||||
flash_support_wrap = false;
|
||||
ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPIRAM_SUPPORT
|
||||
extern bool psram_support_wrap_size(uint32_t wrap_size);
|
||||
if (!psram_support_wrap_size(spiram_wrap_size)) {
|
||||
spiram_support_wrap = false;
|
||||
ESP_EARLY_LOGW(TAG, "SPIRAM do not support wrap size %d.", spiram_wrap_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flash_spiram_wrap_together && !(flash_support_wrap && spiram_support_wrap)) {
|
||||
ESP_EARLY_LOGW(TAG, "Flash and SPIRAM should support wrap together.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size);
|
||||
if (flash_support_wrap && flash_wrap_size > 0) {
|
||||
ESP_EARLY_LOGI(TAG, "Flash wrap enabled.");
|
||||
spi_flash_enable_wrap(flash_wrap_size);
|
||||
esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0));
|
||||
}
|
||||
#if CONFIG_SPIRAM_SUPPORT
|
||||
extern esp_err_t psram_enable_wrap(uint32_t wrap_size);
|
||||
if (spiram_support_wrap && spiram_wrap_size > 0) {
|
||||
ESP_EARLY_LOGI(TAG, "SPIRAM wrap enabled.");
|
||||
psram_enable_wrap(spiram_wrap_size);
|
||||
esp_enable_cache_spiram_wrap((spiram_wrap_sizes[0] > 0), (spiram_wrap_sizes[1] > 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -54,4 +54,12 @@ void spi_flash_enable_interrupts_caches_no_os();
|
||||
// Returns true if cache was flushed, false otherwise
|
||||
bool spi_flash_check_and_flush_cache(uint32_t start_addr, uint32_t length);
|
||||
|
||||
//config cache mode
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
void esp_config_instruction_cache_mode(void);
|
||||
void esp_config_data_cache_mode(void);
|
||||
void esp_switch_rodata_to_dcache(void);
|
||||
#endif
|
||||
|
||||
|
||||
#endif //ESP_SPI_FLASH_CACHE_UTILS_H
|
||||
|
@ -1,5 +1,6 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
|
||||
COMPONENT_SRCDIRS := . $(IDF_TARGET)
|
||||
COMPONENT_PRIV_INCLUDEDIRS := .
|
||||
COMPONENT_ADD_LDFRAGMENTS += linker.lf
|
||||
|
||||
ifdef IS_BOOTLOADER_BUILD
|
||||
|
87
components/spi_flash/esp32/flash_ops_esp32.c
Normal file
87
components/spi_flash/esp32/flash_ops_esp32.c
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 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.
|
||||
|
||||
#include "esp_spi_flash_chip.h"
|
||||
#include "cache_utils.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/cache.h"
|
||||
|
||||
static inline void IRAM_ATTR spi_flash_guard_start()
|
||||
{
|
||||
spi_flash_guard_funcs_t *ops = spi_flash_guard_get();
|
||||
if (ops && s_ops->start) {
|
||||
ops->start();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void IRAM_ATTR spi_flash_guard_end()
|
||||
{
|
||||
spi_flash_guard_funcs_t *ops = spi_flash_guard_get();
|
||||
if (ops && s_ops->end) {
|
||||
ops->end();
|
||||
}
|
||||
}
|
||||
|
||||
esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size)
|
||||
{
|
||||
const uint8_t *ssrc = (const uint8_t *)src;
|
||||
esp_rom_spiflash_result_t rc;
|
||||
rc = spi_flash_unlock();
|
||||
if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
return rc;
|
||||
}
|
||||
/* esp_rom_spiflash_write_encrypted encrypts data in RAM as it writes,
|
||||
so copy to a temporary buffer - 32 bytes at a time.
|
||||
|
||||
Each call to esp_rom_spiflash_write_encrypted takes a 32 byte "row" of
|
||||
data to encrypt, and each row is two 16 byte AES blocks
|
||||
that share a key (as derived from flash address).
|
||||
*/
|
||||
uint8_t encrypt_buf[32] __attribute__((aligned(4)));
|
||||
uint32_t row_size;
|
||||
for (size_t i = 0; i < size; i += row_size) {
|
||||
uint32_t row_addr = dest_addr + i;
|
||||
if (i == 0 && (row_addr % 32) != 0) {
|
||||
/* writing to second block of a 32 byte row */
|
||||
row_size = 16;
|
||||
row_addr -= 16;
|
||||
/* copy to second block in buffer */
|
||||
memcpy(encrypt_buf + 16, ssrc + i, 16);
|
||||
/* decrypt the first block from flash, will reencrypt to same bytes */
|
||||
spi_flash_read_encrypted(row_addr, encrypt_buf, 16);
|
||||
} else if (size - i == 16) {
|
||||
/* 16 bytes left, is first block of a 32 byte row */
|
||||
row_size = 16;
|
||||
/* copy to first block in buffer */
|
||||
memcpy(encrypt_buf, ssrc + i, 16);
|
||||
/* decrypt the second block from flash, will reencrypt to same bytes */
|
||||
spi_flash_read_encrypted(row_addr + 16, encrypt_buf + 16, 16);
|
||||
} else {
|
||||
/* Writing a full 32 byte row (2 blocks) */
|
||||
row_size = 32;
|
||||
memcpy(encrypt_buf, ssrc + i, 32);
|
||||
}
|
||||
|
||||
spi_flash_guard_start();
|
||||
rc = esp_rom_spiflash_write_encrypted(row_addr, (uint32_t *)encrypt_buf, 32);
|
||||
spi_flash_guard_end();
|
||||
if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
bzero(encrypt_buf, sizeof(encrypt_buf));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
65
components/spi_flash/esp32s2beta/flash_ops_esp32s2beta.c
Normal file
65
components/spi_flash/esp32s2beta/flash_ops_esp32s2beta.c
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 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.
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_spi_flash_chip.h"
|
||||
#include "cache_utils.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
#include "esp32s2beta/rom/spi_flash.h"
|
||||
#include "esp32s2beta/rom/cache.h"
|
||||
|
||||
esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size)
|
||||
{
|
||||
const spi_flash_guard_funcs_t *ops = spi_flash_guard_get();
|
||||
esp_rom_spiflash_result_t rc;
|
||||
|
||||
if (!esp_ptr_internal(src)) {
|
||||
uint8_t block[128]; // Need to buffer in RAM as we write
|
||||
while (size > 0) {
|
||||
size_t next_block = MIN(size, sizeof(block));
|
||||
memcpy(block, src, next_block);
|
||||
|
||||
esp_rom_spiflash_result_t r = spi_flash_write_encrypted_chip(dest_addr, block, next_block);
|
||||
if (r != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
return r;
|
||||
}
|
||||
|
||||
size -= next_block;
|
||||
dest_addr += next_block;
|
||||
src = ((uint8_t *)src) + next_block;
|
||||
}
|
||||
bzero(block, sizeof(block));
|
||||
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
}
|
||||
else { // Already in internal memory
|
||||
rc = spi_flash_unlock();
|
||||
if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ops && ops->start) {
|
||||
ops->start();
|
||||
}
|
||||
rc = SPI_Encrypt_Write(dest_addr, src, size);
|
||||
if (ops && ops->end) {
|
||||
ops->end();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
29
components/spi_flash/esp_spi_flash_chip.h
Normal file
29
components/spi_flash/esp_spi_flash_chip.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 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.
|
||||
|
||||
/* Private header with chip-specific routines for SPI flash interaction */
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/spi_flash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/spi_flash.h"
|
||||
#endif
|
||||
|
||||
esp_rom_spiflash_result_t spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size);
|
||||
|
||||
esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock();
|
||||
|
@ -20,8 +20,6 @@
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
#include <esp32/rom/spi_flash.h>
|
||||
#include <esp32/rom/cache.h>
|
||||
#include <soc/soc.h>
|
||||
#include <soc/dport_reg.h>
|
||||
#include <soc/soc_memory_layout.h>
|
||||
@ -32,7 +30,15 @@
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_log.h"
|
||||
#include "cache_utils.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/spi_flash.h"
|
||||
#include "esp32/rom/cache.h"
|
||||
#include "esp32/spiram.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/spi_flash.h"
|
||||
#include "esp32s2beta/rom/cache.h"
|
||||
#include "esp32s2beta/spiram.h"
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Enable built-in checks in queue.h in debug builds
|
||||
@ -40,13 +46,29 @@
|
||||
#endif
|
||||
#include "sys/queue.h"
|
||||
|
||||
#define REGIONS_COUNT 4
|
||||
#define PAGES_PER_REGION 64
|
||||
#define INVALID_ENTRY_VAL 0x100
|
||||
#define VADDR0_START_ADDR 0x3F400000
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define REGIONS_COUNT 4
|
||||
#define IROM0_PAGES_START 64
|
||||
#define IROM0_PAGES_END 256
|
||||
#define DROM0_PAGES_START 0
|
||||
#define DROM0_PAGES_END 64
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define REGIONS_COUNT 8
|
||||
#define IROM0_PAGES_START (PRO_CACHE_IBUS0_MMU_START / sizeof(uint32_t))
|
||||
#define IROM0_PAGES_END (PRO_CACHE_IBUS2_MMU_END / sizeof(uint32_t))
|
||||
#define DROM0_PAGES_START (Cache_Drom0_Using_ICache()? PRO_CACHE_IBUS3_MMU_START / sizeof(uint32_t) : PRO_CACHE_DBUS3_MMU_START /sizeof(uint32_t))
|
||||
#define DROM0_PAGES_END (Cache_Drom0_Using_ICache()? PRO_CACHE_IBUS3_MMU_END / sizeof(uint32_t) : PRO_CACHE_DBUS3_MMU_END / sizeof(uint32_t))
|
||||
#endif
|
||||
#define MMU_ADDR_MASK DPORT_MMU_ADDRESS_MASK
|
||||
#define IROM0_PAGES_NUM (IROM0_PAGES_END - IROM0_PAGES_START)
|
||||
#define DROM0_PAGES_NUM (DROM0_PAGES_END - DROM0_PAGES_START)
|
||||
#define PAGES_LIMIT (IROM0_PAGES_END > DROM0_PAGES_END ? IROM0_PAGES_END:DROM0_PAGES_END)
|
||||
#define INVALID_ENTRY_VAL DPORT_FLASH_MMU_TABLE_INVALID_VAL
|
||||
#define VADDR0_START_ADDR SOC_DROM_LOW
|
||||
#define VADDR1_START_ADDR 0x40000000
|
||||
#define VADDR1_FIRST_USABLE_ADDR 0x400D0000
|
||||
#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + 64)
|
||||
#define VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW
|
||||
#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START)
|
||||
|
||||
typedef struct mmap_entry_{
|
||||
uint32_t handle;
|
||||
@ -70,6 +92,7 @@ static void IRAM_ATTR spi_flash_mmap_init()
|
||||
DPORT_INTERRUPT_DISABLE();
|
||||
for (int i = 0; i < REGIONS_COUNT * PAGES_PER_REGION; ++i) {
|
||||
uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]);
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]);
|
||||
|
||||
if (entry_pro != entry_app) {
|
||||
@ -77,11 +100,14 @@ static void IRAM_ATTR spi_flash_mmap_init()
|
||||
entry_pro = DPORT_FLASH_MMU_TABLE_INVALID_VAL;
|
||||
DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL;
|
||||
}
|
||||
if ((entry_pro & INVALID_ENTRY_VAL) == 0 && (i == 0 || i == PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) {
|
||||
#endif
|
||||
if ((entry_pro & INVALID_ENTRY_VAL) == 0 && (i == DROM0_PAGES_START || i == PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) {
|
||||
s_mmap_page_refcnt[i] = 1;
|
||||
} else {
|
||||
DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL;
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
DPORT_APP_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
DPORT_INTERRUPT_RESTORE();
|
||||
@ -91,13 +117,13 @@ static void IRAM_ATTR get_mmu_region(spi_flash_mmap_memory_t memory, int* out_be
|
||||
{
|
||||
if (memory == SPI_FLASH_MMAP_DATA) {
|
||||
// Vaddr0
|
||||
*out_begin = 0;
|
||||
*out_size = 64;
|
||||
*out_begin = DROM0_PAGES_START;
|
||||
*out_size = DROM0_PAGES_NUM;
|
||||
*region_addr = VADDR0_START_ADDR;
|
||||
} else {
|
||||
// only part of VAddr1 is usable, so adjust for that
|
||||
*out_begin = PRO_IRAM0_FIRST_USABLE_PAGE;
|
||||
*out_size = 3 * 64 - *out_begin;
|
||||
*out_size = IROM0_PAGES_END - *out_begin;
|
||||
*region_addr = VADDR1_FIRST_USABLE_ADDR;
|
||||
}
|
||||
}
|
||||
@ -121,7 +147,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
for (int i = 0; i < page_count; i++) {
|
||||
pages[i] = phys_page+i;
|
||||
pages[i] = (phys_page+i) | DPORT_MMU_ACCESS_FLASH;
|
||||
}
|
||||
ret = spi_flash_mmap_pages(pages, page_count, memory, out_ptr, out_handle);
|
||||
free(pages);
|
||||
@ -140,7 +166,7 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
for (int i = 0; i < page_count; i++) {
|
||||
if (pages[i] < 0 || pages[i]*SPI_FLASH_MMU_PAGE_SIZE >= g_rom_flashchip.chip_size) {
|
||||
if (pages[i] < 0 || (pages[i] & MMU_ADDR_MASK)*SPI_FLASH_MMU_PAGE_SIZE >= g_rom_flashchip.chip_size) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
@ -196,14 +222,25 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
|
||||
for (int i = start; i != start + page_count; ++i, ++pageno) {
|
||||
// sanity check: we won't reconfigure entries with non-zero reference count
|
||||
uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]);
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]);
|
||||
#endif
|
||||
assert(s_mmap_page_refcnt[i] == 0 ||
|
||||
(entry_pro == pages[pageno] &&
|
||||
entry_app == pages[pageno]));
|
||||
(entry_pro == pages[pageno]
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
&& entry_app == pages[pageno]
|
||||
#endif
|
||||
));
|
||||
if (s_mmap_page_refcnt[i] == 0) {
|
||||
if (entry_pro != pages[pageno] || entry_app != pages[pageno]) {
|
||||
if (entry_pro != pages[pageno]
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
|| entry_app != pages[pageno]
|
||||
#endif
|
||||
) {
|
||||
DPORT_PRO_FLASH_MMU_TABLE[i] = pages[pageno];
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
DPORT_APP_FLASH_MMU_TABLE[i] = pages[pageno];
|
||||
#endif
|
||||
need_flush = true;
|
||||
}
|
||||
}
|
||||
@ -227,10 +264,24 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp
|
||||
*/
|
||||
if (need_flush) {
|
||||
#if CONFIG_ESP32_SPIRAM_SUPPORT
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_spiram_writeback_cache();
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
Cache_Flush(0);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
Cache_Invalidate_ICache_All();
|
||||
if (!Cache_Drom0_Using_ICache()) {
|
||||
#if CONFIG_SPIRAM_SUPPORT
|
||||
Cache_WriteBack_All();
|
||||
#endif
|
||||
Cache_Invalidate_DCache_All();
|
||||
}
|
||||
#endif
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
Cache_Flush(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
@ -254,7 +305,9 @@ void IRAM_ATTR spi_flash_munmap(spi_flash_mmap_handle_t handle)
|
||||
assert(s_mmap_page_refcnt[i] > 0);
|
||||
if (--s_mmap_page_refcnt[i] == 0) {
|
||||
DPORT_PRO_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL;
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
LIST_REMOVE(it, entries);
|
||||
@ -327,16 +380,15 @@ uint32_t spi_flash_cache2phys(const void *cached)
|
||||
if (c >= VADDR1_START_ADDR && c < VADDR1_FIRST_USABLE_ADDR) {
|
||||
/* IRAM address, doesn't map to flash */
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
else if (c < VADDR1_FIRST_USABLE_ADDR) {
|
||||
} else if (c < VADDR1_FIRST_USABLE_ADDR) {
|
||||
/* expect cache is in DROM */
|
||||
cache_page = (c - VADDR0_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE;
|
||||
cache_page = (c - VADDR0_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + DROM0_PAGES_START;
|
||||
} else {
|
||||
/* expect cache is in IROM */
|
||||
cache_page = (c - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + 64;
|
||||
cache_page = (c - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START;
|
||||
}
|
||||
|
||||
if (cache_page >= 256) {
|
||||
if (cache_page >= PAGES_LIMIT) {
|
||||
/* cached address was not in IROM or DROM */
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
@ -345,7 +397,7 @@ uint32_t spi_flash_cache2phys(const void *cached)
|
||||
/* page is not mapped */
|
||||
return SPI_FLASH_CACHE2PHYS_FAIL;
|
||||
}
|
||||
uint32_t phys_offs = phys_page * SPI_FLASH_MMU_PAGE_SIZE;
|
||||
uint32_t phys_offs = (phys_page & MMU_ADDR_MASK)* SPI_FLASH_MMU_PAGE_SIZE;
|
||||
return phys_offs | (c & (SPI_FLASH_MMU_PAGE_SIZE-1));
|
||||
}
|
||||
|
||||
@ -356,15 +408,15 @@ const void *IRAM_ATTR spi_flash_phys2cache(uint32_t phys_offs, spi_flash_mmap_me
|
||||
intptr_t base;
|
||||
|
||||
if (memory == SPI_FLASH_MMAP_DATA) {
|
||||
start = 0;
|
||||
end = 64;
|
||||
start = DROM0_PAGES_START;
|
||||
end = DROM0_PAGES_END;
|
||||
base = VADDR0_START_ADDR;
|
||||
page_delta = 0;
|
||||
page_delta = DROM0_PAGES_START > IROM0_PAGES_START ? DROM0_PAGES_START : 0;
|
||||
} else {
|
||||
start = PRO_IRAM0_FIRST_USABLE_PAGE;
|
||||
end = 256;
|
||||
end = IROM0_PAGES_END;
|
||||
base = VADDR1_START_ADDR;
|
||||
page_delta = 64;
|
||||
page_delta = DROM0_PAGES_START > IROM0_PAGES_START ? 0: IROM0_PAGES_START;
|
||||
}
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
DPORT_INTERRUPT_DISABLE();
|
||||
@ -421,12 +473,14 @@ IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length)
|
||||
}
|
||||
|
||||
if (is_page_mapped_in_cache(page)) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if CONFIG_ESP32_SPIRAM_SUPPORT
|
||||
esp_spiram_writeback_cache();
|
||||
#endif
|
||||
Cache_Flush(0);
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
Cache_Flush(1);
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -30,11 +30,18 @@
|
||||
#include "esp_ipc.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_spi_flash_chip.h"
|
||||
#include "esp_log.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#endif
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "cache_utils.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/* bytes erased by SPIEraseBlock() ROM function */
|
||||
#define BLOCK_ERASE_SIZE 65536
|
||||
@ -184,7 +191,7 @@ static inline void IRAM_ATTR spi_flash_guard_op_unlock()
|
||||
}
|
||||
}
|
||||
|
||||
static esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock()
|
||||
esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock()
|
||||
{
|
||||
static bool unlocked = false;
|
||||
if (!unlocked) {
|
||||
@ -420,7 +427,6 @@ out:
|
||||
esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size)
|
||||
{
|
||||
CHECK_WRITE_ADDRESS(dest_addr, size);
|
||||
const uint8_t *ssrc = (const uint8_t *)src;
|
||||
if ((dest_addr % 16) != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@ -430,49 +436,7 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src,
|
||||
|
||||
COUNTER_START();
|
||||
esp_rom_spiflash_result_t rc;
|
||||
rc = spi_flash_unlock();
|
||||
if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
/* esp_rom_spiflash_write_encrypted encrypts data in RAM as it writes,
|
||||
so copy to a temporary buffer - 32 bytes at a time.
|
||||
|
||||
Each call to esp_rom_spiflash_write_encrypted takes a 32 byte "row" of
|
||||
data to encrypt, and each row is two 16 byte AES blocks
|
||||
that share a key (as derived from flash address).
|
||||
*/
|
||||
uint8_t encrypt_buf[32] __attribute__((aligned(4)));
|
||||
uint32_t row_size;
|
||||
for (size_t i = 0; i < size; i += row_size) {
|
||||
uint32_t row_addr = dest_addr + i;
|
||||
if (i == 0 && (row_addr % 32) != 0) {
|
||||
/* writing to second block of a 32 byte row */
|
||||
row_size = 16;
|
||||
row_addr -= 16;
|
||||
/* copy to second block in buffer */
|
||||
memcpy(encrypt_buf + 16, ssrc + i, 16);
|
||||
/* decrypt the first block from flash, will reencrypt to same bytes */
|
||||
spi_flash_read_encrypted(row_addr, encrypt_buf, 16);
|
||||
} else if (size - i == 16) {
|
||||
/* 16 bytes left, is first block of a 32 byte row */
|
||||
row_size = 16;
|
||||
/* copy to first block in buffer */
|
||||
memcpy(encrypt_buf, ssrc + i, 16);
|
||||
/* decrypt the second block from flash, will reencrypt to same bytes */
|
||||
spi_flash_read_encrypted(row_addr + 16, encrypt_buf + 16, 16);
|
||||
} else {
|
||||
/* Writing a full 32 byte row (2 blocks) */
|
||||
row_size = 32;
|
||||
memcpy(encrypt_buf, ssrc + i, 32);
|
||||
}
|
||||
|
||||
spi_flash_guard_start();
|
||||
rc = esp_rom_spiflash_write_encrypted(row_addr, (uint32_t *)encrypt_buf, 32);
|
||||
spi_flash_guard_end();
|
||||
if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
bzero(encrypt_buf, sizeof(encrypt_buf));
|
||||
}
|
||||
rc = spi_flash_write_encrypted_chip(dest_addr, src, size);
|
||||
COUNTER_ADD_BYTES(write, size);
|
||||
COUNTER_STOP(write);
|
||||
|
||||
@ -689,3 +653,76 @@ void spi_flash_dump_counters()
|
||||
}
|
||||
|
||||
#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define SPICACHE SPIMEM0
|
||||
#define SPIFLASH SPIMEM1
|
||||
#define FLASH_WRAP_CMD 0x77
|
||||
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
|
||||
{
|
||||
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
|
||||
uint32_t reg_bkp_usr = SPIFLASH.user.val;
|
||||
SPIFLASH.user.fwrite_dio = 0;
|
||||
SPIFLASH.user.fwrite_dual = 0;
|
||||
SPIFLASH.user.fwrite_qio = 1;
|
||||
SPIFLASH.user.fwrite_quad = 0;
|
||||
SPIFLASH.ctrl.fcmd_dual = 0;
|
||||
SPIFLASH.ctrl.fcmd_quad = 0;
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user.usr_addr = 1;
|
||||
SPIFLASH.user.usr_command = 1;
|
||||
SPIFLASH.user2.usr_command_bitlen = 7;
|
||||
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
|
||||
SPIFLASH.user1.usr_addr_bitlen = 23;
|
||||
SPIFLASH.addr = 0;
|
||||
SPIFLASH.user.usr_miso = 0;
|
||||
SPIFLASH.user.usr_mosi = 1;
|
||||
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
|
||||
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
|
||||
SPIFLASH.cmd.usr = 1;
|
||||
while(SPIFLASH.cmd.usr != 0)
|
||||
{ }
|
||||
|
||||
SPIFLASH.ctrl.val = reg_bkp_ctrl;
|
||||
SPIFLASH.user.val = reg_bkp_usr;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
|
||||
{
|
||||
switch(wrap_size) {
|
||||
case 8:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_8B);
|
||||
case 16:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_16B);
|
||||
case 32:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_32B);
|
||||
case 64:
|
||||
return spi_flash_wrap_set(FLASH_WRAP_MODE_64B);
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
void spi_flash_disable_wrap()
|
||||
{
|
||||
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
|
||||
}
|
||||
|
||||
bool spi_flash_support_wrap_size(uint32_t wrap_size)
|
||||
{
|
||||
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)){
|
||||
return ESP_FAIL;
|
||||
}
|
||||
switch(wrap_size) {
|
||||
case 0:
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -33,10 +33,28 @@ extern "C" {
|
||||
|
||||
#define SPI_FLASH_MMU_PAGE_SIZE 0x10000 /**< Flash cache MMU mapping page size */
|
||||
|
||||
typedef enum {
|
||||
FLASH_WRAP_MODE_8B = 0,
|
||||
FLASH_WRAP_MODE_16B = 2,
|
||||
FLASH_WRAP_MODE_32B = 4,
|
||||
FLASH_WRAP_MODE_64B = 6,
|
||||
FLASH_WRAP_MODE_DISABLE = 1
|
||||
} spi_flash_wrap_mode_t;
|
||||
|
||||
/**
|
||||
* @brief set wrap mode of flash
|
||||
*
|
||||
* @param spi_flash_wrap_mode_t mode: wrap mode support disable, 16 32, 64 byte
|
||||
*
|
||||
* @return esp_err_t : ESP_OK for successful.
|
||||
*
|
||||
*/
|
||||
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Initialize SPI flash access driver
|
||||
*
|
||||
* This function must be called exactly once, before any other
|
||||
* This function must be called exactly once, before any other
|
||||
* spi_flash_* functions are called.
|
||||
* Currently this function is called from startup code. There is
|
||||
* no need to call it from application code.
|
||||
|
@ -11,11 +11,16 @@
|
||||
// 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 "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp32/rom/gpio.h"
|
||||
#include "esp32/rom/spi_flash.h"
|
||||
#include "sdkconfig.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/rom/ets_sys.h"
|
||||
#include "esp32s2beta/rom/gpio.h"
|
||||
#include "esp32s2beta/rom/spi_flash.h"
|
||||
#endif
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
|
||||
@ -27,12 +32,18 @@ extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//wait for spi control ready
|
||||
while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) {
|
||||
}
|
||||
while ((REG_READ(SPI_EXT2_REG(0)) & SPI_ST)) {
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) {
|
||||
}
|
||||
while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) {
|
||||
}
|
||||
#endif
|
||||
//wait for flash status ready
|
||||
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_status(spi, &status)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
@ -69,12 +80,21 @@ esp_rom_spiflash_result_t esp_rom_spiflash_unlock()
|
||||
status &= ESP_ROM_SPIFLASH_QE;
|
||||
|
||||
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
|
||||
while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WREN);
|
||||
while (REG_READ(SPI_MEM_CMD_REG(SPI_IDX)) != 0) {
|
||||
}
|
||||
#endif
|
||||
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(SPI_IDX), SPI_MEM_WRSR_2B);
|
||||
#endif
|
||||
if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
}
|
||||
@ -96,7 +116,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_sp
|
||||
esp_rom_spiflash_wait_idle(spi);
|
||||
|
||||
// Chip erase.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_CE);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_CE);
|
||||
#endif
|
||||
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
|
||||
// check erase is finished.
|
||||
@ -117,7 +141,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector_internal(esp_rom_
|
||||
|
||||
// sector erase 4Kbytes erase is sector erase.
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_SE);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_SE);
|
||||
#endif
|
||||
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
|
||||
esp_rom_spiflash_wait_idle(spi);
|
||||
@ -132,7 +160,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_block_internal(esp_rom_s
|
||||
|
||||
// sector erase 4Kbytes erase is sector erase.
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_BE);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_BE);
|
||||
#endif
|
||||
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
|
||||
esp_rom_spiflash_wait_idle(spi);
|
||||
@ -186,8 +218,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_
|
||||
}
|
||||
temp_bl = 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_PP);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_PP);
|
||||
#endif
|
||||
while ( READ_PERI_REG(PERIPHS_SPI_FLASH_CMD ) != 0 );
|
||||
|
||||
esp_rom_spiflash_wait_idle(spi);
|
||||
@ -218,9 +253,15 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chi
|
||||
while (temp_length > 0) {
|
||||
if (temp_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) {
|
||||
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << ESP_ROM_SPIFLASH_BYTES_LEN));
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S);
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
|
||||
#endif
|
||||
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
|
||||
for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM >> 2); i++) {
|
||||
@ -231,8 +272,13 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chi
|
||||
} else {
|
||||
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(temp_length << ESP_ROM_SPIFLASH_BYTES_LEN ));
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
|
||||
#endif
|
||||
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
|
||||
remain_word_num = (0 == (temp_length & 0x3)) ? (temp_length >> 2) : (temp_length >> 2) + 1;
|
||||
@ -253,7 +299,11 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *
|
||||
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
|
||||
while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); // clear regisrter
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_RDSR);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDSR);
|
||||
#endif
|
||||
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
|
||||
status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS) & (spi->status_mask);
|
||||
@ -283,7 +333,11 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t
|
||||
|
||||
// update status value by status_value
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, status_value); // write status regisrter
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WRSR);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WRSR);
|
||||
#endif
|
||||
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
esp_rom_spiflash_wait_idle(spi);
|
||||
|
||||
@ -297,7 +351,11 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_
|
||||
esp_rom_spiflash_wait_idle(spi);
|
||||
|
||||
//enable write
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WREN); // enable write operation
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WREN); // enable write operation
|
||||
#endif
|
||||
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
|
||||
|
||||
// make sure the flash is ready for writing
|
||||
@ -310,6 +368,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_
|
||||
|
||||
static void spi_cache_mode_switch(uint32_t modebit)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) {
|
||||
REG_CLR_BIT(SPI_USER_REG(0), SPI_USR_MOSI);
|
||||
REG_SET_BIT(SPI_USER_REG(0), SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR);
|
||||
@ -345,7 +404,43 @@ static void spi_cache_mode_switch(uint32_t modebit)
|
||||
REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0x03);
|
||||
}
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
|
||||
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
|
||||
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_QIO_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
|
||||
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xEB);
|
||||
} else if (modebit & SPI_MEM_FASTRD_MODE) {
|
||||
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
|
||||
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_FAST_ADDR_BITSLEN);
|
||||
if ((modebit & SPI_MEM_FREAD_QUAD)) {
|
||||
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x6B);
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
|
||||
} else if ((modebit & SPI_MEM_FREAD_DIO)) {
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_DIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
|
||||
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xBB);
|
||||
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
|
||||
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x3B);
|
||||
} else{
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
|
||||
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x0B);
|
||||
}
|
||||
} else {
|
||||
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
|
||||
if (g_rom_spiflash_dummy_len_plus[0] == 0) {
|
||||
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
|
||||
} else {
|
||||
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[0] - 1);
|
||||
}
|
||||
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
|
||||
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x03);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_lock()
|
||||
@ -374,27 +469,50 @@ esp_rom_spiflash_result_t esp_rom_spiflash_lock()
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode)
|
||||
{
|
||||
uint32_t modebit;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) {
|
||||
}
|
||||
while ((REG_READ(SPI_EXT2_REG(0)) & SPI_ST)) {
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) {
|
||||
}
|
||||
while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) {
|
||||
}
|
||||
#endif
|
||||
//clear old mode bit
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE);
|
||||
CLEAR_PERI_REG_MASK(SPI_CTRL_REG(0), SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
|
||||
CLEAR_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
|
||||
#endif
|
||||
//configure read mode
|
||||
switch (mode) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_FREAD_QIO | SPI_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_FREAD_QUAD | SPI_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_FREAD_DIO | SPI_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_FREAD_DUAL | SPI_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_FASTRD_MODE; break;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_MEM_FREAD_QIO | SPI_MEM_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_MEM_FREAD_QUAD | SPI_MEM_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_MEM_FREAD_DIO | SPI_MEM_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE; break;
|
||||
case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_MEM_FASTRD_MODE; break;
|
||||
#endif
|
||||
case ESP_ROM_SPIFLASH_SLOWRD_MODE: modebit = 0; break;
|
||||
default : modebit = 0;
|
||||
}
|
||||
|
||||
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SET_PERI_REG_MASK(SPI_CTRL_REG(0), modebit);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), modebit);
|
||||
#endif
|
||||
spi_cache_mode_switch(modebit);
|
||||
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
@ -416,9 +534,13 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip()
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num)
|
||||
{
|
||||
// flash write is always 1 line currently
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
|
||||
#endif
|
||||
//check program size
|
||||
if (block_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.block_size))) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
@ -437,9 +559,13 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num)
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num)
|
||||
{
|
||||
// flash write is always 1 line currently
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
|
||||
#endif
|
||||
//check program size
|
||||
if (sector_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.sector_size))) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
@ -463,9 +589,13 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t
|
||||
uint8_t i;
|
||||
|
||||
// flash write is always 1 line currently
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
|
||||
#endif
|
||||
//check program size
|
||||
if ( (target + len) > (g_rom_spiflash_chip.chip_size)) {
|
||||
return ESP_ROM_SPIFLASH_RESULT_ERR;
|
||||
@ -503,6 +633,7 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t
|
||||
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len)
|
||||
{
|
||||
esp_rom_spiflash_result_t ret = ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
@ -528,13 +659,14 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_addr, int32_t len)
|
||||
{
|
||||
// QIO or SIO, non-QIO regard as SIO
|
||||
uint32_t modebit;
|
||||
modebit = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) {
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI);
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR);
|
||||
@ -546,17 +678,44 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI);
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_ADDR);
|
||||
if (modebit & SPI_FREAD_DIO) {
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_QIO_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
|
||||
//REG_SET_FIELD(PERIPHS_SPI_SPI_MEM_H_USRREG2, SPI_USR_COMMAND_VALUE, 0xEB);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xEB);
|
||||
} else if (modebit & SPI_MEM_FASTRD_MODE) {
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
|
||||
if (modebit & SPI_MEM_FREAD_DIO) {
|
||||
#endif
|
||||
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0xBB);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xBB);
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0xBB);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_MEM_USR_COMMAND_VALUE, 0xBB);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if ((modebit & SPI_FREAD_QUAD)) {
|
||||
//REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x6B);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x6B);
|
||||
@ -570,8 +729,21 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if ((modebit & SPI_MEM_FREAD_QUAD)) {
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x6B);
|
||||
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x3B);
|
||||
} else {
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x0B);
|
||||
}
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI);
|
||||
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||
@ -583,6 +755,18 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN);
|
||||
//REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x03);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x03);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
|
||||
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
|
||||
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
} else {
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
|
||||
}
|
||||
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
|
||||
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN);
|
||||
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x03);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_data(&g_rom_spiflash_chip, target, dest_addr, len)) {
|
||||
|
@ -13,3 +13,7 @@ set(COMPONENT_PRIV_REQUIRES bootloader_support)
|
||||
|
||||
register_component()
|
||||
|
||||
set_source_files_properties(
|
||||
"spiffs/src/spiffs_nucleus.c"
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
-Wno-tautological-compare)
|
||||
|
@ -3,3 +3,5 @@ COMPONENT_PRIV_INCLUDEDIRS := . spiffs/src
|
||||
COMPONENT_SRCDIRS := . spiffs/src
|
||||
|
||||
COMPONENT_SUBMODULES := spiffs
|
||||
|
||||
spiffs/src/spiffs_nucleus.o: CFLAGS += -Wno-tautological-compare
|
||||
|
@ -17,7 +17,9 @@
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp_eth.h"
|
||||
#endif
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
@ -41,7 +43,7 @@ static void handle_sta_stop(void *arg, esp_event_base_t base, int32_t event_id,
|
||||
static void handle_sta_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data);
|
||||
static void handle_sta_disconnected(void *arg, esp_event_base_t base, int32_t event_id, void *data);
|
||||
static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static void handle_eth_start(void *arg, esp_event_base_t base, int32_t event_id, void *data);
|
||||
static void handle_eth_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data);
|
||||
static void handle_eth_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data);
|
||||
@ -97,6 +99,16 @@ static void handle_eth_disconnected(void *arg, esp_event_base_t base, int32_t ev
|
||||
tcpip_adapter_down(TCPIP_ADAPTER_IF_ETH);
|
||||
}
|
||||
|
||||
static void handle_eth_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data)
|
||||
{
|
||||
const ip_event_got_ip_t *event = (const ip_event_got_ip_t *) data;
|
||||
ESP_LOGI(TAG, "eth ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
|
||||
IP2STR(&event->ip_info.ip),
|
||||
IP2STR(&event->ip_info.netmask),
|
||||
IP2STR(&event->ip_info.gw));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data)
|
||||
{
|
||||
API_CALL_CHECK("esp_wifi_internal_set_sta_ip", esp_wifi_internal_set_sta_ip(), ESP_OK);
|
||||
@ -108,14 +120,6 @@ static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id
|
||||
IP2STR(&event->ip_info.gw));
|
||||
}
|
||||
|
||||
static void handle_eth_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data)
|
||||
{
|
||||
const ip_event_got_ip_t *event = (const ip_event_got_ip_t *) data;
|
||||
ESP_LOGI(TAG, "eth ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
|
||||
IP2STR(&event->ip_info.ip),
|
||||
IP2STR(&event->ip_info.netmask),
|
||||
IP2STR(&event->ip_info.gw));
|
||||
}
|
||||
|
||||
static void handle_ap_start(void *arg, esp_event_base_t base, int32_t event_id, void *data)
|
||||
{
|
||||
@ -261,7 +265,7 @@ esp_err_t tcpip_adapter_clear_default_wifi_handlers()
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_err_t tcpip_adapter_set_default_eth_handlers()
|
||||
{
|
||||
esp_err_t err;
|
||||
@ -306,3 +310,4 @@ esp_err_t tcpip_adapter_clear_default_eth_handlers()
|
||||
esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, handle_eth_got_ip);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
920
components/ulp/include/esp32s2beta/ulp.h
Normal file
920
components/ulp/include/esp32s2beta/ulp.h
Normal file
@ -0,0 +1,920 @@
|
||||
// Copyright 2016-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.
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ULP_FSM_PREPARE_SLEEP_CYCLES 2 /*!< Cycles spent by FSM preparing ULP for sleep */
|
||||
#define ULP_FSM_WAKEUP_SLEEP_CYCLES 2 /*!< Cycles spent by FSM waking up ULP from sleep */
|
||||
|
||||
/**
|
||||
* @defgroup ulp_registers ULP coprocessor registers
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#define R0 0 /*!< general purpose register 0 */
|
||||
#define R1 1 /*!< general purpose register 1 */
|
||||
#define R2 2 /*!< general purpose register 2 */
|
||||
#define R3 3 /*!< general purpose register 3 */
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup ulp_opcodes ULP coprocessor opcodes, sub opcodes, and various modifiers/flags
|
||||
*
|
||||
* These definitions are not intended to be used directly.
|
||||
* They are used in definitions of instructions later on.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define OPCODE_WR_REG 1 /*!< Instruction: write peripheral register (RTC_CNTL/RTC_IO/SARADC) (not implemented yet) */
|
||||
|
||||
#define OPCODE_RD_REG 2 /*!< Instruction: read peripheral register (RTC_CNTL/RTC_IO/SARADC) (not implemented yet) */
|
||||
|
||||
#define RD_REG_PERIPH_RTC_CNTL 0 /*!< Identifier of RTC_CNTL peripheral for RD_REG and WR_REG instructions */
|
||||
#define RD_REG_PERIPH_RTC_IO 1 /*!< Identifier of RTC_IO peripheral for RD_REG and WR_REG instructions */
|
||||
#define RD_REG_PERIPH_SENS 2 /*!< Identifier of SARADC peripheral for RD_REG and WR_REG instructions */
|
||||
#define RD_REG_PERIPH_RTC_I2C 3 /*!< Identifier of RTC_I2C peripheral for RD_REG and WR_REG instructions */
|
||||
|
||||
#define OPCODE_I2C 3 /*!< Instruction: read/write I2C (not implemented yet) */
|
||||
|
||||
#define OPCODE_DELAY 4 /*!< Instruction: delay (nop) for a given number of cycles */
|
||||
|
||||
#define OPCODE_ADC 5 /*!< Instruction: SAR ADC measurement (not implemented yet) */
|
||||
|
||||
#define OPCODE_ST 6 /*!< Instruction: store indirect to RTC memory */
|
||||
#define SUB_OPCODE_ST 4 /*!< Store 32 bits, 16 MSBs contain PC, 16 LSBs contain value from source register */
|
||||
|
||||
#define OPCODE_ALU 7 /*!< Arithmetic instructions */
|
||||
#define SUB_OPCODE_ALU_REG 0 /*!< Arithmetic instruction, both source values are in register */
|
||||
#define SUB_OPCODE_ALU_IMM 1 /*!< Arithmetic instruction, one source value is an immediate */
|
||||
#define SUB_OPCODE_ALU_CNT 2 /*!< Arithmetic instruction between counter register and an immediate (not implemented yet)*/
|
||||
#define ALU_SEL_ADD 0 /*!< Addition */
|
||||
#define ALU_SEL_SUB 1 /*!< Subtraction */
|
||||
#define ALU_SEL_AND 2 /*!< Logical AND */
|
||||
#define ALU_SEL_OR 3 /*!< Logical OR */
|
||||
#define ALU_SEL_MOV 4 /*!< Copy value (immediate to destination register or source register to destination register */
|
||||
#define ALU_SEL_LSH 5 /*!< Shift left by given number of bits */
|
||||
#define ALU_SEL_RSH 6 /*!< Shift right by given number of bits */
|
||||
|
||||
#define OPCODE_BRANCH 8 /*!< Branch instructions */
|
||||
#define SUB_OPCODE_BX 0 /*!< Branch to absolute PC (immediate or in register) */
|
||||
#define BX_JUMP_TYPE_DIRECT 0 /*!< Unconditional jump */
|
||||
#define BX_JUMP_TYPE_ZERO 1 /*!< Branch if last ALU result is zero */
|
||||
#define BX_JUMP_TYPE_OVF 2 /*!< Branch if last ALU operation caused and overflow */
|
||||
#define SUB_OPCODE_B 1 /*!< Branch to a relative offset */
|
||||
#define B_CMP_L 0 /*!< Branch if R0 is less than an immediate */
|
||||
#define B_CMP_GE 1 /*!< Branch if R0 is greater than or equal to an immediate */
|
||||
|
||||
#define OPCODE_END 9 /*!< Stop executing the program */
|
||||
#define SUB_OPCODE_END 0 /*!< Stop executing the program and optionally wake up the chip */
|
||||
#define SUB_OPCODE_SLEEP 1 /*!< Stop executing the program and run it again after selected interval */
|
||||
|
||||
#define OPCODE_TSENS 10 /*!< Instruction: temperature sensor measurement (not implemented yet) */
|
||||
|
||||
#define OPCODE_HALT 11 /*!< Halt the coprocessor */
|
||||
|
||||
#define OPCODE_LD 13 /*!< Indirect load lower 16 bits from RTC memory */
|
||||
|
||||
#define OPCODE_MACRO 15 /*!< Not a real opcode. Used to identify labels and branches in the program */
|
||||
#define SUB_OPCODE_MACRO_LABEL 0 /*!< Label macro */
|
||||
#define SUB_OPCODE_MACRO_BRANCH 1 /*!< Branch macro */
|
||||
/**@}*/
|
||||
|
||||
/**@{*/
|
||||
#define ESP_ERR_ULP_BASE 0x1200 /*!< Offset for ULP-related error codes */
|
||||
#define ESP_ERR_ULP_SIZE_TOO_BIG (ESP_ERR_ULP_BASE + 1) /*!< Program doesn't fit into RTC memory reserved for the ULP */
|
||||
#define ESP_ERR_ULP_INVALID_LOAD_ADDR (ESP_ERR_ULP_BASE + 2) /*!< Load address is outside of RTC memory reserved for the ULP */
|
||||
#define ESP_ERR_ULP_DUPLICATE_LABEL (ESP_ERR_ULP_BASE + 3) /*!< More than one label with the same number was defined */
|
||||
#define ESP_ERR_ULP_UNDEFINED_LABEL (ESP_ERR_ULP_BASE + 4) /*!< Branch instructions references an undefined label */
|
||||
#define ESP_ERR_ULP_BRANCH_OUT_OF_RANGE (ESP_ERR_ULP_BASE + 5) /*!< Branch target is out of range of B instruction (try replacing with BX) */
|
||||
/**@}*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Instruction format structure
|
||||
*
|
||||
* All ULP instructions are 32 bit long.
|
||||
* This union contains field layouts used by all of the supported instructions.
|
||||
* This union also includes a special "macro" instruction layout.
|
||||
* This is not a real instruction which can be executed by the CPU. It acts
|
||||
* as a token which is removed from the program by the
|
||||
* ulp_process_macros_and_load function.
|
||||
*
|
||||
* These structures are not intended to be used directly.
|
||||
* Preprocessor definitions provided below fill the fields of these structure with
|
||||
* the right arguments.
|
||||
*/
|
||||
typedef union {
|
||||
|
||||
struct {
|
||||
uint32_t cycles : 16; /*!< Number of cycles to sleep */
|
||||
uint32_t unused : 12; /*!< Unused */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_DELAY) */
|
||||
} delay; /*!< Format of DELAY instruction */
|
||||
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register which contains data to store */
|
||||
uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */
|
||||
uint32_t unused1 : 6; /*!< Unused */
|
||||
uint32_t offset : 11; /*!< Offset to add to sreg */
|
||||
uint32_t unused2 : 4; /*!< Unused */
|
||||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ST) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ST) */
|
||||
} st; /*!< Format of ST instruction */
|
||||
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where the data should be loaded to */
|
||||
uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */
|
||||
uint32_t unused1 : 6; /*!< Unused */
|
||||
uint32_t offset : 11; /*!< Offset to add to sreg */
|
||||
uint32_t unused2 : 7; /*!< Unused */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_LD) */
|
||||
} ld; /*!< Format of LD instruction */
|
||||
|
||||
struct {
|
||||
uint32_t unused : 28; /*!< Unused */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_HALT) */
|
||||
} halt; /*!< Format of HALT instruction */
|
||||
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register which contains target PC, expressed in words (used if .reg == 1) */
|
||||
uint32_t addr : 11; /*!< Target PC, expressed in words (used if .reg == 0) */
|
||||
uint32_t unused : 8; /*!< Unused */
|
||||
uint32_t reg : 1; /*!< Target PC in register (1) or immediate (0) */
|
||||
uint32_t type : 3; /*!< Jump condition (BX_JUMP_TYPE_xxx) */
|
||||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_BX) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */
|
||||
} bx; /*!< Format of BRANCH instruction (absolute address) */
|
||||
|
||||
struct {
|
||||
uint32_t imm : 16; /*!< Immediate value to compare against */
|
||||
uint32_t cmp : 1; /*!< Comparison to perform: B_CMP_L or B_CMP_GE */
|
||||
uint32_t offset : 7; /*!< Absolute value of target PC offset w.r.t. current PC, expressed in words */
|
||||
uint32_t sign : 1; /*!< Sign of target PC offset: 0: positive, 1: negative */
|
||||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_B) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */
|
||||
} b; /*!< Format of BRANCH instruction (relative address) */
|
||||
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Destination register */
|
||||
uint32_t sreg : 2; /*!< Register with operand A */
|
||||
uint32_t treg : 2; /*!< Register with operand B */
|
||||
uint32_t unused : 15; /*!< Unused */
|
||||
uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */
|
||||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_REG) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */
|
||||
} alu_reg; /*!< Format of ALU instruction (both sources are registers) */
|
||||
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Destination register */
|
||||
uint32_t sreg : 2; /*!< Register with operand A */
|
||||
uint32_t imm : 16; /*!< Immediate value of operand B */
|
||||
uint32_t unused : 1; /*!< Unused */
|
||||
uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */
|
||||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_IMM) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */
|
||||
} alu_imm; /*!< Format of ALU instruction (one source is an immediate) */
|
||||
|
||||
struct {
|
||||
uint32_t addr : 8; /*!< Address within either RTC_CNTL, RTC_IO, or SARADC */
|
||||
uint32_t periph_sel : 2; /*!< Select peripheral: RTC_CNTL (0), RTC_IO(1), SARADC(2) */
|
||||
uint32_t data : 8; /*!< 8 bits of data to write */
|
||||
uint32_t low : 5; /*!< Low bit */
|
||||
uint32_t high : 5; /*!< High bit */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_WR_REG) */
|
||||
} wr_reg; /*!< Format of WR_REG instruction */
|
||||
|
||||
struct {
|
||||
uint32_t addr : 8; /*!< Address within either RTC_CNTL, RTC_IO, or SARADC */
|
||||
uint32_t periph_sel : 2; /*!< Select peripheral: RTC_CNTL (0), RTC_IO(1), SARADC(2) */
|
||||
uint32_t unused : 8; /*!< Unused */
|
||||
uint32_t low : 5; /*!< Low bit */
|
||||
uint32_t high : 5; /*!< High bit */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_WR_REG) */
|
||||
} rd_reg; /*!< Format of RD_REG instruction */
|
||||
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where to store ADC result */
|
||||
uint32_t mux : 4; /*!< Select SARADC pad (mux + 1) */
|
||||
uint32_t sar_sel : 1; /*!< Select SARADC0 (0) or SARADC1 (1) */
|
||||
uint32_t unused1 : 1; /*!< Unused */
|
||||
uint32_t cycles : 16; /*!< TBD, cycles used for measurement */
|
||||
uint32_t unused2 : 4; /*!< Unused */
|
||||
uint32_t opcode: 4; /*!< Opcode (OPCODE_ADC) */
|
||||
} adc; /*!< Format of ADC instruction */
|
||||
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where to store temperature measurement result */
|
||||
uint32_t wait_delay: 14; /*!< Cycles to wait after measurement is done */
|
||||
uint32_t reserved: 12; /*!< Reserved, set to 0 */
|
||||
uint32_t opcode: 4; /*!< Opcode (OPCODE_TSENS) */
|
||||
} tsens; /*!< Format of TSENS instruction */
|
||||
|
||||
struct {
|
||||
uint32_t i2c_addr : 8; /*!< I2C slave address */
|
||||
uint32_t data : 8; /*!< Data to read or write */
|
||||
uint32_t low_bits : 3; /*!< TBD */
|
||||
uint32_t high_bits : 3; /*!< TBD */
|
||||
uint32_t i2c_sel : 4; /*!< TBD, select reg_i2c_slave_address[7:0] */
|
||||
uint32_t unused : 1; /*!< Unused */
|
||||
uint32_t rw : 1; /*!< Write (1) or read (0) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_I2C) */
|
||||
} i2c; /*!< Format of I2C instruction */
|
||||
|
||||
struct {
|
||||
uint32_t wakeup : 1; /*!< Set to 1 to wake up chip */
|
||||
uint32_t unused : 24; /*!< Unused */
|
||||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_WAKEUP) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */
|
||||
} end; /*!< Format of END instruction with wakeup */
|
||||
|
||||
struct {
|
||||
uint32_t cycle_sel : 4; /*!< Select which one of SARADC_ULP_CP_SLEEP_CYCx_REG to get the sleep duration from */
|
||||
uint32_t unused : 21; /*!< Unused */
|
||||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_SLEEP) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */
|
||||
} sleep; /*!< Format of END instruction with sleep */
|
||||
|
||||
struct {
|
||||
uint32_t label : 16; /*!< Label number */
|
||||
uint32_t unused : 8; /*!< Unused */
|
||||
uint32_t sub_opcode : 4; /*!< SUB_OPCODE_MACRO_LABEL or SUB_OPCODE_MACRO_BRANCH */
|
||||
uint32_t opcode: 4; /*!< Opcode (OPCODE_MACRO) */
|
||||
} macro; /*!< Format of tokens used by LABEL and BRANCH macros */
|
||||
|
||||
} ulp_insn_t;
|
||||
|
||||
_Static_assert(sizeof(ulp_insn_t) == 4, "ULP coprocessor instruction size should be 4 bytes");
|
||||
|
||||
/**
|
||||
* Delay (nop) for a given number of cycles
|
||||
*/
|
||||
#define I_DELAY(cycles_) { .delay = {\
|
||||
.cycles = cycles_, \
|
||||
.unused = 0, \
|
||||
.opcode = OPCODE_DELAY } }
|
||||
|
||||
/**
|
||||
* Halt the coprocessor.
|
||||
*
|
||||
* This instruction halts the coprocessor, but keeps ULP timer active.
|
||||
* As such, ULP program will be restarted again by timer.
|
||||
* To stop the program and prevent the timer from restarting the program,
|
||||
* use I_END(0) instruction.
|
||||
*/
|
||||
#define I_HALT() { .halt = {\
|
||||
.unused = 0, \
|
||||
.opcode = OPCODE_HALT } }
|
||||
|
||||
/**
|
||||
* Map SoC peripheral register to periph_sel field of RD_REG and WR_REG
|
||||
* instructions.
|
||||
*
|
||||
* @param reg peripheral register in RTC_CNTL_, RTC_IO_, SENS_, RTC_I2C peripherals.
|
||||
* @return periph_sel value for the peripheral to which this register belongs.
|
||||
*/
|
||||
static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
||||
uint32_t ret = 3;
|
||||
if (reg < DR_REG_RTCCNTL_BASE) {
|
||||
assert(0 && "invalid register base");
|
||||
} else if (reg < DR_REG_RTCIO_BASE) {
|
||||
ret = RD_REG_PERIPH_RTC_CNTL;
|
||||
} else if (reg < DR_REG_SENS_BASE) {
|
||||
ret = RD_REG_PERIPH_RTC_IO;
|
||||
} else if (reg < DR_REG_RTC_I2C_BASE){
|
||||
ret = RD_REG_PERIPH_SENS;
|
||||
} else if (reg < DR_REG_IO_MUX_BASE){
|
||||
ret = RD_REG_PERIPH_RTC_I2C;
|
||||
} else {
|
||||
assert(0 && "invalid register base");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write literal value to a peripheral register
|
||||
*
|
||||
* reg[high_bit : low_bit] = val
|
||||
* This instruction can access RTC_CNTL_, RTC_IO_, SENS_, and RTC_I2C peripheral registers.
|
||||
*/
|
||||
#define I_WR_REG(reg, low_bit, high_bit, val) {.wr_reg = {\
|
||||
.addr = (reg & 0xff) / sizeof(uint32_t), \
|
||||
.periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \
|
||||
.data = val, \
|
||||
.low = low_bit, \
|
||||
.high = high_bit, \
|
||||
.opcode = OPCODE_WR_REG } }
|
||||
|
||||
/**
|
||||
* Read from peripheral register into R0
|
||||
*
|
||||
* R0 = reg[high_bit : low_bit]
|
||||
* This instruction can access RTC_CNTL_, RTC_IO_, SENS_, and RTC_I2C peripheral registers.
|
||||
*/
|
||||
#define I_RD_REG(reg, low_bit, high_bit) {.rd_reg = {\
|
||||
.addr = (reg & 0xff) / sizeof(uint32_t), \
|
||||
.periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \
|
||||
.unused = 0, \
|
||||
.low = low_bit, \
|
||||
.high = high_bit, \
|
||||
.opcode = OPCODE_RD_REG } }
|
||||
|
||||
/**
|
||||
* Set or clear a bit in the peripheral register.
|
||||
*
|
||||
* Sets bit (1 << shift) of register reg to value val.
|
||||
* This instruction can access RTC_CNTL_, RTC_IO_, SENS_, and RTC_I2C peripheral registers.
|
||||
*/
|
||||
#define I_WR_REG_BIT(reg, shift, val) I_WR_REG(reg, shift, shift, val)
|
||||
|
||||
/**
|
||||
* Wake the SoC from deep sleep.
|
||||
*
|
||||
* This instruction initiates wake up from deep sleep.
|
||||
* Use esp_deep_sleep_enable_ulp_wakeup to enable deep sleep wakeup
|
||||
* triggered by the ULP before going into deep sleep.
|
||||
* Note that ULP program will still keep running until the I_HALT
|
||||
* instruction, and it will still be restarted by timer at regular
|
||||
* intervals, even when the SoC is woken up.
|
||||
*
|
||||
* To stop the ULP program, use I_HALT instruction.
|
||||
*
|
||||
* To disable the timer which start ULP program, use I_END()
|
||||
* instruction. I_END instruction clears the
|
||||
* RTC_CNTL_ULP_CP_SLP_TIMER_EN_S bit of RTC_CNTL_STATE0_REG
|
||||
* register, which controls the ULP timer.
|
||||
*/
|
||||
#define I_WAKE() { .end = { \
|
||||
.wakeup = 1, \
|
||||
.unused = 0, \
|
||||
.sub_opcode = SUB_OPCODE_END, \
|
||||
.opcode = OPCODE_END } }
|
||||
|
||||
/**
|
||||
* Stop ULP program timer.
|
||||
*
|
||||
* This is a convenience macro which disables the ULP program timer.
|
||||
* Once this instruction is used, ULP program will not be restarted
|
||||
* anymore until ulp_run function is called.
|
||||
*
|
||||
* ULP program will continue running after this instruction. To stop
|
||||
* the currently running program, use I_HALT().
|
||||
*/
|
||||
#define I_END() \
|
||||
I_WR_REG_BIT(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN_S, 0)
|
||||
/**
|
||||
* Select the time interval used to run ULP program.
|
||||
*
|
||||
* This instructions selects which of the SENS_SLEEP_CYCLES_Sx
|
||||
* registers' value is used by the ULP program timer.
|
||||
* When the ULP program stops at I_HALT instruction, ULP program
|
||||
* timer start counting. When the counter reaches the value of
|
||||
* the selected SENS_SLEEP_CYCLES_Sx register, ULP program
|
||||
* start running again from the start address (passed to the ulp_run
|
||||
* function).
|
||||
* There are 5 SENS_SLEEP_CYCLES_Sx registers, so 0 <= timer_idx < 5.
|
||||
*
|
||||
* By default, SENS_SLEEP_CYCLES_S0 register is used by the ULP
|
||||
* program timer.
|
||||
*/
|
||||
#define I_SLEEP_CYCLE_SEL(timer_idx) { .sleep = { \
|
||||
.cycle_sel = timer_idx, \
|
||||
.unused = 0, \
|
||||
.sub_opcode = SUB_OPCODE_SLEEP, \
|
||||
.opcode = OPCODE_END } }
|
||||
|
||||
/**
|
||||
* Perform temperature sensor measurement and store it into reg_dest.
|
||||
*
|
||||
* Delay can be set between 1 and ((1 << 14) - 1). Higher values give
|
||||
* higher measurement resolution.
|
||||
*/
|
||||
#define I_TSENS(reg_dest, delay) { .tsens = { \
|
||||
.dreg = reg_dest, \
|
||||
.wait_delay = delay, \
|
||||
.reserved = 0, \
|
||||
.opcode = OPCODE_TSENS } }
|
||||
|
||||
/**
|
||||
* Perform ADC measurement and store result in reg_dest.
|
||||
*
|
||||
* adc_idx selects ADC (0 or 1).
|
||||
* pad_idx selects ADC pad (0 - 7).
|
||||
*/
|
||||
#define I_ADC(reg_dest, adc_idx, pad_idx) { .adc = {\
|
||||
.dreg = reg_dest, \
|
||||
.mux = pad_idx + 1, \
|
||||
.sar_sel = adc_idx, \
|
||||
.unused1 = 0, \
|
||||
.cycles = 0, \
|
||||
.unused2 = 0, \
|
||||
.opcode = OPCODE_ADC } }
|
||||
|
||||
/**
|
||||
* Store value from register reg_val into RTC memory.
|
||||
*
|
||||
* The value is written to an offset calculated by adding value of
|
||||
* reg_addr register and offset_ field (this offset is expressed in 32-bit words).
|
||||
* 32 bits written to RTC memory are built as follows:
|
||||
* - bits [31:21] hold the PC of current instruction, expressed in 32-bit words
|
||||
* - bits [20:16] = 5'b1
|
||||
* - bits [15:0] are assigned the contents of reg_val
|
||||
*
|
||||
* RTC_SLOW_MEM[addr + offset_] = { 5'b0, insn_PC[10:0], val[15:0] }
|
||||
*/
|
||||
#define I_ST(reg_val, reg_addr, offset_) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ST, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
|
||||
/**
|
||||
* Load value from RTC memory into reg_dest register.
|
||||
*
|
||||
* Loads 16 LSBs from RTC memory word given by the sum of value in reg_addr and
|
||||
* value of offset_.
|
||||
*/
|
||||
#define I_LD(reg_dest, reg_addr, offset_) { .ld = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_addr, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.opcode = OPCODE_LD } }
|
||||
|
||||
|
||||
/**
|
||||
* Branch relative if R0 less than immediate value.
|
||||
*
|
||||
* pc_offset is expressed in words, and can be from -127 to 127
|
||||
* imm_value is a 16-bit value to compare R0 against
|
||||
*/
|
||||
#define I_BL(pc_offset, imm_value) { .b = { \
|
||||
.imm = imm_value, \
|
||||
.cmp = B_CMP_L, \
|
||||
.offset = abs(pc_offset), \
|
||||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Branch relative if R0 greater or equal than immediate value.
|
||||
*
|
||||
* pc_offset is expressed in words, and can be from -127 to 127
|
||||
* imm_value is a 16-bit value to compare R0 against
|
||||
*/
|
||||
#define I_BGE(pc_offset, imm_value) { .b = { \
|
||||
.imm = imm_value, \
|
||||
.cmp = B_CMP_GE, \
|
||||
.offset = abs(pc_offset), \
|
||||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Unconditional branch to absolute PC, address in register.
|
||||
*
|
||||
* reg_pc is the register which contains address to jump to.
|
||||
* Address is expressed in 32-bit words.
|
||||
*/
|
||||
#define I_BXR(reg_pc) { .bx = { \
|
||||
.dreg = reg_pc, \
|
||||
.addr = 0, \
|
||||
.unused = 0, \
|
||||
.reg = 1, \
|
||||
.type = BX_JUMP_TYPE_DIRECT, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Unconditional branch to absolute PC, immediate address.
|
||||
*
|
||||
* Address imm_pc is expressed in 32-bit words.
|
||||
*/
|
||||
#define I_BXI(imm_pc) { .bx = { \
|
||||
.dreg = 0, \
|
||||
.addr = imm_pc, \
|
||||
.unused = 0, \
|
||||
.reg = 0, \
|
||||
.type = BX_JUMP_TYPE_DIRECT, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Branch to absolute PC if ALU result is zero, address in register.
|
||||
*
|
||||
* reg_pc is the register which contains address to jump to.
|
||||
* Address is expressed in 32-bit words.
|
||||
*/
|
||||
#define I_BXZR(reg_pc) { .bx = { \
|
||||
.dreg = reg_pc, \
|
||||
.addr = 0, \
|
||||
.unused = 0, \
|
||||
.reg = 1, \
|
||||
.type = BX_JUMP_TYPE_ZERO, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Branch to absolute PC if ALU result is zero, immediate address.
|
||||
*
|
||||
* Address imm_pc is expressed in 32-bit words.
|
||||
*/
|
||||
#define I_BXZI(imm_pc) { .bx = { \
|
||||
.dreg = 0, \
|
||||
.addr = imm_pc, \
|
||||
.unused = 0, \
|
||||
.reg = 0, \
|
||||
.type = BX_JUMP_TYPE_ZERO, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Branch to absolute PC if ALU overflow, address in register
|
||||
*
|
||||
* reg_pc is the register which contains address to jump to.
|
||||
* Address is expressed in 32-bit words.
|
||||
*/
|
||||
#define I_BXFR(reg_pc) { .bx = { \
|
||||
.dreg = reg_pc, \
|
||||
.addr = 0, \
|
||||
.unused = 0, \
|
||||
.reg = 1, \
|
||||
.type = BX_JUMP_TYPE_OVF, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Branch to absolute PC if ALU overflow, immediate address
|
||||
*
|
||||
* Address imm_pc is expressed in 32-bit words.
|
||||
*/
|
||||
#define I_BXFI(imm_pc) { .bx = { \
|
||||
.dreg = 0, \
|
||||
.addr = imm_pc, \
|
||||
.unused = 0, \
|
||||
.reg = 0, \
|
||||
.type = BX_JUMP_TYPE_OVF, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
|
||||
/**
|
||||
* Addition: dest = src1 + src2
|
||||
*/
|
||||
#define I_ADDR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src1, \
|
||||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_ADD, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Subtraction: dest = src1 - src2
|
||||
*/
|
||||
#define I_SUBR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src1, \
|
||||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_SUB, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Logical AND: dest = src1 & src2
|
||||
*/
|
||||
#define I_ANDR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src1, \
|
||||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_AND, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Logical OR: dest = src1 | src2
|
||||
*/
|
||||
#define I_ORR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src1, \
|
||||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_OR, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Copy: dest = src
|
||||
*/
|
||||
#define I_MOVR(reg_dest, reg_src) { .alu_reg = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.treg = 0, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_MOV, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Logical shift left: dest = src << shift
|
||||
*/
|
||||
#define I_LSHR(reg_dest, reg_src, reg_shift) { .alu_reg = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.treg = reg_shift, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_LSH, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
||||
/**
|
||||
* Logical shift right: dest = src >> shift
|
||||
*/
|
||||
#define I_RSHR(reg_dest, reg_src, reg_shift) { .alu_reg = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.treg = reg_shift, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_RSH, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Add register and an immediate value: dest = src1 + imm
|
||||
*/
|
||||
#define I_ADDI(reg_dest, reg_src, imm_) { .alu_imm = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_ADD, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
||||
/**
|
||||
* Subtract register and an immediate value: dest = src - imm
|
||||
*/
|
||||
#define I_SUBI(reg_dest, reg_src, imm_) { .alu_imm = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_SUB, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Logical AND register and an immediate value: dest = src & imm
|
||||
*/
|
||||
#define I_ANDI(reg_dest, reg_src, imm_) { .alu_imm = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_AND, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Logical OR register and an immediate value: dest = src | imm
|
||||
*/
|
||||
#define I_ORI(reg_dest, reg_src, imm_) { .alu_imm = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_OR, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Copy an immediate value into register: dest = imm
|
||||
*/
|
||||
#define I_MOVI(reg_dest, imm_) { .alu_imm = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = 0, \
|
||||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_MOV, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Logical shift left register value by an immediate: dest = src << imm
|
||||
*/
|
||||
#define I_LSHI(reg_dest, reg_src, imm_) { .alu_imm = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_LSH, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
||||
/**
|
||||
* Logical shift right register value by an immediate: dest = val >> imm
|
||||
*/
|
||||
#define I_RSHI(reg_dest, reg_src, imm_) { .alu_imm = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_src, \
|
||||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_RSH, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Define a label with number label_num.
|
||||
*
|
||||
* This is a macro which doesn't generate a real instruction.
|
||||
* The token generated by this macro is removed by ulp_process_macros_and_load
|
||||
* function. Label defined using this macro can be used in branch macros defined
|
||||
* below.
|
||||
*/
|
||||
#define M_LABEL(label_num) { .macro = { \
|
||||
.label = label_num, \
|
||||
.unused = 0, \
|
||||
.sub_opcode = SUB_OPCODE_MACRO_LABEL, \
|
||||
.opcode = OPCODE_MACRO } }
|
||||
|
||||
/**
|
||||
* Token macro used by M_B and M_BX macros. Not to be used directly.
|
||||
*/
|
||||
#define M_BRANCH(label_num) { .macro = { \
|
||||
.label = label_num, \
|
||||
.unused = 0, \
|
||||
.sub_opcode = SUB_OPCODE_MACRO_BRANCH, \
|
||||
.opcode = OPCODE_MACRO } }
|
||||
|
||||
/**
|
||||
* Macro: branch to label label_num if R0 is less than immediate value.
|
||||
*
|
||||
* This macro generates two ulp_insn_t values separated by a comma, and should
|
||||
* be used when defining contents of ulp_insn_t arrays. First value is not a
|
||||
* real instruction; it is a token which is removed by ulp_process_macros_and_load
|
||||
* function.
|
||||
*/
|
||||
#define M_BL(label_num, imm_value) \
|
||||
M_BRANCH(label_num), \
|
||||
I_BL(0, imm_value)
|
||||
|
||||
/**
|
||||
* Macro: branch to label label_num if R0 is greater or equal than immediate value
|
||||
*
|
||||
* This macro generates two ulp_insn_t values separated by a comma, and should
|
||||
* be used when defining contents of ulp_insn_t arrays. First value is not a
|
||||
* real instruction; it is a token which is removed by ulp_process_macros_and_load
|
||||
* function.
|
||||
*/
|
||||
#define M_BGE(label_num, imm_value) \
|
||||
M_BRANCH(label_num), \
|
||||
I_BGE(0, imm_value)
|
||||
|
||||
/**
|
||||
* Macro: unconditional branch to label
|
||||
*
|
||||
* This macro generates two ulp_insn_t values separated by a comma, and should
|
||||
* be used when defining contents of ulp_insn_t arrays. First value is not a
|
||||
* real instruction; it is a token which is removed by ulp_process_macros_and_load
|
||||
* function.
|
||||
*/
|
||||
#define M_BX(label_num) \
|
||||
M_BRANCH(label_num), \
|
||||
I_BXI(0)
|
||||
|
||||
/**
|
||||
* Macro: branch to label if ALU result is zero
|
||||
*
|
||||
* This macro generates two ulp_insn_t values separated by a comma, and should
|
||||
* be used when defining contents of ulp_insn_t arrays. First value is not a
|
||||
* real instruction; it is a token which is removed by ulp_process_macros_and_load
|
||||
* function.
|
||||
*/
|
||||
#define M_BXZ(label_num) \
|
||||
M_BRANCH(label_num), \
|
||||
I_BXZI(0)
|
||||
|
||||
/**
|
||||
* Macro: branch to label if ALU overflow
|
||||
*
|
||||
* This macro generates two ulp_insn_t values separated by a comma, and should
|
||||
* be used when defining contents of ulp_insn_t arrays. First value is not a
|
||||
* real instruction; it is a token which is removed by ulp_process_macros_and_load
|
||||
* function.
|
||||
*/
|
||||
#define M_BXF(label_num) \
|
||||
M_BRANCH(label_num), \
|
||||
I_BXFI(0)
|
||||
|
||||
|
||||
|
||||
#define RTC_SLOW_MEM ((uint32_t*) 0x50000000) /*!< RTC slow memory, 8k size */
|
||||
|
||||
/**
|
||||
* @brief Resolve all macro references in a program and load it into RTC memory
|
||||
* @param load_addr address where the program should be loaded, expressed in 32-bit words
|
||||
* @param program ulp_insn_t array with the program
|
||||
* @param psize size of the program, expressed in 32-bit words
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if auxiliary temporary structure can not be allocated
|
||||
* - one of ESP_ERR_ULP_xxx if program is not valid or can not be loaded
|
||||
*/
|
||||
esp_err_t ulp_process_macros_and_load(uint32_t load_addr, const ulp_insn_t* program, size_t* psize);
|
||||
|
||||
/**
|
||||
* @brief Load ULP program binary into RTC memory
|
||||
*
|
||||
* ULP program binary should have the following format (all values little-endian):
|
||||
*
|
||||
* 1. MAGIC, (value 0x00706c75, 4 bytes)
|
||||
* 2. TEXT_OFFSET, offset of .text section from binary start (2 bytes)
|
||||
* 3. TEXT_SIZE, size of .text section (2 bytes)
|
||||
* 4. DATA_SIZE, size of .data section (2 bytes)
|
||||
* 5. BSS_SIZE, size of .bss section (2 bytes)
|
||||
* 6. (TEXT_OFFSET - 12) bytes of arbitrary data (will not be loaded into RTC memory)
|
||||
* 7. .text section
|
||||
* 8. .data section
|
||||
*
|
||||
* Linker script in components/ulp/ld/esp32.ulp.ld produces ELF files which
|
||||
* correspond to this format. This linker script produces binaries with load_addr == 0.
|
||||
*
|
||||
* @param load_addr address where the program should be loaded, expressed in 32-bit words
|
||||
* @param program_binary pointer to program binary
|
||||
* @param program_size size of the program binary
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if load_addr is out of range
|
||||
* - ESP_ERR_INVALID_SIZE if program_size doesn't match (TEXT_OFFSET + TEXT_SIZE + DATA_SIZE)
|
||||
* - ESP_ERR_NOT_SUPPORTED if the magic number is incorrect
|
||||
*/
|
||||
esp_err_t ulp_load_binary(uint32_t load_addr, const uint8_t* program_binary, size_t program_size);
|
||||
|
||||
/**
|
||||
* @brief Run the program loaded into RTC memory
|
||||
* @param entry_point entry point, expressed in 32-bit words
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t ulp_run(uint32_t entry_point);
|
||||
|
||||
/**
|
||||
* @brief Set one of ULP wakeup period values
|
||||
*
|
||||
* ULP coprocessor starts running the program when the wakeup timer counts up
|
||||
* to a given value (called period). There are 5 period values which can be
|
||||
* programmed into SENS_ULP_CP_SLEEP_CYCx_REG registers, x = 0..4.
|
||||
* By default, wakeup timer will use the period set into SENS_ULP_CP_SLEEP_CYC0_REG,
|
||||
* i.e. period number 0. ULP program code can use SLEEP instruction to select
|
||||
* which of the SENS_ULP_CP_SLEEP_CYCx_REG should be used for subsequent wakeups.
|
||||
*
|
||||
* However, please note that SLEEP instruction issued (from ULP program) while the system
|
||||
* is in deep sleep mode does not have effect, and sleep cycle count 0 is used.
|
||||
*
|
||||
* @param period_index wakeup period setting number (0 - 4)
|
||||
* @param period_us wakeup period, us
|
||||
* @note The ULP FSM requires two clock cycles to wakeup before being able to run the program.
|
||||
* Then additional 16 cycles are reserved after wakeup waiting until the 8M clock is stable.
|
||||
* The FSM also requires two more clock cycles to go to sleep after the program execution is halted.
|
||||
* The minimum wakeup period that may be set up for the ULP
|
||||
* is equal to the total number of cycles spent on the above internal tasks.
|
||||
* For a default configuration of the ULP running at 150kHz it makes about 133us.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if period_index is out of range
|
||||
*/
|
||||
esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -15,19 +15,24 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#include "esp32/ulp.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#include "esp32s2beta/ulp.h"
|
||||
#endif
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/sens_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
@ -112,7 +117,7 @@ esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us)
|
||||
}
|
||||
uint64_t period_us_64 = period_us;
|
||||
uint64_t period_cycles = (period_us_64 << RTC_CLK_CAL_FRACT) / esp_clk_slowclk_cal_get();
|
||||
uint64_t min_sleep_period_cycles = ULP_FSM_PREPARE_SLEEP_CYCLES
|
||||
uint64_t min_sleep_period_cycles = ULP_FSM_PREPARE_SLEEP_CYCLES
|
||||
+ ULP_FSM_WAKEUP_SLEEP_CYCLES
|
||||
+ REG_GET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT);
|
||||
if (period_cycles < min_sleep_period_cycles) {
|
||||
|
@ -14,9 +14,14 @@
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/cpu.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#include "esp32/rom/uart.h"
|
||||
#include "soc/cpu.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#include "esp32s2beta/clk.h"
|
||||
#include "esp32s2beta/rom/uart.h"
|
||||
#endif
|
||||
|
||||
static uint32_t s_test_start, s_test_stop;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user