Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: serial: nrf: Use flow control from device tree #25999

Merged
Merged
Changes from all commits
Commits
File filter
Filter file types
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.

Always

Just for now

@@ -12,7 +12,6 @@ CONFIG_GPIO=y

# enable uart driver
CONFIG_SERIAL=y
CONFIG_UART_0_NRF_FLOW_CONTROL=n

# enable console
CONFIG_CONSOLE=y
@@ -27,9 +27,6 @@ config BT_CTLR

if MODEM

config UART_1_NRF_FLOW_CONTROL
default y

config MODEM_UBLOX_SARA
default y

@@ -40,6 +40,7 @@
rx-pin = <36>;
rts-pin = <39>;
cts-pin = <38>;
hw-flow-control;

sara_r4 {
compatible = "ublox,sara-r4";
@@ -6,7 +6,4 @@ if BOARD_NRF52840DK_NRF52840
config GPIO_NRF_P1
default y

config UART_1_NRF_FLOW_CONTROL
default y

endif # BOARD_NRF52840DK_NRF52840
@@ -55,12 +55,6 @@ config UART_0_NRF_PARITY_BIT
help
Enable parity bit.

config UART_0_NRF_FLOW_CONTROL
bool "Enable flow control"
help
Enable flow control. If selected, additionally two pins, RTS and CTS
have to be configured.

config UART_0_NRF_TX_BUFFER_SIZE
int "Size of RAM buffer"
depends on UART_0_NRF_UARTE
@@ -124,12 +118,6 @@ config UART_1_NRF_PARITY_BIT
help
Enable parity bit.

config UART_1_NRF_FLOW_CONTROL
bool "Enable flow control"
help
Enable flow control. If selected, additionally two pins, RTS and CTS
have to be configured.

config UART_1_NRF_TX_BUFFER_SIZE
int "Size of RAM buffer"
depends on UART_INTERRUPT_DRIVEN
@@ -192,12 +180,6 @@ config UART_2_NRF_PARITY_BIT
help
Enable parity bit.

config UART_2_NRF_FLOW_CONTROL
bool "Enable flow control"
help
Enable flow control. If selected, additionally two pins, RTS and CTS
have to be configured.

config UART_2_NRF_TX_BUFFER_SIZE
int "Size of RAM buffer"
range 1 65535
@@ -259,12 +241,6 @@ config UART_3_NRF_PARITY_BIT
help
Enable parity bit.

config UART_3_NRF_FLOW_CONTROL
bool "Enable flow control"
help
Enable flow control. If selected, additionally two pins, RTS and CTS
have to be configured.

config UART_3_NRF_TX_BUFFER_SIZE
int "Size of RAM buffer"
range 1 65535
@@ -33,11 +33,19 @@
#define RX_PIN NRF_UART_PSEL_DISCONNECTED
#endif

#define HW_FLOW_CONTROL (HAS_PROP(rts_pin) && HAS_PROP(cts_pin))
#if HW_FLOW_CONTROL
#define RTS_PIN PROP(rts_pin)
#define CTS_PIN PROP(cts_pin)
#endif
#define HW_FLOW_CONTROL_AVAILABLE (HAS_PROP(rts_pin) || HAS_PROP(cts_pin))

/* Protect against enabling flow control without pins set. */
BUILD_ASSERT((PROP(hw_flow_control) && HW_FLOW_CONTROL_AVAILABLE) ||
!PROP(hw_flow_control));

#define RTS_PIN \
COND_CODE_1(HAS_PROP(rts_pin), \
(PROP(rts_pin)), (NRF_UART_PSEL_DISCONNECTED))

#define CTS_PIN \
COND_CODE_1(HAS_PROP(cts_pin), \
(PROP(cts_pin)), (NRF_UART_PSEL_DISCONNECTED))

#define IRQN DT_INST_IRQN(0)
#define IRQ_PRIO DT_INST_IRQ(0, priority)
@@ -49,23 +57,11 @@ struct uart_nrfx_data {
struct uart_config uart_config;
};

/**
* @brief Structure for UART configuration.
*/
struct uart_nrfx_config {
bool rts_cts_pins_set;
};

static inline struct uart_nrfx_data *get_dev_data(struct device *dev)
{
return dev->driver_data;
}

static inline const struct uart_nrfx_config *get_dev_config(struct device *dev)
{
return dev->config_info;
}

#ifdef CONFIG_UART_0_ASYNC
static struct {
uart_callback_t callback;
@@ -85,8 +81,8 @@ static struct {
const uint8_t *volatile tx_buffer;
size_t tx_buffer_length;
volatile size_t tx_counter;
#if HW_FLOW_CONTROL
int32_t tx_timeout;
#if HW_FLOW_CONTROL_AVAILABLE
s32_t tx_timeout;
struct k_delayed_work tx_timeout_work;
#endif
} uart0_cb;
@@ -347,7 +343,7 @@ static int uart_nrfx_configure(struct device *dev,
uart_cfg.hwfc = NRF_UART_HWFC_DISABLED;
break;
case UART_CFG_FLOW_CTRL_RTS_CTS:
if (get_dev_config(dev)->rts_cts_pins_set) {
if (HW_FLOW_CONTROL_AVAILABLE) {
uart_cfg.hwfc = NRF_UART_HWFC_ENABLED;
} else {
return -ENOTSUP;
@@ -423,7 +419,7 @@ static int uart_nrfx_tx(struct device *dev, const uint8_t *buf, size_t len,
}

uart0_cb.tx_buffer = buf;
#if HW_FLOW_CONTROL
#if HW_FLOW_CONTROL_AVAILABLE
uart0_cb.tx_timeout = timeout;
#endif
nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_TXDRDY);
@@ -442,7 +438,7 @@ static int uart_nrfx_tx_abort(struct device *dev)
if (uart0_cb.tx_buffer_length == 0) {
return -EINVAL;
}
#if HW_FLOW_CONTROL
#if HW_FLOW_CONTROL_AVAILABLE
if (uart0_cb.tx_timeout != SYS_FOREVER_MS) {
k_delayed_work_cancel(&uart0_cb.tx_timeout_work);
}
@@ -621,7 +617,7 @@ static void tx_isr(void)
uart0_cb.tx_counter++;
if (uart0_cb.tx_counter < uart0_cb.tx_buffer_length &&
!uart0_cb.tx_abort) {
#if HW_FLOW_CONTROL
#if HW_FLOW_CONTROL_AVAILABLE
if (uart0_cb.tx_timeout != SYS_FOREVER_MS) {
k_delayed_work_submit(&uart0_cb.tx_timeout_work,
K_MSEC(uart0_cb.tx_timeout));
@@ -633,7 +629,7 @@ static void tx_isr(void)

nrf_uart_txd_set(uart0_addr, txd);
} else {
#if HW_FLOW_CONTROL
#if HW_FLOW_CONTROL_AVAILABLE

if (uart0_cb.tx_timeout != SYS_FOREVER_MS) {
k_delayed_work_cancel(&uart0_cb.tx_timeout_work);
@@ -736,7 +732,7 @@ static void rx_timeout(struct k_work *work)
rx_rdy_evt();
}

#if HW_FLOW_CONTROL
#if HW_FLOW_CONTROL_AVAILABLE
static void tx_timeout(struct k_work *work)
{
struct uart_event evt;
@@ -958,17 +954,20 @@ static int uart_nrfx_init(struct device *dev)
}

nrf_uart_txrx_pins_set(uart0_addr, TX_PIN, RX_PIN);
#if HW_FLOW_CONTROL
/* Setting default height state of the RTS PIN to avoid glitches
* on the line during peripheral activation/deactivation.
*/
nrf_gpio_pin_write(RTS_PIN, 1);
nrf_gpio_cfg_output(RTS_PIN);

nrf_gpio_cfg_input(CTS_PIN, NRF_GPIO_PIN_NOPULL);
if (HAS_PROP(rts_pin)) {
/* Setting default height state of the RTS PIN to avoid glitches
* on the line during peripheral activation/deactivation.
*/
nrf_gpio_pin_write(RTS_PIN, 1);
nrf_gpio_cfg_output(RTS_PIN);
}

if (HAS_PROP(cts_pin)) {
nrf_gpio_cfg_input(CTS_PIN, NRF_GPIO_PIN_NOPULL);
}

nrf_uart_hwfc_pins_set(uart0_addr, RTS_PIN, CTS_PIN);
#endif

/* Set initial configuration */
err = uart_nrfx_configure(dev, &get_dev_data(dev)->uart_config);
@@ -1007,7 +1006,7 @@ static int uart_nrfx_init(struct device *dev)

#ifdef CONFIG_UART_0_ASYNC
k_delayed_work_init(&uart0_cb.rx_timeout_work, rx_timeout);
#if HW_FLOW_CONTROL
#if HW_FLOW_CONTROL_AVAILABLE
k_delayed_work_init(&uart0_cb.tx_timeout_work, tx_timeout);
#endif
#endif
@@ -1069,9 +1068,11 @@ static void uart_nrfx_pins_enable(struct device *dev, bool enable)
nrf_gpio_cfg_input(rx_pin, NRF_GPIO_PIN_NOPULL);
}

if (get_dev_config(dev)->rts_cts_pins_set) {
if (HAS_PROP(rts_pin)) {
nrf_gpio_pin_write(rts_pin, 1);
nrf_gpio_cfg_output(rts_pin);
}
if (HAS_PROP(cts_pin)) {
nrf_gpio_cfg_input(cts_pin,
NRF_GPIO_PIN_NOPULL);
}
@@ -1080,10 +1081,14 @@ static void uart_nrfx_pins_enable(struct device *dev, bool enable)
if (RX_PIN_USED) {
nrf_gpio_cfg_default(rx_pin);
}
if (get_dev_config(dev)->rts_cts_pins_set) {
nrf_gpio_cfg_default(cts_pin);

if (HAS_PROP(rts_pin)) {
nrf_gpio_cfg_default(rts_pin);
}

if (HAS_PROP(cts_pin)) {
nrf_gpio_cfg_default(cts_pin);
}
}
}

@@ -1140,24 +1145,17 @@ static struct uart_nrfx_data uart_nrfx_uart0_data = {
#else
.parity = UART_CFG_PARITY_NONE,
#endif /* CONFIG_UART_0_NRF_PARITY_BIT */
#ifdef CONFIG_UART_0_NRF_FLOW_CONTROL
.flow_ctrl = UART_CFG_FLOW_CTRL_RTS_CTS,
#else
.flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
#endif /* CONFIG_UART_0_NRF_FLOW_CONTROL */
.flow_ctrl = PROP(hw_flow_control) ?
UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE,
}
};

static const struct uart_nrfx_config uart_nrfx_uart0_config = {
.rts_cts_pins_set = HW_FLOW_CONTROL,
};

DEVICE_DEFINE(uart_nrfx_uart0,
DT_INST_LABEL(0),
uart_nrfx_init,
uart_nrfx_pm_control,
&uart_nrfx_uart0_data,
&uart_nrfx_uart0_config,
NULL,
/* Initialize UART device before UART console. */
PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE,