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