drivers: esp32: update to hal_espressif v5.1

Modify necessary drivers to meet updated hal.

Signed-off-by: Lucas Tamborrino <lucas.tamborrino@espressif.com>
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
This commit is contained in:
Lucas Tamborrino 2024-03-05 11:19:27 -03:00 committed by Carles Cufí
parent 37f9958fea
commit fe57a12cf2
20 changed files with 657 additions and 476 deletions

View file

@ -10,42 +10,27 @@
#include <hal/adc_hal.h>
#include <hal/adc_types.h>
#include <esp_adc_cal.h>
#include <esp_heap_caps.h>
#include <esp_private/periph_ctrl.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/adc.h>
#include "driver/periph_ctrl.h"
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(adc_esp32, CONFIG_ADC_LOG_LEVEL);
#if CONFIG_SOC_SERIES_ESP32
#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_VREF
#define ADC_RESOLUTION_MIN SOC_ADC_DIGI_MIN_BITWIDTH
#define ADC_RESOLUTION_MAX SOC_ADC_DIGI_MAX_BITWIDTH
#if CONFIG_SOC_SERIES_ESP32
#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_VREF
/* Due to significant measurement discrepancy in higher voltage range, we
* clip the value instead of yet another correction. The IDF implementation
* for ESP32-S2 is doing it, so we copy that approach in Zephyr driver
*/
#define ADC_CLIP_MVOLT_11DB 2550
#elif CONFIG_SOC_SERIES_ESP32S2
#else
#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
#define ADC_RESOLUTION_MIN SOC_ADC_DIGI_MAX_BITWIDTH
#define ADC_RESOLUTION_MAX SOC_ADC_MAX_BITWIDTH
#elif CONFIG_SOC_SERIES_ESP32C3
#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
#define ADC_RESOLUTION_MIN SOC_ADC_DIGI_MAX_BITWIDTH
#define ADC_RESOLUTION_MAX SOC_ADC_DIGI_MAX_BITWIDTH
#elif CONFIG_SOC_SERIES_ESP32S3
#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP_FIT
#define ADC_RESOLUTION_MIN SOC_ADC_DIGI_MIN_BITWIDTH
#define ADC_RESOLUTION_MAX SOC_ADC_DIGI_MAX_BITWIDTH
#endif
/* Convert resolution in bits to esp32 enum values */
@ -64,9 +49,9 @@ struct adc_esp32_conf {
};
struct adc_esp32_data {
adc_atten_t attenuation[ADC_CHANNEL_MAX];
uint8_t resolution[ADC_CHANNEL_MAX];
esp_adc_cal_characteristics_t chars[ADC_CHANNEL_MAX];
adc_atten_t attenuation[SOC_ADC_MAX_CHANNEL_NUM];
uint8_t resolution[SOC_ADC_MAX_CHANNEL_NUM];
esp_adc_cal_characteristics_t chars[SOC_ADC_MAX_CHANNEL_NUM];
uint16_t meas_ref_internal;
uint16_t *buffer;
uint16_t *buffer_repeat;
@ -334,7 +319,7 @@ static const struct adc_driver_api api_esp32_driver_api = {
#define ESP32_ADC_INIT(inst) \
\
static const struct adc_esp32_conf adc_esp32_conf_##inst = { \
.unit = DT_PROP(DT_DRV_INST(inst), unit), \
.unit = DT_PROP(DT_DRV_INST(inst), unit) - 1, \
.channel_count = DT_PROP(DT_DRV_INST(inst), channel_count), \
}; \
\

View file

@ -14,29 +14,29 @@
#undef CPU_RESET_REASON
#define CPU_RESET_REASON SW_CPU_RESET
#include <zephyr/dt-bindings/clock/esp32_clock.h>
#include "esp32/rom/rtc.h"
#include "soc/dport_reg.h"
#include <esp32/rom/rtc.h>
#include <soc/dport_reg.h>
#elif defined(CONFIG_SOC_SERIES_ESP32S2)
#define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
#include <zephyr/dt-bindings/clock/esp32s2_clock.h>
#include "esp32s2/rom/rtc.h"
#include "soc/dport_reg.h"
#include <esp32s2/rom/rtc.h>
#include <soc/dport_reg.h>
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
#define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
#include <zephyr/dt-bindings/clock/esp32s3_clock.h>
#include "esp32s3/rom/rtc.h"
#include "soc/dport_reg.h"
#include "esp32s3/clk.h"
#include <esp32s3/rom/rtc.h>
#include <soc/dport_reg.h>
#elif CONFIG_SOC_SERIES_ESP32C3
#define DT_CPU_COMPAT espressif_riscv
#include <zephyr/dt-bindings/clock/esp32c3_clock.h>
#include "esp32c3/rom/rtc.h"
#include <esp32c3/rom/rtc.h>
#include <soc/soc_caps.h>
#include <soc/soc.h>
#include <soc/rtc.h>
#endif /* CONFIG_SOC_SERIES_ESP32xx */
#include "esp_rom_sys.h"
#include <esp_rom_sys.h>
#include <esp_rom_uart.h>
#include <soc/rtc.h>
#include <soc/i2s_reg.h>
#include <soc/apb_ctrl_reg.h>
@ -44,8 +44,10 @@
#include <hal/clk_gate_ll.h>
#include <soc.h>
#include <zephyr/drivers/clock_control.h>
#include <driver/periph_ctrl.h>
#include <hal/cpu_hal.h>
#include <esp_private/periph_ctrl.h>
#include <esp_private/esp_clk.h>
#include <esp_cpu.h>
#include <esp_rom_caps.h>
struct esp32_clock_config {
int clk_src_sel;
@ -54,21 +56,6 @@ struct esp32_clock_config {
int xtal_div;
};
static uint8_t const xtal_freq[] = {
#if defined(CONFIG_SOC_SERIES_ESP32) || \
defined(CONFIG_SOC_SERIES_ESP32S3)
[ESP32_CLK_XTAL_24M] = 24,
[ESP32_CLK_XTAL_26M] = 26,
[ESP32_CLK_XTAL_40M] = 40,
[ESP32_CLK_XTAL_AUTO] = 0
#elif defined(CONFIG_SOC_SERIES_ESP32S2)
[ESP32_CLK_XTAL_40M] = 40,
#elif defined(CONFIG_SOC_SERIES_ESP32C3)
[ESP32_CLK_XTAL_32M] = 32,
[ESP32_CLK_XTAL_40M] = 40,
#endif
};
static int clock_control_esp32_on(const struct device *dev,
clock_control_subsys_t sys)
{
@ -377,7 +364,7 @@ static void esp32_clock_perip_init(void)
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
SYSTEM_WIFI_CLK_BT_EN_M |
SYSTEM_WIFI_CLK_UNUSED_BIT5 |
SYSTEM_WIFI_CLK_I2C_CLK_EN |
SYSTEM_WIFI_CLK_UNUSED_BIT12 |
SYSTEM_WIFI_CLK_SDIO_HOST_EN;
}
@ -424,8 +411,14 @@ static void esp32_clock_perip_init(void)
/* Enable RNG clock. */
periph_module_enable(PERIPH_RNG_MODULE);
esp_rom_uart_tx_wait_idle(0);
esp_rom_uart_set_clock_baudrate(0, UART_CLK_FREQ_ROM, 115200);
/* Enable TimerGroup 0 clock to ensure its reference counter will never
* be decremented to 0 during normal operation and preventing it from
* being disabled.
* If the TimerGroup 0 clock is disabled and then reenabled, the watchdog
* registers (Flashboot protection included) will be reenabled, and some
* seconds later, will trigger an unintended reset.
*/
periph_module_enable(PERIPH_TIMG0_MODULE);
}
#endif /* CONFIG_SOC_SERIES_ESP32S3 */
@ -472,7 +465,7 @@ static void esp32_clock_perip_init(void)
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
SYSTEM_WIFI_CLK_BT_EN_M |
SYSTEM_WIFI_CLK_UNUSED_BIT5 |
SYSTEM_WIFI_CLK_I2C_CLK_EN |
SYSTEM_WIFI_CLK_UNUSED_BIT12;
}
@ -529,10 +522,10 @@ static int clock_control_esp32_init(const struct device *dev)
if (rtc_clk_apb_freq_get() < APB_CLK_FREQ || rtc_get_reset_reason(0) != CPU_RESET_REASON) {
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
clk_cfg.xtal_freq = xtal_freq[cfg->xtal_freq_sel];
clk_cfg.xtal_freq = cfg->xtal_freq_sel;
clk_cfg.cpu_freq_mhz = cfg->cpu_freq;
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
clk_cfg.slow_clk_src = rtc_clk_slow_freq_get();
clk_cfg.fast_clk_src = rtc_clk_fast_freq_get();
rtc_clk_init(clk_cfg);
}
@ -563,10 +556,19 @@ static int clock_control_esp32_init(const struct device *dev)
rtc_clk_cpu_freq_set_config(&new_config);
/* Re-calculate the ccount to make time calculation correct */
cpu_hal_set_cycle_count((uint64_t)cpu_hal_get_cycle_count() * new_freq_mhz / old_freq_mhz);
esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz);
esp32_clock_perip_init();
uint32_t clock_hz = esp_clk_apb_freq();
#if ESP_ROM_UART_CLK_IS_XTAL
clock_hz = esp_clk_xtal_freq();
#endif
esp_rom_uart_tx_wait_idle(ESP_CONSOLE_UART_NUM);
#if !defined(ESP_CONSOLE_UART_NONE)
esp_rom_uart_set_clock_baudrate(ESP_CONSOLE_UART_NUM, clock_hz, ESP_CONSOLE_UART_BAUDRATE);
#endif
return 0;
}

View file

