1 /*
2  * Copyright (c) 2006-2024 RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2012-05-15     lgnq         first version.
9  * 2012-05-28     bernard      change interfaces
10  * 2013-02-20     bernard      use RT_SERIAL_RB_BUFSZ to define
11  *                             the size of ring buffer.
12  */
13 
14 #ifndef __DEV_SERIAL_H__
15 #define __DEV_SERIAL_H__
16 
17 #include <rtthread.h>
18 /**
19  * @defgroup    group_drivers_serial Serial
20  * @brief       Serial driver api
21  * @ingroup     group_device_driver
22  *
23  * <b>Example</b>
24  * @code {.c}
25  *
26  * #include <rtthread.h>
27  *
28  * #define SAMPLE_UART_NAME       "uart2"
29  * static struct rt_semaphore rx_sem;
30  * static rt_device_t serial;
31  *
32  * static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
33  * {
34  *
35  *     rt_sem_release(&rx_sem);
36  *
37  *     return RT_EOK;
38  * }
39  *
40  * static void serial_thread_entry(void *parameter)
41  * {
42  *     char ch;
43  *
44  *     while (1)
45  *     {
46  *
47  *         while (rt_device_read(serial, -1, &ch, 1) != 1)
48  *         {
49  *
50  *             rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
51  *         }
52  *
53  *         ch = ch + 1;
54  *         rt_device_write(serial, 0, &ch, 1);
55  *     }
56  * }
57  *
58  * static int uart_sample(int argc, char *argv[])
59  * {
60  *     rt_err_t ret = RT_EOK;
61  *     char uart_name[RT_NAME_MAX];
62  *     char str[] = "hello RT-Thread!\r\n";
63  *
64  *     if (argc == 2)
65  *     {
66  *         rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
67  *     }
68  *     else
69  *     {
70  *         rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
71  *     }
72  *
73  *
74  *     serial = rt_device_find(uart_name);
75  *     if (!serial)
76  *     {
77  *         rt_kprintf("find %s failed!\n", uart_name);
78  *         return -RT_ERROR;
79  *     }
80  *
81  *
82  *     rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
83  *
84  *     rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
85  *
86  *     rt_device_set_rx_indicate(serial, uart_input);
87  *
88  *     rt_device_write(serial, 0, str, (sizeof(str) - 1));
89  *
90  *
91  *     rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
92  *
93  *     if (thread != RT_NULL)
94  *     {
95  *         rt_thread_startup(thread);
96  *     }
97  *     else
98  *     {
99  *         ret = -RT_ERROR;
100  *     }
101  *
102  *     return ret;
103  * }
104  *
105  * MSH_CMD_EXPORT(uart_sample, uart device sample);
106  * @endcode
107  */
108 
109 
110 /*!
111  * @addtogroup group_drivers_serial
112  * @{
113  */
114 #define BAUD_RATE_2400                  2400
115 #define BAUD_RATE_4800                  4800
116 #define BAUD_RATE_9600                  9600
117 #define BAUD_RATE_19200                 19200
118 #define BAUD_RATE_38400                 38400
119 #define BAUD_RATE_57600                 57600
120 #define BAUD_RATE_115200                115200
121 #define BAUD_RATE_230400                230400
122 #define BAUD_RATE_460800                460800
123 #define BAUD_RATE_500000                500000
124 #define BAUD_RATE_576000                576000
125 #define BAUD_RATE_921600                921600
126 #define BAUD_RATE_1000000               1000000
127 #define BAUD_RATE_1152000               1152000
128 #define BAUD_RATE_1500000               1500000
129 #define BAUD_RATE_2000000               2000000
130 #define BAUD_RATE_2500000               2500000
131 #define BAUD_RATE_3000000               3000000
132 #define BAUD_RATE_3500000               3500000
133 #define BAUD_RATE_4000000               4000000
134 
135 #define DATA_BITS_5                     5
136 #define DATA_BITS_6                     6
137 #define DATA_BITS_7                     7
138 #define DATA_BITS_8                     8
139 #define DATA_BITS_9                     9
140 
141 #define STOP_BITS_1                     0
142 #define STOP_BITS_2                     1
143 #define STOP_BITS_3                     2
144 #define STOP_BITS_4                     3
145 
146 #ifdef _WIN32
147 #include <windows.h>
148 #else
149 #define PARITY_NONE                     0
150 #define PARITY_ODD                      1
151 #define PARITY_EVEN                     2
152 #endif
153 
154 #define BIT_ORDER_LSB                   0
155 #define BIT_ORDER_MSB                   1
156 
157 #define NRZ_NORMAL                      0       /* Non Return to Zero : normal mode */
158 #define NRZ_INVERTED                    1       /* Non Return to Zero : inverted mode */
159 
160 #ifndef RT_SERIAL_RB_BUFSZ
161 #define RT_SERIAL_RB_BUFSZ              64
162 #endif
163 
164 #define RT_SERIAL_EVENT_RX_IND          0x01    /* Rx indication */
165 #define RT_SERIAL_EVENT_TX_DONE         0x02    /* Tx complete   */
166 #define RT_SERIAL_EVENT_RX_DMADONE      0x03    /* Rx DMA transfer done */
167 #define RT_SERIAL_EVENT_TX_DMADONE      0x04    /* Tx DMA transfer done */
168 #define RT_SERIAL_EVENT_RX_TIMEOUT      0x05    /* Rx timeout    */
169 
170 #define RT_SERIAL_DMA_RX                0x01
171 #define RT_SERIAL_DMA_TX                0x02
172 
173 #define RT_SERIAL_RX_INT                0x01
174 #define RT_SERIAL_TX_INT                0x02
175 
176 #define RT_SERIAL_ERR_OVERRUN           0x01
177 #define RT_SERIAL_ERR_FRAMING           0x02
178 #define RT_SERIAL_ERR_PARITY            0x03
179 
180 #define RT_SERIAL_TX_DATAQUEUE_SIZE     2048
181 #define RT_SERIAL_TX_DATAQUEUE_LWM      30
182 
183 #define RT_SERIAL_FLOWCONTROL_CTSRTS    1
184 #define RT_SERIAL_FLOWCONTROL_NONE      0
185 
186 /* Default config for serial_configure structure */
187 #define RT_SERIAL_CONFIG_DEFAULT           \
188 {                                          \
189     BAUD_RATE_115200, /* 115200 bits/s */  \
190     DATA_BITS_8,      /* 8 databits */     \
191     STOP_BITS_1,      /* 1 stopbit */      \
192     PARITY_NONE,      /* No parity  */     \
193     BIT_ORDER_LSB,    /* LSB first sent */ \
194     NRZ_NORMAL,       /* Normal mode */    \
195     RT_SERIAL_RB_BUFSZ, /* Buffer size */  \
196     RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \
197     0                                      \
198 }
199 
200 /**
201  * @brief Sets a hook function when RX indicate is called
202  *
203  */
204 typedef void (*rt_hw_serial_rxind_hookproto_t)(rt_device_t dev, rt_size_t size);
205 RT_OBJECT_HOOKLIST_DECLARE(rt_hw_serial_rxind_hookproto_t, rt_hw_serial_rxind);
206 
207 struct serial_configure
208 {
209     rt_uint32_t baud_rate;
210 
211     rt_uint32_t data_bits               :4;
212     rt_uint32_t stop_bits               :2;
213     rt_uint32_t parity                  :2;
214     rt_uint32_t bit_order               :1;
215     rt_uint32_t invert                  :1;
216     rt_uint32_t bufsz                   :16;
217     rt_uint32_t flowcontrol             :1;
218     rt_uint32_t reserved                :5;
219 };
220 
221 /*
222  * Serial FIFO mode
223  */
224 struct rt_serial_rx_fifo
225 {
226     /* software fifo */
227     rt_uint8_t *buffer;
228 
229     rt_uint16_t put_index, get_index;
230 
231     rt_bool_t is_full;
232 };
233 
234 struct rt_serial_tx_fifo
235 {
236     struct rt_completion completion;
237 };
238 
239 /*
240  * Serial DMA mode
241  */
242 struct rt_serial_rx_dma
243 {
244     rt_bool_t activated;
245 };
246 
247 struct rt_serial_tx_dma
248 {
249     rt_bool_t activated;
250     struct rt_data_queue data_queue;
251 };
252 
253 struct rt_serial_device
254 {
255     struct rt_device          parent;
256 
257     const struct rt_uart_ops *ops;
258     struct serial_configure   config;
259 
260     void *serial_rx;
261     void *serial_tx;
262 
263     struct rt_spinlock spinlock;
264 #ifdef RT_USING_SERIAL_BYPASS
265     struct rt_serial_bypass* bypass;
266 #endif
267     struct rt_device_notify rx_notify;
268 };
269 typedef struct rt_serial_device rt_serial_t;
270 
271 /**
272  * @brief Configure the serial device
273  */
274 struct rt_uart_ops
275 {
276     rt_err_t (*configure)(struct rt_serial_device *serial, struct serial_configure *cfg);
277     rt_err_t (*control)(struct rt_serial_device *serial, int cmd, void *arg);
278 
279     int (*putc)(struct rt_serial_device *serial, char c);
280     int (*getc)(struct rt_serial_device *serial);
281 
282     rt_ssize_t (*dma_transmit)(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
283 };
284 
285 /**
286  * @brief Serial interrupt service routine
287  * @param serial    serial device
288  * @param event     event mask
289  * @ingroup group_drivers_serial
290  */
291 void rt_hw_serial_isr(struct rt_serial_device *serial, int event);
292 
293 /**
294  * @brief Register a serial device to device list
295  *
296  * @param serial    serial device
297  * @param name      device name
298  * @param flag      device flag
299  * @param data      device private data
300  * @return rt_err_t        error code
301  * @note This function will register a serial device to system device list,
302  *       and add a device object to system object list.
303  * @ingroup group_drivers_serial
304  */
305 rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
306                                const char              *name,
307                                rt_uint32_t              flag,
308                                void                    *data);
309 
310 /**
311  * @brief     register a serial device to system device list and add a device object to system object list
312  *
313  * @param serial    serial device
314  * @return rt_err_t error code
315  *
316  * @ingroup group_drivers_serial
317  */
318 rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial);
319 
320 /*! @}*/
321 
322 #endif
323