1 /*
2  * Copyright (c) 2022 Trackunit Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/types.h>
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/uart.h>
11 #include <zephyr/sys/ring_buffer.h>
12 #include <zephyr/sys/atomic.h>
13 
14 #include <zephyr/modem/pipe.h>
15 #include <zephyr/modem/stats.h>
16 
17 #ifndef ZEPHYR_MODEM_BACKEND_UART_
18 #define ZEPHYR_MODEM_BACKEND_UART_
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 struct modem_backend_uart_isr {
25 	struct ring_buf receive_rdb[2];
26 	struct ring_buf transmit_rb;
27 	atomic_t transmit_buf_len;
28 	atomic_t receive_buf_len;
29 	uint8_t receive_rdb_used;
30 	uint32_t transmit_buf_put_limit;
31 };
32 
33 struct modem_backend_uart_async_common {
34 	uint8_t *transmit_buf;
35 	uint32_t transmit_buf_size;
36 	struct k_work rx_disabled_work;
37 	atomic_t state;
38 };
39 
40 #ifdef CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC
41 
42 struct rx_queue_event {
43 	uint8_t *buf;
44 	size_t len;
45 };
46 
47 struct modem_backend_uart_async {
48 	struct modem_backend_uart_async_common common;
49 	struct k_mem_slab rx_slab;
50 	struct k_msgq rx_queue;
51 	struct rx_queue_event rx_event;
52 	struct rx_queue_event rx_queue_buf[CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC_BUFFER_COUNT];
53 	uint32_t rx_buf_size;
54 	uint8_t rx_buf_count;
55 };
56 
57 #else
58 
59 struct modem_backend_uart_async {
60 	struct modem_backend_uart_async_common common;
61 	uint8_t *receive_bufs[2];
62 	uint32_t receive_buf_size;
63 	struct ring_buf receive_rb;
64 	struct k_spinlock receive_rb_lock;
65 };
66 
67 #endif /* CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC */
68 
69 struct modem_backend_uart {
70 	const struct device *uart;
71 	const struct gpio_dt_spec *dtr_gpio;
72 	struct modem_pipe pipe;
73 	struct k_work_delayable receive_ready_work;
74 	struct k_work transmit_idle_work;
75 
76 #if CONFIG_MODEM_STATS
77 	struct modem_stats_buffer receive_buf_stats;
78 	struct modem_stats_buffer transmit_buf_stats;
79 #endif
80 
81 	union {
82 		struct modem_backend_uart_isr isr;
83 		struct modem_backend_uart_async async;
84 	};
85 };
86 
87 struct modem_backend_uart_config {
88 	const struct device *uart;
89 	const struct gpio_dt_spec *dtr_gpio;
90 	/* Address must be word-aligned when CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC is enabled. */
91 	uint8_t *receive_buf;
92 	uint32_t receive_buf_size;
93 	uint8_t *transmit_buf;
94 	uint32_t transmit_buf_size;
95 };
96 
97 struct modem_pipe *modem_backend_uart_init(struct modem_backend_uart *backend,
98 					   const struct modem_backend_uart_config *config);
99 
100 #ifdef __cplusplus
101 }
102 #endif
103 
104 #endif /* ZEPHYR_MODEM_BACKEND_UART_ */
105