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:
parent
37f9958fea
commit
fe57a12cf2
|
@ -10,42 +10,27 @@
|
||||||
#include <hal/adc_hal.h>
|
#include <hal/adc_hal.h>
|
||||||
#include <hal/adc_types.h>
|
#include <hal/adc_types.h>
|
||||||
#include <esp_adc_cal.h>
|
#include <esp_adc_cal.h>
|
||||||
#include <esp_heap_caps.h>
|
#include <esp_private/periph_ctrl.h>
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
#include <zephyr/drivers/adc.h>
|
#include <zephyr/drivers/adc.h>
|
||||||
#include "driver/periph_ctrl.h"
|
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(adc_esp32, CONFIG_ADC_LOG_LEVEL);
|
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_MIN SOC_ADC_DIGI_MIN_BITWIDTH
|
||||||
#define ADC_RESOLUTION_MAX SOC_ADC_DIGI_MAX_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
|
/* Due to significant measurement discrepancy in higher voltage range, we
|
||||||
* clip the value instead of yet another correction. The IDF implementation
|
* 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
|
* for ESP32-S2 is doing it, so we copy that approach in Zephyr driver
|
||||||
*/
|
*/
|
||||||
#define ADC_CLIP_MVOLT_11DB 2550
|
#define ADC_CLIP_MVOLT_11DB 2550
|
||||||
|
#else
|
||||||
#elif CONFIG_SOC_SERIES_ESP32S2
|
|
||||||
#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
|
#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
|
#endif
|
||||||
|
|
||||||
/* Convert resolution in bits to esp32 enum values */
|
/* Convert resolution in bits to esp32 enum values */
|
||||||
|
@ -64,9 +49,9 @@ struct adc_esp32_conf {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct adc_esp32_data {
|
struct adc_esp32_data {
|
||||||
adc_atten_t attenuation[ADC_CHANNEL_MAX];
|
adc_atten_t attenuation[SOC_ADC_MAX_CHANNEL_NUM];
|
||||||
uint8_t resolution[ADC_CHANNEL_MAX];
|
uint8_t resolution[SOC_ADC_MAX_CHANNEL_NUM];
|
||||||
esp_adc_cal_characteristics_t chars[ADC_CHANNEL_MAX];
|
esp_adc_cal_characteristics_t chars[SOC_ADC_MAX_CHANNEL_NUM];
|
||||||
uint16_t meas_ref_internal;
|
uint16_t meas_ref_internal;
|
||||||
uint16_t *buffer;
|
uint16_t *buffer;
|
||||||
uint16_t *buffer_repeat;
|
uint16_t *buffer_repeat;
|
||||||
|
@ -334,7 +319,7 @@ static const struct adc_driver_api api_esp32_driver_api = {
|
||||||
#define ESP32_ADC_INIT(inst) \
|
#define ESP32_ADC_INIT(inst) \
|
||||||
\
|
\
|
||||||
static const struct adc_esp32_conf adc_esp32_conf_##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), \
|
.channel_count = DT_PROP(DT_DRV_INST(inst), channel_count), \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
|
|
|
@ -14,29 +14,29 @@
|
||||||
#undef CPU_RESET_REASON
|
#undef CPU_RESET_REASON
|
||||||
#define CPU_RESET_REASON SW_CPU_RESET
|
#define CPU_RESET_REASON SW_CPU_RESET
|
||||||
#include <zephyr/dt-bindings/clock/esp32_clock.h>
|
#include <zephyr/dt-bindings/clock/esp32_clock.h>
|
||||||
#include "esp32/rom/rtc.h"
|
#include <esp32/rom/rtc.h>
|
||||||
#include "soc/dport_reg.h"
|
#include <soc/dport_reg.h>
|
||||||
#elif defined(CONFIG_SOC_SERIES_ESP32S2)
|
#elif defined(CONFIG_SOC_SERIES_ESP32S2)
|
||||||
#define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
|
#define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
|
||||||
#include <zephyr/dt-bindings/clock/esp32s2_clock.h>
|
#include <zephyr/dt-bindings/clock/esp32s2_clock.h>
|
||||||
#include "esp32s2/rom/rtc.h"
|
#include <esp32s2/rom/rtc.h>
|
||||||
#include "soc/dport_reg.h"
|
#include <soc/dport_reg.h>
|
||||||
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
|
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||||
#define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
|
#define DT_CPU_COMPAT cdns_tensilica_xtensa_lx7
|
||||||
#include <zephyr/dt-bindings/clock/esp32s3_clock.h>
|
#include <zephyr/dt-bindings/clock/esp32s3_clock.h>
|
||||||
#include "esp32s3/rom/rtc.h"
|
#include <esp32s3/rom/rtc.h>
|
||||||
#include "soc/dport_reg.h"
|
#include <soc/dport_reg.h>
|
||||||
#include "esp32s3/clk.h"
|
|
||||||
#elif CONFIG_SOC_SERIES_ESP32C3
|
#elif CONFIG_SOC_SERIES_ESP32C3
|
||||||
#define DT_CPU_COMPAT espressif_riscv
|
#define DT_CPU_COMPAT espressif_riscv
|
||||||
#include <zephyr/dt-bindings/clock/esp32c3_clock.h>
|
#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_caps.h>
|
||||||
#include <soc/soc.h>
|
#include <soc/soc.h>
|
||||||
#include <soc/rtc.h>
|
#include <soc/rtc.h>
|
||||||
#endif /* CONFIG_SOC_SERIES_ESP32xx */
|
#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/rtc.h>
|
||||||
#include <soc/i2s_reg.h>
|
#include <soc/i2s_reg.h>
|
||||||
#include <soc/apb_ctrl_reg.h>
|
#include <soc/apb_ctrl_reg.h>
|
||||||
|
@ -44,8 +44,10 @@
|
||||||
#include <hal/clk_gate_ll.h>
|
#include <hal/clk_gate_ll.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <zephyr/drivers/clock_control.h>
|
#include <zephyr/drivers/clock_control.h>
|
||||||
#include <driver/periph_ctrl.h>
|
#include <esp_private/periph_ctrl.h>
|
||||||
#include <hal/cpu_hal.h>
|
#include <esp_private/esp_clk.h>
|
||||||
|
#include <esp_cpu.h>
|
||||||
|
#include <esp_rom_caps.h>
|
||||||
|
|
||||||
struct esp32_clock_config {
|
struct esp32_clock_config {
|
||||||
int clk_src_sel;
|
int clk_src_sel;
|
||||||
|
@ -54,21 +56,6 @@ struct esp32_clock_config {
|
||||||
int xtal_div;
|
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,
|
static int clock_control_esp32_on(const struct device *dev,
|
||||||
clock_control_subsys_t sys)
|
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 |
|
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
|
||||||
SYSTEM_WIFI_CLK_BT_EN_M |
|
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_UNUSED_BIT12 |
|
||||||
SYSTEM_WIFI_CLK_SDIO_HOST_EN;
|
SYSTEM_WIFI_CLK_SDIO_HOST_EN;
|
||||||
}
|
}
|
||||||
|
@ -424,8 +411,14 @@ static void esp32_clock_perip_init(void)
|
||||||
/* Enable RNG clock. */
|
/* Enable RNG clock. */
|
||||||
periph_module_enable(PERIPH_RNG_MODULE);
|
periph_module_enable(PERIPH_RNG_MODULE);
|
||||||
|
|
||||||
esp_rom_uart_tx_wait_idle(0);
|
/* Enable TimerGroup 0 clock to ensure its reference counter will never
|
||||||
esp_rom_uart_set_clock_baudrate(0, UART_CLK_FREQ_ROM, 115200);
|
* 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 */
|
#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 |
|
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
|
||||||
SYSTEM_WIFI_CLK_BT_EN_M |
|
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_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) {
|
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();
|
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.cpu_freq_mhz = cfg->cpu_freq;
|
||||||
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
|
clk_cfg.slow_clk_src = rtc_clk_slow_freq_get();
|
||||||
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
|
clk_cfg.fast_clk_src = rtc_clk_fast_freq_get();
|
||||||
rtc_clk_init(clk_cfg);
|
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);
|
rtc_clk_cpu_freq_set_config(&new_config);
|
||||||
|
|
||||||
/* Re-calculate the ccount to make time calculation correct */
|
/* 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();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
/* Include esp-idf headers first to avoid redefining BIT() macro */
|
/* Include esp-idf headers first to avoid redefining BIT() macro */
|
||||||
#include <soc/rtc_cntl_reg.h>
|
#include <soc/rtc_cntl_reg.h>
|
||||||
#include <soc/timer_group_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 <soc/periph_defs.h>
|
||||||
#include <hal/timer_types.h>
|
|
||||||
#include <hal/timer_hal.h>
|
#include <hal/timer_hal.h>
|
||||||
|
#include <hal/timer_ll.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <zephyr/drivers/counter.h>
|
#include <zephyr/drivers/counter.h>
|
||||||
#include <zephyr/spinlock.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);
|
timer_hal_init(&data->hal_ctx, cfg->group, cfg->index);
|
||||||
data->alarm_cfg.callback = NULL;
|
data->alarm_cfg.callback = NULL;
|
||||||
timer_hal_intr_disable(&data->hal_ctx);
|
timer_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id),
|
||||||
timer_hal_clear_intr_status(&data->hal_ctx);
|
false);
|
||||||
timer_hal_set_auto_reload(&data->hal_ctx, cfg->config.auto_reload);
|
timer_ll_clear_intr_status(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id));
|
||||||
timer_hal_set_divider(&data->hal_ctx, cfg->config.divider);
|
timer_ll_enable_auto_reload(data->hal_ctx.dev, data->hal_ctx.timer_id,
|
||||||
timer_hal_set_counter_increase(&data->hal_ctx, cfg->config.counter_dir);
|
cfg->config.auto_reload);
|
||||||
timer_hal_set_alarm_enable(&data->hal_ctx, cfg->config.alarm_en);
|
timer_ll_set_clock_prescale(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.divider);
|
||||||
if (cfg->config.intr_type == TIMER_INTR_LEVEL) {
|
timer_ll_set_count_direction(data->hal_ctx.dev, data->hal_ctx.timer_id,
|
||||||
timer_hal_set_level_int_enable(&data->hal_ctx, true);
|
cfg->config.counter_dir);
|
||||||
}
|
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.alarm_en);
|
||||||
timer_hal_set_counter_value(&data->hal_ctx, 0);
|
timer_ll_set_reload_value(data->hal_ctx.dev, data->hal_ctx.timer_id, 0);
|
||||||
timer_hal_set_counter_enable(&data->hal_ctx, cfg->config.counter_en);
|
timer_ll_enable_counter(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.counter_en);
|
||||||
esp_intr_alloc(cfg->irq_source,
|
esp_intr_alloc(cfg->irq_source, 0, (ISR_HANDLER)counter_esp32_isr, (void *)dev, NULL);
|
||||||
0,
|
|
||||||
(ISR_HANDLER)counter_esp32_isr,
|
|
||||||
(void *)dev,
|
|
||||||
NULL);
|
|
||||||
k_spin_unlock(&lock, key);
|
k_spin_unlock(&lock, key);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -106,7 +103,7 @@ static int counter_esp32_start(const struct device *dev)
|
||||||
struct counter_esp32_data *data = dev->data;
|
struct counter_esp32_data *data = dev->data;
|
||||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
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);
|
k_spin_unlock(&lock, key);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -117,7 +114,7 @@ static int counter_esp32_stop(const struct device *dev)
|
||||||
struct counter_esp32_data *data = dev->data;
|
struct counter_esp32_data *data = dev->data;
|
||||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
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);
|
k_spin_unlock(&lock, key);
|
||||||
|
|
||||||
return 0;
|
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;
|
struct counter_esp32_data *data = dev->data;
|
||||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
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);
|
k_spin_unlock(&lock, key);
|
||||||
|
|
||||||
return 0;
|
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);
|
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||||
|
|
||||||
if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
|
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 {
|
} 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_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id), true);
|
||||||
timer_hal_set_alarm_enable(&data->hal_ctx, TIMER_ALARM_EN);
|
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.callback = alarm_cfg->callback;
|
||||||
data->alarm_cfg.user_data = alarm_cfg->user_data;
|
data->alarm_cfg.user_data = alarm_cfg->user_data;
|
||||||
k_spin_unlock(&lock, key);
|
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);
|
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||||
|
|
||||||
timer_hal_intr_disable(&data->hal_ctx);
|
timer_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id),
|
||||||
timer_hal_set_alarm_enable(&data->hal_ctx, TIMER_ALARM_DIS);
|
false);
|
||||||
|
timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_ALARM_DIS);
|
||||||
k_spin_unlock(&lock, key);
|
k_spin_unlock(&lock, key);
|
||||||
|
|
||||||
return 0;
|
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;
|
struct counter_esp32_data *data = dev->data;
|
||||||
|
|
||||||
timer_hal_get_intr_status_reg(&data->hal_ctx);
|
return timer_ll_get_intr_status(data->hal_ctx.dev);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t counter_esp32_get_top_value(const struct device *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);
|
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) \
|
#define ESP32_COUNTER_GET_CLK_DIV(idx) \
|
||||||
|
|
|
@ -13,9 +13,7 @@
|
||||||
#include <hal/rtc_io_types.h>
|
#include <hal/rtc_io_types.h>
|
||||||
#include <hal/rtc_io_hal.h>
|
#include <hal/rtc_io_hal.h>
|
||||||
#include <hal/rtc_io_ll.h>
|
#include <hal/rtc_io_ll.h>
|
||||||
#include <hal/dac_hal.h>
|
#include "driver/dac.h"
|
||||||
#include <hal/dac_types.h>
|
|
||||||
#include "driver/dac_common.h"
|
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(esp32_dac, CONFIG_DAC_LOG_LEVEL);
|
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);
|
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);
|
LOG_ERR("Channel %d is not valid", channel_cfg->channel_id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +64,7 @@ static int dac_esp32_init(const struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clock_control_on(cfg->clock_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);
|
LOG_ERR("DAC clock setup failed (%d)", -EIO);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,11 @@ LOG_MODULE_REGISTER(dma_esp32_gdma, CONFIG_DMA_LOG_LEVEL);
|
||||||
|
|
||||||
#include <hal/gdma_hal.h>
|
#include <hal/gdma_hal.h>
|
||||||
#include <hal/gdma_ll.h>
|
#include <hal/gdma_ll.h>
|
||||||
#include <gdma_channel.h>
|
#include <soc/gdma_channel.h>
|
||||||
#include <hal/dma_types.h>
|
#include <hal/dma_types.h>
|
||||||
|
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <soc/soc_memory_types.h>
|
#include <esp_memory_utils.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/drivers/dma.h>
|
#include <zephyr/drivers/dma.h>
|
||||||
|
@ -34,6 +34,8 @@ LOG_MODULE_REGISTER(dma_esp32_gdma, CONFIG_DMA_LOG_LEVEL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DMA_MAX_CHANNEL SOC_GDMA_PAIRS_PER_GROUP
|
#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 {
|
struct dma_esp32_data {
|
||||||
gdma_hal_context_t hal;
|
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);
|
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(
|
||||||
gdma_ll_rx_connect_to_periph(data->hal.dev, dma_channel->channel_id,
|
data->hal.dev, dma_channel->channel_id,
|
||||||
dma_channel->periph_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) {
|
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);
|
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(
|
||||||
gdma_ll_tx_connect_to_periph(data->hal.dev, dma_channel->channel_id,
|
data->hal.dev, dma_channel->channel_id,
|
||||||
dma_channel->periph_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
|
* 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;
|
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) {
|
switch (config_dma->channel_direction) {
|
||||||
case MEMORY_TO_MEMORY:
|
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 = &config->dma_channel[i];
|
||||||
dma_channel->cb = NULL;
|
dma_channel->cb = NULL;
|
||||||
dma_channel->dir = DMA_UNCONFIGURED;
|
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));
|
memset(&dma_channel->desc, 0, sizeof(dma_descriptor_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <soc/apb_ctrl_reg.h>
|
#include <soc/apb_ctrl_reg.h>
|
||||||
#include <esp_system.h>
|
#include <esp_system.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <hal/cpu_hal.h>
|
#include <esp_cpu.h>
|
||||||
#include <zephyr/drivers/entropy.h>
|
#include <zephyr/drivers/entropy.h>
|
||||||
|
|
||||||
static inline uint32_t entropy_esp32_get_u32(void)
|
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;
|
uint32_t ccount;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ccount = cpu_hal_get_cycle_count();
|
ccount = esp_cpu_get_cycle_count();
|
||||||
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16);
|
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16);
|
||||||
last_ccount = ccount;
|
last_ccount = ccount;
|
||||||
|
|
||||||
|
|
|
@ -285,9 +285,12 @@ int eth_esp32_initialize(const struct device *dev)
|
||||||
goto err;
|
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_reset_desc_chain(&dev_data->hal);
|
||||||
emac_hal_init_mac_default(&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);
|
res = generate_mac_addr(dev_data->mac_addr);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
|
|
|
@ -14,13 +14,11 @@
|
||||||
* HAL includes go first to
|
* HAL includes go first to
|
||||||
* avoid BIT macro redefinition
|
* avoid BIT macro redefinition
|
||||||
*/
|
*/
|
||||||
#include <esp_spi_flash.h>
|
#include <esp_flash.h>
|
||||||
#include <hal/spi_ll.h>
|
#include <spi_flash_mmap.h>
|
||||||
#include <hal/spi_flash_ll.h>
|
|
||||||
#include <hal/spi_flash_hal.h>
|
|
||||||
#include <soc/spi_struct.h>
|
#include <soc/spi_struct.h>
|
||||||
#include <spi_flash_defs.h>
|
|
||||||
#include <esp_flash_encrypt.h>
|
#include <esp_flash_encrypt.h>
|
||||||
|
#include <esp_flash_internal.h>
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
|
@ -30,30 +28,6 @@
|
||||||
#include <zephyr/drivers/flash.h>
|
#include <zephyr/drivers/flash.h>
|
||||||
#include <soc.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>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL);
|
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);
|
flash_esp32_sem_take(dev);
|
||||||
if (!esp_flash_encryption_enabled()) {
|
if (!esp_flash_encryption_enabled()) {
|
||||||
ret = spi_flash_read(address, buffer, length);
|
ret = esp_flash_read(NULL, buffer, address, length);
|
||||||
} else {
|
} else {
|
||||||
ret = spi_flash_read_encrypted(address, buffer, length);
|
ret = esp_flash_read_encrypted(NULL, address, buffer, length);
|
||||||
}
|
}
|
||||||
flash_esp32_sem_give(dev);
|
flash_esp32_sem_give(dev);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -118,9 +92,9 @@ static int flash_esp32_write(const struct device *dev,
|
||||||
|
|
||||||
flash_esp32_sem_take(dev);
|
flash_esp32_sem_take(dev);
|
||||||
if (!esp_flash_encryption_enabled()) {
|
if (!esp_flash_encryption_enabled()) {
|
||||||
ret = spi_flash_write(address, buffer, length);
|
ret = esp_flash_write(NULL, buffer, address, length);
|
||||||
} else {
|
} else {
|
||||||
ret = spi_flash_write_encrypted(address, buffer, length);
|
ret = esp_flash_write_encrypted(NULL, address, buffer, length);
|
||||||
}
|
}
|
||||||
flash_esp32_sem_give(dev);
|
flash_esp32_sem_give(dev);
|
||||||
return ret;
|
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)
|
static int flash_esp32_erase(const struct device *dev, off_t start, size_t len)
|
||||||
{
|
{
|
||||||
flash_esp32_sem_take(dev);
|
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);
|
flash_esp32_sem_give(dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -160,11 +134,16 @@ flash_esp32_get_parameters(const struct device *dev)
|
||||||
static int flash_esp32_init(const struct device *dev)
|
static int flash_esp32_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct flash_esp32_dev_data *const dev_data = dev->data;
|
struct flash_esp32_dev_data *const dev_data = dev->data;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_MULTITHREADING
|
#ifdef CONFIG_MULTITHREADING
|
||||||
k_sem_init(&dev_data->sem, 1, 1);
|
k_sem_init(&dev_data->sem, 1, 1);
|
||||||
#endif /* CONFIG_MULTITHREADING */
|
#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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <hal/i2c_ll.h>
|
#include <hal/i2c_ll.h>
|
||||||
#include <hal/i2c_hal.h>
|
#include <hal/i2c_hal.h>
|
||||||
#include <hal/gpio_hal.h>
|
#include <hal/gpio_hal.h>
|
||||||
|
#include <clk_ctrl_os.h>
|
||||||
|
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <errno.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_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_CLK_LIMIT_XTAL (40 * 1000 * 1000 / 20) /* Limited by RTC, no more than XTAL/20 */
|
||||||
|
|
||||||
|
#define I2C_CLOCK_INVALID (-1)
|
||||||
|
|
||||||
enum i2c_status_t {
|
enum i2c_status_t {
|
||||||
I2C_STATUS_READ, /* read status for current master command */
|
I2C_STATUS_READ, /* read status for current master command */
|
||||||
I2C_STATUS_WRITE, /* write 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;
|
const uint32_t scl_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* I2C clock characteristic, The order is the same as i2c_sclk_t. */
|
static uint32_t i2c_get_src_clk_freq(i2c_clock_source_t clk_src)
|
||||||
static uint32_t i2c_clk_alloc[I2C_SCLK_MAX] = {
|
{
|
||||||
0,
|
uint32_t periph_src_clk_hz = 0;
|
||||||
|
|
||||||
|
switch (clk_src) {
|
||||||
#if SOC_I2C_SUPPORT_APB
|
#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
|
#endif
|
||||||
#if SOC_I2C_SUPPORT_XTAL
|
#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
|
#endif
|
||||||
#if SOC_I2C_SUPPORT_RTC
|
#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
|
#endif
|
||||||
#if SOC_I2C_SUPPORT_REF_TICK
|
#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
|
#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++) {
|
i2c_clock_source_t clk_srcs[] = SOC_I2C_CLKS;
|
||||||
if (clk_freq <= i2c_clk_alloc[clk]) {
|
|
||||||
return clk;
|
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
|
#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 */
|
gpio_pin_set_dt(&config->sda.gpio, 1); /* STOP, SDA low -> high while SCL is HIGH */
|
||||||
i2c_esp32_config_pin(dev);
|
i2c_esp32_config_pin(dev);
|
||||||
#else
|
#else
|
||||||
i2c_hal_master_clr_bus(&data->hal);
|
i2c_ll_master_clr_bus(data->hal.dev);
|
||||||
#endif
|
#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)
|
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;
|
int timeout;
|
||||||
uint8_t filter_cfg;
|
uint8_t filter_cfg;
|
||||||
|
|
||||||
i2c_hal_get_scl_timing(&data->hal, &scl_high_period, &scl_low_period);
|
i2c_ll_get_scl_timing(data->hal.dev, &scl_high_period, &scl_low_period);
|
||||||
i2c_hal_get_start_timing(&data->hal, &scl_rstart_setup, &scl_start_hold);
|
i2c_ll_get_start_timing(data->hal.dev, &scl_rstart_setup, &scl_start_hold);
|
||||||
i2c_hal_get_stop_timing(&data->hal, &scl_stop_setup, &scl_stop_hold);
|
i2c_ll_get_stop_timing(data->hal.dev, &scl_stop_setup, &scl_stop_hold);
|
||||||
i2c_hal_get_sda_timing(&data->hal, &sda_sample, &sda_hold);
|
i2c_ll_get_sda_timing(data->hal.dev, &sda_sample, &sda_hold);
|
||||||
i2c_hal_get_tout(&data->hal, &timeout);
|
i2c_ll_get_tout(data->hal.dev, &timeout);
|
||||||
i2c_hal_get_filter(&data->hal, &filter_cfg);
|
i2c_ll_get_filter(data->hal.dev, &filter_cfg);
|
||||||
|
|
||||||
/* to reset the I2C hw module, we need re-enable the hw */
|
/* to reset the I2C hw module, we need re-enable the hw */
|
||||||
clock_control_off(config->clock_dev, config->clock_subsys);
|
clock_control_off(config->clock_dev, config->clock_subsys);
|
||||||
i2c_master_clear_bus(dev);
|
i2c_master_clear_bus(dev);
|
||||||
clock_control_on(config->clock_dev, config->clock_subsys);
|
clock_control_on(config->clock_dev, config->clock_subsys);
|
||||||
|
|
||||||
i2c_hal_master_init(&data->hal, config->index);
|
i2c_hal_master_init(&data->hal);
|
||||||
i2c_hal_disable_intr_mask(&data->hal, I2C_LL_INTR_MASK);
|
i2c_ll_disable_intr_mask(data->hal.dev, I2C_LL_INTR_MASK);
|
||||||
i2c_hal_clr_intsts_mask(&data->hal, I2C_LL_INTR_MASK);
|
i2c_ll_clear_intr_mask(data->hal.dev, I2C_LL_INTR_MASK);
|
||||||
i2c_hal_set_scl_timing(&data->hal, scl_high_period, scl_low_period);
|
i2c_ll_set_scl_timing(data->hal.dev, scl_high_period, scl_low_period);
|
||||||
i2c_hal_set_start_timing(&data->hal, scl_rstart_setup, scl_start_hold);
|
i2c_ll_set_start_timing(data->hal.dev, scl_rstart_setup, scl_start_hold);
|
||||||
i2c_hal_set_stop_timing(&data->hal, scl_stop_setup, scl_stop_hold);
|
i2c_ll_set_stop_timing(data->hal.dev, scl_stop_setup, scl_stop_hold);
|
||||||
i2c_hal_set_sda_timing(&data->hal, sda_sample, sda_hold);
|
i2c_ll_set_sda_timing(data->hal.dev, sda_sample, sda_hold);
|
||||||
i2c_hal_set_tout(&data->hal, timeout);
|
i2c_ll_set_tout(data->hal.dev, timeout);
|
||||||
i2c_hal_set_filter(&data->hal, filter_cfg);
|
i2c_ll_set_filter(data->hal.dev, filter_cfg);
|
||||||
#else
|
#else
|
||||||
i2c_hal_master_fsm_rst(&data->hal);
|
i2c_ll_master_fsm_rst(data->hal.dev);
|
||||||
i2c_master_clear_bus(dev);
|
i2c_master_clear_bus(dev);
|
||||||
#endif
|
#endif
|
||||||
i2c_hal_update_config(&data->hal);
|
i2c_ll_update(data->hal.dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int i2c_esp32_recover(const struct device *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;
|
struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data;
|
||||||
|
|
||||||
if (config->scl_timeout > 0) {
|
if (config->scl_timeout > 0) {
|
||||||
i2c_sclk_t sclk = i2c_get_clk_src(config->bitrate);
|
i2c_clock_source_t sclk = i2c_get_clk_src(config->bitrate);
|
||||||
uint32_t clk_freq_mhz = i2c_clk_alloc[sclk];
|
uint32_t clk_freq_mhz = i2c_get_src_clk_freq(sclk);
|
||||||
uint32_t timeout_cycles = MIN(I2C_LL_MAX_TIMEOUT,
|
uint32_t timeout_cycles = MIN(I2C_LL_MAX_TIMEOUT,
|
||||||
clk_freq_mhz / MHZ(1) * config->scl_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);
|
LOG_DBG("SCL timeout: %d us, value: %d", config->scl_timeout, timeout_cycles);
|
||||||
} else {
|
} else {
|
||||||
/* Disabling the timeout by clearing the I2C_TIME_OUT_EN bit does not seem to work,
|
/* 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
|
* at least for ESP32-C3 (tested with communication to bq76952 chip). So we set the
|
||||||
* timeout to maximum supported value instead.
|
* timeout to maximum supported value instead.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32)
|
i2c_ll_set_tout(data->hal.dev, I2C_LL_MAX_TIMEOUT);
|
||||||
i2c_hal_set_tout(&data->hal, I2C_LL_MAX_TIMEOUT);
|
|
||||||
#else
|
|
||||||
i2c_hal_set_tout_en(&data->hal, 0);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,19 +306,21 @@ static int i2c_esp32_configure(const struct device *dev, uint32_t dev_config)
|
||||||
rx_mode = I2C_DATA_MODE_LSB_FIRST;
|
rx_mode = I2C_DATA_MODE_LSB_FIRST;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_hal_master_init(&data->hal, config->index);
|
i2c_hal_master_init(&data->hal);
|
||||||
i2c_hal_set_data_mode(&data->hal, tx_mode, rx_mode);
|
i2c_ll_set_data_mode(data->hal.dev, tx_mode, rx_mode);
|
||||||
i2c_hal_set_filter(&data->hal, I2C_FILTER_CYC_NUM_DEF);
|
i2c_ll_set_filter(data->hal.dev, I2C_FILTER_CYC_NUM_DEF);
|
||||||
i2c_hal_update_config(&data->hal);
|
i2c_ll_update(data->hal.dev);
|
||||||
|
|
||||||
if (config->bitrate == 0) {
|
if (config->bitrate == 0) {
|
||||||
LOG_ERR("Error configuring I2C speed.");
|
LOG_ERR("Error configuring I2C speed.");
|
||||||
return -ENOTSUP;
|
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_esp32_configure_timeout(dev);
|
||||||
i2c_hal_update_config(&data->hal);
|
i2c_ll_update(data->hal.dev);
|
||||||
|
|
||||||
return 0;
|
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;
|
struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data;
|
||||||
|
|
||||||
/* reset fifo buffers */
|
/* reset fifo buffers */
|
||||||
i2c_hal_txfifo_rst(&data->hal);
|
i2c_ll_txfifo_rst(data->hal.dev);
|
||||||
i2c_hal_rxfifo_rst(&data->hal);
|
i2c_ll_rxfifo_rst(data->hal.dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int IRAM_ATTR i2c_esp32_transmit(const struct device *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;
|
int ret = 0;
|
||||||
|
|
||||||
/* Start transmission*/
|
/* Start transmission*/
|
||||||
i2c_hal_update_config(&data->hal);
|
i2c_ll_update(data->hal.dev);
|
||||||
i2c_hal_trans_start(&data->hal);
|
i2c_ll_trans_start(data->hal.dev);
|
||||||
data->cmd_idx = 0;
|
data->cmd_idx = 0;
|
||||||
|
|
||||||
ret = k_sem_take(&data->cmd_sem, K_MSEC(I2C_TRANSFER_TIMEOUT_MSEC));
|
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;
|
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
|
.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)
|
static void IRAM_ATTR i2c_esp32_master_stop(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct i2c_esp32_data *data = (struct i2c_esp32_data *const)(dev)->data;
|
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
|
.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)
|
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;
|
data->status = I2C_STATUS_WRITE;
|
||||||
|
|
||||||
/* write address value in tx buffer */
|
/* 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) {
|
if (data->dev_config & I2C_ADDR_10_BITS) {
|
||||||
addr_byte = (addr >> 8) & 0xFF;
|
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++;
|
addr_len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
const i2c_hw_cmd_t cmd_end = {
|
const i2c_ll_hw_cmd_t cmd_end = {
|
||||||
.op_code = I2C_LL_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,
|
.op_code = I2C_LL_CMD_WRITE,
|
||||||
.ack_en = true,
|
.ack_en = true,
|
||||||
.byte_num = addr_len,
|
.byte_num = addr_len,
|
||||||
};
|
};
|
||||||
|
|
||||||
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
|
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
|
||||||
i2c_hal_write_cmd_reg(&data->hal, cmd_end, data->cmd_idx++);
|
i2c_ll_write_cmd_reg(data->hal.dev, cmd_end, data->cmd_idx++);
|
||||||
i2c_hal_enable_master_tx_it(&data->hal);
|
i2c_ll_master_enable_tx_it(data->hal.dev);
|
||||||
|
|
||||||
return i2c_esp32_transmit(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;
|
data->status = I2C_STATUS_READ;
|
||||||
|
|
||||||
i2c_hw_cmd_t cmd = {
|
i2c_ll_hw_cmd_t cmd = {
|
||||||
.op_code = I2C_LL_CMD_READ,
|
.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,
|
.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;
|
cmd.byte_num = rd_filled;
|
||||||
|
|
||||||
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
|
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
|
||||||
i2c_hal_write_cmd_reg(&data->hal, cmd_end, data->cmd_idx++);
|
i2c_ll_write_cmd_reg(data->hal.dev, cmd_end, data->cmd_idx++);
|
||||||
i2c_hal_enable_master_rx_it(&data->hal);
|
i2c_ll_master_enable_tx_it(data->hal.dev);
|
||||||
ret = i2c_esp32_transmit(dev);
|
ret = i2c_esp32_transmit(dev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
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_buf += rd_filled;
|
||||||
msg_len -= 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;
|
data->status = I2C_STATUS_WRITE;
|
||||||
|
|
||||||
i2c_hw_cmd_t cmd = {
|
i2c_ll_hw_cmd_t cmd = {
|
||||||
.op_code = I2C_LL_CMD_WRITE,
|
.op_code = I2C_LL_CMD_WRITE,
|
||||||
.ack_en = true,
|
.ack_en = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const i2c_hw_cmd_t cmd_end = {
|
const i2c_ll_hw_cmd_t cmd_end = {
|
||||||
.op_code = I2C_LL_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;
|
cmd.byte_num = wr_filled;
|
||||||
|
|
||||||
if (wr_filled > 0) {
|
if (wr_filled > 0) {
|
||||||
i2c_hal_write_txfifo(&data->hal, msg_buf, wr_filled);
|
i2c_ll_write_txfifo(data->hal.dev, msg_buf, wr_filled);
|
||||||
i2c_hal_write_cmd_reg(&data->hal, cmd, data->cmd_idx++);
|
i2c_ll_write_cmd_reg(data->hal.dev, cmd, data->cmd_idx++);
|
||||||
i2c_hal_write_cmd_reg(&data->hal, cmd_end, data->cmd_idx++);
|
i2c_ll_write_cmd_reg(data->hal.dev, cmd_end, data->cmd_idx++);
|
||||||
i2c_hal_enable_master_tx_it(&data->hal);
|
i2c_ll_master_enable_tx_it(data->hal.dev);
|
||||||
ret = i2c_esp32_transmit(dev);
|
ret = i2c_esp32_transmit(dev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -567,7 +589,7 @@ static int IRAM_ATTR i2c_esp32_transfer(const struct device *dev, struct i2c_msg
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i2c_hal_is_bus_busy(&data->hal)) {
|
while (i2c_ll_is_bus_busy(data->hal.dev)) {
|
||||||
k_busy_wait(1);
|
k_busy_wait(1);
|
||||||
if (timeout-- == 0) {
|
if (timeout-- == 0) {
|
||||||
return -EBUSY;
|
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++) {
|
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);
|
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. */
|
/* 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. */
|
/* 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_ll_disable_intr_mask(data->hal.dev, I2C_LL_INTR_MASK);
|
||||||
i2c_hal_clr_intsts_mask(&data->hal, 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) {
|
if ((msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
|
||||||
ret = i2c_esp32_read_msg(dev, msgs, addr);
|
ret = i2c_esp32_read_msg(dev, msgs, addr);
|
||||||
|
|
|
@ -12,12 +12,14 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||||
#include "esp_attr.h"
|
#include <esp_memory_utils.h>
|
||||||
#include <hal/cpu_hal.h>
|
#include <esp_attr.h>
|
||||||
#include <hal/interrupt_controller_hal.h>
|
#include <esp_cpu.h>
|
||||||
|
#include <esp_private/rtc_ctrl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "soc/soc.h"
|
#include <soc/soc.h>
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(esp32_intc, CONFIG_LOG_DEFAULT_LEVEL);
|
LOG_MODULE_REGISTER(esp32_intc, CONFIG_LOG_DEFAULT_LEVEL);
|
||||||
|
|
||||||
|
@ -73,9 +75,9 @@ struct intr_alloc_table_entry {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Default handler for unhandled interrupts. */
|
/* 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];
|
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);
|
irq_disable(n);
|
||||||
intr_alloc_table[n * CONFIG_MP_MAX_NUM_CPUS].handler = f;
|
intr_alloc_table[n * CONFIG_MP_MAX_NUM_CPUS].handler = f;
|
||||||
irq_connect_dynamic(n, n, (intc_dyn_handler_t)f, arg, 0);
|
irq_connect_dynamic(n, 0, (intc_dyn_handler_t)f, arg, 0);
|
||||||
irq_enable(n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linked list of vector descriptions, sorted by cpu.intno value */
|
/* 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 */
|
/* Check if interrupt is not reserved by design */
|
||||||
int x = vd->intno;
|
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");
|
INTC_LOG("....Unusable: reserved");
|
||||||
return false;
|
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");
|
INTC_LOG("....Unusable: special-purpose int");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* Check if the interrupt level is acceptable */
|
|
||||||
if (!(flags & (1 << interrupt_controller_hal_get_level(x)))) {
|
#ifndef SOC_CPU_HAS_FLEXIBLE_INTC
|
||||||
INTC_LOG("....Unusable: incompatible level");
|
/* Check if the interrupt priority is acceptable */
|
||||||
|
if (!(flags & (1 << intr_desc.priority))) {
|
||||||
|
INTC_LOG("....Unusable: incompatible priority");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* check if edge/level type matches what we want */
|
/* check if edge/level type matches what we want */
|
||||||
if (((flags & ESP_INTR_FLAG_EDGE) &&
|
if (((flags & ESP_INTR_FLAG_EDGE) && (intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL)) ||
|
||||||
(interrupt_controller_hal_get_type(x) == INTTP_LEVEL)) ||
|
(((!(flags & ESP_INTR_FLAG_EDGE)) && (intr_desc.type == ESP_CPU_INTR_TYPE_EDGE)))) {
|
||||||
(((!(flags & ESP_INTR_FLAG_EDGE)) &&
|
|
||||||
(interrupt_controller_hal_get_type(x) == INTTP_EDGE)))) {
|
|
||||||
INTC_LOG("....Unusable: incompatible trigger type");
|
INTC_LOG("....Unusable: incompatible trigger type");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* check if interrupt is reserved at runtime */
|
/* check if interrupt is reserved at runtime */
|
||||||
if (vd->flags & VECDESC_FL_RESERVED) {
|
if (vd->flags & VECDESC_FL_RESERVED) {
|
||||||
INTC_LOG("....Unusable: reserved at runtime.");
|
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));
|
memset(&empty_vect_desc, 0, sizeof(struct vector_desc_t));
|
||||||
|
|
||||||
|
|
||||||
/* Level defaults to any low/med interrupt */
|
/* Level defaults to any low/med interrupt */
|
||||||
if (!(flags & ESP_INTR_FLAG_LEVELMASK)) {
|
if (!(flags & ESP_INTR_FLAG_LEVELMASK)) {
|
||||||
flags |= ESP_INTR_FLAG_LOWMED;
|
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;
|
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",
|
INTC_LOG("Int %d reserved %d level %d %s hasIsr %d",
|
||||||
x,
|
x, intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD,
|
||||||
interrupt_controller_hal_get_cpu_desc_flags(x, cpu) == INTDESC_RESVD,
|
intr_desc.priority,
|
||||||
interrupt_controller_hal_get_level(x),
|
intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL ? "LEVEL" : "EDGE",
|
||||||
interrupt_controller_hal_get_type(x) == INTTP_LEVEL ? "LEVEL" : "EDGE",
|
|
||||||
intr_has_handler(x, cpu));
|
intr_has_handler(x, cpu));
|
||||||
|
|
||||||
if (!is_vect_desc_usable(vd, flags, cpu, force)) {
|
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++;
|
no++;
|
||||||
svdesc = svdesc->next;
|
svdesc = svdesc->next;
|
||||||
}
|
}
|
||||||
if (no < best_shared_ct ||
|
if (no < best_shared_ct || best_level > intr_desc.priority) {
|
||||||
best_level > interrupt_controller_hal_get_level(x)) {
|
|
||||||
/*
|
/*
|
||||||
* Seems like this shared vector is both okay and has
|
* Seems like this shared vector is both okay and has
|
||||||
* the least amount of ISRs already attached to it.
|
* the least amount of ISRs already attached to it.
|
||||||
*/
|
*/
|
||||||
best = x;
|
best = x;
|
||||||
best_shared_ct = no;
|
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: "
|
INTC_LOG("...int %d more usable as a shared int: "
|
||||||
"has %d existing vectors", x, no);
|
"has %d existing vectors", x, no);
|
||||||
} else {
|
} 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
|
* Remember it in case we don't find any other shared
|
||||||
* interrupt that qualifies.
|
* interrupt that qualifies.
|
||||||
*/
|
*/
|
||||||
if (best_level > interrupt_controller_hal_get_level(x)) {
|
if (best_level > intr_desc.priority) {
|
||||||
best = x;
|
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);
|
INTC_LOG("...int %d usable as new shared int", x);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
* Seems this interrupt is feasible. Select it and break out of the loop
|
||||||
* No need to search further.
|
* No need to search further.
|
||||||
*/
|
*/
|
||||||
if (best_level > interrupt_controller_hal_get_level(x)) {
|
if (best_level > intr_desc.priority) {
|
||||||
best = x;
|
best = x;
|
||||||
best_level = interrupt_controller_hal_get_level(x);
|
best_level = intr_desc.priority;
|
||||||
} else {
|
} else {
|
||||||
INTC_LOG("...worse than int %d", best);
|
INTC_LOG("...worse than int %d", best);
|
||||||
}
|
}
|
||||||
|
@ -493,7 +500,8 @@ static void IRAM_ATTR shared_intr_isr(void *arg)
|
||||||
esp_intr_lock();
|
esp_intr_lock();
|
||||||
while (sh_vec) {
|
while (sh_vec) {
|
||||||
if (!sh_vec->disabled) {
|
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);
|
sh_vec->isr(sh_vec->arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,7 +521,7 @@ int esp_intr_alloc_intrstatus(int source,
|
||||||
struct intr_handle_data_t *ret = NULL;
|
struct intr_handle_data_t *ret = NULL;
|
||||||
int force = -1;
|
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. */
|
/* Shared interrupts should be level-triggered. */
|
||||||
if ((flags & ESP_INTR_FLAG_SHARED) && (flags & ESP_INTR_FLAG_EDGE)) {
|
if ((flags & ESP_INTR_FLAG_SHARED) && (flags & ESP_INTR_FLAG_EDGE)) {
|
||||||
return -EINVAL;
|
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.
|
* 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.
|
* CPU1 does not have access to the RTC fast memory through this region.
|
||||||
*/
|
*/
|
||||||
if ((flags & ESP_INTR_FLAG_IRAM) &&
|
if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) &&
|
||||||
(ptrdiff_t) handler >= SOC_RTC_IRAM_HIGH &&
|
!esp_ptr_in_rtc_iram_fast(handler)) {
|
||||||
(ptrdiff_t) handler < SOC_RTC_DATA_LOW) {
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +561,7 @@ int esp_intr_alloc_intrstatus(int source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INTC_LOG("%s (cpu %d): Args okay."
|
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
|
* Check 'special' interrupt sources. These are tied to one specific
|
||||||
|
@ -590,7 +597,7 @@ int esp_intr_alloc_intrstatus(int source,
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_intr_lock();
|
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. */
|
/* See if we can find an interrupt that matches the flags. */
|
||||||
int intr = get_available_int(flags, cpu, force, source);
|
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);
|
non_iram_int_mask[cpu] |= (1 << intr);
|
||||||
}
|
}
|
||||||
if (source >= 0) {
|
if (source >= 0) {
|
||||||
intr_matrix_set(cpu, source, intr);
|
esp_rom_route_intr_matrix(cpu, source, intr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill return handle data. */
|
/* Fill return handle data. */
|
||||||
|
@ -668,6 +675,19 @@ int esp_intr_alloc_intrstatus(int source,
|
||||||
esp_intr_disable(ret);
|
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();
|
esp_intr_unlock();
|
||||||
|
|
||||||
/* Fill return handle if needed, otherwise free handle. */
|
/* 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
|
* 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.
|
* 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. */
|
/* Also kill non_iram mask bit. */
|
||||||
non_iram_int_mask[handle->vector_desc->cpu] &= ~(1 << (handle->vector_desc->intno));
|
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) {
|
if (source >= 0) {
|
||||||
/* Disabled using int matrix; re-connect to enable */
|
/* 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 {
|
} else {
|
||||||
/* Re-enable using cpu int ena reg */
|
/* 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 */
|
return -EINVAL; /* Can only enable these ints on this cpu */
|
||||||
}
|
}
|
||||||
irq_enable(handle->vector_desc->intno);
|
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 (source >= 0) {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
/* Disable using int matrix */
|
/* 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 {
|
} else {
|
||||||
/* Disable using per-cpu regs */
|
/* 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();
|
esp_intr_unlock();
|
||||||
return -EINVAL; /* Can only enable these ints on this cpu */
|
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)
|
void IRAM_ATTR esp_intr_noniram_disable(void)
|
||||||
{
|
{
|
||||||
|
esp_intr_lock();
|
||||||
int oldint;
|
int oldint;
|
||||||
int cpu = esp_core_id();
|
int cpu = esp_cpu_get_core_id();
|
||||||
int non_iram_ints = ~non_iram_int_mask[cpu];
|
int non_iram_ints = ~non_iram_int_mask[cpu];
|
||||||
|
|
||||||
if (non_iram_int_disabled_flag[cpu]) {
|
if (non_iram_int_disabled_flag[cpu]) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
non_iram_int_disabled_flag[cpu] = true;
|
non_iram_int_disabled_flag[cpu] = true;
|
||||||
oldint = interrupt_controller_hal_read_interrupt_mask();
|
oldint = esp_cpu_intr_get_enabled_mask();
|
||||||
interrupt_controller_hal_disable_interrupts(non_iram_ints);
|
esp_cpu_intr_disable(non_iram_ints);
|
||||||
/* Save which ints we did disable */
|
rtc_isr_noniram_disable(cpu);
|
||||||
non_iram_int_disabled[cpu] = oldint & non_iram_ints;
|
non_iram_int_disabled[cpu] = oldint & non_iram_ints;
|
||||||
|
esp_intr_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR esp_intr_noniram_enable(void)
|
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];
|
int non_iram_ints = non_iram_int_disabled[cpu];
|
||||||
|
|
||||||
if (!non_iram_int_disabled_flag[cpu]) {
|
if (!non_iram_int_disabled_flag[cpu]) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
non_iram_int_disabled_flag[cpu] = false;
|
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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
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;
|
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;
|
max_precision_n /= 2;
|
||||||
if (!max_precision_n) {
|
if (!max_precision_n) {
|
||||||
channel->resolution = i;
|
channel->resolution = i;
|
||||||
|
@ -164,10 +164,12 @@ static int pwm_led_esp32_timer_config(struct pwm_ledc_esp32_channel_config *chan
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_LEDC_SUPPORT_REF_TICK
|
||||||
channel->clock_src = LEDC_REF_TICK;
|
channel->clock_src = LEDC_REF_TICK;
|
||||||
if (!pwm_led_esp32_calculate_max_resolution(channel)) {
|
if (!pwm_led_esp32_calculate_max_resolution(channel)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ESP32 - S2,S3 and C3 variants have only 14 bits counter.
|
* 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.
|
* 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'.
|
* 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;
|
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;
|
prescaler = ((uint64_t) APB_CLK_FREQ << 8) / channel->freq / precision;
|
||||||
break;
|
break;
|
||||||
|
#if SOC_LEDC_SUPPORT_REF_TICK
|
||||||
case LEDC_REF_TICK:
|
case LEDC_REF_TICK:
|
||||||
prescaler = ((uint64_t) REF_CLK_FREQ << 8) / channel->freq / precision;
|
prescaler = ((uint64_t) REF_CLK_FREQ << 8) / channel->freq / precision;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
LOG_ERR("Invalid clock source (%d)", channel->clock_src);
|
LOG_ERR("Invalid clock source (%d)", channel->clock_src);
|
||||||
return -EINVAL;
|
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) {
|
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);
|
ledc_hal_set_clock_divider(&data->hal, channel->timer_num, prescaler);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include <hal/mcpwm_hal.h>
|
#include <hal/mcpwm_hal.h>
|
||||||
#include <hal/mcpwm_ll.h>
|
#include <hal/mcpwm_ll.h>
|
||||||
#include "driver/mcpwm.h"
|
#include <driver/mcpwm.h>
|
||||||
|
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(mcpwm_esp32, CONFIG_PWM_LOG_LEVEL);
|
LOG_MODULE_REGISTER(mcpwm_esp32, CONFIG_PWM_LOG_LEVEL);
|
||||||
|
|
||||||
|
#define SOC_MCPWM_BASE_CLK_HZ (160000000U)
|
||||||
#ifdef CONFIG_PWM_CAPTURE
|
#ifdef CONFIG_PWM_CAPTURE
|
||||||
#define SKIP_IRQ_NUM 4U
|
#define SKIP_IRQ_NUM 4U
|
||||||
#define MCPWM_INTR_CAP0 BIT(0)
|
#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) *
|
set_duty = mcpwm_ll_timer_get_peak(data->hal.dev, channel->timer_id, false) *
|
||||||
channel->duty / 100;
|
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,
|
mcpwm_ll_operator_set_compare_value(data->hal.dev, channel->operator_id,
|
||||||
channel->generator_id, set_duty);
|
channel->generator_id, set_duty);
|
||||||
mcpwm_ll_operator_enable_update_compare_on_tez(data->hal.dev, channel->operator_id,
|
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) {
|
if (duty_type == MCPWM_DUTY_MODE_0) {
|
||||||
mcpwm_ll_generator_set_action_on_timer_event(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_compare_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
data->hal.dev, channel->operator_id, channel->generator_id,
|
||||||
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_LOW);
|
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_LOW);
|
||||||
} else if (duty_type == MCPWM_DUTY_MODE_1) {
|
} else if (duty_type == MCPWM_DUTY_MODE_1) {
|
||||||
mcpwm_ll_generator_set_action_on_timer_event(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_compare_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
data->hal.dev, channel->operator_id, channel->generator_id,
|
||||||
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_HIGH);
|
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_HIGH);
|
||||||
} else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
|
} else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
|
||||||
mcpwm_ll_generator_set_action_on_timer_event(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_compare_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
data->hal.dev, channel->operator_id, channel->generator_id,
|
||||||
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_LOW);
|
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_LOW);
|
||||||
} else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
|
} else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
|
||||||
mcpwm_ll_generator_set_action_on_timer_event(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_timer_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
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(
|
mcpwm_ll_generator_set_action_on_compare_event(
|
||||||
data->hal.dev, channel->operator_id, channel->generator_id,
|
data->hal.dev, channel->operator_id, channel->generator_id,
|
||||||
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_HIGH);
|
MCPWM_TIMER_DIRECTION_UP, channel->generator_id, MCPWM_ACTION_FORCE_HIGH);
|
||||||
|
@ -259,8 +260,8 @@ static int mcpwm_esp32_set_cycles(const struct device *dev, uint32_t channel_idx
|
||||||
return ret;
|
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);
|
MCPWM_TIMER_START_NO_STOP);
|
||||||
|
|
||||||
k_sem_give(&data->cmd_sem);
|
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_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;
|
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,
|
mcpwm_ll_capture_set_prescale(data->hal.dev, capture->capture_signal,
|
||||||
cap_conf.cap_prescale);
|
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);
|
mcpwm_ll_intr_clear_capture_status(data->hal.dev, 1 << capture->capture_signal);
|
||||||
|
|
||||||
capture->skip_irq = 0;
|
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 =
|
capture->capture_data[capture->skip_irq].value =
|
||||||
mcpwm_ll_capture_get_value(data->hal.dev, capture->capture_signal);
|
mcpwm_ll_capture_get_value(data->hal.dev, capture->capture_signal);
|
||||||
capture->capture_data[capture->skip_irq].edge =
|
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_NEG_EDGE
|
||||||
: MCPWM_POS_EDGE;
|
: MCPWM_POS_EDGE;
|
||||||
capture->skip_irq++;
|
capture->skip_irq++;
|
||||||
|
@ -550,7 +552,7 @@ static const struct pwm_driver_api mcpwm_esp32_api = {
|
||||||
}, \
|
}, \
|
||||||
.init_config = \
|
.init_config = \
|
||||||
{ \
|
{ \
|
||||||
.host_id = idx, \
|
.group_id = idx, \
|
||||||
}, \
|
}, \
|
||||||
.cmd_sem = Z_SEM_INITIALIZER(mcpwm_esp32_data_##idx.cmd_sem, 1, 1), \
|
.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)}; \
|
CAPTURE_INIT(idx)}; \
|
||||||
\
|
\
|
||||||
DEVICE_DT_INST_DEFINE(idx, &mcpwm_esp32_init, NULL, &mcpwm_esp32_data_##idx, \
|
DEVICE_DT_INST_DEFINE(idx, &mcpwm_esp32_init, NULL, &mcpwm_esp32_data_##idx, \
|
||||||
&mcpwm_esp32_config_##idx, POST_KERNEL, \
|
&mcpwm_esp32_config_##idx, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \
|
||||||
CONFIG_PWM_INIT_PRIORITY, &mcpwm_esp32_api);
|
&mcpwm_esp32_api);
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(ESP32_MCPWM_INIT)
|
DT_INST_FOREACH_STATUS_OKAY(ESP32_MCPWM_INIT)
|
||||||
|
|
|
@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(esp32_temp, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
#if CONFIG_SOC_SERIES_ESP32
|
#if CONFIG_SOC_SERIES_ESP32
|
||||||
#error "Temperature sensor not supported on ESP32"
|
#error "Temperature sensor not supported on ESP32"
|
||||||
#endif /* CONFIG_IDF_TARGET_ESP32 */
|
#endif /* CONFIG_SOC_SERIES_ESP32 */
|
||||||
|
|
||||||
struct esp32_temp_data {
|
struct esp32_temp_data {
|
||||||
struct k_mutex mutex;
|
struct k_mutex mutex;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <hal/uart_ll.h>
|
#include <hal/uart_ll.h>
|
||||||
#include <hal/uart_hal.h>
|
#include <hal/uart_hal.h>
|
||||||
#include <hal/uart_types.h>
|
#include <hal/uart_types.h>
|
||||||
|
#include <esp_clk_tree.h>
|
||||||
#include <zephyr/drivers/pinctrl.h>
|
#include <zephyr/drivers/pinctrl.h>
|
||||||
|
|
||||||
#include <soc/uart_reg.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_stop_bits_t stop_bit;
|
||||||
uart_word_length_t data_bit;
|
uart_word_length_t data_bit;
|
||||||
uart_hw_flowcontrol_t hw_flow;
|
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);
|
uart_hal_get_parity(&data->hal, &parity);
|
||||||
switch (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;
|
const struct uart_esp32_config *config = dev->config;
|
||||||
struct uart_esp32_data *data = dev->data;
|
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);
|
int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -313,7 +321,10 @@ static int uart_esp32_configure(const struct device *dev, const struct uart_conf
|
||||||
return -ENOTSUP;
|
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);
|
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.channel_direction = MEMORY_TO_PERIPHERAL;
|
||||||
dma_cfg.dma_callback = uart_esp32_dma_tx_done;
|
dma_cfg.dma_callback = uart_esp32_dma_tx_done;
|
||||||
dma_cfg.user_data = (void *)dev;
|
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.block_count = 1;
|
||||||
dma_cfg.head_block = &dma_blk;
|
dma_cfg.head_block = &dma_blk;
|
||||||
dma_blk.block_size = len;
|
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.channel_direction = PERIPHERAL_TO_MEMORY;
|
||||||
dma_cfg.dma_callback = uart_esp32_dma_rx_done;
|
dma_cfg.dma_callback = uart_esp32_dma_rx_done;
|
||||||
dma_cfg.user_data = (void *)dev;
|
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.block_count = 1;
|
||||||
dma_cfg.head_block = &dma_blk;
|
dma_cfg.head_block = &dma_blk;
|
||||||
dma_blk.block_size = len;
|
dma_blk.block_size = len;
|
||||||
|
|
|
@ -9,12 +9,13 @@
|
||||||
/* Include esp-idf headers first to avoid redefining BIT() macro */
|
/* Include esp-idf headers first to avoid redefining BIT() macro */
|
||||||
#include <hal/spi_hal.h>
|
#include <hal/spi_hal.h>
|
||||||
#include <esp_attr.h>
|
#include <esp_attr.h>
|
||||||
|
#include <esp_clk_tree.h>
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(esp32_spi, CONFIG_SPI_LOG_LEVEL);
|
LOG_MODULE_REGISTER(esp32_spi, CONFIG_SPI_LOG_LEVEL);
|
||||||
|
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <soc/soc_memory_types.h>
|
#include <esp_memory_utils.h>
|
||||||
#include <zephyr/drivers/spi.h>
|
#include <zephyr/drivers/spi.h>
|
||||||
#ifndef CONFIG_SOC_SERIES_ESP32C3
|
#ifndef CONFIG_SOC_SERIES_ESP32C3
|
||||||
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
#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_enable_clock(data->hal_gdma.dev, true);
|
||||||
gdma_ll_tx_reset_channel(data->hal_gdma.dev, cfg->dma_host);
|
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_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_tx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, GDMA_TRIG_PERIPH_SPI,
|
||||||
gdma_ll_rx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, cfg->dma_host);
|
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;
|
channel_offset = 0;
|
||||||
#else
|
#else
|
||||||
channel_offset = 1;
|
channel_offset = 1;
|
||||||
|
@ -235,6 +238,13 @@ static int spi_esp32_init(const struct device *dev)
|
||||||
return err;
|
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);
|
spi_context_unlock_unconditionally(&data->ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -312,11 +322,11 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
|
||||||
spi_hal_timing_param_t timing_param = {
|
spi_hal_timing_param_t timing_param = {
|
||||||
.half_duplex = hal_dev->half_duplex,
|
.half_duplex = hal_dev->half_duplex,
|
||||||
.no_compensate = hal_dev->no_compensate,
|
.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,
|
.duty_cycle = cfg->duty_cycle == 0 ? 128 : cfg->duty_cycle,
|
||||||
.input_delay_ns = cfg->input_delay_ns,
|
.input_delay_ns = cfg->input_delay_ns,
|
||||||
.use_gpio = !cfg->use_iomux,
|
.use_gpio = !cfg->use_iomux,
|
||||||
|
.clk_src_hz = data->clock_source_hz,
|
||||||
};
|
};
|
||||||
|
|
||||||
spi_hal_cal_clock_conf(&timing_param, &freq, &hal_dev->timing_conf);
|
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_setup = DT_INST_PROP_OR(idx, cs_setup_time, 0), \
|
||||||
.cs_hold = DT_INST_PROP_OR(idx, cs_hold_time, 0), \
|
.cs_hold = DT_INST_PROP_OR(idx, cs_hold_time, 0), \
|
||||||
.line_idle_low = DT_INST_PROP(idx, line_idle_low), \
|
.line_idle_low = DT_INST_PROP(idx, line_idle_low), \
|
||||||
|
.clock_source = SPI_CLK_SRC_DEFAULT, \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
DEVICE_DT_INST_DEFINE(idx, &spi_esp32_init, \
|
DEVICE_DT_INST_DEFINE(idx, &spi_esp32_init, \
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct spi_esp32_config {
|
||||||
int cs_setup;
|
int cs_setup;
|
||||||
int cs_hold;
|
int cs_hold;
|
||||||
bool line_idle_low;
|
bool line_idle_low;
|
||||||
|
spi_clock_source_t clock_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spi_esp32_data {
|
struct spi_esp32_data {
|
||||||
|
@ -55,6 +56,7 @@ struct spi_esp32_data {
|
||||||
int irq_line;
|
int irq_line;
|
||||||
lldesc_t dma_desc_tx;
|
lldesc_t dma_desc_tx;
|
||||||
lldesc_t dma_desc_rx;
|
lldesc_t dma_desc_rx;
|
||||||
|
uint32_t clock_source_hz;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ZEPHYR_DRIVERS_SPI_ESP32_SPIM_H_ */
|
#endif /* ZEPHYR_DRIVERS_SPI_ESP32_SPIM_H_ */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <soc/system_reg.h>
|
#include <soc/system_reg.h>
|
||||||
#include <hal/systimer_hal.h>
|
#include <hal/systimer_hal.h>
|
||||||
#include <hal/systimer_ll.h>
|
#include <hal/systimer_ll.h>
|
||||||
|
#include <esp_private/systimer.h>
|
||||||
#include <rom/ets_sys.h>
|
#include <rom/ets_sys.h>
|
||||||
#include <esp_attr.h>
|
#include <esp_attr.h>
|
||||||
|
|
||||||
|
@ -41,26 +42,26 @@ static systimer_hal_context_t systimer_hal;
|
||||||
static void set_systimer_alarm(uint64_t time)
|
static void set_systimer_alarm(uint64_t time)
|
||||||
{
|
{
|
||||||
systimer_hal_select_alarm_mode(&systimer_hal,
|
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_counter_value_t alarm = {.val = time};
|
||||||
|
|
||||||
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0, false);
|
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0, false);
|
||||||
systimer_ll_set_alarm_target(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0, alarm.val);
|
systimer_ll_set_alarm_target(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0, alarm.val);
|
||||||
systimer_ll_apply_alarm_value(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0);
|
systimer_ll_apply_alarm_value(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0);
|
||||||
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_LL_ALARM_OS_TICK_CORE0, true);
|
systimer_ll_enable_alarm(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0, true);
|
||||||
systimer_ll_enable_alarm_int(systimer_hal.dev, SYSTIMER_LL_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)
|
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)
|
static void sys_timer_isr(const void *arg)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(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);
|
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||||
uint64_t now = get_systimer_alarm();
|
uint64_t now = get_systimer_alarm();
|
||||||
|
@ -146,10 +147,10 @@ static int sys_clock_driver_init(void)
|
||||||
|
|
||||||
systimer_hal_init(&systimer_hal);
|
systimer_hal_init(&systimer_hal);
|
||||||
systimer_hal_connect_alarm_counter(&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_enable_counter(&systimer_hal, SYSTIMER_COUNTER_OS_TICK);
|
||||||
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK, 0, true);
|
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_OS_TICK, 0, true);
|
||||||
last_count = get_systimer_alarm();
|
last_count = get_systimer_alarm();
|
||||||
set_systimer_alarm(last_count + CYC_PER_TICK);
|
set_systimer_alarm(last_count + CYC_PER_TICK);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -15,6 +15,9 @@ menuconfig WIFI_ESP32
|
||||||
select MBEDTLS_ECDH_C
|
select MBEDTLS_ECDH_C
|
||||||
select MBEDTLS_ECDSA_C
|
select MBEDTLS_ECDSA_C
|
||||||
select MBEDTLS_ECP_C
|
select MBEDTLS_ECP_C
|
||||||
|
select THREAD_STACK_INFO
|
||||||
|
select DYNAMIC_THREAD
|
||||||
|
select DYNAMIC_THREAD_ALLOC
|
||||||
help
|
help
|
||||||
Enable ESP32 SoC WiFi support. Only supported in single
|
Enable ESP32 SoC WiFi support. Only supported in single
|
||||||
core mode because the network stack is not aware of SMP
|
core mode because the network stack is not aware of SMP
|
||||||
|
@ -43,28 +46,31 @@ config ESP32_WIFI_STA_RECONNECT
|
||||||
help
|
help
|
||||||
Set auto WiFI reconnection when disconnected.
|
Set auto WiFI reconnection when disconnected.
|
||||||
|
|
||||||
config ESP32_WIFI_EVENT_TASK_STACK_SIZE
|
config ESP32_WIFI_SW_COEXIST_ENABLE
|
||||||
int "Event Task Stack Size"
|
bool
|
||||||
default 4096
|
help
|
||||||
|
Software controls WiFi/Bluetooth coexistence. Not supported yet.
|
||||||
|
|
||||||
config ESP32_WIFI_EVENT_TASK_PRIO
|
config ESP32_WIFI_NET_ALLOC_SPIRAM
|
||||||
int "Event Task Priority"
|
bool "Allocate memory of WiFi and NET in SPIRAM"
|
||||||
default 4
|
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
|
config ESP32_WIFI_STATIC_RX_BUFFER_NUM
|
||||||
int "Max number of WiFi static RX buffers"
|
int "Max number of WiFi static RX buffers"
|
||||||
range 2 25
|
range 2 25
|
||||||
default 10
|
default 10
|
||||||
help
|
help
|
||||||
Set the number of WiFi static RX buffers. Each buffer takes approximately
|
Set the number of WiFi static RX buffers. Each buffer takes approximately 1.6KB of RAM.
|
||||||
1.6KB of RAM. The static rx buffers are allocated when esp_wifi_init is
|
The static rx buffers are allocated when esp_wifi_init is called, they are not freed
|
||||||
called, they are not freed until esp_wifi_deinit is called.
|
until esp_wifi_deinit is called.
|
||||||
|
|
||||||
WiFi hardware use these buffers to receive all 802.11 frames. A higher
|
WiFi hardware use these buffers to receive all 802.11 frames.
|
||||||
number may allow higher throughput but increases memory use.
|
A higher number may allow higher throughput but increases memory use. If ESP32_WIFI_AMPDU_RX_ENABLED
|
||||||
If ESP32_WIFI_AMPDU_RX_ENABLED is enabled, this value is recommended to
|
is enabled, this value is recommended to set equal or bigger than ESP32_WIFI_RX_BA_WIN in order to
|
||||||
set equal or bigger than ESP32_WIFI_RX_BA_WIN in order to achieve better
|
achieve better throughput and compatibility with both stations and APs.
|
||||||
throughput and compatibility with both stations and APs.
|
|
||||||
|
|
||||||
config ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM
|
config ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM
|
||||||
int "Max number of WiFi dynamic RX buffers"
|
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
|
config ESP32_WIFI_CACHE_TX_BUFFER_NUM
|
||||||
int "Max number of WiFi cache TX buffers"
|
int "Max number of WiFi cache TX buffers"
|
||||||
|
depends on ESP_SPIRAM
|
||||||
range 16 128
|
range 16 128
|
||||||
default 32
|
default 32
|
||||||
help
|
help
|
||||||
|
@ -162,6 +169,7 @@ config ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM
|
||||||
|
|
||||||
config ESP32_WIFI_CSI_ENABLED
|
config ESP32_WIFI_CSI_ENABLED
|
||||||
bool "WiFi CSI(Channel State Information)"
|
bool "WiFi CSI(Channel State Information)"
|
||||||
|
default n
|
||||||
help
|
help
|
||||||
Select this option to enable CSI(Channel State Information) feature.
|
Select this option to enable CSI(Channel State Information) feature.
|
||||||
CSI takes about CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM KB of RAM.
|
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
|
should be 16 to achieve better throughput and compatibility with both
|
||||||
stations and APs.
|
stations and APs.
|
||||||
|
|
||||||
choice ESP32_WIFI_TASK_CORE_ID
|
config ESP32_WIFI_AMSDU_TX_ENABLED
|
||||||
prompt "WiFi Task Core ID"
|
bool "WiFi AMSDU TX"
|
||||||
default ESP32_WIFI_TASK_PINNED_TO_CORE_0
|
depends on ESP_SPIRAM
|
||||||
|
default n
|
||||||
help
|
help
|
||||||
Pinned WiFi task to core 0 (core 1 not supported yet)
|
Select this option to enable AMSDU TX feature
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
config ESP32_WIFI_IRAM_OPT
|
config ESP32_WIFI_IRAM_OPT
|
||||||
bool "WiFi IRAM speed optimization"
|
bool "WiFi IRAM speed optimization"
|
||||||
|
default n if (BT && ESP_SPIRAM && SOC_SERIES_ESP32)
|
||||||
|
default y
|
||||||
help
|
help
|
||||||
Select this option to place frequently called Wi-Fi library functions in IRAM.
|
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
|
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
|
config ESP32_WIFI_RX_IRAM_OPT
|
||||||
bool "WiFi RX IRAM speed optimization"
|
bool "WiFi RX IRAM speed optimization"
|
||||||
|
default n if (BT && ESP_SPIRAM && SOC_SERIES_ESP32)
|
||||||
help
|
help
|
||||||
Select this option to place frequently called Wi-Fi library RX functions in IRAM.
|
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
|
When this option is disabled, more than 17Kbytes of IRAM memory will be saved
|
||||||
but Wi-Fi performance will be reduced.
|
but Wi-Fi performance will be reduced.
|
||||||
|
|
||||||
config ESP32_WIFI_NET_ALLOC_SPIRAM
|
config ESP32_WIFI_FTM_ENABLE
|
||||||
bool "Allocate memory of WiFi and NET in SPIRAM"
|
bool "WiFi FTM"
|
||||||
depends on ESP_SPIRAM
|
default n
|
||||||
|
depends on SOC_SERIES_ESP32C3
|
||||||
help
|
help
|
||||||
Allocate memory of WiFi and NET stack in SPIRAM, increasing available RAM memory space
|
Enable feature Fine Timing Measurement for calculating WiFi Round-Trip-Time (RTT).
|
||||||
for application stack.
|
|
||||||
|
|
||||||
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
|
bool
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Hidden option to enable Wi-Fi SoftAP functions in WPA supplicant and RF libraries.
|
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
|
endif # WIFI_ESP32
|
||||||
|
|
|
@ -16,12 +16,13 @@ LOG_MODULE_REGISTER(esp32_wifi, CONFIG_WIFI_LOG_LEVEL);
|
||||||
#include <zephyr/net/conn_mgr/connectivity_wifi_mgmt.h>
|
#include <zephyr/net/conn_mgr/connectivity_wifi_mgmt.h>
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include "esp_networking_priv.h"
|
|
||||||
#include "esp_private/wifi.h"
|
#include "esp_private/wifi.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_wpa.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)
|
#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;
|
struct esp32_wifi_status status;
|
||||||
scan_result_cb_t scan_cb;
|
scan_result_cb_t scan_cb;
|
||||||
uint8_t state;
|
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 struct net_mgmt_event_callback esp32_dhcp_cb;
|
||||||
|
|
||||||
static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
|
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)
|
static int esp32_wifi_send(const struct device *dev, struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
struct esp32_wifi_runtime *data = dev->data;
|
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);
|
strncpy(res.ssid, ap_list_buffer[k].ssid, ssid_len);
|
||||||
res.rssi = ap_list_buffer[k].rssi;
|
res.rssi = ap_list_buffer[k].rssi;
|
||||||
res.channel = ap_list_buffer[k].primary;
|
res.channel = ap_list_buffer[k].primary;
|
||||||
res.security = WIFI_SECURITY_TYPE_NONE;
|
switch (ap_list_buffer[k].authmode) {
|
||||||
if (ap_list_buffer[k].authmode > WIFI_AUTH_OPEN) {
|
case WIFI_AUTH_OPEN:
|
||||||
|
res.security = WIFI_SECURITY_TYPE_NONE;
|
||||||
|
break;
|
||||||
|
case WIFI_AUTH_WPA2_PSK:
|
||||||
res.security = WIFI_SECURITY_TYPE_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) {
|
if (esp32_data.scan_cb) {
|
||||||
|
@ -232,8 +228,9 @@ out:
|
||||||
esp32_data.scan_cb = NULL;
|
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;
|
esp32_data.state = ESP32_STA_CONNECTED;
|
||||||
#if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
|
#if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
|
||||||
net_dhcpv4_start(esp32_wifi_iface);
|
net_dhcpv4_start(esp32_wifi_iface);
|
||||||
|
@ -242,7 +239,7 @@ static void esp_wifi_handle_connect_event(void)
|
||||||
#endif
|
#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;
|
wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
|
||||||
|
|
||||||
|
@ -280,56 +277,66 @@ 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);
|
wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *) event_data;
|
||||||
ARG_UNUSED(p3);
|
|
||||||
|
|
||||||
system_event_t evt;
|
LOG_DBG("Station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid);
|
||||||
uint8_t s_con_cnt = 0;
|
wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
|
||||||
|
|
||||||
while (1) {
|
if (!(esp32_data.ap_connection_cnt++)) {
|
||||||
k_msgq_get(&esp_wifi_msgq, &evt, K_FOREVER);
|
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, eth_esp32_rx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (evt.event_id) {
|
static void esp_wifi_handle_ap_disconnect_event(void *event_data)
|
||||||
case ESP32_WIFI_EVENT_STA_START:
|
{
|
||||||
esp32_data.state = ESP32_STA_STARTED;
|
wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
|
||||||
net_eth_carrier_on(esp32_wifi_iface);
|
|
||||||
break;
|
LOG_DBG("station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid);
|
||||||
case ESP32_WIFI_EVENT_STA_STOP:
|
wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, 0);
|
||||||
esp32_data.state = ESP32_STA_STOPPED;
|
|
||||||
net_eth_carrier_off(esp32_wifi_iface);
|
if (!(--esp32_data.ap_connection_cnt)) {
|
||||||
break;
|
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
|
||||||
case ESP32_WIFI_EVENT_STA_CONNECTED:
|
}
|
||||||
esp_wifi_handle_connect_event();
|
}
|
||||||
break;
|
|
||||||
case ESP32_WIFI_EVENT_STA_DISCONNECTED:
|
void esp_wifi_event_handler(const char *event_base, int32_t event_id, void *event_data,
|
||||||
esp_wifi_handle_disconnect_event(&evt.event_info);
|
size_t event_data_size, uint32_t ticks_to_wait)
|
||||||
break;
|
{
|
||||||
case ESP32_WIFI_EVENT_SCAN_DONE:
|
LOG_DBG("Wi-Fi event: %d", event_id);
|
||||||
scan_done_handler();
|
switch (event_id) {
|
||||||
break;
|
case WIFI_EVENT_STA_START:
|
||||||
case ESP32_WIFI_EVENT_AP_STOP:
|
esp32_data.state = ESP32_STA_STARTED;
|
||||||
esp32_data.state = ESP32_AP_STOPPED;
|
net_eth_carrier_on(esp32_wifi_iface);
|
||||||
net_eth_carrier_off(esp32_wifi_iface);
|
break;
|
||||||
break;
|
case WIFI_EVENT_STA_STOP:
|
||||||
case ESP32_WIFI_EVENT_AP_STACONNECTED:
|
esp32_data.state = ESP32_STA_STOPPED;
|
||||||
esp32_data.state = ESP32_AP_CONNECTED;
|
net_eth_carrier_off(esp32_wifi_iface);
|
||||||
if (!s_con_cnt) {
|
break;
|
||||||
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, eth_esp32_rx);
|
case WIFI_EVENT_STA_CONNECTED:
|
||||||
}
|
esp_wifi_handle_sta_connect_event(event_data);
|
||||||
s_con_cnt++;
|
break;
|
||||||
break;
|
case WIFI_EVENT_STA_DISCONNECTED:
|
||||||
case ESP32_WIFI_EVENT_AP_STADISCONNECTED:
|
esp_wifi_handle_sta_disconnect_event(event_data);
|
||||||
esp32_data.state = ESP32_AP_DISCONNECTED;
|
break;
|
||||||
s_con_cnt--;
|
case WIFI_EVENT_SCAN_DONE:
|
||||||
if (!s_con_cnt) {
|
scan_done_handler();
|
||||||
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
|
break;
|
||||||
}
|
case WIFI_EVENT_AP_STOP:
|
||||||
break;
|
esp32_data.state = ESP32_AP_STOPPED;
|
||||||
default:
|
net_eth_carrier_off(esp32_wifi_iface);
|
||||||
break;
|
break;
|
||||||
}
|
case WIFI_EVENT_AP_STACONNECTED:
|
||||||
|
esp32_data.state = ESP32_AP_CONNECTED;
|
||||||
|
esp_wifi_handle_ap_connect_event(event_data);
|
||||||
|
break;
|
||||||
|
case WIFI_EVENT_AP_STADISCONNECTED:
|
||||||
|
esp32_data.state = ESP32_AP_DISCONNECTED;
|
||||||
|
esp_wifi_handle_ap_disconnect_event(event_data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +357,7 @@ static int esp32_wifi_connect(const struct device *dev,
|
||||||
struct wifi_connect_req_params *params)
|
struct wifi_connect_req_params *params)
|
||||||
{
|
{
|
||||||
struct esp32_wifi_runtime *data = dev->data;
|
struct esp32_wifi_runtime *data = dev->data;
|
||||||
|
wifi_mode_t mode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (data->state == ESP32_STA_CONNECTING || data->state == ESP32_STA_CONNECTED) {
|
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;
|
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) {
|
if (data->state != ESP32_STA_STARTED) {
|
||||||
LOG_ERR("Wi-Fi not in station mode");
|
LOG_ERR("Wi-Fi not in station mode");
|
||||||
wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, -1);
|
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);
|
memcpy(wifi_config.sta.ssid, params->ssid, params->ssid_length);
|
||||||
wifi_config.sta.ssid[params->ssid_length] = '\0';
|
wifi_config.sta.ssid[params->ssid_length] = '\0';
|
||||||
|
switch (params->security) {
|
||||||
if (params->security == WIFI_SECURITY_TYPE_PSK) {
|
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);
|
memcpy(wifi_config.sta.password, params->psk, params->psk_length);
|
||||||
wifi_config.sta.password[params->psk_length] = '\0';
|
wifi_config.sta.password[params->psk_length] = '\0';
|
||||||
wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
|
wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
|
||||||
|
wifi_config.sta.pmf_cfg.required = false;
|
||||||
data->status.security = WIFI_AUTH_WPA2_PSK;
|
data->status.security = WIFI_AUTH_WPA2_PSK;
|
||||||
} else if (params->security == WIFI_SECURITY_TYPE_NONE) {
|
break;
|
||||||
wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
|
case WIFI_SECURITY_TYPE_SAE:
|
||||||
data->status.security = WIFI_AUTH_OPEN;
|
#if defined(CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE)
|
||||||
} else {
|
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");
|
LOG_ERR("Authentication method not supported");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -396,15 +446,15 @@ static int esp32_wifi_connect(const struct device *dev,
|
||||||
data->status.channel = params->channel;
|
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_config(ESP_IF_WIFI_STA, &wifi_config);
|
||||||
ret |= esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
|
if (ret) {
|
||||||
ret |= esp_wifi_connect();
|
LOG_ERR("Failed to set Wi-Fi configuration (%d)", ret);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != ESP_OK) {
|
ret = esp_wifi_connect();
|
||||||
LOG_ERR("Failed to connect to Wi-Fi access point");
|
if (ret) {
|
||||||
|
LOG_ERR("Failed to connect to Wi-Fi access point (%d)", ret);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +497,7 @@ static int esp32_wifi_ap_enable(const struct device *dev,
|
||||||
struct wifi_connect_req_params *params)
|
struct wifi_connect_req_params *params)
|
||||||
{
|
{
|
||||||
struct esp32_wifi_runtime *data = dev->data;
|
struct esp32_wifi_runtime *data = dev->data;
|
||||||
esp_err_t ret = 0;
|
esp_err_t err = 0;
|
||||||
|
|
||||||
/* Build Wi-Fi configuration for AP mode */
|
/* Build Wi-Fi configuration for AP mode */
|
||||||
wifi_config_t wifi_config = {
|
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';
|
data->status.ssid[params->ssid_length] = '\0';
|
||||||
|
|
||||||
strncpy((char *) wifi_config.ap.ssid, params->ssid, params->ssid_length);
|
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));
|
memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password));
|
||||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||||
data->status.security = 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);
|
strncpy((char *) wifi_config.ap.password, params->psk, params->psk_length);
|
||||||
wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
|
wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
|
||||||
data->status.security = 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 */
|
/* Start Wi-Fi in AP mode with configuration built above */
|
||||||
ret = esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
|
err = esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
|
||||||
ret |= esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
|
if (err) {
|
||||||
ret |= esp_wifi_start();
|
LOG_ERR("Failed to set Wi-Fi mode (%d)", err);
|
||||||
if (ret != ESP_OK) {
|
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");
|
LOG_ERR("Failed to enable Wi-Fi AP mode");
|
||||||
return -EAGAIN;
|
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)
|
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();
|
err = esp_wifi_stop();
|
||||||
if (ret != ESP_OK) {
|
if (err) {
|
||||||
LOG_ERR("Failed to disable Wi-Fi AP mode");
|
LOG_ERR("Failed to disable Wi-Fi AP mode: (%d)", err);
|
||||||
return -EAGAIN;
|
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) {
|
if (mode == ESP32_WIFI_MODE_STA) {
|
||||||
esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
|
esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
|
||||||
esp_wifi_sta_get_ap_info(&ap_info);
|
esp_wifi_sta_get_ap_info(&ap_info);
|
||||||
|
|
||||||
status->iface_mode = WIFI_MODE_INFRA;
|
status->iface_mode = WIFI_MODE_INFRA;
|
||||||
status->channel = ap_info.primary;
|
status->channel = ap_info.primary;
|
||||||
status->rssi = ap_info.rssi;
|
status->rssi = ap_info.rssi;
|
||||||
memcpy(status->bssid, ap_info.bssid, WIFI_MAC_ADDR_LEN);
|
memcpy(status->bssid, ap_info.bssid, WIFI_MAC_ADDR_LEN);
|
||||||
|
|
||||||
if (ap_info.phy_11n) {
|
if (ap_info.phy_11b) {
|
||||||
status->link_mode = WIFI_4;
|
|
||||||
} else if (ap_info.phy_11g) {
|
|
||||||
status->link_mode |= WIFI_3;
|
|
||||||
} else if (ap_info.phy_11b) {
|
|
||||||
status->link_mode = WIFI_1;
|
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) {
|
} else if (mode == ESP32_WIFI_MODE_AP) {
|
||||||
esp_wifi_get_config(ESP_IF_WIFI_AP, &conf);
|
esp_wifi_get_config(ESP_IF_WIFI_AP, &conf);
|
||||||
status->iface_mode = WIFI_MODE_AP;
|
status->iface_mode = WIFI_MODE_AP;
|
||||||
status->link_mode = WIFI_LINK_MODE_UNKNOWN;
|
status->link_mode = WIFI_LINK_MODE_UNKNOWN;
|
||||||
status->channel = conf.ap.channel;
|
status->channel = conf.ap.channel;
|
||||||
|
status->beacon_interval = conf.ap.beacon_interval;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
status->iface_mode = WIFI_MODE_UNKNOWN;
|
status->iface_mode = WIFI_MODE_UNKNOWN;
|
||||||
status->link_mode = WIFI_LINK_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:
|
case WIFI_AUTH_WPA2_PSK:
|
||||||
status->security = WIFI_SECURITY_TYPE_PSK;
|
status->security = WIFI_SECURITY_TYPE_PSK;
|
||||||
break;
|
break;
|
||||||
|
case WIFI_AUTH_WPA3_PSK:
|
||||||
|
status->security = WIFI_SECURITY_TYPE_SAE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
status->security = WIFI_SECURITY_TYPE_UNKNOWN;
|
status->security = WIFI_SECURITY_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -596,6 +674,7 @@ static void esp32_wifi_init(struct net_if *iface)
|
||||||
net_if_carrier_off(iface);
|
net_if_carrier_off(iface);
|
||||||
|
|
||||||
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
|
||||||
esp_err_t ret = esp_wifi_init(&config);
|
esp_err_t ret = esp_wifi_init(&config);
|
||||||
|
|
||||||
esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
|
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();
|
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)) {
|
if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
|
||||||
net_mgmt_init_event_callback(&esp32_dhcp_cb, wifi_event_handler, DHCPV4_MASK);
|
net_mgmt_init_event_callback(&esp32_dhcp_cb, wifi_event_handler, DHCPV4_MASK);
|
||||||
net_mgmt_add_event_callback(&esp32_dhcp_cb);
|
net_mgmt_add_event_callback(&esp32_dhcp_cb);
|
||||||
|
|
|
@ -8,20 +8,20 @@
|
||||||
#define ZEPHYR_INCLUDE_DRIVERS_DMA_ESP32_H_
|
#define ZEPHYR_INCLUDE_DRIVERS_DMA_ESP32_H_
|
||||||
|
|
||||||
enum gdma_trigger_peripheral {
|
enum gdma_trigger_peripheral {
|
||||||
GDMA_TRIG_PERIPH_M2M = -1,
|
ESP_GDMA_TRIG_PERIPH_M2M = -1,
|
||||||
GDMA_TRIG_PERIPH_SPI2 = 0,
|
ESP_GDMA_TRIG_PERIPH_SPI2 = 0,
|
||||||
GDMA_TRIG_PERIPH_SPI3 = 1,
|
ESP_GDMA_TRIG_PERIPH_SPI3 = 1,
|
||||||
GDMA_TRIG_PERIPH_UHCI0 = 2,
|
ESP_GDMA_TRIG_PERIPH_UHCI0 = 2,
|
||||||
GDMA_TRIG_PERIPH_I2S0 = 3,
|
ESP_GDMA_TRIG_PERIPH_I2S0 = 3,
|
||||||
GDMA_TRIG_PERIPH_I2S1 = 4,
|
ESP_GDMA_TRIG_PERIPH_I2S1 = 4,
|
||||||
GDMA_TRIG_PERIPH_LCD0 = 5,
|
ESP_GDMA_TRIG_PERIPH_LCD0 = 5,
|
||||||
GDMA_TRIG_PERIPH_CAM0 = 5,
|
ESP_GDMA_TRIG_PERIPH_CAM0 = 5,
|
||||||
GDMA_TRIG_PERIPH_AES = 6,
|
ESP_GDMA_TRIG_PERIPH_AES = 6,
|
||||||
GDMA_TRIG_PERIPH_SHA = 7,
|
ESP_GDMA_TRIG_PERIPH_SHA = 7,
|
||||||
GDMA_TRIG_PERIPH_ADC0 = 8,
|
ESP_GDMA_TRIG_PERIPH_ADC0 = 8,
|
||||||
GDMA_TRIG_PERIPH_DAC0 = 8,
|
ESP_GDMA_TRIG_PERIPH_DAC0 = 8,
|
||||||
GDMA_TRIG_PERIPH_RMT = 9,
|
ESP_GDMA_TRIG_PERIPH_RMT = 9,
|
||||||
GDMA_TRIG_PERIPH_INVALID = 0x3F,
|
ESP_GDMA_TRIG_PERIPH_INVALID = 0x3F,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ESP32_DT_INST_DMA_CTLR(n, name) \
|
#define ESP32_DT_INST_DMA_CTLR(n, name) \
|
||||||
|
|
Loading…
Reference in a new issue