@ -9,10 +9,11 @@
/* Include esp-idf headers first to avoid redefining BIT() macro */
#include <soc/rtc_cntl_reg.h>
#include <soc/timer_group_reg.h>
#include <driver/periph_ctrl.h>
#include <periph_ctrl.h>
#include <driver/timer_types_legacy.h>
#include <soc/periph_defs.h>
#include <hal/timer_types.h>
#include <hal/timer_hal.h>
#include <hal/timer_ll.h>
#include <string.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/spinlock.h>
@ -80,22 +81,18 @@ static int counter_esp32_init(const struct device *dev)
timer_hal_init(&data->hal_ctx, cfg->group, cfg->index);
data->alarm_cfg.callback = NULL;
timer_hal_intr_disable(&data->hal_ctx);
timer_hal_clear_intr_status(&data->hal_ctx);
timer_hal_set_auto_reload(&data->hal_ctx, cfg->config.auto_reload);
timer_hal_set_divider(&data->hal_ctx, cfg->config.divider);
timer_hal_set_counter_increase(&data->hal_ctx, cfg->config.counter_dir);
timer_hal_set_alarm_enable(&data->hal_ctx, cfg->config.alarm_en);
if (cfg->config.intr_type == TIMER_INTR_LEVEL) {
timer_hal_set_level_int_enable(&data->hal_ctx, true);
}
timer_hal_set_counter_value(&data->hal_ctx, 0);
timer_hal_set_counter_enable(&data->hal_ctx, cfg->config.counter_en);
esp_intr_alloc(cfg->irq_source,
0,
(ISR_HANDLER)counter_esp32_isr,
(void *)dev,
NULL);
timer_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id),
false);
timer_ll_clear_intr_status(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id));
timer_ll_enable_auto_reload(data->hal_ctx.dev, data->hal_ctx.timer_id,
cfg->config.auto_reload);
timer_ll_set_clock_prescale(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.divider);
timer_ll_set_count_direction(data->hal_ctx.dev, data->hal_ctx.timer_id,
cfg->config.counter_dir);
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.alarm_en);
timer_ll_set_reload_value(data->hal_ctx.dev, data->hal_ctx.timer_id, 0);
timer_ll_enable_counter(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.counter_en);
esp_intr_alloc(cfg->irq_source, 0, (ISR_HANDLER)counter_esp32_isr, (void *)dev, NULL);
k_spin_unlock(&lock, key);
return 0;
@ -106,7 +103,7 @@ static int counter_esp32_start(const struct device *dev)
struct counter_esp32_data *data = dev->data;
k_spinlock_key_t key = k_spin_lock(&lock);
timer_hal_set_counter_enable(&data->hal_ctx, TIMER_START);
timer_ll_enable_counter(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_START);
k_spin_unlock(&lock, key);
return 0;
@ -117,7 +114,7 @@ static int counter_esp32_stop(const struct device *dev)
struct counter_esp32_data *data = dev->data;
k_spinlock_key_t key = k_spin_lock(&lock);
timer_hal_set_counter_enable(&data->hal_ctx, TIMER_PAUSE);
timer_ll_enable_counter(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_PAUSE);
k_spin_unlock(&lock, key);
return 0;
@ -128,7 +125,7 @@ static int counter_esp32_get_value(const struct device *dev, uint32_t *ticks)
struct counter_esp32_data *data = dev->data;
k_spinlock_key_t key = k_spin_lock(&lock);
timer_hal_get_counter_value(&data->hal_ctx, (uint64_t *)ticks);
*ticks = timer_ll_get_counter_value(data->hal_ctx.dev, data->hal_ctx.timer_id);
k_spin_unlock(&lock, key);
return 0;
@ -146,13 +143,15 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
k_spinlock_key_t key = k_spin_lock(&lock);
if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
timer_hal_set_alarm_value(&data->hal_ctx, (now + alarm_cfg->ticks));
timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id,
(now + alarm_cfg->ticks));
} else {
timer_hal_set_alarm_value(&data->hal_ctx, alarm_cfg->ticks);
timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id,
alarm_cfg->ticks);
}
timer_hal_intr_enable(&data->hal_ctx);
timer_hal_set_alarm_enable(&data->hal_ctx, TIMER_ALARM_EN);
timer_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id), true);
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_ALARM_EN);
data->alarm_cfg.callback = alarm_cfg->callback;
data->alarm_cfg.user_data = alarm_cfg->user_data;
k_spin_unlock(&lock, key);
@ -167,8 +166,9 @@ static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id)
k_spinlock_key_t key = k_spin_lock(&lock);
timer_hal_intr_disable(&data->hal_ctx);
timer_hal_set_alarm_enable(&data->hal_ctx, TIMER_ALARM_DIS);
timer_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id),
false);
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_ALARM_DIS);
k_spin_unlock(&lock, key);
return 0;
@ -190,9 +190,7 @@ static uint32_t counter_esp32_get_pending_int(const struct device *dev)
{
struct counter_esp32_data *data = dev->data;
timer_hal_get_intr_status_reg(&data->hal_ctx);
return 0;
return timer_ll_get_intr_status(data->hal_ctx.dev);
}
static uint32_t counter_esp32_get_top_value(const struct device *dev)
@ -226,7 +224,7 @@ static void counter_esp32_isr(void *arg)
data->alarm_cfg.callback(dev, 0, now, data->alarm_cfg.user_data);
}
timer_hal_clear_intr_status(&data->hal_ctx);
timer_ll_clear_intr_status(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id));
}
#define ESP32_COUNTER_GET_CLK_DIV(idx) \

View file

