HAL call function used to retrieve the configured baudrate returns the real calculated value, which might not be exactly as the configured. For baudrate of 115200, HAL api returns 115201, which then causes uart_basic_api test to fail. Instead of returning the calculated baudrate value, returns the configured one. Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
591 lines
15 KiB
C
591 lines
15 KiB
C
/*
|
|
* Copyright (c) 2019 Mohamed ElShahawi (extremegtx@hotmail.com)
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#define DT_DRV_COMPAT espressif_esp32_uart
|
|
|
|
/* Include esp-idf headers first to avoid redefining BIT() macro */
|
|
/* TODO: include w/o prefix */
|
|
#ifdef CONFIG_SOC_ESP32
|
|
#include <esp32/rom/ets_sys.h>
|
|
#include <esp32/rom/gpio.h>
|
|
#include <soc/dport_reg.h>
|
|
#elif defined(CONFIG_SOC_ESP32S2)
|
|
#include <esp32s2/rom/ets_sys.h>
|
|
#include <esp32s2/rom/gpio.h>
|
|
#include <soc/dport_reg.h>
|
|
#elif defined(CONFIG_SOC_ESP32C3)
|
|
#include <esp32c3/rom/ets_sys.h>
|
|
#include <esp32c3/rom/gpio.h>
|
|
#endif
|
|
#include <soc/uart_struct.h>
|
|
#include "stubs.h"
|
|
#include <hal/uart_ll.h>
|
|
#include <hal/uart_hal.h>
|
|
#include <hal/uart_types.h>
|
|
|
|
#include <drivers/gpio.h>
|
|
|
|
#include <soc/gpio_sig_map.h>
|
|
#include <soc/uart_reg.h>
|
|
#include <device.h>
|
|
#include <soc.h>
|
|
#include <drivers/uart.h>
|
|
|
|
#ifndef CONFIG_SOC_ESP32C3
|
|
#include <drivers/interrupt_controller/intc_esp32.h>
|
|
#else
|
|
#include <drivers/interrupt_controller/intc_esp32c3.h>
|
|
#endif
|
|
#include <drivers/clock_control.h>
|
|
#include <errno.h>
|
|
#include <sys/util.h>
|
|
#include <esp_attr.h>
|
|
|
|
#ifdef CONFIG_SOC_ESP32C3
|
|
#define ISR_HANDLER isr_handler_t
|
|
#else
|
|
#define ISR_HANDLER intr_handler_t
|
|
#endif
|
|
|
|
struct uart_esp32_pin {
|
|
const char *gpio_name;
|
|
int pin;
|
|
};
|
|
|
|
struct uart_esp32_config {
|
|
const struct device *clock_dev;
|
|
|
|
const struct uart_esp32_pin tx;
|
|
const struct uart_esp32_pin rx;
|
|
const struct uart_esp32_pin rts;
|
|
const struct uart_esp32_pin cts;
|
|
|
|
const clock_control_subsys_t clock_subsys;
|
|
|
|
uint8_t uart_num;
|
|
int irq_source;
|
|
};
|
|
|
|
/* driver data */
|
|
struct uart_esp32_data {
|
|
struct uart_config uart_config;
|
|
uart_hal_context_t hal;
|
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
|
uart_irq_callback_user_data_t irq_cb;
|
|
void *irq_cb_data;
|
|
#endif
|
|
int irq_line;
|
|
};
|
|
|
|
#define UART_FIFO_LIMIT (UART_LL_FIFO_DEF_LEN)
|
|
#define UART_TX_FIFO_THRESH 0x1
|
|
#define UART_RX_FIFO_THRESH 0x16
|
|
|
|
|
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
|
static void uart_esp32_isr(void *arg);
|
|
#endif
|
|
|
|
static int uart_esp32_poll_in(const struct device *dev, unsigned char *p_char)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
int inout_rd_len = 1;
|
|
|
|
if (uart_hal_get_rxfifo_len(&data->hal) == 0) {
|
|
return -1;
|
|
}
|
|
|
|
uart_hal_read_rxfifo(&data->hal, p_char, &inout_rd_len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void uart_esp32_poll_out(const struct device *dev, unsigned char c)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
uint32_t written;
|
|
|
|
/* Wait for space in FIFO */
|
|
while (uart_hal_get_txfifo_len(&data->hal) == 0) {
|
|
; /* Wait */
|
|
}
|
|
|
|
/* Send a character */
|
|
uart_hal_write_txfifo(&data->hal, &c, 1, &written);
|
|
}
|
|
|
|
static int uart_esp32_err_check(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
uint32_t mask = uart_hal_get_intsts_mask(&data->hal);
|
|
uint32_t err = mask & (UART_INTR_PARITY_ERR | UART_INTR_FRAM_ERR);
|
|
|
|
return err;
|
|
}
|
|
|
|
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
|
|
static int uart_esp32_config_get(const struct device *dev,
|
|
struct uart_config *cfg)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
uart_parity_t parity;
|
|
uart_stop_bits_t stop_bit;
|
|
uart_word_length_t data_bit;
|
|
uart_hw_flowcontrol_t hw_flow;
|
|
|
|
cfg->baudrate = data->uart_config.baudrate;
|
|
|
|
uart_hal_get_parity(&data->hal, &parity);
|
|
switch (parity) {
|
|
case UART_PARITY_DISABLE:
|
|
cfg->parity = UART_CFG_PARITY_NONE;
|
|
break;
|
|
case UART_PARITY_EVEN:
|
|
cfg->parity = UART_CFG_PARITY_EVEN;
|
|
break;
|
|
case UART_PARITY_ODD:
|
|
cfg->parity = UART_CFG_PARITY_ODD;
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
uart_hal_get_stop_bits(&data->hal, &stop_bit);
|
|
switch (stop_bit) {
|
|
case UART_STOP_BITS_1:
|
|
cfg->stop_bits = UART_CFG_STOP_BITS_1;
|
|
break;
|
|
case UART_STOP_BITS_1_5:
|
|
cfg->stop_bits = UART_CFG_STOP_BITS_1_5;
|
|
break;
|
|
case UART_STOP_BITS_2:
|
|
cfg->stop_bits = UART_CFG_STOP_BITS_2;
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
uart_hal_get_data_bit_num(&data->hal, &data_bit);
|
|
switch (data_bit) {
|
|
case UART_DATA_5_BITS:
|
|
cfg->data_bits = UART_CFG_DATA_BITS_5;
|
|
break;
|
|
case UART_DATA_6_BITS:
|
|
cfg->data_bits = UART_CFG_DATA_BITS_6;
|
|
break;
|
|
case UART_DATA_7_BITS:
|
|
cfg->data_bits = UART_CFG_DATA_BITS_7;
|
|
break;
|
|
case UART_DATA_8_BITS:
|
|
cfg->data_bits = UART_CFG_DATA_BITS_8;
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
uart_hal_get_hw_flow_ctrl(&data->hal, &hw_flow);
|
|
switch (hw_flow) {
|
|
case UART_HW_FLOWCTRL_DISABLE:
|
|
cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
|
|
break;
|
|
case UART_HW_FLOWCTRL_CTS_RTS:
|
|
cfg->flow_ctrl = UART_CFG_FLOW_CTRL_RTS_CTS;
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
|
|
|
|
static int uart_esp32_configure_pins(const struct device *dev, const struct uart_config *uart)
|
|
{
|
|
const struct uart_esp32_config *const cfg = dev->config;
|
|
|
|
do {
|
|
if (cfg->tx.gpio_name == NULL || cfg->rx.gpio_name == NULL)
|
|
break;
|
|
|
|
/* TX pin config */
|
|
const struct device *tx_dev = device_get_binding(cfg->tx.gpio_name);
|
|
|
|
if (!tx_dev)
|
|
break;
|
|
gpio_pin_set(tx_dev, cfg->tx.pin, 1);
|
|
gpio_pin_configure(tx_dev, cfg->tx.pin, GPIO_OUTPUT);
|
|
esp_rom_gpio_matrix_out(cfg->tx.pin,
|
|
uart_periph_signal[cfg->uart_num].tx_sig, 0, 0);
|
|
|
|
/* RX pin config */
|
|
const struct device *rx_dev = device_get_binding(cfg->rx.gpio_name);
|
|
|
|
if (!rx_dev)
|
|
break;
|
|
gpio_pin_configure(rx_dev, cfg->rx.pin, GPIO_PULL_UP | GPIO_INPUT);
|
|
esp_rom_gpio_matrix_in(cfg->rx.pin, uart_periph_signal[cfg->uart_num].rx_sig, 0);
|
|
|
|
if (uart->flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS) {
|
|
if (cfg->rts.gpio_name == NULL || cfg->cts.gpio_name == NULL)
|
|
break;
|
|
|
|
/* CTS pin config */
|
|
const struct device *cts_dev = device_get_binding(cfg->cts.gpio_name);
|
|
|
|
if (!cts_dev)
|
|
break;
|
|
gpio_pin_configure(cts_dev, cfg->cts.pin, GPIO_PULL_UP | GPIO_INPUT);
|
|
esp_rom_gpio_matrix_in(cfg->cts.pin,
|
|
uart_periph_signal[cfg->uart_num].cts_sig, 0);
|
|
|
|
/* RTS pin config */
|
|
const struct device *rts_dev = device_get_binding(cfg->rts.gpio_name);
|
|
|
|
if (!rts_dev)
|
|
break;
|
|
gpio_pin_configure(rts_dev, cfg->rts.pin, GPIO_OUTPUT);
|
|
esp_rom_gpio_matrix_out(cfg->rts.pin,
|
|
uart_periph_signal[cfg->uart_num].rts_sig, 0, 0);
|
|
}
|
|
return 0;
|
|
|
|
} while (0);
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int uart_esp32_configure(const struct device *dev, const struct uart_config *cfg)
|
|
{
|
|
const struct uart_esp32_config *config = dev->config;
|
|
struct uart_esp32_data *data = dev->data;
|
|
int ret = uart_esp32_configure_pins(dev, cfg);
|
|
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
clock_control_on(config->clock_dev, config->clock_subsys);
|
|
|
|
uart_hal_set_sclk(&data->hal, UART_SCLK_APB);
|
|
uart_hal_set_rxfifo_full_thr(&data->hal, UART_RX_FIFO_THRESH);
|
|
uart_hal_set_txfifo_empty_thr(&data->hal, UART_TX_FIFO_THRESH);
|
|
uart_hal_rxfifo_rst(&data->hal);
|
|
|
|
switch (cfg->parity) {
|
|
case UART_CFG_PARITY_NONE:
|
|
uart_hal_set_parity(&data->hal, UART_PARITY_DISABLE);
|
|
break;
|
|
case UART_CFG_PARITY_EVEN:
|
|
uart_hal_set_parity(&data->hal, UART_PARITY_EVEN);
|
|
break;
|
|
case UART_CFG_PARITY_ODD:
|
|
uart_hal_set_parity(&data->hal, UART_PARITY_ODD);
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
switch (cfg->stop_bits) {
|
|
case UART_CFG_STOP_BITS_1:
|
|
uart_hal_set_stop_bits(&data->hal, UART_STOP_BITS_1);
|
|
break;
|
|
case UART_CFG_STOP_BITS_1_5:
|
|
uart_hal_set_stop_bits(&data->hal, UART_STOP_BITS_1_5);
|
|
break;
|
|
case UART_CFG_STOP_BITS_2:
|
|
uart_hal_set_stop_bits(&data->hal, UART_STOP_BITS_2);
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
switch (cfg->data_bits) {
|
|
case UART_CFG_DATA_BITS_5:
|
|
uart_hal_set_data_bit_num(&data->hal, UART_DATA_5_BITS);
|
|
break;
|
|
case UART_CFG_DATA_BITS_6:
|
|
uart_hal_set_data_bit_num(&data->hal, UART_DATA_6_BITS);
|
|
break;
|
|
case UART_CFG_DATA_BITS_7:
|
|
uart_hal_set_data_bit_num(&data->hal, UART_DATA_7_BITS);
|
|
break;
|
|
case UART_CFG_DATA_BITS_8:
|
|
uart_hal_set_data_bit_num(&data->hal, UART_DATA_8_BITS);
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
switch (cfg->flow_ctrl) {
|
|
case UART_CFG_FLOW_CTRL_NONE:
|
|
uart_hal_set_hw_flow_ctrl(&data->hal, UART_HW_FLOWCTRL_DISABLE, 0);
|
|
break;
|
|
case UART_CFG_FLOW_CTRL_RTS_CTS:
|
|
uart_hal_set_hw_flow_ctrl(&data->hal, UART_HW_FLOWCTRL_CTS_RTS, 10);
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
uart_hal_set_baudrate(&data->hal, cfg->baudrate);
|
|
|
|
uart_hal_set_rx_timeout(&data->hal, 0x16);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int uart_esp32_init(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
int ret = uart_esp32_configure(dev, &data->uart_config);
|
|
|
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
|
const struct uart_esp32_config *config = dev->config;
|
|
|
|
data->irq_line =
|
|
esp_intr_alloc(config->irq_source,
|
|
0,
|
|
(ISR_HANDLER)uart_esp32_isr,
|
|
(void *)dev,
|
|
NULL);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
|
|
|
static int uart_esp32_fifo_fill(const struct device *dev,
|
|
const uint8_t *tx_data, int len)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
uint32_t written = 0;
|
|
|
|
if (len < 0) {
|
|
return 0;
|
|
}
|
|
|
|
uart_hal_write_txfifo(&data->hal, tx_data, len, &written);
|
|
return written;
|
|
}
|
|
|
|
static int uart_esp32_fifo_read(const struct device *dev,
|
|
uint8_t *rx_data, const int len)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
const int num_rx = uart_hal_get_rxfifo_len(&data->hal);
|
|
int read = MIN(len, num_rx);
|
|
|
|
if (!read) {
|
|
return 0;
|
|
}
|
|
|
|
uart_hal_read_rxfifo(&data->hal, rx_data, &read);
|
|
return read;
|
|
}
|
|
|
|
static void uart_esp32_irq_tx_enable(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
uart_hal_clr_intsts_mask(&data->hal, UART_INTR_TXFIFO_EMPTY);
|
|
uart_hal_ena_intr_mask(&data->hal, UART_INTR_TXFIFO_EMPTY);
|
|
}
|
|
|
|
static void uart_esp32_irq_tx_disable(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
uart_hal_disable_intr_mask(&data->hal, UART_INTR_TXFIFO_EMPTY);
|
|
}
|
|
|
|
static int uart_esp32_irq_tx_ready(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
return (uart_hal_get_txfifo_len(&data->hal) > 0 &&
|
|
uart_hal_get_intr_ena_status(&data->hal) & UART_INTR_TXFIFO_EMPTY);
|
|
}
|
|
|
|
static void uart_esp32_irq_rx_enable(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
uart_hal_clr_intsts_mask(&data->hal, UART_INTR_RXFIFO_FULL);
|
|
uart_hal_clr_intsts_mask(&data->hal, UART_INTR_RXFIFO_TOUT);
|
|
uart_hal_ena_intr_mask(&data->hal, UART_INTR_RXFIFO_FULL);
|
|
uart_hal_ena_intr_mask(&data->hal, UART_INTR_RXFIFO_TOUT);
|
|
}
|
|
|
|
static void uart_esp32_irq_rx_disable(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
uart_hal_disable_intr_mask(&data->hal, UART_INTR_RXFIFO_FULL);
|
|
uart_hal_disable_intr_mask(&data->hal, UART_INTR_RXFIFO_TOUT);
|
|
}
|
|
|
|
static int uart_esp32_irq_tx_complete(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
return uart_hal_is_tx_idle(&data->hal);
|
|
}
|
|
|
|
static int uart_esp32_irq_rx_ready(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
return (uart_hal_get_rxfifo_len(&data->hal) > 0);
|
|
}
|
|
|
|
static void uart_esp32_irq_err_enable(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
/* enable framing, parity */
|
|
uart_hal_ena_intr_mask(&data->hal, UART_INTR_FRAM_ERR);
|
|
uart_hal_ena_intr_mask(&data->hal, UART_INTR_PARITY_ERR);
|
|
}
|
|
|
|
static void uart_esp32_irq_err_disable(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
uart_hal_disable_intr_mask(&data->hal, UART_INTR_FRAM_ERR);
|
|
uart_hal_disable_intr_mask(&data->hal, UART_INTR_PARITY_ERR);
|
|
}
|
|
|
|
static int uart_esp32_irq_is_pending(const struct device *dev)
|
|
{
|
|
return uart_esp32_irq_rx_ready(dev) || uart_esp32_irq_tx_ready(dev);
|
|
}
|
|
|
|
static int uart_esp32_irq_update(const struct device *dev)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
uart_hal_clr_intsts_mask(&data->hal, UART_INTR_RXFIFO_FULL);
|
|
uart_hal_clr_intsts_mask(&data->hal, UART_INTR_RXFIFO_TOUT);
|
|
uart_hal_clr_intsts_mask(&data->hal, UART_INTR_TXFIFO_EMPTY);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void uart_esp32_irq_callback_set(const struct device *dev,
|
|
uart_irq_callback_user_data_t cb,
|
|
void *cb_data)
|
|
{
|
|
struct uart_esp32_data *data = dev->data;
|
|
|
|
data->irq_cb = cb;
|
|
data->irq_cb_data = cb_data;
|
|
}
|
|
|
|
static void uart_esp32_isr(void *arg)
|
|
{
|
|
const struct device *dev = (const struct device *)arg;
|
|
struct uart_esp32_data *data = dev->data;
|
|
uint32_t uart_intr_status = uart_hal_get_intsts_mask(&data->hal);
|
|
|
|
if (uart_intr_status == 0) {
|
|
return;
|
|
}
|
|
uart_hal_clr_intsts_mask(&data->hal, uart_intr_status);
|
|
|
|
/* Verify if the callback has been registered */
|
|
if (data->irq_cb) {
|
|
data->irq_cb(dev, data->irq_cb_data);
|
|
}
|
|
}
|
|
|
|
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
|
|
|
|
static const DRAM_ATTR struct uart_driver_api uart_esp32_api = {
|
|
.poll_in = uart_esp32_poll_in,
|
|
.poll_out = uart_esp32_poll_out,
|
|
.err_check = uart_esp32_err_check,
|
|
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
|
|
.configure = uart_esp32_configure,
|
|
.config_get = uart_esp32_config_get,
|
|
#endif
|
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
|
.fifo_fill = uart_esp32_fifo_fill,
|
|
.fifo_read = uart_esp32_fifo_read,
|
|
.irq_tx_enable = uart_esp32_irq_tx_enable,
|
|
.irq_tx_disable = uart_esp32_irq_tx_disable,
|
|
.irq_tx_ready = uart_esp32_irq_tx_ready,
|
|
.irq_rx_enable = uart_esp32_irq_rx_enable,
|
|
.irq_rx_disable = uart_esp32_irq_rx_disable,
|
|
.irq_tx_complete = uart_esp32_irq_tx_complete,
|
|
.irq_rx_ready = uart_esp32_irq_rx_ready,
|
|
.irq_err_enable = uart_esp32_irq_err_enable,
|
|
.irq_err_disable = uart_esp32_irq_err_disable,
|
|
.irq_is_pending = uart_esp32_irq_is_pending,
|
|
.irq_update = uart_esp32_irq_update,
|
|
.irq_callback_set = uart_esp32_irq_callback_set,
|
|
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
|
|
};
|
|
|
|
#define GPIO0_NAME COND_CODE_1(DT_NODE_HAS_STATUS(DT_NODELABEL(gpio0), okay), \
|
|
(DT_LABEL(DT_INST(0, espressif_esp32_gpio))), (NULL))
|
|
#define GPIO1_NAME COND_CODE_1(DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay), \
|
|
(DT_LABEL(DT_INST(1, espressif_esp32_gpio))), (NULL))
|
|
|
|
#define DT_UART_ESP32_GPIO_NAME(idx, pin) ( \
|
|
DT_INST_PROP(idx, pin) < 32 ? GPIO0_NAME : GPIO1_NAME)
|
|
|
|
#define ESP32_UART_INIT(idx) \
|
|
static const DRAM_ATTR struct uart_esp32_config uart_esp32_cfg_port_##idx = { \
|
|
.uart_num = DT_INST_PROP(idx, peripheral), \
|
|
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \
|
|
.tx = { \
|
|
.pin = DT_INST_PROP(idx, tx_pin), \
|
|
.gpio_name = DT_UART_ESP32_GPIO_NAME(idx, tx_pin), \
|
|
}, \
|
|
.rx = { \
|
|
.pin = DT_INST_PROP(idx, rx_pin), \
|
|
.gpio_name = DT_UART_ESP32_GPIO_NAME(idx, rx_pin), \
|
|
}, \
|
|
IF_ENABLED(DT_NODE_HAS_PROP(idx, hw_flow_control), ( \
|
|
.rts = { \
|
|
.pin = DT_INST_PROP(idx, rts_pin), \
|
|
.gpio_name = DT_UART_ESP32_GPIO_NAME(idx, rts_pin), \
|
|
}, \
|
|
.cts = { \
|
|
.pin = DT_INST_PROP(idx, cts_pin), \
|
|
.gpio_name = DT_UART_ESP32_GPIO_NAME(idx, cts_pin), \
|
|
},)) \
|
|
.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(idx, offset), \
|
|
.irq_source = DT_INST_IRQN(idx) \
|
|
}; \
|
|
\
|
|
static struct uart_esp32_data uart_esp32_data_##idx = { \
|
|
.uart_config = { \
|
|
.baudrate = DT_INST_PROP(idx, current_speed),\
|
|
.parity = UART_CFG_PARITY_NONE, \
|
|
.stop_bits = UART_CFG_STOP_BITS_1, \
|
|
.data_bits = UART_CFG_DATA_BITS_8, \
|
|
.flow_ctrl = \
|
|
COND_CODE_1(DT_NODE_HAS_PROP(idx, hw_flow_control), \
|
|
(UART_CFG_FLOW_CTRL_RTS_CTS), (UART_CFG_FLOW_CTRL_NONE)) \
|
|
}, \
|
|
.hal = { \
|
|
.dev = \
|
|
(uart_dev_t *)DT_REG_ADDR(DT_NODELABEL(uart##idx)), \
|
|
}, \
|
|
}; \
|
|
\
|
|
DEVICE_DT_INST_DEFINE(idx, \
|
|
&uart_esp32_init, \
|
|
NULL, \
|
|
&uart_esp32_data_##idx, \
|
|
&uart_esp32_cfg_port_##idx, \
|
|
PRE_KERNEL_1, \
|
|
CONFIG_SERIAL_INIT_PRIORITY, \
|
|
&uart_esp32_api);
|
|
|
|
DT_INST_FOREACH_STATUS_OKAY(ESP32_UART_INIT);
|