forked from espressif/esp-idf
Merge branch 'fix/p4_spi_master_clock_sourse_sel' into 'master'
fix(spi_master): Fix p4 spi clock source support other than XTAL See merge request espressif/esp-idf!28392
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -126,6 +126,7 @@ We have two bits to control the interrupt:
|
|||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "hal/spi_hal.h"
|
#include "hal/spi_hal.h"
|
||||||
#include "hal/spi_ll.h"
|
#include "hal/spi_ll.h"
|
||||||
|
#include "hal/hal_utils.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
#include "esp_cache.h"
|
#include "esp_cache.h"
|
||||||
@@ -163,7 +164,6 @@ typedef struct {
|
|||||||
|
|
||||||
struct spi_device_t {
|
struct spi_device_t {
|
||||||
int id;
|
int id;
|
||||||
int real_clk_freq_hz;
|
|
||||||
QueueHandle_t trans_queue;
|
QueueHandle_t trans_queue;
|
||||||
QueueHandle_t ret_queue;
|
QueueHandle_t ret_queue;
|
||||||
spi_device_interface_config_t cfg;
|
spi_device_interface_config_t cfg;
|
||||||
@@ -368,11 +368,30 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
|||||||
#endif
|
#endif
|
||||||
spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT;
|
spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT;
|
||||||
uint32_t clock_source_hz = 0;
|
uint32_t clock_source_hz = 0;
|
||||||
|
uint32_t clock_source_div = 1;
|
||||||
if (dev_config->clock_source) {
|
if (dev_config->clock_source) {
|
||||||
clk_src = dev_config->clock_source;
|
clk_src = dev_config->clock_source;
|
||||||
}
|
}
|
||||||
esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
|
esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
|
||||||
|
#if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
|
||||||
|
SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= MIN(clock_source_hz / 2, (80 * 1000000))), "invalid sclk speed", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
|
if (clock_source_hz / 2 > (80 * 1000000)) { //clock_source_hz beyond peripheral HW limitation, calc pre-divider
|
||||||
|
hal_utils_clk_info_t clk_cfg = {
|
||||||
|
.src_freq_hz = clock_source_hz,
|
||||||
|
.exp_freq_hz = dev_config->clock_speed_hz * 2, //we have (hs_clk = 2*mst_clk), calc hs_clk first
|
||||||
|
.round_opt = HAL_DIV_ROUND,
|
||||||
|
};
|
||||||
|
hal_utils_calc_clk_div_integer(&clk_cfg, &clock_source_div);
|
||||||
|
}
|
||||||
|
clock_source_div *= 2; //convert to mst_clk function divider
|
||||||
|
if (clock_source_div > SPI_LL_CLK_SRC_PRE_DIV_MAX) {
|
||||||
|
clock_source_div = SPI_LL_CLK_SRC_PRE_DIV_MAX;
|
||||||
|
}
|
||||||
|
clock_source_hz /= clock_source_div; //actual freq enter to SPI peripheral
|
||||||
|
#else
|
||||||
SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= clock_source_hz), "invalid sclk speed", ESP_ERR_INVALID_ARG);
|
SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= clock_source_hz), "invalid sclk speed", ESP_ERR_INVALID_ARG);
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
//The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
|
//The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
|
||||||
//duplex mode does absolutely nothing on the ESP32.
|
//duplex mode does absolutely nothing on the ESP32.
|
||||||
@@ -416,10 +435,10 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
|||||||
|
|
||||||
//output values of timing configuration
|
//output values of timing configuration
|
||||||
spi_hal_timing_conf_t temp_timing_conf;
|
spi_hal_timing_conf_t temp_timing_conf;
|
||||||
int freq;
|
esp_err_t ret = spi_hal_cal_clock_conf(&timing_param, &temp_timing_conf);
|
||||||
esp_err_t ret = spi_hal_cal_clock_conf(&timing_param, &freq, &temp_timing_conf);
|
|
||||||
temp_timing_conf.clock_source = clk_src;
|
|
||||||
SPI_CHECK(ret == ESP_OK, "assigned clock speed not supported", ret);
|
SPI_CHECK(ret == ESP_OK, "assigned clock speed not supported", ret);
|
||||||
|
temp_timing_conf.clock_source = clk_src;
|
||||||
|
temp_timing_conf.source_pre_div = clock_source_div;
|
||||||
|
|
||||||
//Allocate memory for device
|
//Allocate memory for device
|
||||||
dev = malloc(sizeof(spi_device_t));
|
dev = malloc(sizeof(spi_device_t));
|
||||||
@@ -447,7 +466,6 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
|||||||
//We want to save a copy of the dev config in the dev struct.
|
//We want to save a copy of the dev config in the dev struct.
|
||||||
memcpy(&dev->cfg, dev_config, sizeof(spi_device_interface_config_t));
|
memcpy(&dev->cfg, dev_config, sizeof(spi_device_interface_config_t));
|
||||||
dev->cfg.duty_cycle_pos = duty_cycle;
|
dev->cfg.duty_cycle_pos = duty_cycle;
|
||||||
dev->real_clk_freq_hz = freq;
|
|
||||||
// TODO: if we have to change the apb clock among transactions, re-calculate this each time the apb clock lock is locked.
|
// TODO: if we have to change the apb clock among transactions, re-calculate this each time the apb clock lock is locked.
|
||||||
|
|
||||||
//Set CS pin, CS options
|
//Set CS pin, CS options
|
||||||
@@ -483,7 +501,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
|||||||
hal_dev->positive_cs = dev_config->flags & SPI_DEVICE_POSITIVE_CS ? 1 : 0;
|
hal_dev->positive_cs = dev_config->flags & SPI_DEVICE_POSITIVE_CS ? 1 : 0;
|
||||||
|
|
||||||
*handle = dev;
|
*handle = dev;
|
||||||
ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %dkHz", host_id + 1, freecs, freq / 1000);
|
ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %d Hz", host_id + 1, freecs, temp_timing_conf.real_freq);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
||||||
@@ -545,7 +563,7 @@ esp_err_t spi_device_get_actual_freq(spi_device_handle_t handle, int* freq_khz)
|
|||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
*freq_khz = handle->real_clk_freq_hz / 1000;
|
*freq_khz = handle->hal_dev.timing_conf.real_freq / 1000;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,6 +585,11 @@ static SPI_MASTER_ISR_ATTR void spi_setup_device(spi_device_t *dev)
|
|||||||
/* Configuration has not been applied yet. */
|
/* Configuration has not been applied yet. */
|
||||||
spi_hal_setup_device(hal, hal_dev);
|
spi_hal_setup_device(hal, hal_dev);
|
||||||
SPI_MASTER_PERI_CLOCK_ATOMIC() {
|
SPI_MASTER_PERI_CLOCK_ATOMIC() {
|
||||||
|
#if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
|
||||||
|
//we set mst_div as const 2, then (hs_clk = 2*mst_clk) to ensure timing turning work as past
|
||||||
|
//and sure (hs_div * mst_div = source_pre_div)
|
||||||
|
spi_ll_clk_source_pre_div(hal->hw, hal_dev->timing_conf.source_pre_div / 2, 2);
|
||||||
|
#endif
|
||||||
spi_ll_set_clk_source(hal->hw, hal_dev->timing_conf.clock_source);
|
spi_ll_set_clk_source(hal->hw, hal_dev->timing_conf.clock_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -40,6 +40,8 @@ extern "C" {
|
|||||||
|
|
||||||
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
|
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
|
||||||
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words
|
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words
|
||||||
|
#define SPI_LL_SUPPORT_CLK_SRC_PRE_DIV 1 //clock source have divider before peripheral
|
||||||
|
#define SPI_LL_CLK_SRC_PRE_DIV_MAX 512//div1(8bit) * div2(8bit but set const 2)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data structure holding calculated clock configuration. Since the
|
* The data structure holding calculated clock configuration. Since the
|
||||||
@@ -175,6 +177,12 @@ static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_s
|
|||||||
{
|
{
|
||||||
uint32_t clk_id = 0;
|
uint32_t clk_id = 0;
|
||||||
switch (clk_source) {
|
switch (clk_source) {
|
||||||
|
case SPI_CLK_SRC_SPLL:
|
||||||
|
clk_id = 4;
|
||||||
|
break;
|
||||||
|
case SPI_CLK_SRC_RC_FAST:
|
||||||
|
clk_id = 1;
|
||||||
|
break;
|
||||||
case SPI_CLK_SRC_XTAL:
|
case SPI_CLK_SRC_XTAL:
|
||||||
clk_id = 0;
|
clk_id = 0;
|
||||||
break;
|
break;
|
||||||
@@ -193,6 +201,32 @@ static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_s
|
|||||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
#define spi_ll_set_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; spi_ll_set_clk_source(__VA_ARGS__)
|
#define spi_ll_set_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; spi_ll_set_clk_source(__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config clock source integrate pre_div before it enter GPSPI peripheral
|
||||||
|
*
|
||||||
|
* @note 1. For timing turning(e.g. input_delay) feature available, should be (mst_div >= 2)
|
||||||
|
* 2. From peripheral limitation: (sour_freq/hs_div <= 160M) and (sour_freq/hs_div/mst_div <= 80M)
|
||||||
|
*
|
||||||
|
* @param hw Beginning address of the peripheral registers.
|
||||||
|
* @param hs_div Timing turning clock divider: (hs_clk_o = sour_freq/hs_div)
|
||||||
|
* @param mst_div Functional output clock divider: (mst_clk_o = sour_freq/hs_div/mst_div)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void spi_ll_clk_source_pre_div(spi_dev_t *hw, uint8_t hs_div, uint8_t mst_div)
|
||||||
|
{
|
||||||
|
if (hw == &GPSPI2) {
|
||||||
|
HP_SYS_CLKRST.peri_clk_ctrl116.reg_gpspi2_hs_clk_div_num = hs_div - 1;
|
||||||
|
HP_SYS_CLKRST.peri_clk_ctrl116.reg_gpspi2_mst_clk_div_num = mst_div - 1;
|
||||||
|
} else if (hw == &GPSPI3) {
|
||||||
|
HP_SYS_CLKRST.peri_clk_ctrl117.reg_gpspi3_hs_clk_div_num = hs_div - 1;
|
||||||
|
HP_SYS_CLKRST.peri_clk_ctrl117.reg_gpspi3_mst_clk_div_num = mst_div - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||||
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
|
#define spi_ll_clk_sour_pre_div(...) (void)__DECLARE_RCC_ATOMIC_ENV; spi_ll_clk_sour_pre_div(__VA_ARGS__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize SPI peripheral (master).
|
* Initialize SPI peripheral (master).
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -70,6 +70,8 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
spi_ll_clock_val_t clock_reg; ///< Register value used by the LL layer
|
spi_ll_clock_val_t clock_reg; ///< Register value used by the LL layer
|
||||||
spi_clock_source_t clock_source; ///< Clock source of each device used by LL layer
|
spi_clock_source_t clock_source; ///< Clock source of each device used by LL layer
|
||||||
|
uint32_t source_pre_div; ///< Pre divider befor enter SPI peripheral
|
||||||
|
int real_freq; ///< Output of the actual frequency
|
||||||
int timing_dummy; ///< Extra dummy needed to compensate the timing
|
int timing_dummy; ///< Extra dummy needed to compensate the timing
|
||||||
int timing_miso_delay; ///< Extra miso delay clocks to compensate the timing
|
int timing_miso_delay; ///< Extra miso delay clocks to compensate the timing
|
||||||
} spi_hal_timing_conf_t;
|
} spi_hal_timing_conf_t;
|
||||||
@@ -222,12 +224,11 @@ void spi_hal_fetch_result(const spi_hal_context_t *hal);
|
|||||||
* It is highly suggested to do this at initialization, since it takes long time.
|
* It is highly suggested to do this at initialization, since it takes long time.
|
||||||
*
|
*
|
||||||
* @param timing_param Input parameters to calculate timing configuration
|
* @param timing_param Input parameters to calculate timing configuration
|
||||||
* @param out_freq Output of the actual frequency, left NULL if not required.
|
|
||||||
* @param timing_conf Output of the timing configuration.
|
* @param timing_conf Output of the timing configuration.
|
||||||
*
|
*
|
||||||
* @return ESP_OK if desired is available, otherwise fail.
|
* @return ESP_OK if desired is available, otherwise fail.
|
||||||
*/
|
*/
|
||||||
esp_err_t spi_hal_cal_clock_conf(const spi_hal_timing_param_t *timing_param, int *out_freq, spi_hal_timing_conf_t *timing_conf);
|
esp_err_t spi_hal_cal_clock_conf(const spi_hal_timing_param_t *timing_param, spi_hal_timing_conf_t *timing_conf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the frequency actual used.
|
* Get the frequency actual used.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -52,7 +52,7 @@ void spi_hal_deinit(spi_hal_context_t *hal)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t spi_hal_cal_clock_conf(const spi_hal_timing_param_t *timing_param, int *out_freq, spi_hal_timing_conf_t *timing_conf)
|
esp_err_t spi_hal_cal_clock_conf(const spi_hal_timing_param_t *timing_param, spi_hal_timing_conf_t *timing_conf)
|
||||||
{
|
{
|
||||||
spi_hal_timing_conf_t temp_conf = {};
|
spi_hal_timing_conf_t temp_conf = {};
|
||||||
|
|
||||||
@@ -73,12 +73,10 @@ Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output dat
|
|||||||
ESP_ERR_NOT_SUPPORTED, freq_limit / 1000. / 1000 );
|
ESP_ERR_NOT_SUPPORTED, freq_limit / 1000. / 1000 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
temp_conf.real_freq = eff_clk_n;
|
||||||
if (timing_conf) {
|
if (timing_conf) {
|
||||||
*timing_conf = temp_conf;
|
*timing_conf = temp_conf;
|
||||||
}
|
}
|
||||||
if (out_freq) {
|
|
||||||
*out_freq = eff_clk_n;
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -991,6 +991,14 @@ config SOC_SPI_SUPPORT_CLK_XTAL
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_SPI_SUPPORT_CLK_RC_FAST
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SOC_SPI_SUPPORT_CLK_SPLL
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_MEMSPI_IS_INDEPENDENT
|
config SOC_MEMSPI_IS_INDEPENDENT
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@@ -403,14 +403,10 @@ typedef enum {
|
|||||||
* @brief Type of SPI clock source.
|
* @brief Type of SPI clock source.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
|
SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
|
||||||
#if SOC_CLK_TREE_SUPPORTED
|
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST_20M as SPI source clock */
|
||||||
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
|
SPI_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SPLL as SPI source clock */
|
||||||
SPI_CLK_SRC_SPLL_480 = SOC_MOD_CLK_SPLL,
|
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_SPLL, /*!< Select SPLL as SPI source clock */
|
||||||
SPI_CLK_SRC_DEFAULT = SPI_CLK_SRC_SPLL_480, /*!< Select SPLL_480M as SPI source clock */
|
|
||||||
#else
|
|
||||||
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
|
|
||||||
#endif
|
|
||||||
} soc_periph_spi_clk_src_t;
|
} soc_periph_spi_clk_src_t;
|
||||||
|
|
||||||
/////////////////////////////////////////////////PSRAM////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////PSRAM////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -427,10 +427,8 @@
|
|||||||
#define SOC_SPI_SUPPORT_CD_SIG 1
|
#define SOC_SPI_SUPPORT_CD_SIG 1
|
||||||
#define SOC_SPI_SUPPORT_OCT 1
|
#define SOC_SPI_SUPPORT_OCT 1
|
||||||
#define SOC_SPI_SUPPORT_CLK_XTAL 1
|
#define SOC_SPI_SUPPORT_CLK_XTAL 1
|
||||||
// #define SOC_SPI_SUPPORT_CLK_RC_FAST 1 //bellow clks are waiting for clock tree
|
#define SOC_SPI_SUPPORT_CLK_RC_FAST 1
|
||||||
// #define SOC_SPI_SUPPORT_CLK_SPLL_F480M 1 //super pll
|
#define SOC_SPI_SUPPORT_CLK_SPLL 1
|
||||||
// #define SOC_SPI_SUPPORT_CLK_SDIO 1 //sdio pll
|
|
||||||
// #define SOC_SPI_SUPPORT_CLK_APLL 1 //audio pll
|
|
||||||
|
|
||||||
// Peripheral supports DIO, DOUT, QIO, or QOUT
|
// Peripheral supports DIO, DOUT, QIO, or QOUT
|
||||||
// host_id = 0 -> SPI0/SPI1, host_id = 1 -> SPI2,
|
// host_id = 0 -> SPI0/SPI1, host_id = 1 -> SPI2,
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||||
|
Reference in New Issue
Block a user