@ -13,9 +13,7 @@
#include <hal/rtc_io_types.h>
#include <hal/rtc_io_hal.h>
#include <hal/rtc_io_ll.h>
#include <hal/dac_hal.h>
#include <hal/dac_types.h>
#include "driver/dac_common.h"
#include "driver/dac.h"
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(esp32_dac, CONFIG_DAC_LOG_LEVEL);
@ -41,7 +39,7 @@ static int dac_esp32_channel_setup(const struct device *dev,
{
ARG_UNUSED(dev);
if (channel_cfg->channel_id > DAC_CHANNEL_MAX) {
if (channel_cfg->channel_id > SOC_DAC_CHAN_NUM) {
LOG_ERR("Channel %d is not valid", channel_cfg->channel_id);
return -EINVAL;
}
@ -66,7 +64,7 @@ static int dac_esp32_init(const struct device *dev)
}
if (clock_control_on(cfg->clock_dev,
(clock_control_subsys_t) cfg->clock_subsys) != 0) {
(clock_control_subsys_t) &cfg->clock_subsys) != 0) {
LOG_ERR("DAC clock setup failed (%d)", -EIO);
return -EIO;
}

View file

@ -11,11 +11,11 @@ LOG_MODULE_REGISTER(dma_esp32_gdma, CONFIG_DMA_LOG_LEVEL);
#include <hal/gdma_hal.h>
#include <hal/gdma_ll.h>
#include <gdma_channel.h>
#include <soc/gdma_channel.h>
#include <hal/dma_types.h>
#include <soc.h>
#include <soc/soc_memory_types.h>
#include <esp_memory_utils.h>
#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/dma.h>
@ -34,6 +34,8 @@ LOG_MODULE_REGISTER(dma_esp32_gdma, CONFIG_DMA_LOG_LEVEL);
#endif
#define DMA_MAX_CHANNEL SOC_GDMA_PAIRS_PER_GROUP
#define ESP_DMA_M2M_ON 0
#define ESP_DMA_M2M_OFF 1
struct dma_esp32_data {
gdma_hal_context_t hal;
@ -181,10 +183,12 @@ static int dma_esp32_config_rx(const struct device *dev, struct dma_esp32_channe
gdma_ll_rx_reset_channel(data->hal.dev, dma_channel->channel_id);
if (dma_channel->periph_id != SOC_GDMA_TRIG_PERIPH_M2M0) {
gdma_ll_rx_connect_to_periph(data->hal.dev, dma_channel->channel_id,
dma_channel->periph_id);
}
gdma_ll_rx_connect_to_periph(
data->hal.dev, dma_channel->channel_id,
dma_channel->periph_id == SOC_GDMA_TRIG_PERIPH_M2M0 ? ESP_DMA_M2M_ON
: ESP_DMA_M2M_OFF,
dma_channel->periph_id == SOC_GDMA_TRIG_PERIPH_M2M0 ? ESP_DMA_M2M_ON
: dma_channel->periph_id);
if (config_dma->dest_burst_length) {
/*
@ -236,10 +240,12 @@ static int dma_esp32_config_tx(const struct device *dev, struct dma_esp32_channe
gdma_ll_tx_reset_channel(data->hal.dev, dma_channel->channel_id);
if (dma_channel->periph_id != SOC_GDMA_TRIG_PERIPH_M2M0) {
gdma_ll_tx_connect_to_periph(data->hal.dev, dma_channel->channel_id,
dma_channel->periph_id);
}
gdma_ll_tx_connect_to_periph(
data->hal.dev, dma_channel->channel_id,
dma_channel->periph_id == SOC_GDMA_TRIG_PERIPH_M2M0 ? ESP_DMA_M2M_ON
: ESP_DMA_M2M_OFF,
dma_channel->periph_id == SOC_GDMA_TRIG_PERIPH_M2M0 ? ESP_DMA_M2M_ON
: dma_channel->periph_id);
/*
* TX channel can always enable burst mode, no matter data alignment
@ -288,9 +294,6 @@ static int dma_esp32_config(const struct device *dev, uint32_t channel,
dma_channel->channel_id = channel / 2;
gdma_ll_enable_m2m_mode(data->hal.dev, dma_channel->channel_id,
config_dma->channel_direction == MEMORY_TO_MEMORY);
switch (config_dma->channel_direction) {
case MEMORY_TO_MEMORY:
/*
@ -538,7 +541,7 @@ static int dma_esp32_init(const struct device *dev)
dma_channel = &config->dma_channel[i];
dma_channel->cb = NULL;
dma_channel->dir = DMA_UNCONFIGURED;
dma_channel->periph_id = GDMA_TRIG_PERIPH_INVALID;
dma_channel->periph_id = ESP_GDMA_TRIG_PERIPH_INVALID;
memset(&dma_channel->desc, 0, sizeof(dma_descriptor_t));
}

View file

@ -13,7 +13,7 @@
#include <soc/apb_ctrl_reg.h>
#include <esp_system.h>
#include <soc.h>
#include <hal/cpu_hal.h>
#include <esp_cpu.h>
#include <zephyr/drivers/entropy.h>
static inline uint32_t entropy_esp32_get_u32(void)
@ -33,7 +33,7 @@ static inline uint32_t entropy_esp32_get_u32(void)
uint32_t ccount;
do {
ccount = cpu_hal_get_cycle_count();
ccount = esp_cpu_get_cycle_count();
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16);
last_ccount = ccount;

View file

@ -285,9 +285,12 @@ int eth_esp32_initialize(const struct device *dev)
goto err;
}
/* Set dma_burst_len as ETH_DMA_BURST_LEN_32 by default */
emac_hal_dma_config_t dma_config = { .dma_burst_len = 0 };
emac_hal_reset_desc_chain(&dev_data->hal);
emac_hal_init_mac_default(&dev_data->hal);
emac_hal_init_dma_default(&dev_data->hal);
emac_hal_init_dma_default(&dev_data->hal, &dma_config);
res = generate_mac_addr(dev_data->mac_addr);
if (res != 0) {

View file

@ -14,13 +14,11 @@
* HAL includes go first to
* avoid BIT macro redefinition
*/
#include <esp_spi_flash.h>
#include <hal/spi_ll.h>
#include <hal/spi_flash_ll.h>
#include <hal/spi_flash_hal.h>
#include <esp_flash.h>
#include <spi_flash_mmap.h>
#include <soc/spi_struct.h>
#include <spi_flash_defs.h>
#include <esp_flash_encrypt.h>
#include <esp_flash_internal.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
@ -30,30 +28,6 @@
#include <zephyr/drivers/flash.h>
#include <soc.h>
#if defined(CONFIG_SOC_SERIES_ESP32)
#include "soc/dport_reg.h"
#include "esp32/rom/cache.h"
#include "esp32/rom/spi_flash.h"
#include "esp32/spiram.h"
#elif defined(CONFIG_SOC_SERIES_ESP32S2)
#include "soc/spi_mem_reg.h"
#include "esp32s2/rom/cache.h"
#include "esp32s2/rom/spi_flash.h"
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
#include "soc/spi_mem_reg.h"
#include "esp32s3/rom/cache.h"
#include "esp32s3/rom/spi_flash.h"
#elif defined(CONFIG_SOC_SERIES_ESP32C3)
#include "soc/spi_periph.h"
#include "soc/spi_mem_reg.h"
#include "soc/dport_access.h"
#include "esp32c3/dport_access.h"
#include "esp32c3/rom/cache.h"
#include "esp32c3/rom/spi_flash.h"
#endif
#include "soc/mmu.h"
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL);
@ -101,9 +75,9 @@ static int flash_esp32_read(const struct device *dev, off_t address, void *buffe
flash_esp32_sem_take(dev);
if (!esp_flash_encryption_enabled()) {
ret = spi_flash_read(address, buffer, length);
ret = esp_flash_read(NULL, buffer, address, length);
} else {
ret = spi_flash_read_encrypted(address, buffer, length);
ret = esp_flash_read_encrypted(NULL, address, buffer, length);
}
flash_esp32_sem_give(dev);
return ret;
@ -118,9 +92,9 @@ static int flash_esp32_write(const struct device *dev,
flash_esp32_sem_take(dev);
if (!esp_flash_encryption_enabled()) {
ret = spi_flash_write(address, buffer, length);
ret = esp_flash_write(NULL, buffer, address, length);
} else {
ret = spi_flash_write_encrypted(address, buffer, length);
ret = esp_flash_write_encrypted(NULL, address, buffer, length);
}
flash_esp32_sem_give(dev);
return ret;
@ -129,7 +103,7 @@ static int flash_esp32_write(const struct device *dev,
static int flash_esp32_erase(const struct device *dev, off_t start, size_t len)
{
flash_esp32_sem_take(dev);
int ret = spi_flash_erase_range(start, len);
int ret = esp_flash_erase_region(NULL, start, len);
flash_esp32_sem_give(dev);
return ret;
}
@ -160,11 +134,16 @@ flash_esp32_get_parameters(const struct device *dev)
static int flash_esp32_init(const struct device *dev)
{
struct flash_esp32_dev_data *const dev_data = dev->data;
uint32_t ret = 0;
#ifdef CONFIG_MULTITHREADING
k_sem_init(&dev_data->sem, 1, 1);
#endif /* CONFIG_MULTITHREADING */
ret = esp_flash_init_default_chip();
if (ret != 0) {
LOG_ERR("esp_flash_init_default_chip failed %d", ret);
return 0;
}
return 0;
}

View file

@ -13,6 +13,7 @@
#include <hal/i2c_ll.h>
#include <hal/i2c_hal.h>
#include <hal/gpio_hal.h>
#include <clk_ctrl_os.h>
#include <soc.h>
#include <errno.h>
@ -40,6 +41,8 @@ LOG_MODULE_REGISTER(i2c_esp32, CONFIG_I2C_LOG_LEVEL);
#define I2C_CLK_LIMIT_RTC (20 * 1000 * 1000 / 20) /* Limited by RTC, no more than RTC/20 */
#define I2C_CLK_LIMIT_XTAL (40 * 1000 * 1000 / 20) /* Limited by RTC, no more than XTAL/20 */
#define I2C_CLOCK_INVALID (-1)
enum i2c_status_t {
I2C_STATUS_READ, /* read status for current master command */
I2C_STATUS_WRITE, /* write status for current master command */
@ -93,31 +96,52 @@ struct i2c_esp32_config {
const uint32_t scl_timeout;
};
/* I2C clock characteristic, The order is the same as i2c_sclk_t. */
static uint32_t i2c_clk_alloc[I2C_SCLK_MAX] = {
0,
static uint32_t i2c_get_src_clk_freq(i2c_clock_source_t clk_src)
{
uint32_t periph_src_clk_hz = 0;
switch (clk_src) {
#if SOC_I2C_SUPPORT_APB
I2C_CLK_LIMIT_APB, /* I2C APB clock characteristic */
case I2C_CLK_SRC_APB:
periph_src_clk_hz = esp_clk_apb_freq();
break;
#endif
#if SOC_I2C_SUPPORT_XTAL
I2C_CLK_LIMIT_XTAL, /* I2C XTAL characteristic */
case I2C_CLK_SRC_XTAL:
periph_src_clk_hz = esp_clk_xtal_freq();
break;
#endif
#if SOC_I2C_SUPPORT_RTC
I2C_CLK_LIMIT_RTC, /* I2C 20M RTC characteristic */
case I2C_CLK_SRC_RC_FAST:
periph_rtc_dig_clk8m_enable();
periph_src_clk_hz = periph_rtc_dig_clk8m_get_freq();
break;
#endif
#if SOC_I2C_SUPPORT_REF_TICK
I2C_CLK_LIMIT_REF_TICK, /* I2C REF_TICK characteristic */
case RMT_CLK_SRC_REF_TICK:
periph_src_clk_hz = REF_CLK_FREQ;
break;
#endif
};
default:
LOG_ERR("clock source %d is not supported", clk_src);
break;
}
static i2c_sclk_t i2c_get_clk_src(uint32_t clk_freq)
return periph_src_clk_hz;
}
static i2c_clock_source_t i2c_get_clk_src(uint32_t clk_freq)
{
for (i2c_sclk_t clk = I2C_SCLK_DEFAULT + 1; clk < I2C_SCLK_MAX; clk++) {
if (clk_freq <= i2c_clk_alloc[clk]) {
return clk;
i2c_clock_source_t clk_srcs[] = SOC_I2C_CLKS;
for (size_t i = 0; i < ARRAY_SIZE(clk_srcs); i++) {
/* I2C SCL clock frequency should not larger than clock source frequency/20 */
if (clk_freq <= (i2c_get_src_clk_freq(clk_srcs[i]) / 20)) {
return clk_srcs[i];
}
}
return I2C_SCLK_MAX; /* flag invalid */
return I2C_CLOCK_INVALID;
}
#ifndef SOC_I2C_SUPPORT_HW_CLR_BUS
@ -181,9 +205,9 @@ static void IRAM_ATTR i2c_master_clear_bus(const struct device *dev)
gpio_pin_set_dt(&config->sda.gpio, 1); /* STOP, SDA low -> high while SCL is HIGH */
i2c_esp32_config_pin(dev);
#else
i2c_hal_master_clr_bus(&data->hal);
i2c_ll_master_clr_bus(data->hal.dev);
#endif
i2c_hal_update_config(&data->hal);
i2c_ll_update(data->hal.dev);
}
static void IRAM_ATTR i2c_hw_fsm_reset(const struct device *dev)
@ -199,32 +223,32 @@ static void IRAM_ATTR i2c_hw_fsm_reset(const struct device *dev)
int timeout;
uint8_t filter_cfg;
i2c_hal_get_scl_timing(&data->hal, &scl_high_period, &scl_low_period);
i2c_hal_get_start_timing(&data->hal, &scl_rstart_setup, &scl_start_hold);
i2c_hal_get_stop_timing(&data->hal, &scl_stop_setup, &scl_stop_hold);
i2c_hal_get_sda_timing(&data->hal, &sda_sample, &sda_hold);
i2c_hal_get_tout(&data->hal, &timeout);
i2c_hal_get_filter(&data->hal, &filter_cfg);
i2c_ll_get_scl_timing(data->hal.dev, &scl_high_period, &scl_low_period);
i2c_ll_get_start_timing(data->hal.dev, &scl_rstart_setup, &scl_start_hold);
i2c_ll_get_stop_timing(data->hal.dev, &scl_stop_setup, &scl_stop_hold);
i2c_ll_get_sda_timing(data->hal.dev, &sda_sample, &sda_hold);
i2c_ll_get_tout(data->hal.dev, &timeout);
i2c_ll_get_filter(data->hal.dev, &filter_cfg);
/* to reset the I2C hw module, we need re-enable the hw */
clock_control_off(config->clock_dev, config->clock_subsys);
i2c_master_clear_bus(dev);
clock_control_on(config->clock_dev, config->clock_subsys);
i2c_hal_master_init(&data->hal, config->index);
i2c_hal_disable_intr_mask(&data->hal, I2C_LL_INTR_MASK);
i2c_hal_clr_intsts_mask(&data->hal, I2C_LL_INTR_MASK);
i2c_hal_set_scl_timing(&data->hal, scl_high_period, scl_low_period);
i2c_hal_set_start_timing(&data->hal, scl_rstart_setup, scl_start_hold);
i2c_hal_set_stop_timing(&data->hal, scl_stop_setup, scl_stop_hold);
i2c_hal_set_sda_timing(&data->hal, sda_sample, sda_hold);
i2c_hal_set_tout(&data->hal, timeout);
i2c_hal_set_filter(&data->hal, filter_cfg);
i2c_hal_master_init(&data->hal);
i2c_ll_disable_intr_mask(data->hal.dev, I2C_LL_INTR_MASK);
i2c_ll_clear_intr_mask(data->hal.dev, I2C_LL_INTR_MASK);
i2c_ll_set_scl_timing(data->hal.dev, scl_high_period, scl_low_period);
i2c_ll_set_start_timing(data->hal.dev, scl_rstart_setup, scl_start_hold);
i2c_ll_set_stop_timing(data->hal.dev, scl_stop_setup, scl_stop_hold);
i2c_ll_set_sda_timing(data->hal.dev, sda_sample, sda_hold);
i2c_ll_set_tout(data->hal.dev, timeout);
i2c_ll_set_filter(data->hal.dev, filter_cfg);
#else
i2c_hal_master_fsm_rst(&data->hal);
i2c_ll_master_fsm_rst(data->hal.dev);
i2c_master_clear_bus(dev);
#endif
i2c_hal_update_config(&data->hal);
i2c_ll_update(data->hal.dev);
}
static int i2c_esp32_recover(const struct device *dev)
@ -244,22 +268,18 @@ static void IRAM_ATTR i2c_esp32_configure_timeout(const struct device *dev)
struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data;
if (config->scl_timeout > 0) {
i2c_sclk_t sclk = i2c_get_clk_src(config->bitrate);
uint32_t clk_freq_mhz = i2c_clk_alloc[sclk];
i2c_clock_source_t sclk = i2c_get_clk_src(config->bitrate);
uint32_t clk_freq_mhz = i2c_get_src_clk_freq(sclk);
uint32_t timeout_cycles = MIN(I2C_LL_MAX_TIMEOUT,
clk_freq_mhz / MHZ(1) * config->scl_timeout);
i2c_hal_set_tout(&data->hal, timeout_cycles);
i2c_ll_set_tout(data->hal.dev, timeout_cycles);
LOG_DBG("SCL timeout: %d us, value: %d", config->scl_timeout, timeout_cycles);
} else {
/* Disabling the timeout by clearing the I2C_TIME_OUT_EN bit does not seem to work,
* at least for ESP32-C3 (tested with communication to bq76952 chip). So we set the
* timeout to maximum supported value instead.
*/
#if defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32)
i2c_hal_set_tout(&data->hal, I2C_LL_MAX_TIMEOUT);
#else
i2c_hal_set_tout_en(&data->hal, 0);
#endif
i2c_ll_set_tout(data->hal.dev, I2C_LL_MAX_TIMEOUT);
}
}
@ -286,19 +306,21 @@ static int i2c_esp32_configure(const struct device *dev, uint32_t dev_config)
rx_mode = I2C_DATA_MODE_LSB_FIRST;
}
i2c_hal_master_init(&data->hal, config->index);
i2c_hal_set_data_mode(&data->hal, tx_mode, rx_mode);
i2c_hal_set_filter(&data->hal, I2C_FILTER_CYC_NUM_DEF);
i2c_hal_update_config(&data->hal);
i2c_hal_master_init(&data->hal);
i2c_ll_set_data_mode(data->hal.dev, tx_mode, rx_mode);
i2c_ll_set_filter(data->hal.dev, I2C_FILTER_CYC_NUM_DEF);
i2c_ll_update(data->hal.dev);
if (config->bitrate == 0) {
LOG_ERR("Error configuring I2C speed.");
return -ENOTSUP;
}
i2c_hal_set_bus_timing(&data->hal, config->bitrate, i2c_get_clk_src(config->bitrate));
i2c_clock_source_t sclk = i2c_get_clk_src(config->bitrate);
i2c_hal_set_bus_timing(&data->hal, config->bitrate, sclk, i2c_get_src_clk_freq(sclk));
i2c_esp32_configure_timeout(dev);
i2c_hal_update_config(&data->hal);
i2c_ll_update(data->hal.dev);
return 0;
}
@ -308,8 +330,8 @@ static void IRAM_ATTR i2c_esp32_reset_fifo(const struct device *dev)
struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data;
/* reset fifo buffers */
i2c_hal_txfifo_rst(&data->hal);
i2c_hal_rxfifo_rst(&data->hal);
i2c_ll_txfifo_rst(data->hal.dev);
i2c_ll_rxfifo_rst(data->hal.dev);
}
static int IRAM_ATTR i2c_esp32_transmit(const struct device *dev)
@ -318,8 +340,8 @@ static int IRAM_ATTR i2c_esp32_transmit(const struct device *dev)
int ret = 0;
/* Start transmission*/
i2c_hal_update_config(&data->hal);
i2c_hal_trans_start(&data->hal);
i2c_ll_update(data->hal.dev);
i2c_ll_trans_start(data->hal.dev);
data->cmd_idx = 0;
ret = k_sem_take(&data->cmd_sem, K_MSEC(I2C_TRANSFER_TIMEOUT_MSEC));
@ -345,22 +367,22 @@ static void IRAM_ATTR i2c_esp32_master_start(const struct device *dev)
{
struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data;
i2c_hw_cmd_t cmd = {
i2c_ll_hw_cmd_t cmd = {
.op_code = I2C_LL_CMD_RESTART
};
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
}
static void IRAM_ATTR i2c_esp32_master_stop(const struct device *dev)
{
struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data;
i2c_hw_cmd_t cmd = {
i2c_ll_hw_cmd_t cmd = {
.op_code = I2C_LL_CMD_STOP
};
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
}
static int IRAM_ATTR i2c_esp32_write_addr(const struct device *dev, uint16_t addr)
@ -372,26 +394,26 @@ static int IRAM_ATTR i2c_esp32_write_addr(const struct device *dev, uint16_t add
data->status = I2C_STATUS_WRITE;
/* write address value in tx buffer */
i2c_hal_write_txfifo(&data->hal, &addr_byte, 1);
i2c_ll_write_txfifo(data->hal.dev, &addr_byte, 1);
if (data->dev_config & I2C_ADDR_10_BITS) {
addr_byte = (addr >> 8) & 0xFF;
i2c_hal_write_txfifo(&data->hal, &addr_byte, 1);
i2c_ll_write_txfifo(data->hal.dev, &addr_byte, 1);
addr_len++;
}
const i2c_hw_cmd_t cmd_end = {
const i2c_ll_hw_cmd_t cmd_end = {
.op_code = I2C_LL_CMD_END,
};
i2c_hw_cmd_t cmd = {
i2c_ll_hw_cmd_t cmd = {
.op_code = I2C_LL_CMD_WRITE,
.ack_en = true,
.byte_num = addr_len,
};
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
i2c_hal_write_cmd_reg(&data->hal, cmd_end, data->cmd_idx++);
i2c_hal_enable_master_tx_it(&data->hal);
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
i2c_ll_write_cmd_reg(data->hal.dev, cmd_end, data->cmd_idx++);
i2c_ll_master_enable_tx_it(data->hal.dev);
return i2c_esp32_transmit(dev);
}
@ -407,10 +429,10 @@ static int IRAM_ATTR i2c_esp32_master_read(const struct device *dev, struct i2c_
data->status = I2C_STATUS_READ;
i2c_hw_cmd_t cmd = {
i2c_ll_hw_cmd_t cmd = {
.op_code = I2C_LL_CMD_READ,
};
const i2c_hw_cmd_t cmd_end = {
const i2c_ll_hw_cmd_t cmd_end = {
.op_code = I2C_LL_CMD_END,
};
@ -429,15 +451,15 @@ static int IRAM_ATTR i2c_esp32_master_read(const struct device *dev, struct i2c_
}
cmd.byte_num = rd_filled;
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
i2c_hal_write_cmd_reg(&data->hal, cmd_end, data->cmd_idx++);
i2c_hal_enable_master_rx_it(&data->hal);
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
i2c_ll_write_cmd_reg(data->hal.dev, cmd_end, data->cmd_idx++);
i2c_ll_master_enable_tx_it(data->hal.dev);
ret = i2c_esp32_transmit(dev);
if (ret < 0) {
return ret;
}
i2c_hal_read_rxfifo(&data->hal, msg_buf, rd_filled);
i2c_ll_read_rxfifo(data->hal.dev, msg_buf, rd_filled);
msg_buf += rd_filled;
msg_len -= rd_filled;
}
@ -491,12 +513,12 @@ static int IRAM_ATTR i2c_esp32_master_write(const struct device *dev, struct i2c
data->status = I2C_STATUS_WRITE;
i2c_hw_cmd_t cmd = {
i2c_ll_hw_cmd_t cmd = {
.op_code = I2C_LL_CMD_WRITE,
.ack_en = true,
};
const i2c_hw_cmd_t cmd_end = {
const i2c_ll_hw_cmd_t cmd_end = {
.op_code = I2C_LL_CMD_END,
};
@ -505,10 +527,10 @@ static int IRAM_ATTR i2c_esp32_master_write(const struct device *dev, struct i2c
cmd.byte_num = wr_filled;
if (wr_filled > 0) {
i2c_hal_write_txfifo(&data->hal, msg_buf, wr_filled);
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
i2c_hal_write_cmd_reg(&data->hal, cmd_end, data->cmd_idx++);
i2c_hal_enable_master_tx_it(&data->hal);
i2c_ll_write_txfifo(data->hal.dev, msg_buf, wr_filled);
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
i2c_ll_write_cmd_reg(data->hal.dev, cmd_end, data->cmd_idx++);
i2c_ll_master_enable_tx_it(data->hal.dev);
ret = i2c_esp32_transmit(dev);
if (ret < 0) {
return ret;
@ -567,7 +589,7 @@ static int IRAM_ATTR i2c_esp32_transfer(const struct device *dev, struct i2c_msg
return 0;
}
while (i2c_hal_is_bus_busy(&data->hal)) {
while (i2c_ll_is_bus_busy(data->hal.dev)) {
k_busy_wait(1);
if (timeout-- == 0) {
return -EBUSY;
@ -617,7 +639,7 @@ static int IRAM_ATTR i2c_esp32_transfer(const struct device *dev, struct i2c_msg
for (; num_msgs > 0; num_msgs--, msgs++) {
if (data->status == I2C_STATUS_TIMEOUT || i2c_hal_is_bus_busy(&data->hal)) {
if (data->status == I2C_STATUS_TIMEOUT || i2c_ll_is_bus_busy(data->hal.dev)) {
i2c_hw_fsm_reset(dev);
}
@ -626,8 +648,8 @@ static int IRAM_ATTR i2c_esp32_transfer(const struct device *dev, struct i2c_msg
/* These two interrupts some times can not be cleared when the FSM gets stuck. */
/* So we disable them when these two interrupt occurs and re-enable them here. */
i2c_hal_disable_intr_mask(&data->hal, I2C_LL_INTR_MASK);
i2c_hal_clr_intsts_mask(&data->hal, I2C_LL_INTR_MASK);
i2c_ll_disable_intr_mask(data->hal.dev, I2C_LL_INTR_MASK);
i2c_ll_clear_intr_mask(data->hal.dev, I2C_LL_INTR_MASK);
if ((msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
ret = i2c_esp32_read_msg(dev, msgs, addr);

View file

@ -12,12 +12,14 @@
#include <string.h>
#include <soc.h>
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
#include "esp_attr.h"
#include <hal/cpu_hal.h>
#include <hal/interrupt_controller_hal.h>
#include <esp_memory_utils.h>
#include <esp_attr.h>
#include <esp_cpu.h>
#include <esp_private/rtc_ctrl.h>
#include <limits.h>
#include <assert.h>
#include "soc/soc.h"
#include <soc/soc.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(esp32_intc, CONFIG_LOG_DEFAULT_LEVEL);
@ -73,9 +75,9 @@ struct intr_alloc_table_entry {
};
/* Default handler for unhandled interrupts. */
void default_intr_handler(void *arg)
void IRAM_ATTR default_intr_handler(void *arg)
{
printk("Unhandled interrupt %d on cpu %d!\n", (int)arg, esp_core_id());
esp_rom_printf("Unhandled interrupt %d on cpu %d!\n", (int)arg, esp_cpu_get_core_id());
}
static struct intr_alloc_table_entry intr_alloc_table[ESP_INTC_INTS_NUM * CONFIG_MP_MAX_NUM_CPUS];
@ -84,8 +86,7 @@ static void set_interrupt_handler(int n, intc_handler_t f, void *arg)
{
irq_disable(n);
intr_alloc_table[n * CONFIG_MP_MAX_NUM_CPUS].handler = f;
irq_connect_dynamic(n, n, (intc_dyn_handler_t)f, arg, 0);
irq_enable(n);
irq_connect_dynamic(n, 0, (intc_dyn_handler_t)f, arg, 0);
}
/* Linked list of vector descriptions, sorted by cpu.intno value */
@ -271,28 +272,33 @@ static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, in
{
/* Check if interrupt is not reserved by design */
int x = vd->intno;
esp_cpu_intr_desc_t intr_desc;
if (interrupt_controller_hal_get_cpu_desc_flags(x, cpu) == INTDESC_RESVD) {
esp_cpu_intr_get_desc(cpu, x, &intr_desc);
if (intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD) {
INTC_LOG("....Unusable: reserved");
return false;
}
if (interrupt_controller_hal_get_cpu_desc_flags(x, cpu) == INTDESC_SPECIAL && force == -1) {
if (intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_SPECIAL && force == -1) {
INTC_LOG("....Unusable: special-purpose int");
return false;
}
/* Check if the interrupt level is acceptable */
if (!(flags & (1 << interrupt_controller_hal_get_level(x)))) {
INTC_LOG("....Unusable: incompatible level");
#ifndef SOC_CPU_HAS_FLEXIBLE_INTC
/* Check if the interrupt priority is acceptable */
if (!(flags & (1 << intr_desc.priority))) {
INTC_LOG("....Unusable: incompatible priority");
return false;
}
/* check if edge/level type matches what we want */
if (((flags & ESP_INTR_FLAG_EDGE) &&
(interrupt_controller_hal_get_type(x) == INTTP_LEVEL)) ||
(((!(flags & ESP_INTR_FLAG_EDGE)) &&
(interrupt_controller_hal_get_type(x) == INTTP_EDGE)))) {
if (((flags & ESP_INTR_FLAG_EDGE) && (intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL)) ||
(((!(flags & ESP_INTR_FLAG_EDGE)) && (intr_desc.type == ESP_CPU_INTR_TYPE_EDGE)))) {
INTC_LOG("....Unusable: incompatible trigger type");
return false;
}
#endif
/* check if interrupt is reserved at runtime */
if (vd->flags & VECDESC_FL_RESERVED) {
INTC_LOG("....Unusable: reserved at runtime.");
@ -353,7 +359,6 @@ static int get_available_int(int flags, int cpu, int force, int source)
memset(&empty_vect_desc, 0, sizeof(struct vector_desc_t));
/* Level defaults to any low/med interrupt */
if (!(flags & ESP_INTR_FLAG_LEVELMASK)) {
flags |= ESP_INTR_FLAG_LOWMED;
@ -403,11 +408,14 @@ static int get_available_int(int flags, int cpu, int force, int source)
vd = &empty_vect_desc;
}
esp_cpu_intr_desc_t intr_desc;
esp_cpu_intr_get_desc(cpu, x, &intr_desc);
INTC_LOG("Int %d reserved %d level %d %s hasIsr %d",
x,
interrupt_controller_hal_get_cpu_desc_flags(x, cpu) == INTDESC_RESVD,
interrupt_controller_hal_get_level(x),
interrupt_controller_hal_get_type(x) == INTTP_LEVEL ? "LEVEL" : "EDGE",
x, intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD,
intr_desc.priority,
intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL ? "LEVEL" : "EDGE",
intr_has_handler(x, cpu));
if (!is_vect_desc_usable(vd, flags, cpu, force)) {
@ -430,15 +438,14 @@ static int get_available_int(int flags, int cpu, int force, int source)
no++;
svdesc = svdesc->next;
}
if (no < best_shared_ct ||
best_level > interrupt_controller_hal_get_level(x)) {
if (no < best_shared_ct || best_level > intr_desc.priority) {
/*
* Seems like this shared vector is both okay and has
* the least amount of ISRs already attached to it.
*/
best = x;
best_shared_ct = no;
best_level = interrupt_controller_hal_get_level(x);
best_level = intr_desc.priority;
INTC_LOG("...int %d more usable as a shared int: "
"has %d existing vectors", x, no);
} else {
@ -453,9 +460,9 @@ static int get_available_int(int flags, int cpu, int force, int source)
* Remember it in case we don't find any other shared
* interrupt that qualifies.
*/
if (best_level > interrupt_controller_hal_get_level(x)) {
if (best_level > intr_desc.priority) {
best = x;
best_level = interrupt_controller_hal_get_level(x);
best_level = intr_desc.priority;
INTC_LOG("...int %d usable as new shared int", x);
}
} else {
@ -467,9 +474,9 @@ static int get_available_int(int flags, int cpu, int force, int source)
* Seems this interrupt is feasible. Select it and break out of the loop
* No need to search further.
*/
if (best_level > interrupt_controller_hal_get_level(x)) {
if (best_level > intr_desc.priority) {
best = x;
best_level = interrupt_controller_hal_get_level(x);
best_level = intr_desc.priority;
} else {
INTC_LOG("...worse than int %d", best);
}
@ -493,7 +500,8 @@ static void IRAM_ATTR shared_intr_isr(void *arg)
esp_intr_lock();
while (sh_vec) {
if (!sh_vec->disabled) {
if (!(sh_vec->statusreg) || (*sh_vec->statusreg & sh_vec->statusmask)) {
if ((sh_vec->statusreg == NULL) ||
(*sh_vec->statusreg & sh_vec->statusmask)) {
sh_vec->isr(sh_vec->arg);
}
}
@ -513,7 +521,7 @@ int esp_intr_alloc_intrstatus(int source,
struct intr_handle_data_t *ret = NULL;
int force = -1;
INTC_LOG("%s (cpu %d): checking args", __func__, esp_core_id());
INTC_LOG("%s (cpu %d): checking args", __func__, esp_cpu_get_core_id());
/* Shared interrupts should be level-triggered. */
if ((flags & ESP_INTR_FLAG_SHARED) && (flags & ESP_INTR_FLAG_EDGE)) {
return -EINVAL;
@ -536,9 +544,8 @@ int esp_intr_alloc_intrstatus(int source,
* we need to make sure the interrupt is connected to the CPU0.
* CPU1 does not have access to the RTC fast memory through this region.
*/
if ((flags & ESP_INTR_FLAG_IRAM) &&
(ptrdiff_t) handler >= SOC_RTC_IRAM_HIGH &&
(ptrdiff_t) handler < SOC_RTC_DATA_LOW) {
if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) &&
!esp_ptr_in_rtc_iram_fast(handler)) {
return -EINVAL;
}
@ -554,7 +561,7 @@ int esp_intr_alloc_intrstatus(int source,
}
}
INTC_LOG("%s (cpu %d): Args okay."
"Resulting flags 0x%X", __func__, esp_core_id(), flags);
"Resulting flags 0x%X", __func__, esp_cpu_get_core_id(), flags);
/*
* Check 'special' interrupt sources. These are tied to one specific
@ -590,7 +597,7 @@ int esp_intr_alloc_intrstatus(int source,
}
esp_intr_lock();
int cpu = esp_core_id();
int cpu = esp_cpu_get_core_id();
/* See if we can find an interrupt that matches the flags. */
int intr = get_available_int(flags, cpu, force, source);
@ -650,7 +657,7 @@ int esp_intr_alloc_intrstatus(int source,
non_iram_int_mask[cpu] |= (1 << intr);
}
if (source >= 0) {
intr_matrix_set(cpu, source, intr);
esp_rom_route_intr_matrix(cpu, source, intr);
}
/* Fill return handle data. */
@ -668,6 +675,19 @@ int esp_intr_alloc_intrstatus(int source,
esp_intr_disable(ret);
}
#ifdef SOC_CPU_HAS_FLEXIBLE_INTC
/* Extract the level from the interrupt passed flags */
int level = esp_intr_flags_to_level(flags);
esp_cpu_intr_set_priority(intr, level);
if (flags & ESP_INTR_FLAG_EDGE) {
esp_cpu_intr_set_type(intr, ESP_CPU_INTR_TYPE_EDGE);
} else {
esp_cpu_intr_set_type(intr, ESP_CPU_INTR_TYPE_LEVEL);
}
#endif
esp_intr_unlock();
/* Fill return handle if needed, otherwise free handle. */
@ -769,7 +789,9 @@ int esp_intr_free(struct intr_handle_data_t *handle)
* few bytes of memory we save.(We can also not use the same exit path for empty
* shared ints anymore if we delete the desc.) For now, just mark it as free.
*/
handle->vector_desc->flags &= !(VECDESC_FL_NONSHARED | VECDESC_FL_RESERVED);
handle->vector_desc->flags &= ~(VECDESC_FL_NONSHARED |
VECDESC_FL_RESERVED | VECDESC_FL_SHARED);
/* Also kill non_iram mask bit. */
non_iram_int_mask[handle->vector_desc->cpu] &= ~(1 << (handle->vector_desc->intno));
}
@ -818,10 +840,12 @@ int IRAM_ATTR esp_intr_enable(struct intr_handle_data_t *handle)
}
if (source >= 0) {
/* Disabled using int matrix; re-connect to enable */
intr_matrix_set(handle->vector_desc->cpu, source, handle->vector_desc->intno);
esp_rom_route_intr_matrix(handle->vector_desc->cpu,
source, handle->vector_desc->intno);
} else {
/* Re-enable using cpu int ena reg */
if (handle->vector_desc->cpu != esp_core_id()) {
if (handle->vector_desc->cpu != esp_cpu_get_core_id()) {
esp_intr_unlock();
return -EINVAL; /* Can only enable these ints on this cpu */
}
irq_enable(handle->vector_desc->intno);
@ -860,11 +884,12 @@ int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle)
if (source >= 0) {
if (disabled) {
/* Disable using int matrix */
intr_matrix_set(handle->vector_desc->cpu, source, INT_MUX_DISABLED_INTNO);
esp_rom_route_intr_matrix(handle->vector_desc->cpu,
source, INT_MUX_DISABLED_INTNO);
}
} else {
/* Disable using per-cpu regs */
if (handle->vector_desc->cpu != esp_core_id()) {
if (handle->vector_desc->cpu != esp_cpu_get_core_id()) {
esp_intr_unlock();
return -EINVAL; /* Can only enable these ints on this cpu */
}
@ -877,28 +902,33 @@ int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle)
void IRAM_ATTR esp_intr_noniram_disable(void)
{
esp_intr_lock();
int oldint;
int cpu = esp_core_id();
int cpu = esp_cpu_get_core_id();
int non_iram_ints = ~non_iram_int_mask[cpu];
if (non_iram_int_disabled_flag[cpu]) {
abort();
}
non_iram_int_disabled_flag[cpu] = true;
oldint = interrupt_controller_hal_read_interrupt_mask();
interrupt_controller_hal_disable_interrupts(non_iram_ints);
/* Save which ints we did disable */
oldint = esp_cpu_intr_get_enabled_mask();
esp_cpu_intr_disable(non_iram_ints);
rtc_isr_noniram_disable(cpu);
non_iram_int_disabled[cpu] = oldint & non_iram_ints;
esp_intr_unlock();
}
void IRAM_ATTR esp_intr_noniram_enable(void)
{
int cpu = esp_core_id();
esp_intr_lock();
int cpu = esp_cpu_get_core_id();
int non_iram_ints = non_iram_int_disabled[cpu];
if (!non_iram_int_disabled_flag[cpu]) {
abort();
}
non_iram_int_disabled_flag[cpu] = false;
interrupt_controller_hal_enable_interrupts(non_iram_ints);
esp_cpu_intr_enable(non_iram_ints);
rtc_isr_noniram_enable(cpu);
esp_intr_unlock();
}

View file

@ -127,7 +127,7 @@ static int pwm_led_esp32_calculate_max_resolution(struct pwm_ledc_esp32_channel_
uint64_t clock_freq = channel->clock_src == LEDC_APB_CLK ? APB_CLK_FREQ : REF_CLK_FREQ;
uint32_t max_precision_n = clock_freq/channel->freq;
for (uint8_t i = 0; i <= SOC_LEDC_TIMER_BIT_WIDE_NUM; i++) {
for (uint8_t i = 0; i <= SOC_LEDC_TIMER_BIT_WIDTH; i++) {
max_precision_n /= 2;
if (!max_precision_n) {
channel->resolution = i;
@ -164,10 +164,12 @@ static int pwm_led_esp32_timer_config(struct pwm_ledc_esp32_channel_config *chan
return 0;
}
#if SOC_LEDC_SUPPORT_REF_TICK
channel->clock_src = LEDC_REF_TICK;
if (!pwm_led_esp32_calculate_max_resolution(channel)) {
return 0;
}
#endif
/**
* ESP32 - S2,S3 and C3 variants have only 14 bits counter.
@ -178,7 +180,7 @@ static int pwm_led_esp32_timer_config(struct pwm_ledc_esp32_channel_config *chan
* so select the slow clock source (1MHz) with highest counter resolution.
* this can be handled on the func 'pwm_led_esp32_timer_set' with 'prescaler'.
*/
channel->resolution = SOC_LEDC_TIMER_BIT_WIDE_NUM;
channel->resolution = SOC_LEDC_TIMER_BIT_WIDTH;
return 0;
}
@ -199,9 +201,11 @@ static int pwm_led_esp32_timer_set(const struct device *dev,
*/
prescaler = ((uint64_t) APB_CLK_FREQ << 8) / channel->freq / precision;
break;
#if SOC_LEDC_SUPPORT_REF_TICK
case LEDC_REF_TICK:
prescaler = ((uint64_t) REF_CLK_FREQ << 8) / channel->freq / precision;
break;
#endif
default:
LOG_ERR("Invalid clock source (%d)", channel->clock_src);
return -EINVAL;
@ -213,7 +217,7 @@ static int pwm_led_esp32_timer_set(const struct device *dev,
}
if (channel->speed_mode == LEDC_LOW_SPEED_MODE) {
ledc_hal_set_slow_clk(&data->hal, channel->clock_src);
ledc_hal_set_slow_clk_sel(&data->hal, channel->clock_src);
}
ledc_hal_set_clock_divider(&data->hal, channel->timer_num, prescaler);

View file

@ -8,7 +8,7 @@
#include <hal/mcpwm_hal.h>
#include <hal/mcpwm_ll.h>
#include "driver/mcpwm.h"
#include <driver/mcpwm.h>
#include <soc.h>
#include <errno.h>
@ -23,6 +23,7 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mcpwm_esp32, CONFIG_PWM_LOG_LEVEL);
#define SOC_MCPWM_BASE_CLK_HZ (160000000U)
#ifdef CONFIG_PWM_CAPTURE
#define SKIP_IRQ_NUM 4U
#define MCPWM_INTR_CAP0 BIT(0)
@ -109,7 +110,7 @@ static void mcpwm_esp32_duty_set(const struct device *dev,
set_duty = mcpwm_ll_timer_get_peak(data->hal.dev, channel->timer_id, false) *
channel->duty / 100;
mcpwm_ll_operator_select_timer(data->hal.dev, channel->operator_id, channel->timer_id);
mcpwm_ll_operator_connect_timer(data->hal.dev, channel->operator_id, channel->timer_id);
mcpwm_ll_operator_set_compare_value(data->hal.dev, channel->operator_id,
channel->generator_id, set_duty);
mcpwm_ll_operator_enable_update_compare_on_tez(data->hal.dev, channel->operator_id,
@ -118,40 +119,40 @@ static void mcpwm_esp32_duty_set(const struct device *dev,
if (duty_type == MCPWM_DUTY_MODE_0) {
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_GEN_ACTION_HIGH);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH);
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_GEN_ACTION_KEEP);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_GEN_ACTION_KEEP);
mcpwm_ll_generator_set_action_on_compare_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_LOW);
} else if (duty_type == MCPWM_DUTY_MODE_1) {
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_GEN_ACTION_LOW);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_LOW);
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_NO_CHANGE);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_NO_CHANGE);
mcpwm_ll_generator_set_action_on_compare_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_HIGH);
} else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_LOW);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW);
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_LOW);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW);
mcpwm_ll_generator_set_action_on_compare_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_LOW);
} else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_HIGH);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH);
mcpwm_ll_generator_set_action_on_timer_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_HIGH);
MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH);
mcpwm_ll_generator_set_action_on_compare_event(
data->hal.dev, channel->operator_id, channel->generator_id,
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_HIGH);
@ -259,7 +260,7 @@ static int mcpwm_esp32_set_cycles(const struct device *dev, uint32_t channel_idx
return ret;
}
mcpwm_ll_timer_set_execute_command(data->hal.dev, channel->timer_id,
mcpwm_ll_timer_set_start_stop_command(data->hal.dev, channel->timer_id,
MCPWM_TIMER_START_NO_STOP);
k_sem_give(&data->cmd_sem);
@ -326,7 +327,7 @@ static int mcpwm_esp32_disable_capture(const struct device *dev, uint32_t channe
}
mcpwm_ll_capture_enable_channel(data->hal.dev, capture->capture_signal, false);
mcpwm_ll_intr_enable_capture(data->hal.dev, capture->capture_signal, false);
mcpwm_ll_intr_enable(data->hal.dev, MCPWM_LL_EVENT_CAPTURE(capture->capture_signal), false);
return 0;
}
@ -381,7 +382,7 @@ static int mcpwm_esp32_enable_capture(const struct device *dev, uint32_t channel
mcpwm_ll_capture_set_prescale(data->hal.dev, capture->capture_signal,
cap_conf.cap_prescale);
mcpwm_ll_intr_enable_capture(data->hal.dev, capture->capture_signal, true);
mcpwm_ll_intr_enable(data->hal.dev, MCPWM_LL_EVENT_CAPTURE(capture->capture_signal), true);
mcpwm_ll_intr_clear_capture_status(data->hal.dev, 1 << capture->capture_signal);
capture->skip_irq = 0;
@ -476,7 +477,8 @@ static void IRAM_ATTR mcpwm_esp32_isr(const struct device *dev)
capture->capture_data[capture->skip_irq].value =
mcpwm_ll_capture_get_value(data->hal.dev, capture->capture_signal);
capture->capture_data[capture->skip_irq].edge =
mcpwm_ll_capture_is_negedge(data->hal.dev, capture->capture_signal)
mcpwm_ll_capture_get_edge(data->hal.dev, capture->capture_signal) ==
MCPWM_CAP_EDGE_NEG
? MCPWM_NEG_EDGE
: MCPWM_POS_EDGE;
capture->skip_irq++;
@ -550,7 +552,7 @@ static const struct pwm_driver_api mcpwm_esp32_api = {
}, \
.init_config = \
{ \
.host_id = idx, \
.group_id = idx, \
}, \
.cmd_sem = Z_SEM_INITIALIZER(mcpwm_esp32_data_##idx.cmd_sem, 1, 1), \
}; \
@ -567,7 +569,7 @@ static const struct pwm_driver_api mcpwm_esp32_api = {
CAPTURE_INIT(idx)}; \
\
DEVICE_DT_INST_DEFINE(idx, &mcpwm_esp32_init, NULL, &mcpwm_esp32_data_##idx, \
&mcpwm_esp32_config_##idx, POST_KERNEL, \
CONFIG_PWM_INIT_PRIORITY, &mcpwm_esp32_api);
&mcpwm_esp32_config_##idx, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \
&mcpwm_esp32_api);
DT_INST_FOREACH_STATUS_OKAY(ESP32_MCPWM_INIT)

View file

@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(esp32_temp, CONFIG_SENSOR_LOG_LEVEL);
#if CONFIG_SOC_SERIES_ESP32
#error "Temperature sensor not supported on ESP32"
#endif /* CONFIG_IDF_TARGET_ESP32 */
#endif /* CONFIG_SOC_SERIES_ESP32 */
struct esp32_temp_data {
struct k_mutex mutex;

View file

@ -35,7 +35,7 @@
#include <hal/uart_ll.h>
#include <hal/uart_hal.h>
#include <hal/uart_types.h>
#include <esp_clk_tree.h>
#include <zephyr/drivers/pinctrl.h>
#include <soc/uart_reg.h>
@ -160,8 +160,13 @@ static int uart_esp32_config_get(const struct device *dev, struct uart_config *c
uart_stop_bits_t stop_bit;
uart_word_length_t data_bit;
uart_hw_flowcontrol_t hw_flow;
uart_sclk_t src_clk;
uint32_t sclk_freq;
uart_hal_get_baudrate(&data->hal, &cfg->baudrate);
uart_hal_get_sclk(&data->hal, &src_clk);
esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk,
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq);
uart_hal_get_baudrate(&data->hal, &cfg->baudrate, sclk_freq);
uart_hal_get_parity(&data->hal, &parity);
switch (parity) {
@ -235,6 +240,9 @@ static int uart_esp32_configure(const struct device *dev, const struct uart_conf
{
const struct uart_esp32_config *config = dev->config;
struct uart_esp32_data *data = dev->data;
uart_sclk_t src_clk;
uint32_t sclk_freq;
int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
if (ret < 0) {
@ -313,7 +321,10 @@ static int uart_esp32_configure(const struct device *dev, const struct uart_conf
return -ENOTSUP;
}
uart_hal_set_baudrate(&data->hal, cfg->baudrate);
uart_hal_get_sclk(&data->hal, &src_clk);
esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk,
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq);
uart_hal_set_baudrate(&data->hal, cfg->baudrate, sclk_freq);
uart_hal_set_rx_timeout(&data->hal, 0x16);
@ -709,7 +720,7 @@ static int uart_esp32_async_tx(const struct device *dev, const uint8_t *buf, siz
dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL;
dma_cfg.dma_callback = uart_esp32_dma_tx_done;
dma_cfg.user_data = (void *)dev;
dma_cfg.dma_slot = GDMA_TRIG_PERIPH_UHCI0;
dma_cfg.dma_slot = ESP_GDMA_TRIG_PERIPH_UHCI0;
dma_cfg.block_count = 1;
dma_cfg.head_block = &dma_blk;
dma_blk.block_size = len;
@ -770,7 +781,7 @@ static int uart_esp32_async_rx_enable(const struct device *dev, uint8_t *buf, si
dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY;
dma_cfg.dma_callback = uart_esp32_dma_rx_done;
dma_cfg.user_data = (void *)dev;
dma_cfg.dma_slot = GDMA_TRIG_PERIPH_UHCI0;
dma_cfg.dma_slot = ESP_GDMA_TRIG_PERIPH_UHCI0;
dma_cfg.block_count = 1;
dma_cfg.head_block = &dma_blk;
dma_blk.block_size = len;

View file

@ -9,12 +9,13 @@
/* Include esp-idf headers first to avoid redefining BIT() macro */
#include <hal/spi_hal.h>
#include <esp_attr.h>
#include <esp_clk_tree.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(esp32_spi, CONFIG_SPI_LOG_LEVEL);
#include <soc.h>
#include <soc/soc_memory_types.h>
#include <esp_memory_utils.h>
#include <zephyr/drivers/spi.h>
#ifndef CONFIG_SOC_SERIES_ESP32C3
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
@ -177,8 +178,10 @@ static int spi_esp32_init_dma(const struct device *dev)
gdma_ll_enable_clock(data->hal_gdma.dev, true);
gdma_ll_tx_reset_channel(data->hal_gdma.dev, cfg->dma_host);
gdma_ll_rx_reset_channel(data->hal_gdma.dev, cfg->dma_host);
gdma_ll_tx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, cfg->dma_host);
gdma_ll_rx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, cfg->dma_host);
gdma_ll_tx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, GDMA_TRIG_PERIPH_SPI,
cfg->dma_host);
gdma_ll_rx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, GDMA_TRIG_PERIPH_SPI,
cfg->dma_host);
channel_offset = 0;
#else
channel_offset = 1;
@ -235,6 +238,13 @@ static int spi_esp32_init(const struct device *dev)
return err;
}
err = esp_clk_tree_src_get_freq_hz(
cfg->clock_source, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &data->clock_source_hz);
if (err) {
LOG_ERR("Could not get clock source frequency (%d)", err);
return err;
}
spi_context_unlock_unconditionally(&data->ctx);
return 0;
@ -312,11 +322,11 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
spi_hal_timing_param_t timing_param = {
.half_duplex = hal_dev->half_duplex,
.no_compensate = hal_dev->no_compensate,
.clock_speed_hz = spi_cfg->frequency,
.expected_freq = spi_cfg->frequency,
.duty_cycle = cfg->duty_cycle == 0 ? 128 : cfg->duty_cycle,
.input_delay_ns = cfg->input_delay_ns,
.use_gpio = !cfg->use_iomux,
.clk_src_hz = data->clock_source_hz,
};
spi_hal_cal_clock_conf(&timing_param, &freq, &hal_dev->timing_conf);
@ -520,6 +530,7 @@ static const struct spi_driver_api spi_api = {
.cs_setup = DT_INST_PROP_OR(idx, cs_setup_time, 0), \
.cs_hold = DT_INST_PROP_OR(idx, cs_hold_time, 0), \
.line_idle_low = DT_INST_PROP(idx, line_idle_low), \
.clock_source = SPI_CLK_SRC_DEFAULT, \
}; \
\
DEVICE_DT_INST_DEFINE(idx, &spi_esp32_init, \

View file

@ -39,6 +39,7 @@ struct spi_esp32_config {
int cs_setup;
int cs_hold;
bool line_idle_low;
spi_clock_source_t clock_source;
};
struct spi_esp32_data {
@ -55,6 +56,7 @@ struct spi_esp32_data {
int irq_line;
lldesc_t dma_desc_tx;
lldesc_t dma_desc_rx;
uint32_t clock_source_hz;
};
#endif /* ZEPHYR_DRIVERS_SPI_ESP32_SPIM_H_ */

View file

@ -10,6 +10,7 @@
#include <soc/system_reg.h>
#include <hal/systimer_hal.h>
#include <hal/systimer_ll.h>
#include <esp_private/systimer.h>
#include <rom/ets_sys.h>
#include <esp_attr.h>
@ -41,26 +42,26 @@ static systimer_hal_context_t systimer_hal;
static void set_systimer_alarm(uint64_t time)
{
systimer_hal_select_alarm_mode(&systimer_hal,
SYSTIMER_LL_ALARM_OS_TICK_CORE0, SYSTIMER_ALARM_MODE_ONESHOT);
SYSTIMER_ALARM_OS_TICK_CORE0, SYSTIMER_ALARM_MODE_ONESHOT);
systimer_counter_value_t alarm = {.val = time};
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0, false);
systimer_ll_set_alarm_target(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0, alarm.val);
systimer_ll_apply_alarm_value(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0);
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0, true);
systimer_ll_enable_alarm_int(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0, true);
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0, false);
systimer_ll_set_alarm_target(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0, alarm.val);
systimer_ll_apply_alarm_value(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0);
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0, true);
systimer_ll_enable_alarm_int(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0, true);
}
static uint64_t get_systimer_alarm(void)
{
return systimer_hal_get_counter_value(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK);
return systimer_hal_get_counter_value(&systimer_hal, SYSTIMER_COUNTER_OS_TICK);
}
static void sys_timer_isr(const void *arg)
{
ARG_UNUSED(arg);
systimer_ll_clear_alarm_int(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0);
systimer_ll_clear_alarm_int(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0);
k_spinlock_key_t key = k_spin_lock(&lock);
uint64_t now = get_systimer_alarm();
@ -146,10 +147,10 @@ static int sys_clock_driver_init(void)
systimer_hal_init(&systimer_hal);
systimer_hal_connect_alarm_counter(&systimer_hal,
SYSTIMER_LL_ALARM_OS_TICK_CORE0, SYSTIMER_LL_COUNTER_OS_TICK);
SYSTIMER_ALARM_OS_TICK_CORE0, SYSTIMER_COUNTER_OS_TICK);
systimer_hal_enable_counter(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK);
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK, 0, true);
systimer_hal_enable_counter(&systimer_hal, SYSTIMER_COUNTER_OS_TICK);
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_OS_TICK, 0, true);
last_count = get_systimer_alarm();
set_systimer_alarm(last_count + CYC_PER_TICK);
return 0;

View file

@ -15,6 +15,9 @@ menuconfig WIFI_ESP32
select MBEDTLS_ECDH_C
select MBEDTLS_ECDSA_C
select MBEDTLS_ECP_C
select THREAD_STACK_INFO
select DYNAMIC_THREAD
select DYNAMIC_THREAD_ALLOC
help
Enable ESP32 SoC WiFi support. Only supported in single
core mode because the network stack is not aware of SMP
@ -43,28 +46,31 @@ config ESP32_WIFI_STA_RECONNECT
help
Set auto WiFI reconnection when disconnected.
config ESP32_WIFI_EVENT_TASK_STACK_SIZE
int "Event Task Stack Size"
default 4096
config ESP32_WIFI_SW_COEXIST_ENABLE
bool
help
Software controls WiFi/Bluetooth coexistence. Not supported yet.
config ESP32_WIFI_EVENT_TASK_PRIO
int "Event Task Priority"
default 4
config ESP32_WIFI_NET_ALLOC_SPIRAM
bool "Allocate memory of WiFi and NET in SPIRAM"
depends on ESP_SPIRAM
help
Allocate memory of WiFi and NET stack in SPIRAM, increasing available RAM memory space
for application stack.
config ESP32_WIFI_STATIC_RX_BUFFER_NUM
int "Max number of WiFi static RX buffers"
range 2 25
default 10
help
Set the number of WiFi static RX buffers. Each buffer takes approximately
1.6KB of RAM. The static rx buffers are allocated when esp_wifi_init is
called, they are not freed until esp_wifi_deinit is called.
Set the number of WiFi static RX buffers. Each buffer takes approximately 1.6KB of RAM.
The static rx buffers are allocated when esp_wifi_init is called, they are not freed
until esp_wifi_deinit is called.
WiFi hardware use these buffers to receive all 802.11 frames. A higher
number may allow higher throughput but increases memory use.
If ESP32_WIFI_AMPDU_RX_ENABLED is enabled, this value is recommended to
set equal or bigger than ESP32_WIFI_RX_BA_WIN in order to achieve better
throughput and compatibility with both stations and APs.
WiFi hardware use these buffers to receive all 802.11 frames.
A higher number may allow higher throughput but increases memory use. If ESP32_WIFI_AMPDU_RX_ENABLED
is enabled, this value is recommended to set equal or bigger than ESP32_WIFI_RX_BA_WIN in order to
achieve better throughput and compatibility with both stations and APs.
config ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM
int "Max number of WiFi dynamic RX buffers"
@ -133,6 +139,7 @@ config ESP32_WIFI_STATIC_TX_BUFFER_NUM
config ESP32_WIFI_CACHE_TX_BUFFER_NUM
int "Max number of WiFi cache TX buffers"
depends on ESP_SPIRAM
range 16 128
default 32
help
@ -162,6 +169,7 @@ config ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM
config ESP32_WIFI_CSI_ENABLED
bool "WiFi CSI(Channel State Information)"
default n
help
Select this option to enable CSI(Channel State Information) feature.
CSI takes about CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM KB of RAM.
@ -211,23 +219,17 @@ config ESP32_WIFI_RX_BA_WIN
should be 16 to achieve better throughput and compatibility with both
stations and APs.
choice ESP32_WIFI_TASK_CORE_ID
prompt "WiFi Task Core ID"
default ESP32_WIFI_TASK_PINNED_TO_CORE_0
config ESP32_WIFI_AMSDU_TX_ENABLED
bool "WiFi AMSDU TX"
depends on ESP_SPIRAM
default n
help
Pinned WiFi task to core 0 (core 1 not supported yet)
config ESP32_WIFI_TASK_PINNED_TO_CORE_0
bool "Core 0"
endchoice
config ESP32_WIFI_SW_COEXIST_ENABLE
bool
help
Software controls WiFi/Bluetooth coexistence. Not supported yet.
Select this option to enable AMSDU TX feature
config ESP32_WIFI_IRAM_OPT
bool "WiFi IRAM speed optimization"
default n if (BT && ESP_SPIRAM && SOC_SERIES_ESP32)
default y
help
Select this option to place frequently called Wi-Fi library functions in IRAM.
When this option is disabled, more than 10Kbytes of IRAM memory will be saved
@ -235,22 +237,79 @@ config ESP32_WIFI_IRAM_OPT
config ESP32_WIFI_RX_IRAM_OPT
bool "WiFi RX IRAM speed optimization"
default n if (BT && ESP_SPIRAM && SOC_SERIES_ESP32)
help
Select this option to place frequently called Wi-Fi library RX functions in IRAM.
When this option is disabled, more than 17Kbytes of IRAM memory will be saved
but Wi-Fi performance will be reduced.
config ESP32_WIFI_NET_ALLOC_SPIRAM
bool "Allocate memory of WiFi and NET in SPIRAM"
depends on ESP_SPIRAM
config ESP32_WIFI_FTM_ENABLE
bool "WiFi FTM"
default n
depends on SOC_SERIES_ESP32C3
help
Allocate memory of WiFi and NET stack in SPIRAM, increasing available RAM memory space
for application stack.
Enable feature Fine Timing Measurement for calculating WiFi Round-Trip-Time (RTT).
config ESP_WIFI_SOFTAP_SUPPORT
config ESP32_WIFI_FTM_INITIATOR_SUPPORT
bool "FTM Initiator support"
default y
depends on ESP32_WIFI_FTM_ENABLE
config ESP32_WIFI_FTM_RESPONDER_SUPPORT
bool "FTM Responder support"
default y
depends on ESP32_WIFI_FTM_ENABLE
config ESP32_WIFI_SOFTAP_SUPPORT
bool
default y
help
Hidden option to enable Wi-Fi SoftAP functions in WPA supplicant and RF libraries.
config ESP32_WIFI_MBEDTLS_CRYPTO
bool "Use MbedTLS crypto APIs"
default n
select MBEDTLS_ECP_C
select MBEDTLS_ECDH_C
select MBEDTLS_ECDSA_C
select MBEDTLS_PKCS5_C
select MBEDTLS_PK_WRITE_C
select MBEDTLS_CIPHER_MODE_CTR_ENABLED
select MBEDTLS_MAC_CMAC_ENABLED
select MBEDTLS_ZEPHYR_ENTROPY
help
Select this option to use MbedTLS crypto APIs which utilize hardware acceleration.
config ESP32_WIFI_ENABLE_WPA3_SAE
bool "WPA3-Personal"
default n
select ESP32_WIFI_MBEDTLS_CRYPTO
help
Select this option to allow the device to establish a WPA3-Personal connection.
config ESP32_WIFI_ENABLE_WPA3_OWE_STA
bool "OWE STA"
default y
depends on ESP32_WIFI_ENABLE_WPA3_SAE
help
Select this option to allow the device to establish OWE connection with eligible AP's.
config ESP32_WIFI_ENABLE_SAE_PK
bool "SAE-PK"
default y
depends on ESP32_WIFI_ENABLE_WPA3_SAE
help
Select this option to enable SAE-PK
config ESP32_WIFI_DEBUG_PRINT
bool "Print debug messages from WPA Supplicant"
default n
help
Select this option to print logging information from WPA supplicant,
this includes handshake information and key hex dumps depending
on the project logging level.
Enabling this could increase the build size ~60kb
depending on the project logging level.
endif # WIFI_ESP32

View file

@ -16,12 +16,13 @@ LOG_MODULE_REGISTER(esp32_wifi, CONFIG_WIFI_LOG_LEVEL);
#include <zephyr/net/conn_mgr/connectivity_wifi_mgmt.h>
#include <zephyr/device.h>
#include <soc.h>
#include "esp_networking_priv.h"
#include "esp_private/wifi.h"
#include "esp_event.h"
#include "esp_timer.h"
#include "esp_system.h"
#include "esp_wpa.h"
#include <esp_mac.h>
#include "wifi/wifi_event.h"
#define DHCPV4_MASK (NET_EVENT_IPV4_DHCP_BOUND | NET_EVENT_IPV4_DHCP_STOP)
@ -58,14 +59,9 @@ struct esp32_wifi_runtime {
struct esp32_wifi_status status;
scan_result_cb_t scan_cb;
uint8_t state;
uint8_t ap_connection_cnt;
};
static void esp_wifi_event_task(void *, void *, void *);
K_MSGQ_DEFINE(esp_wifi_msgq, sizeof(system_event_t), 10, 4);
K_THREAD_STACK_DEFINE(esp_wifi_event_stack, CONFIG_ESP32_WIFI_EVENT_TASK_STACK_SIZE);
static struct k_thread esp_wifi_event_thread;
static struct net_mgmt_event_callback esp32_dhcp_cb;
static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
@ -82,28 +78,6 @@ static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt
}
}
/* internal wifi library callback function */
esp_err_t esp_event_send_internal(esp_event_base_t event_base,
int32_t event_id,
void *event_data,
size_t event_data_size,
uint32_t ticks_to_wait)
{
system_event_t evt = {
.event_id = event_id,
};
if (event_data_size > sizeof(evt.event_info)) {
LOG_ERR("MSG %d wont find %d > %d",
event_id, event_data_size, sizeof(evt.event_info));
return -EIO;
}
memcpy(&evt.event_info, event_data, event_data_size);
k_msgq_put(&esp_wifi_msgq, &evt, K_FOREVER);
return 0;
}
static int esp32_wifi_send(const struct device *dev, struct net_pkt *pkt)
{
struct esp32_wifi_runtime *data = dev->data;
@ -208,9 +182,31 @@ static void scan_done_handler(void)
strncpy(res.ssid, ap_list_buffer[k].ssid, ssid_len);
res.rssi = ap_list_buffer[k].rssi;
res.channel = ap_list_buffer[k].primary;
switch (ap_list_buffer[k].authmode) {
case WIFI_AUTH_OPEN:
res.security = WIFI_SECURITY_TYPE_NONE;
if (ap_list_buffer[k].authmode > WIFI_AUTH_OPEN) {
break;
case WIFI_AUTH_WPA2_PSK:
res.security = WIFI_SECURITY_TYPE_PSK;
break;
case WIFI_AUTH_WPA3_PSK:
res.security = WIFI_SECURITY_TYPE_SAE;
break;
case WIFI_AUTH_WAPI_PSK:
res.security = WIFI_SECURITY_TYPE_WAPI;
break;
case WIFI_AUTH_WPA2_ENTERPRISE:
res.security = WIFI_SECURITY_TYPE_EAP;
break;
case WIFI_AUTH_WEP:
res.security = WIFI_SECURITY_TYPE_WEP;
break;
case WIFI_AUTH_WPA_PSK:
res.security = WIFI_SECURITY_TYPE_WPA_PSK;
break;
default:
res.security = WIFI_SECURITY_TYPE_UNKNOWN;
break;
}
if (esp32_data.scan_cb) {
@ -232,8 +228,9 @@ out:
esp32_data.scan_cb = NULL;
}
static void esp_wifi_handle_connect_event(void)
static void esp_wifi_handle_sta_connect_event(void *event_data)
{
ARG_UNUSED(event_data);
esp32_data.state = ESP32_STA_CONNECTED;
#if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
net_dhcpv4_start(esp32_wifi_iface);
@ -242,7 +239,7 @@ static void esp_wifi_handle_connect_event(void)
#endif
}
static void esp_wifi_handle_disconnect_event(void *event_data)
static void esp_wifi_handle_sta_disconnect_event(void *event_data)
{
wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
@ -280,57 +277,67 @@ static void esp_wifi_handle_disconnect_event(void *event_data)
}
}
static void esp_wifi_event_task(void *p1, void *p2, void *p3)
static void esp_wifi_handle_ap_connect_event(void *event_data)
{
ARG_UNUSED(p2);
ARG_UNUSED(p3);
wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *) event_data;
system_event_t evt;
uint8_t s_con_cnt = 0;
LOG_DBG("Station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid);
wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
while (1) {
k_msgq_get(&esp_wifi_msgq, &evt, K_FOREVER);
if (!(esp32_data.ap_connection_cnt++)) {
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, eth_esp32_rx);
}
}
switch (evt.event_id) {
case ESP32_WIFI_EVENT_STA_START:
static void esp_wifi_handle_ap_disconnect_event(void *event_data)
{
wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
LOG_DBG("station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid);
wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, 0);
if (!(--esp32_data.ap_connection_cnt)) {
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
}
}
void esp_wifi_event_handler(const char *event_base, int32_t event_id, void *event_data,
size_t event_data_size, uint32_t ticks_to_wait)
{
LOG_DBG("Wi-Fi event: %d", event_id);
switch (event_id) {
case WIFI_EVENT_STA_START:
esp32_data.state = ESP32_STA_STARTED;
net_eth_carrier_on(esp32_wifi_iface);
break;
case ESP32_WIFI_EVENT_STA_STOP:
case WIFI_EVENT_STA_STOP:
esp32_data.state = ESP32_STA_STOPPED;
net_eth_carrier_off(esp32_wifi_iface);
break;
case ESP32_WIFI_EVENT_STA_CONNECTED:
esp_wifi_handle_connect_event();
case WIFI_EVENT_STA_CONNECTED:
esp_wifi_handle_sta_connect_event(event_data);
break;
case ESP32_WIFI_EVENT_STA_DISCONNECTED:
esp_wifi_handle_disconnect_event(&evt.event_info);
case WIFI_EVENT_STA_DISCONNECTED:
esp_wifi_handle_sta_disconnect_event(event_data);
break;
case ESP32_WIFI_EVENT_SCAN_DONE:
case WIFI_EVENT_SCAN_DONE:
scan_done_handler();
break;
case ESP32_WIFI_EVENT_AP_STOP:
case WIFI_EVENT_AP_STOP:
esp32_data.state = ESP32_AP_STOPPED;
net_eth_carrier_off(esp32_wifi_iface);
break;
case ESP32_WIFI_EVENT_AP_STACONNECTED:
case WIFI_EVENT_AP_STACONNECTED:
esp32_data.state = ESP32_AP_CONNECTED;
if (!s_con_cnt) {
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, eth_esp32_rx);
}
s_con_cnt++;
esp_wifi_handle_ap_connect_event(event_data);
break;
case ESP32_WIFI_EVENT_AP_STADISCONNECTED:
case WIFI_EVENT_AP_STADISCONNECTED:
esp32_data.state = ESP32_AP_DISCONNECTED;
s_con_cnt--;
if (!s_con_cnt) {
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
}
esp_wifi_handle_ap_disconnect_event(event_data);
break;
default:
break;
}
}
}
static int esp32_wifi_disconnect(const struct device *dev)
@ -350,6 +357,7 @@ static int esp32_wifi_connect(const struct device *dev,
struct wifi_connect_req_params *params)
{
struct esp32_wifi_runtime *data = dev->data;
wifi_mode_t mode;
int ret;
if (data->state == ESP32_STA_CONNECTING || data->state == ESP32_STA_CONNECTED) {
@ -357,6 +365,25 @@ static int esp32_wifi_connect(const struct device *dev,
return -EALREADY;
}
ret = esp_wifi_get_mode(&mode);
if (ret) {
LOG_ERR("Failed to get Wi-Fi mode (%d)", ret);
return -EAGAIN;
}
if (mode != ESP32_WIFI_MODE_STA) {
ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
if (ret) {
LOG_ERR("Failed to set Wi-Fi mode (%d)", ret);
return -EAGAIN;
}
ret = esp_wifi_start();
if (ret) {
LOG_ERR("Failed to start Wi-Fi driver (%d)", ret);
return -EAGAIN;
}
}
if (data->state != ESP32_STA_STARTED) {
LOG_ERR("Wi-Fi not in station mode");
wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, -1);
@ -374,16 +401,39 @@ static int esp32_wifi_connect(const struct device *dev,
memcpy(wifi_config.sta.ssid, params->ssid, params->ssid_length);
wifi_config.sta.ssid[params->ssid_length] = '\0';
if (params->security == WIFI_SECURITY_TYPE_PSK) {
switch (params->security) {
case WIFI_SECURITY_TYPE_NONE:
wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
data->status.security = WIFI_AUTH_OPEN;
wifi_config.sta.pmf_cfg.required = false;
break;
case WIFI_SECURITY_TYPE_PSK:
memcpy(wifi_config.sta.password, params->psk, params->psk_length);
wifi_config.sta.password[params->psk_length] = '\0';
wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
wifi_config.sta.pmf_cfg.required = false;
data->status.security = WIFI_AUTH_WPA2_PSK;
} else if (params->security == WIFI_SECURITY_TYPE_NONE) {
wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
data->status.security = WIFI_AUTH_OPEN;
break;
case WIFI_SECURITY_TYPE_SAE:
#if defined(CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE)
if (params->sae_password) {
memcpy(wifi_config.sta.password, params->sae_password,
params->sae_password_length);
wifi_config.sta.password[params->sae_password_length] = '\0';
} else {
memcpy(wifi_config.sta.password, params->psk, params->psk_length);
wifi_config.sta.password[params->psk_length] = '\0';
}
data->status.security = WIFI_AUTH_WPA3_PSK;
wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA3_PSK;
wifi_config.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH;
break;
#else
LOG_ERR("WPA3 not supported for STA mode. Enable "
"CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE");
return -EINVAL;
#endif /* CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE */
default:
LOG_ERR("Authentication method not supported");
return -EIO;
}
@ -396,15 +446,15 @@ static int esp32_wifi_connect(const struct device *dev,
data->status.channel = params->channel;
}
wifi_config.sta.pmf_cfg.capable = true;
wifi_config.sta.pmf_cfg.required = false;
ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
ret |= esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
ret |= esp_wifi_connect();
if (ret) {
LOG_ERR("Failed to set Wi-Fi configuration (%d)", ret);
return -EINVAL;
}
if (ret != ESP_OK) {
LOG_ERR("Failed to connect to Wi-Fi access point");
ret = esp_wifi_connect();
if (ret) {
LOG_ERR("Failed to connect to Wi-Fi access point (%d)", ret);
return -EAGAIN;
}
@ -447,7 +497,7 @@ static int esp32_wifi_ap_enable(const struct device *dev,
struct wifi_connect_req_params *params)
{
struct esp32_wifi_runtime *data = dev->data;
esp_err_t ret = 0;
esp_err_t err = 0;
/* Build Wi-Fi configuration for AP mode */
wifi_config_t wifi_config = {
@ -462,22 +512,41 @@ static int esp32_wifi_ap_enable(const struct device *dev,
data->status.ssid[params->ssid_length] = '\0';
strncpy((char *) wifi_config.ap.ssid, params->ssid, params->ssid_length);
wifi_config.ap.ssid_len = params->ssid_length;
if (params->psk_length == 0) {
switch (params->security) {
case WIFI_SECURITY_TYPE_NONE:
memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password));
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
data->status.security = WIFI_AUTH_OPEN;
} else {
wifi_config.ap.pmf_cfg.required = false;
break;
case WIFI_SECURITY_TYPE_PSK:
strncpy((char *) wifi_config.ap.password, params->psk, params->psk_length);
wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
data->status.security = WIFI_AUTH_WPA2_PSK;
wifi_config.ap.pmf_cfg.required = false;
break;
default:
LOG_ERR("Authentication method not supported");
return -EINVAL;
}
/* Start Wi-Fi in AP mode with configuration built above */
ret = esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
ret |= esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
ret |= esp_wifi_start();
if (ret != ESP_OK) {
err = esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
if (err) {
LOG_ERR("Failed to set Wi-Fi mode (%d)", err);
return -EINVAL;
}
err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
if (err) {
LOG_ERR("Failed to set Wi-Fi configuration (%d)", err);
return -EINVAL;
}
err = esp_wifi_start();
if (err) {
LOG_ERR("Failed to enable Wi-Fi AP mode");
return -EAGAIN;
}
@ -489,11 +558,11 @@ static int esp32_wifi_ap_enable(const struct device *dev,
static int esp32_wifi_ap_disable(const struct device *dev)
{
esp_err_t ret = esp_wifi_set_mode(ESP32_WIFI_MODE_NULL);
int err = 0;
ret |= esp_wifi_start();
if (ret != ESP_OK) {
LOG_ERR("Failed to disable Wi-Fi AP mode");
err = esp_wifi_stop();
if (err) {
LOG_ERR("Failed to disable Wi-Fi AP mode: (%d)", err);
return -EAGAIN;
}
@ -537,24 +606,30 @@ static int esp32_wifi_status(const struct device *dev, struct wifi_iface_status
if (mode == ESP32_WIFI_MODE_STA) {
esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
esp_wifi_sta_get_ap_info(&ap_info);
status->iface_mode = WIFI_MODE_INFRA;
status->channel = ap_info.primary;
status->rssi = ap_info.rssi;
memcpy(status->bssid, ap_info.bssid, WIFI_MAC_ADDR_LEN);
if (ap_info.phy_11n) {
status->link_mode = WIFI_4;
} else if (ap_info.phy_11g) {
status->link_mode |= WIFI_3;
} else if (ap_info.phy_11b) {
if (ap_info.phy_11b) {
status->link_mode = WIFI_1;
} else if (ap_info.phy_11g) {
status->link_mode = WIFI_3;
} else if (ap_info.phy_11n) {
status->link_mode = WIFI_4;
} else if (ap_info.phy_11ax) {
status->link_mode = WIFI_6;
}
status->beacon_interval = conf.sta.listen_interval;
} else if (mode == ESP32_WIFI_MODE_AP) {
esp_wifi_get_config(ESP_IF_WIFI_AP, &conf);
status->iface_mode = WIFI_MODE_AP;
status->link_mode = WIFI_LINK_MODE_UNKNOWN;
status->channel = conf.ap.channel;
status->beacon_interval = conf.ap.beacon_interval;
} else {
status->iface_mode = WIFI_MODE_UNKNOWN;
status->link_mode = WIFI_LINK_MODE_UNKNOWN;
@ -569,6 +644,9 @@ static int esp32_wifi_status(const struct device *dev, struct wifi_iface_status
case WIFI_AUTH_WPA2_PSK:
status->security = WIFI_SECURITY_TYPE_PSK;
break;
case WIFI_AUTH_WPA3_PSK:
status->security = WIFI_SECURITY_TYPE_SAE;
break;
default:
status->security = WIFI_SECURITY_TYPE_UNKNOWN;
}
@ -596,6 +674,7 @@ static void esp32_wifi_init(struct net_if *iface)
net_if_carrier_off(iface);
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
esp_err_t ret = esp_wifi_init(&config);
esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
@ -634,14 +713,6 @@ static int esp32_wifi_dev_init(const struct device *dev)
{
esp_timer_init();
k_tid_t tid = k_thread_create(&esp_wifi_event_thread, esp_wifi_event_stack,
CONFIG_ESP32_WIFI_EVENT_TASK_STACK_SIZE,
esp_wifi_event_task, NULL, NULL, NULL,
CONFIG_ESP32_WIFI_EVENT_TASK_PRIO, K_INHERIT_PERMS,
K_NO_WAIT);
k_thread_name_set(tid, "esp_event");
if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
net_mgmt_init_event_callback(&esp32_dhcp_cb, wifi_event_handler, DHCPV4_MASK);
net_mgmt_add_event_callback(&esp32_dhcp_cb);

View file

@ -8,20 +8,20 @@
#define ZEPHYR_INCLUDE_DRIVERS_DMA_ESP32_H_
enum gdma_trigger_peripheral {
GDMA_TRIG_PERIPH_M2M = -1,
GDMA_TRIG_PERIPH_SPI2 = 0,
GDMA_TRIG_PERIPH_SPI3 = 1,
GDMA_TRIG_PERIPH_UHCI0 = 2,
GDMA_TRIG_PERIPH_I2S0 = 3,
GDMA_TRIG_PERIPH_I2S1 = 4,
GDMA_TRIG_PERIPH_LCD0 = 5,
GDMA_TRIG_PERIPH_CAM0 = 5,
GDMA_TRIG_PERIPH_AES = 6,
GDMA_TRIG_PERIPH_SHA = 7,
GDMA_TRIG_PERIPH_ADC0 = 8,
GDMA_TRIG_PERIPH_DAC0 = 8,
GDMA_TRIG_PERIPH_RMT = 9,
GDMA_TRIG_PERIPH_INVALID = 0x3F,
ESP_GDMA_TRIG_PERIPH_M2M = -1,
ESP_GDMA_TRIG_PERIPH_SPI2 = 0,
ESP_GDMA_TRIG_PERIPH_SPI3 = 1,
ESP_GDMA_TRIG_PERIPH_UHCI0 = 2,
ESP_GDMA_TRIG_PERIPH_I2S0 = 3,
ESP_GDMA_TRIG_PERIPH_I2S1 = 4,
ESP_GDMA_TRIG_PERIPH_LCD0 = 5,
ESP_GDMA_TRIG_PERIPH_CAM0 = 5,
ESP_GDMA_TRIG_PERIPH_AES = 6,
ESP_GDMA_TRIG_PERIPH_SHA = 7,
ESP_GDMA_TRIG_PERIPH_ADC0 = 8,
ESP_GDMA_TRIG_PERIPH_DAC0 = 8,
ESP_GDMA_TRIG_PERIPH_RMT = 9,
ESP_GDMA_TRIG_PERIPH_INVALID = 0x3F,
};
#define ESP32_DT_INST_DMA_CTLR(n, name) \