Skip to content

Commit 994aa6c

Browse files
committed
modem: backend: uart: Add hw-flow-control for UART
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 <[email protected]>
1 parent 6e3095f commit 994aa6c

File tree

9 files changed

+503
-15
lines changed

9 files changed

+503
-15
lines changed

include/zephyr/modem/backend/uart.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,25 @@ struct modem_backend_uart_isr {
3030
uint32_t transmit_buf_put_limit;
3131
};
3232

33+
#if CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC_ENABLED
34+
struct rx_queue_event_t {
35+
uint8_t *buf;
36+
size_t len;
37+
};
38+
39+
struct modem_backend_uart_async {
40+
struct k_mem_slab rx_slab;
41+
struct k_msgq rx_queue;
42+
struct rx_queue_event_t rx_event;
43+
struct rx_queue_event_t rx_queue_buf[CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC_BUFFER_COUNT];
44+
uint32_t rx_buf_size;
45+
uint8_t rx_buf_count;
46+
uint8_t *transmit_buf;
47+
uint32_t transmit_buf_size;
48+
struct k_work rx_disabled_work;
49+
atomic_t state;
50+
};
51+
#else
3352
struct modem_backend_uart_async {
3453
uint8_t *receive_bufs[2];
3554
uint32_t receive_buf_size;
@@ -40,7 +59,7 @@ struct modem_backend_uart_async {
4059
struct k_work rx_disabled_work;
4160
atomic_t state;
4261
};
43-
62+
#endif /* CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC_ENABLED */
4463
struct modem_backend_uart {
4564
const struct device *uart;
4665
struct modem_pipe pipe;
@@ -60,7 +79,7 @@ struct modem_backend_uart {
6079

6180
struct modem_backend_uart_config {
6281
const struct device *uart;
63-
uint8_t *receive_buf;
82+
uint8_t *receive_buf __aligned(sizeof(uint32_t));
6483
uint32_t receive_buf_size;
6584
uint8_t *transmit_buf;
6685
uint32_t transmit_buf_size;

subsys/modem/backends/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ zephyr_library()
66
zephyr_library_sources_ifdef(CONFIG_MODEM_BACKEND_TTY modem_backend_tty.c)
77
zephyr_library_sources_ifdef(CONFIG_MODEM_BACKEND_UART modem_backend_uart.c)
88
zephyr_library_sources_ifdef(CONFIG_MODEM_BACKEND_UART_ISR modem_backend_uart_isr.c)
9-
zephyr_library_sources_ifdef(CONFIG_MODEM_BACKEND_UART_ASYNC modem_backend_uart_async.c)
9+
zephyr_library_sources_ifdef(CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC_DISABLED modem_backend_uart_async.c)
10+
zephyr_library_sources_ifdef(CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC_ENABLED modem_backend_uart_async_hwfc.c)

subsys/modem/backends/Kconfig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,29 @@ config MODEM_BACKEND_UART_ASYNC_RECEIVE_IDLE_TIMEOUT_MS
4848
int "Modem async UART receive idle timeout in milliseconds"
4949
default 30
5050

51+
choice MODEM_BACKEND_UART_ASYNC_HWFC_CHOICE
52+
prompt "Modem async UART hardware flow control"
53+
default MODEM_BACKEND_UART_ASYNC_HWFC_DISABLED
54+
help
55+
Select whether to enable or disable hardware flow control (HWFC)
56+
for the modem async UART backend.
57+
58+
config MODEM_BACKEND_UART_ASYNC_HWFC_DISABLED
59+
bool "Hardware flow control is disabled"
60+
61+
config MODEM_BACKEND_UART_ASYNC_HWFC_ENABLED
62+
bool "Hardware flow control is enabled"
63+
select EXPERIMENTAL
64+
endchoice
65+
66+
if MODEM_BACKEND_UART_ASYNC_HWFC_ENABLED
67+
68+
config MODEM_BACKEND_UART_ASYNC_HWFC_BUFFER_COUNT
69+
int "Modem async UART buffer count"
70+
range 2 4
71+
default 3
5172
endif
5273

74+
endif # MODEM_BACKEND_UART_ASYNC
75+
5376
endif # MODEM_BACKEND_UART

subsys/modem/backends/modem_backend_uart.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ struct modem_pipe *modem_backend_uart_init(struct modem_backend_uart *backend,
4545

4646
#ifdef CONFIG_MODEM_BACKEND_UART_ASYNC
4747
if (modem_backend_uart_async_is_supported(backend)) {
48-
modem_backend_uart_async_init(backend, config);
48+
if (modem_backend_uart_async_init(backend, config)) {
49+
return NULL;
50+
}
4951
return &backend->pipe;
5052
}
5153
#endif /* CONFIG_MODEM_BACKEND_UART_ASYNC */

subsys/modem/backends/modem_backend_uart_async.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ static void init_stats(struct modem_backend_uart *backend)
310310
}
311311
#endif
312312

313-
void modem_backend_uart_async_init(struct modem_backend_uart *backend,
314-
const struct modem_backend_uart_config *config)
313+
int modem_backend_uart_async_init(struct modem_backend_uart *backend,
314+
const struct modem_backend_uart_config *config)
315315
{
316316
uint32_t receive_buf_size_quarter = config->receive_buf_size / 4;
317317

@@ -332,4 +332,6 @@ void modem_backend_uart_async_init(struct modem_backend_uart *backend,
332332
#if CONFIG_MODEM_STATS
333333
init_stats(backend);
334334
#endif
335+
336+
return 0;
335337
}

subsys/modem/backends/modem_backend_uart_async.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ extern "C" {
1515

1616
bool modem_backend_uart_async_is_supported(struct modem_backend_uart *backend);
1717

18-
void modem_backend_uart_async_init(struct modem_backend_uart *backend,
19-
const struct modem_backend_uart_config *config);
18+
int modem_backend_uart_async_init(struct modem_backend_uart *backend,
19+
const struct modem_backend_uart_config *config);
2020

2121
#ifdef __cplusplus
2222
}

0 commit comments

Comments
 (0)