1 // Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <string.h>
16 #include <stdbool.h>
17 #include <stdarg.h>
18 #include <sys/errno.h>
19 #include <sys/lock.h>
20 #include <sys/fcntl.h>
21 #include <sys/param.h>
22 #include "esp_vfs.h"
23 #include "esp_vfs_dev.h"
24 #include "esp_attr.h"
25 #include "soc/uart_periph.h"
26 #include "driver/uart.h"
27 #include "sdkconfig.h"
28 #include "driver/uart_select.h"
29 #include "esp_rom_uart.h"
30 
31 // TODO: make the number of UARTs chip dependent
32 #define UART_NUM SOC_UART_NUM
33 
34 // Token signifying that no character is available
35 #define NONE -1
36 
37 #if CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF
38 #   define DEFAULT_TX_MODE ESP_LINE_ENDINGS_CRLF
39 #elif CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR
40 #   define DEFAULT_TX_MODE ESP_LINE_ENDINGS_CR
41 #else
42 #   define DEFAULT_TX_MODE ESP_LINE_ENDINGS_LF
43 #endif
44 
45 #if CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF
46 #   define DEFAULT_RX_MODE ESP_LINE_ENDINGS_CRLF
47 #elif CONFIG_NEWLIB_STDIN_LINE_ENDING_CR
48 #   define DEFAULT_RX_MODE ESP_LINE_ENDINGS_CR
49 #else
50 #   define DEFAULT_RX_MODE ESP_LINE_ENDINGS_LF
51 #endif
52 
53 // UART write bytes function type
54 typedef void (*tx_func_t)(int, int);
55 // UART read bytes function type
56 typedef int (*rx_func_t)(int);
57 
58 // Basic functions for sending and receiving bytes over UART
59 static void uart_tx_char(int fd, int c);
60 static int uart_rx_char(int fd);
61 
62 // Functions for sending and receiving bytes which use UART driver
63 static void uart_tx_char_via_driver(int fd, int c);
64 static int uart_rx_char_via_driver(int fd);
65 
66 typedef struct {
67     // Pointers to UART peripherals
68     uart_dev_t* uart;
69     // One-character buffer used for newline conversion code, per UART
70     int peek_char;
71     // per-UART locks, lazily initialized
72     _lock_t read_lock;
73     _lock_t write_lock;
74     // Per-UART non-blocking flag. Note: default implementation does not honor this
75     // flag, all reads are non-blocking. This option becomes effective if UART
76     // driver is used.
77     bool non_blocking;
78     // Newline conversion mode when transmitting
79     esp_line_endings_t tx_mode;
80     // Newline conversion mode when receiving
81     esp_line_endings_t rx_mode;
82     // Functions used to write bytes to UART. Default to "basic" functions.
83     tx_func_t tx_func;
84     // Functions used to read bytes from UART. Default to "basic" functions.
85     rx_func_t rx_func;
86 } vfs_uart_context_t;
87 
88 #define VFS_CTX_DEFAULT_VAL(uart_dev) (vfs_uart_context_t) {\
89     .uart = (uart_dev),\
90     .peek_char = NONE,\
91     .tx_mode = DEFAULT_TX_MODE,\
92     .rx_mode = DEFAULT_RX_MODE,\
93     .tx_func = uart_tx_char,\
94     .rx_func = uart_rx_char,\
95 }
96 
97 //If the context should be dynamically initialized, remove this structure
98 //and point s_ctx to allocated data.
99 static vfs_uart_context_t s_context[UART_NUM] = {
100     VFS_CTX_DEFAULT_VAL(&UART0),
101     VFS_CTX_DEFAULT_VAL(&UART1),
102 #if UART_NUM > 2
103     VFS_CTX_DEFAULT_VAL(&UART2),
104 #endif
105 };
106 
107 static vfs_uart_context_t* s_ctx[UART_NUM] = {
108     &s_context[0],
109     &s_context[1],
110 #if UART_NUM > 2
111     &s_context[2],
112 #endif
113 };
114 
115 #ifdef CONFIG_VFS_SUPPORT_SELECT
116 
117 typedef struct {
118     esp_vfs_select_sem_t select_sem;
119     fd_set *readfds;
120     fd_set *writefds;
121     fd_set *errorfds;
122     fd_set readfds_orig;
123     fd_set writefds_orig;
124     fd_set errorfds_orig;
125 } uart_select_args_t;
126 
127 static uart_select_args_t **s_registered_selects = NULL;
128 static int s_registered_select_num = 0;
129 static portMUX_TYPE s_registered_select_lock = portMUX_INITIALIZER_UNLOCKED;
130 
131 static esp_err_t uart_end_select(void *end_select_args);
132 
133 #endif // CONFIG_VFS_SUPPORT_SELECT
134 
uart_open(const char * path,int flags,int mode)135 static int uart_open(const char * path, int flags, int mode)
136 {
137     // this is fairly primitive, we should check if file is opened read only,
138     // and error out if write is requested
139     int fd = -1;
140 
141     if (strcmp(path, "/0") == 0) {
142         fd = 0;
143     } else if (strcmp(path, "/1") == 0) {
144         fd = 1;
145     } else if (strcmp(path, "/2") == 0) {
146         fd = 2;
147     } else {
148         errno = ENOENT;
149         return fd;
150     }
151 
152     s_ctx[fd]->non_blocking = ((flags & O_NONBLOCK) == O_NONBLOCK);
153 
154     return fd;
155 }
156 
uart_tx_char(int fd,int c)157 static void uart_tx_char(int fd, int c)
158 {
159     uart_dev_t* uart = s_ctx[fd]->uart;
160     while (uart->status.txfifo_cnt >= 127) {
161         ;
162     }
163 #if CONFIG_IDF_TARGET_ESP32
164     uart->fifo.rw_byte = c;
165 #else // CONFIG_IDF_TARGET_ESP32
166     uart->ahb_fifo.rw_byte = c;
167 #endif
168 }
169 
uart_tx_char_via_driver(int fd,int c)170 static void uart_tx_char_via_driver(int fd, int c)
171 {
172     char ch = (char) c;
173     uart_write_bytes(fd, &ch, 1);
174 }
175 
uart_rx_char(int fd)176 static int uart_rx_char(int fd)
177 {
178     uart_dev_t* uart = s_ctx[fd]->uart;
179     if (uart->status.rxfifo_cnt == 0) {
180         return NONE;
181     }
182 #if CONFIG_IDF_TARGET_ESP32
183     return uart->fifo.rw_byte;
184 #else // CONFIG_IDF_TARGET_ESP32
185     return READ_PERI_REG(UART_FIFO_AHB_REG(fd));
186 #endif
187 }
188 
uart_rx_char_via_driver(int fd)189 static int uart_rx_char_via_driver(int fd)
190 {
191     uint8_t c;
192     int timeout = s_ctx[fd]->non_blocking ? 0 : portMAX_DELAY;
193     int n = uart_read_bytes(fd, &c, 1, timeout);
194     if (n <= 0) {
195         return NONE;
196     }
197     return c;
198 }
199 
uart_write(int fd,const void * data,size_t size)200 static ssize_t uart_write(int fd, const void * data, size_t size)
201 {
202     assert(fd >=0 && fd < 3);
203     const char *data_c = (const char *)data;
204     /*  Even though newlib does stream locking on each individual stream, we need
205      *  a dedicated UART lock if two streams (stdout and stderr) point to the
206      *  same UART.
207      */
208     _lock_acquire_recursive(&s_ctx[fd]->write_lock);
209     for (size_t i = 0; i < size; i++) {
210         int c = data_c[i];
211         if (c == '\n' && s_ctx[fd]->tx_mode != ESP_LINE_ENDINGS_LF) {
212             s_ctx[fd]->tx_func(fd, '\r');
213             if (s_ctx[fd]->tx_mode == ESP_LINE_ENDINGS_CR) {
214                 continue;
215             }
216         }
217         s_ctx[fd]->tx_func(fd, c);
218     }
219     _lock_release_recursive(&s_ctx[fd]->write_lock);
220     return size;
221 }
222 
223 /* Helper function which returns a previous character or reads a new one from
224  * UART. Previous character can be returned ("pushed back") using
225  * uart_return_char function.
226  */
uart_read_char(int fd)227 static int uart_read_char(int fd)
228 {
229     /* return character from peek buffer, if it is there */
230     if (s_ctx[fd]->peek_char != NONE) {
231         int c = s_ctx[fd]->peek_char;
232         s_ctx[fd]->peek_char = NONE;
233         return c;
234     }
235     return s_ctx[fd]->rx_func(fd);
236 }
237 
238 /* Push back a character; it will be returned by next call to uart_read_char */
uart_return_char(int fd,int c)239 static void uart_return_char(int fd, int c)
240 {
241     assert(s_ctx[fd]->peek_char == NONE);
242     s_ctx[fd]->peek_char = c;
243 }
244 
uart_read(int fd,void * data,size_t size)245 static ssize_t uart_read(int fd, void* data, size_t size)
246 {
247     assert(fd >=0 && fd < 3);
248     char *data_c = (char *) data;
249     size_t received = 0;
250     _lock_acquire_recursive(&s_ctx[fd]->read_lock);
251     while (received < size) {
252         int c = uart_read_char(fd);
253         if (c == '\r') {
254             if (s_ctx[fd]->rx_mode == ESP_LINE_ENDINGS_CR) {
255                 c = '\n';
256             } else if (s_ctx[fd]->rx_mode == ESP_LINE_ENDINGS_CRLF) {
257                 /* look ahead */
258                 int c2 = uart_read_char(fd);
259                 if (c2 == NONE) {
260                     /* could not look ahead, put the current character back */
261                     uart_return_char(fd, c);
262                     break;
263                 }
264                 if (c2 == '\n') {
265                     /* this was \r\n sequence. discard \r, return \n */
266                     c = '\n';
267                 } else {
268                     /* \r followed by something else. put the second char back,
269                      * it will be processed on next iteration. return \r now.
270                      */
271                     uart_return_char(fd, c2);
272                 }
273             }
274         } else if (c == NONE) {
275             break;
276         }
277         data_c[received] = (char) c;
278         ++received;
279         if (c == '\n') {
280             break;
281         }
282     }
283     _lock_release_recursive(&s_ctx[fd]->read_lock);
284     if (received > 0) {
285         return received;
286     }
287     errno = EWOULDBLOCK;
288     return -1;
289 }
290 
uart_fstat(int fd,struct stat * st)291 static int uart_fstat(int fd, struct stat * st)
292 {
293     assert(fd >=0 && fd < 3);
294     memset(st, 0, sizeof(*st));
295     st->st_mode = S_IFCHR;
296     return 0;
297 }
298 
uart_close(int fd)299 static int uart_close(int fd)
300 {
301     assert(fd >=0 && fd < 3);
302     return 0;
303 }
304 
uart_fcntl(int fd,int cmd,int arg)305 static int uart_fcntl(int fd, int cmd, int arg)
306 {
307     assert(fd >=0 && fd < 3);
308     int result = 0;
309     if (cmd == F_GETFL) {
310         if (s_ctx[fd]->non_blocking) {
311             result |= O_NONBLOCK;
312         }
313     } else if (cmd == F_SETFL) {
314         s_ctx[fd]->non_blocking = (arg & O_NONBLOCK) != 0;
315     } else {
316         // unsupported operation
317         result = -1;
318         errno = ENOSYS;
319     }
320     return result;
321 }
322 
323 #ifdef CONFIG_VFS_SUPPORT_DIR
324 
uart_access(const char * path,int amode)325 static int uart_access(const char *path, int amode)
326 {
327     int ret = -1;
328 
329     if (strcmp(path, "/0") == 0 || strcmp(path, "/1") == 0 || strcmp(path, "/2") == 0) {
330         if (F_OK == amode) {
331             ret = 0; //path exists
332         } else {
333             if ((((amode & R_OK) == R_OK) || ((amode & W_OK) == W_OK)) && ((amode & X_OK) != X_OK)) {
334                 ret = 0; //path is readable and/or writable but not executable
335             } else {
336                 errno = EACCES;
337             }
338         }
339     } else {
340         errno = ENOENT;
341     }
342 
343     return ret;
344 }
345 
346 #endif // CONFIG_VFS_SUPPORT_DIR
347 
uart_fsync(int fd)348 static int uart_fsync(int fd)
349 {
350     assert(fd >= 0 && fd < 3);
351     _lock_acquire_recursive(&s_ctx[fd]->write_lock);
352     esp_rom_uart_tx_wait_idle((uint8_t) fd);
353     _lock_release_recursive(&s_ctx[fd]->write_lock);
354     return 0;
355 }
356 
357 #ifdef CONFIG_VFS_SUPPORT_SELECT
358 
register_select(uart_select_args_t * args)359 static esp_err_t register_select(uart_select_args_t *args)
360 {
361     esp_err_t ret = ESP_ERR_INVALID_ARG;
362 
363     if (args) {
364         portENTER_CRITICAL(&s_registered_select_lock);
365         const int new_size = s_registered_select_num + 1;
366         if ((s_registered_selects = realloc(s_registered_selects, new_size * sizeof(uart_select_args_t *))) == NULL) {
367             ret = ESP_ERR_NO_MEM;
368         } else {
369             s_registered_selects[s_registered_select_num] = args;
370             s_registered_select_num = new_size;
371             ret = ESP_OK;
372         }
373         portEXIT_CRITICAL(&s_registered_select_lock);
374     }
375 
376     return ret;
377 }
378 
unregister_select(uart_select_args_t * args)379 static esp_err_t unregister_select(uart_select_args_t *args)
380 {
381     esp_err_t ret = ESP_OK;
382     if (args) {
383         ret = ESP_ERR_INVALID_STATE;
384         portENTER_CRITICAL(&s_registered_select_lock);
385         for (int i = 0; i < s_registered_select_num; ++i) {
386             if (s_registered_selects[i] == args) {
387                 const int new_size = s_registered_select_num - 1;
388                 // The item is removed by overwriting it with the last item. The subsequent rellocation will drop the
389                 // last item.
390                 s_registered_selects[i] = s_registered_selects[new_size];
391                 s_registered_selects = realloc(s_registered_selects, new_size * sizeof(uart_select_args_t *));
392                 if (s_registered_selects || new_size == 0) {
393                     s_registered_select_num = new_size;
394                     ret = ESP_OK;
395                 } else {
396                     ret = ESP_ERR_NO_MEM;
397                 }
398                 break;
399             }
400         }
401         portEXIT_CRITICAL(&s_registered_select_lock);
402     }
403     return ret;
404 }
405 
select_notif_callback_isr(uart_port_t uart_num,uart_select_notif_t uart_select_notif,BaseType_t * task_woken)406 static void select_notif_callback_isr(uart_port_t uart_num, uart_select_notif_t uart_select_notif, BaseType_t *task_woken)
407 {
408     portENTER_CRITICAL_ISR(&s_registered_select_lock);
409     for (int i = 0; i < s_registered_select_num; ++i) {
410         uart_select_args_t *args = s_registered_selects[i];
411         if (args) {
412             switch (uart_select_notif) {
413                 case UART_SELECT_READ_NOTIF:
414                     if (FD_ISSET(uart_num, &args->readfds_orig)) {
415                         FD_SET(uart_num, args->readfds);
416                         esp_vfs_select_triggered_isr(args->select_sem, task_woken);
417                     }
418                     break;
419                 case UART_SELECT_WRITE_NOTIF:
420                     if (FD_ISSET(uart_num, &args->writefds_orig)) {
421                         FD_SET(uart_num, args->writefds);
422                         esp_vfs_select_triggered_isr(args->select_sem, task_woken);
423                     }
424                     break;
425                 case UART_SELECT_ERROR_NOTIF:
426                     if (FD_ISSET(uart_num, &args->errorfds_orig)) {
427                         FD_SET(uart_num, args->errorfds);
428                         esp_vfs_select_triggered_isr(args->select_sem, task_woken);
429                     }
430                     break;
431             }
432         }
433     }
434     portEXIT_CRITICAL_ISR(&s_registered_select_lock);
435 }
436 
uart_start_select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,esp_vfs_select_sem_t select_sem,void ** end_select_args)437 static esp_err_t uart_start_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
438         esp_vfs_select_sem_t select_sem, void **end_select_args)
439 {
440     const int max_fds = MIN(nfds, UART_NUM);
441     *end_select_args = NULL;
442 
443     for (int i = 0; i < max_fds; ++i) {
444         if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds)) {
445             if (!uart_is_driver_installed(i)) {
446                 return ESP_ERR_INVALID_STATE;
447             }
448         }
449     }
450 
451     uart_select_args_t *args = malloc(sizeof(uart_select_args_t));
452 
453     if (args == NULL) {
454         return ESP_ERR_NO_MEM;
455     }
456 
457     args->select_sem = select_sem;
458     args->readfds = readfds;
459     args->writefds = writefds;
460     args->errorfds = exceptfds;
461     args->readfds_orig = *readfds; // store the original values because they will be set to zero
462     args->writefds_orig = *writefds;
463     args->errorfds_orig = *exceptfds;
464     FD_ZERO(readfds);
465     FD_ZERO(writefds);
466     FD_ZERO(exceptfds);
467 
468     portENTER_CRITICAL(uart_get_selectlock());
469 
470     //uart_set_select_notif_callback sets the callbacks in UART ISR
471     for (int i = 0; i < max_fds; ++i) {
472         if (FD_ISSET(i, &args->readfds_orig) || FD_ISSET(i, &args->writefds_orig) || FD_ISSET(i, &args->errorfds_orig)) {
473             uart_set_select_notif_callback(i, select_notif_callback_isr);
474         }
475     }
476 
477     for (int i = 0; i < max_fds; ++i) {
478         if (FD_ISSET(i, &args->readfds_orig)) {
479             size_t buffered_size;
480             if (uart_get_buffered_data_len(i, &buffered_size) == ESP_OK && buffered_size > 0) {
481                 // signalize immediately when data is buffered
482                 FD_SET(i, readfds);
483                 esp_vfs_select_triggered(args->select_sem);
484             }
485         }
486     }
487 
488     esp_err_t ret = register_select(args);
489     if (ret != ESP_OK) {
490         portEXIT_CRITICAL(uart_get_selectlock());
491         free(args);
492         return ret;
493     }
494 
495     portEXIT_CRITICAL(uart_get_selectlock());
496 
497     *end_select_args = args;
498     return ESP_OK;
499 }
500 
uart_end_select(void * end_select_args)501 static esp_err_t uart_end_select(void *end_select_args)
502 {
503     uart_select_args_t *args = end_select_args;
504 
505     portENTER_CRITICAL(uart_get_selectlock());
506     esp_err_t ret = unregister_select(args);
507     for (int i = 0; i < UART_NUM; ++i) {
508         uart_set_select_notif_callback(i, NULL);
509     }
510     portEXIT_CRITICAL(uart_get_selectlock());
511 
512     if (args) {
513         free(args);
514     }
515 
516     return ret;
517 }
518 
519 #endif // CONFIG_VFS_SUPPORT_SELECT
520 
521 #ifdef CONFIG_VFS_SUPPORT_TERMIOS
uart_tcsetattr(int fd,int optional_actions,const struct termios * p)522 static int uart_tcsetattr(int fd, int optional_actions, const struct termios *p)
523 {
524     if (fd < 0 || fd >= UART_NUM) {
525         errno = EBADF;
526         return -1;
527     }
528 
529     if (p == NULL) {
530         errno = EINVAL;
531         return -1;
532     }
533 
534     switch (optional_actions) {
535         case TCSANOW:
536             // nothing to do
537             break;
538         case TCSADRAIN:
539             if (uart_wait_tx_done(fd, portMAX_DELAY) != ESP_OK) {
540                 errno = EINVAL;
541                 return -1;
542             }
543 
544             /* FALLTHRU */
545 
546         case TCSAFLUSH:
547             if (uart_flush_input(fd) != ESP_OK) {
548                 errno = EINVAL;
549                 return -1;
550             }
551             break;
552         default:
553             errno = EINVAL;
554             return -1;
555     }
556 
557     if (p->c_iflag & IGNCR) {
558         s_ctx[fd]->rx_mode = ESP_LINE_ENDINGS_CRLF;
559     } else if (p->c_iflag & ICRNL) {
560         s_ctx[fd]->rx_mode = ESP_LINE_ENDINGS_CR;
561     } else {
562         s_ctx[fd]->rx_mode = ESP_LINE_ENDINGS_LF;
563     }
564 
565     // output line endings are not supported because there is no alternative in termios for converting LF to CR
566 
567     {
568         uart_word_length_t data_bits;
569         const tcflag_t csize_bits = p->c_cflag & CSIZE;
570 
571         switch (csize_bits) {
572             case CS5:
573                 data_bits = UART_DATA_5_BITS;
574                 break;
575             case CS6:
576                 data_bits = UART_DATA_6_BITS;
577                 break;
578             case CS7:
579                 data_bits = UART_DATA_7_BITS;
580                 break;
581             case CS8:
582                 data_bits = UART_DATA_8_BITS;
583                 break;
584             default:
585                 errno = EINVAL;
586                 return -1;
587         }
588 
589         if (uart_set_word_length(fd, data_bits) != ESP_OK) {
590             errno = EINVAL;
591             return -1;
592         }
593     }
594 
595     if (uart_set_stop_bits(fd, (p->c_cflag & CSTOPB) ? UART_STOP_BITS_2 : UART_STOP_BITS_1) != ESP_OK) {
596         errno = EINVAL;
597         return -1;
598     }
599 
600     if (uart_set_parity(fd, (p->c_cflag & PARENB) ?
601                 ((p->c_cflag & PARODD) ? UART_PARITY_ODD : UART_PARITY_EVEN)
602                 :
603                 UART_PARITY_DISABLE) != ESP_OK) {
604         errno = EINVAL;
605         return -1;
606     }
607 
608     if (p->c_cflag & (CBAUD | CBAUDEX)) {
609         if (p->c_ispeed != p->c_ospeed) {
610             errno = EINVAL;
611             return -1;
612         } else {
613             uint32_t b;
614             if (p->c_cflag & BOTHER) {
615                 b = p->c_ispeed;
616             } else {
617                 switch (p->c_ispeed) {
618                     case B0:
619                         b = 0;
620                         break;
621                     case B50:
622                         b = 50;
623                         break;
624                     case B75:
625                         b = 75;
626                         break;
627                     case B110:
628                         b = 110;
629                         break;
630                     case B134:
631                         b = 134;
632                         break;
633                     case B150:
634                         b = 150;
635                         break;
636                     case B200:
637                         b = 200;
638                         break;
639                     case B300:
640                         b = 300;
641                         break;
642                     case B600:
643                         b = 600;
644                         break;
645                     case B1200:
646                         b = 1200;
647                         break;
648                     case B1800:
649                         b = 1800;
650                         break;
651                     case B2400:
652                         b = 2400;
653                         break;
654                     case B4800:
655                         b = 4800;
656                         break;
657                     case B9600:
658                         b = 9600;
659                         break;
660                     case B19200:
661                         b = 19200;
662                         break;
663                     case B38400:
664                         b = 38400;
665                         break;
666                     case B57600:
667                         b = 57600;
668                         break;
669                     case B115200:
670                         b = 115200;
671                         break;
672                     case B230400:
673                         b = 230400;
674                         break;
675                     case B460800:
676                         b = 460800;
677                         break;
678                     case B500000:
679                         b = 500000;
680                         break;
681                     case B576000:
682                         b = 576000;
683                         break;
684                     case B921600:
685                         b = 921600;
686                         break;
687                     case B1000000:
688                         b = 1000000;
689                         break;
690                     case B1152000:
691                         b = 1152000;
692                         break;
693                     case B1500000:
694                         b = 1500000;
695                         break;
696                     case B2000000:
697                         b = 2000000;
698                         break;
699                     case B2500000:
700                         b = 2500000;
701                         break;
702                     case B3000000:
703                         b = 3000000;
704                         break;
705                     case B3500000:
706                         b = 3500000;
707                         break;
708                     case B4000000:
709                         b = 4000000;
710                         break;
711                     default:
712                         errno = EINVAL;
713                         return -1;
714                 }
715             }
716 
717             if (uart_set_baudrate(fd, b) != ESP_OK) {
718                 errno = EINVAL;
719                 return -1;
720             }
721         }
722     }
723 
724     return 0;
725 }
726 
uart_tcgetattr(int fd,struct termios * p)727 static int uart_tcgetattr(int fd, struct termios *p)
728 {
729     if (fd < 0 || fd >= UART_NUM) {
730         errno = EBADF;
731         return -1;
732     }
733 
734     if (p == NULL) {
735         errno = EINVAL;
736         return -1;
737     }
738 
739     memset(p, 0, sizeof(struct termios));
740 
741     if (s_ctx[fd]->rx_mode == ESP_LINE_ENDINGS_CRLF) {
742         p->c_iflag |= IGNCR;
743     } else if (s_ctx[fd]->rx_mode == ESP_LINE_ENDINGS_CR) {
744         p->c_iflag |= ICRNL;
745     }
746 
747     {
748         uart_word_length_t data_bits;
749 
750         if (uart_get_word_length(fd, &data_bits) != ESP_OK) {
751             errno = EINVAL;
752             return -1;
753         }
754 
755         p->c_cflag &= (~CSIZE);
756 
757         switch (data_bits) {
758             case UART_DATA_5_BITS:
759                 p->c_cflag |= CS5;
760                 break;
761             case UART_DATA_6_BITS:
762                 p->c_cflag |= CS6;
763                 break;
764             case UART_DATA_7_BITS:
765                 p->c_cflag |= CS7;
766                 break;
767             case UART_DATA_8_BITS:
768                 p->c_cflag |= CS8;
769                 break;
770             default:
771                 errno = ENOSYS;
772                 return -1;
773         }
774     }
775 
776     {
777         uart_stop_bits_t stop_bits;
778         if (uart_get_stop_bits(fd, &stop_bits) != ESP_OK) {
779             errno = EINVAL;
780             return -1;
781         }
782 
783         switch (stop_bits) {
784             case UART_STOP_BITS_1:
785                 // nothing to do
786                 break;
787             case UART_STOP_BITS_2:
788                 p->c_cflag |= CSTOPB;
789                 break;
790             default:
791                 // UART_STOP_BITS_1_5 is unsupported by termios
792                 errno = ENOSYS;
793                 return -1;
794         }
795     }
796 
797     {
798         uart_parity_t parity_mode;
799         if (uart_get_parity(fd, &parity_mode) != ESP_OK) {
800             errno = EINVAL;
801             return -1;
802         }
803 
804         switch (parity_mode) {
805             case UART_PARITY_EVEN:
806                 p->c_cflag |= PARENB;
807                 break;
808             case UART_PARITY_ODD:
809                 p->c_cflag |= (PARENB | PARODD);
810                 break;
811             case UART_PARITY_DISABLE:
812                 // nothing to do
813                 break;
814             default:
815                 errno = ENOSYS;
816                 return -1;
817         }
818     }
819 
820     {
821         uint32_t baudrate;
822         if (uart_get_baudrate(fd, &baudrate) != ESP_OK) {
823             errno = EINVAL;
824             return -1;
825         }
826 
827         p->c_cflag |= (CBAUD | CBAUDEX);
828 
829         speed_t sp;
830         switch (baudrate) {
831             case 0:
832                 sp = B0;
833                 break;
834             case 50:
835                 sp = B50;
836                 break;
837             case 75:
838                 sp = B75;
839                 break;
840             case 110:
841                 sp = B110;
842                 break;
843             case 134:
844                 sp = B134;
845                 break;
846             case 150:
847                 sp = B150;
848                 break;
849             case 200:
850                 sp = B200;
851                 break;
852             case 300:
853                 sp = B300;
854                 break;
855             case 600:
856                 sp = B600;
857                 break;
858             case 1200:
859                 sp = B1200;
860                 break;
861             case 1800:
862                 sp = B1800;
863                 break;
864             case 2400:
865                 sp = B2400;
866                 break;
867             case 4800:
868                 sp = B4800;
869                 break;
870             case 9600:
871                 sp = B9600;
872                 break;
873             case 19200:
874                 sp = B19200;
875                 break;
876             case 38400:
877                 sp = B38400;
878                 break;
879             case 57600:
880                 sp = B57600;
881                 break;
882             case 115200:
883                 sp = B115200;
884                 break;
885             case 230400:
886                 sp = B230400;
887                 break;
888             case 460800:
889                 sp = B460800;
890                 break;
891             case 500000:
892                 sp = B500000;
893                 break;
894             case 576000:
895                 sp = B576000;
896                 break;
897             case 921600:
898                 sp = B921600;
899                 break;
900             case 1000000:
901                 sp = B1000000;
902                 break;
903             case 1152000:
904                 sp = B1152000;
905                 break;
906             case 1500000:
907                 sp = B1500000;
908                 break;
909             case 2000000:
910                 sp = B2000000;
911                 break;
912             case 2500000:
913                 sp = B2500000;
914                 break;
915             case 3000000:
916                 sp = B3000000;
917                 break;
918             case 3500000:
919                 sp = B3500000;
920                 break;
921             case 4000000:
922                 sp = B4000000;
923                 break;
924             default:
925                 p->c_cflag |= BOTHER;
926                 sp = baudrate;
927                 break;
928         }
929 
930         p->c_ispeed = p->c_ospeed = sp;
931     }
932 
933     return 0;
934 }
935 
uart_tcdrain(int fd)936 static int uart_tcdrain(int fd)
937 {
938     if (fd < 0 || fd >= UART_NUM) {
939         errno = EBADF;
940         return -1;
941     }
942 
943     if (uart_wait_tx_done(fd, portMAX_DELAY) != ESP_OK) {
944         errno = EINVAL;
945         return -1;
946     }
947 
948     return 0;
949 }
950 
uart_tcflush(int fd,int select)951 static int uart_tcflush(int fd, int select)
952 {
953     if (fd < 0 || fd >= UART_NUM) {
954         errno = EBADF;
955         return -1;
956     }
957 
958     if (select == TCIFLUSH) {
959         if (uart_flush_input(fd) != ESP_OK) {
960             errno = EINVAL;
961             return -1;
962         }
963     } else {
964         // output flushing is not supported
965         errno = EINVAL;
966         return -1;
967     }
968 
969     return 0;
970 }
971 #endif // CONFIG_VFS_SUPPORT_TERMIOS
972 
esp_vfs_dev_uart_register(void)973 void esp_vfs_dev_uart_register(void)
974 {
975     esp_vfs_t vfs = {
976         .flags = ESP_VFS_FLAG_DEFAULT,
977         .write = &uart_write,
978         .open = &uart_open,
979         .fstat = &uart_fstat,
980         .close = &uart_close,
981         .read = &uart_read,
982         .fcntl = &uart_fcntl,
983         .fsync = &uart_fsync,
984 #ifdef CONFIG_VFS_SUPPORT_DIR
985         .access = &uart_access,
986 #endif // CONFIG_VFS_SUPPORT_DIR
987 #ifdef CONFIG_VFS_SUPPORT_SELECT
988         .start_select = &uart_start_select,
989         .end_select = &uart_end_select,
990 #endif // CONFIG_VFS_SUPPORT_SELECT
991 #ifdef CONFIG_VFS_SUPPORT_TERMIOS
992         .tcsetattr = &uart_tcsetattr,
993         .tcgetattr = &uart_tcgetattr,
994         .tcdrain = &uart_tcdrain,
995         .tcflush = &uart_tcflush,
996 #endif // CONFIG_VFS_SUPPORT_TERMIOS
997     };
998     ESP_ERROR_CHECK(esp_vfs_register("/dev/uart", &vfs, NULL));
999 }
1000 
esp_vfs_dev_uart_port_set_rx_line_endings(int uart_num,esp_line_endings_t mode)1001 int esp_vfs_dev_uart_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode)
1002 {
1003     if (uart_num < 0 || uart_num >= UART_NUM) {
1004         errno = EBADF;
1005         return -1;
1006     }
1007     s_ctx[uart_num]->rx_mode = mode;
1008     return 0;
1009 }
1010 
esp_vfs_dev_uart_port_set_tx_line_endings(int uart_num,esp_line_endings_t mode)1011 int esp_vfs_dev_uart_port_set_tx_line_endings(int uart_num, esp_line_endings_t mode)
1012 {
1013     if (uart_num < 0 || uart_num >= UART_NUM) {
1014         errno = EBADF;
1015         return -1;
1016     }
1017     s_ctx[uart_num]->tx_mode = mode;
1018     return 0;
1019 }
1020 
esp_vfs_dev_uart_set_rx_line_endings(esp_line_endings_t mode)1021 void esp_vfs_dev_uart_set_rx_line_endings(esp_line_endings_t mode)
1022 {
1023     for (int i = 0; i < UART_NUM; ++i) {
1024         s_ctx[i]->rx_mode = mode;
1025     }
1026 }
1027 
esp_vfs_dev_uart_set_tx_line_endings(esp_line_endings_t mode)1028 void esp_vfs_dev_uart_set_tx_line_endings(esp_line_endings_t mode)
1029 {
1030     for (int i = 0; i < UART_NUM; ++i) {
1031         s_ctx[i]->tx_mode = mode;
1032     }
1033 }
1034 
esp_vfs_dev_uart_use_nonblocking(int uart_num)1035 void esp_vfs_dev_uart_use_nonblocking(int uart_num)
1036 {
1037     _lock_acquire_recursive(&s_ctx[uart_num]->read_lock);
1038     _lock_acquire_recursive(&s_ctx[uart_num]->write_lock);
1039     s_ctx[uart_num]->tx_func = uart_tx_char;
1040     s_ctx[uart_num]->rx_func = uart_rx_char;
1041     _lock_release_recursive(&s_ctx[uart_num]->write_lock);
1042     _lock_release_recursive(&s_ctx[uart_num]->read_lock);
1043 }
1044 
esp_vfs_dev_uart_use_driver(int uart_num)1045 void esp_vfs_dev_uart_use_driver(int uart_num)
1046 {
1047     _lock_acquire_recursive(&s_ctx[uart_num]->read_lock);
1048     _lock_acquire_recursive(&s_ctx[uart_num]->write_lock);
1049     s_ctx[uart_num]->tx_func = uart_tx_char_via_driver;
1050     s_ctx[uart_num]->rx_func = uart_rx_char_via_driver;
1051     _lock_release_recursive(&s_ctx[uart_num]->write_lock);
1052     _lock_release_recursive(&s_ctx[uart_num]->read_lock);
1053 }
1054