Add Asynchronous UART implementation, which does not drop data when automatic hardware-flow-control is set in the device tree. With automatic hardware flow control, the CTS pin will be automatically deactivated when there are no more asynchronous UART RX buffers available. After buffer space becomes available, and UART RX is restarted, the CTS pin will be activated. Signed-off-by: Markus Lassila <markus.lassila@nordicsemi.no>
65 lines
1.8 KiB
C
65 lines
1.8 KiB
C
/*
|
|
* Copyright (c) 2023 Trackunit Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include "modem_backend_uart_isr.h"
|
|
#include "modem_backend_uart_async.h"
|
|
|
|
#include <zephyr/modem/backend/uart.h>
|
|
|
|
#include <string.h>
|
|
|
|
static void modem_backend_uart_receive_ready_handler(struct k_work *item)
|
|
{
|
|
struct modem_backend_uart *backend = CONTAINER_OF(
|
|
k_work_delayable_from_work(item), struct modem_backend_uart, receive_ready_work);
|
|
|
|
modem_pipe_notify_receive_ready(&backend->pipe);
|
|
}
|
|
|
|
static void modem_backend_uart_transmit_idle_handler(struct k_work *item)
|
|
{
|
|
struct modem_backend_uart *backend =
|
|
CONTAINER_OF(item, struct modem_backend_uart, transmit_idle_work);
|
|
|
|
modem_pipe_notify_transmit_idle(&backend->pipe);
|
|
}
|
|
|
|
struct modem_pipe *modem_backend_uart_init(struct modem_backend_uart *backend,
|
|
const struct modem_backend_uart_config *config)
|
|
{
|
|
__ASSERT_NO_MSG(config->uart != NULL);
|
|
__ASSERT_NO_MSG(config->receive_buf != NULL);
|
|
__ASSERT_NO_MSG(config->receive_buf_size > 1);
|
|
__ASSERT_NO_MSG((config->receive_buf_size % 2) == 0);
|
|
__ASSERT_NO_MSG(config->transmit_buf != NULL);
|
|
__ASSERT_NO_MSG(config->transmit_buf_size > 0);
|
|
|
|
memset(backend, 0x00, sizeof(*backend));
|
|
backend->uart = config->uart;
|
|
k_work_init_delayable(&backend->receive_ready_work,
|
|
modem_backend_uart_receive_ready_handler);
|
|
k_work_init(&backend->transmit_idle_work, modem_backend_uart_transmit_idle_handler);
|
|
|
|
#ifdef CONFIG_MODEM_BACKEND_UART_ASYNC
|
|
if (modem_backend_uart_async_is_supported(backend)) {
|
|
if (modem_backend_uart_async_init(backend, config)) {
|
|
return NULL;
|
|
}
|
|
return &backend->pipe;
|
|
}
|
|
#endif /* CONFIG_MODEM_BACKEND_UART_ASYNC */
|
|
|
|
#ifdef CONFIG_MODEM_BACKEND_UART_ISR
|
|
modem_backend_uart_isr_init(backend, config);
|
|
|
|
return &backend->pipe;
|
|
#endif /* CONFIG_MODEM_BACKEND_UART_ISR */
|
|
|
|
__ASSERT(0, "No supported UART API");
|
|
|
|
return NULL;
|
|
}
|