drivers: serial: nrfx_uarte2: Fix re-enabling the receiver
Move providing of the first buffer in uart_rx_enable from that function to the callback which is called from nrfx_uarte_rx_enable context. By doing this nrfx_uarte_rx_buffer_set is called when RX configuration flags are already known to the driver. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
490fb20148
commit
7bededbc29
1 changed files with 33 additions and 9 deletions
|
@ -115,6 +115,9 @@ struct uarte_async_data {
|
|||
uart_callback_t user_callback;
|
||||
void *user_data;
|
||||
|
||||
uint8_t *en_rx_buf;
|
||||
size_t en_rx_len;
|
||||
|
||||
struct k_timer tx_timer;
|
||||
struct k_timer rx_timer;
|
||||
|
||||
|
@ -288,6 +291,22 @@ static void on_rx_buf_req(const struct device *dev)
|
|||
struct uarte_async_data *adata = data->async;
|
||||
const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev);
|
||||
|
||||
/* If buffer is not null it indicates that event comes from RX enabling
|
||||
* function context. We need to pass provided buffer to the driver.
|
||||
*/
|
||||
if (adata->en_rx_buf) {
|
||||
uint8_t *buf = adata->en_rx_buf;
|
||||
size_t len = adata->en_rx_len;
|
||||
nrfx_err_t err;
|
||||
|
||||
adata->en_rx_buf = NULL;
|
||||
adata->en_rx_len = 0;
|
||||
|
||||
err = nrfx_uarte_rx_buffer_set(nrfx_dev, buf, len);
|
||||
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
struct uart_event evt = {
|
||||
.type = UART_RX_BUF_REQUEST
|
||||
};
|
||||
|
@ -296,8 +315,6 @@ static void on_rx_buf_req(const struct device *dev)
|
|||
* reception of one buffer was terminated to restart another transfer.
|
||||
*/
|
||||
if (!K_TIMEOUT_EQ(adata->rx_timeout, K_NO_WAIT)) {
|
||||
/* Read and clear any pending new data information. */
|
||||
nrfx_uarte_rx_new_data_check(nrfx_dev);
|
||||
nrfx_uarte_rxdrdy_enable(nrfx_dev);
|
||||
}
|
||||
data->async->user_callback(dev, &evt, data->async->user_data);
|
||||
|
@ -469,22 +486,28 @@ static int api_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int
|
|||
if (timeout != SYS_FOREVER_US) {
|
||||
adata->idle_cnt = RX_TIMEOUT_DIV + 1;
|
||||
adata->rx_timeout = K_USEC(timeout / RX_TIMEOUT_DIV);
|
||||
nrfx_uarte_rxdrdy_enable(nrfx_dev);
|
||||
} else {
|
||||
adata->rx_timeout = K_NO_WAIT;
|
||||
}
|
||||
|
||||
err = nrfx_uarte_rx_buffer_set(nrfx_dev, buf, len);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
return -EIO;
|
||||
}
|
||||
/* Store the buffer. It will be passed to the driver in the event handler.
|
||||
* We do that instead of calling nrfx_uarte_rx_buffer_set here to ensure
|
||||
* that nrfx_uarte_rx_buffer_set is called when RX enable configuration
|
||||
* flags are already known to the driver (e.g. if flushed data shall be
|
||||
* kept or not).
|
||||
*/
|
||||
adata->en_rx_buf = buf;
|
||||
adata->en_rx_len = len;
|
||||
|
||||
atomic_or(&data->flags, UARTE_DATA_FLAG_RX_ENABLED);
|
||||
|
||||
err = nrfx_uarte_rx_enable(nrfx_dev, flags);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
atomic_and(&data->flags, ~UARTE_DATA_FLAG_RX_ENABLED);
|
||||
return (err == NRFX_ERROR_BUSY) ? -EBUSY : -EIO;
|
||||
}
|
||||
|
||||
atomic_or(&data->flags, UARTE_DATA_FLAG_RX_ENABLED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -932,7 +955,8 @@ static int uarte_nrfx_pm_action(const struct device *dev,
|
|||
UARTE_MEMORY_SECTION(idx) __aligned(4); \
|
||||
static nrfx_uarte_rx_cache_t uarte##idx##_rx_cache_scratch; \
|
||||
IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \
|
||||
(static uint8_t a2i_rx_buf##idx[CONFIG_UART_##idx##_A2I_RX_SIZE];)) \
|
||||
(static uint8_t a2i_rx_buf##idx[CONFIG_UART_##idx##_A2I_RX_SIZE] \
|
||||
UARTE_MEMORY_SECTION(idx) __aligned(4);)) \
|
||||
PINCTRL_DT_DEFINE(UARTE(idx)); \
|
||||
static const struct uart_async_to_irq_config uarte_a2i_config_##idx = \
|
||||
UART_ASYNC_TO_IRQ_API_CONFIG_INITIALIZER(&a2i_api, \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue