vfs_uart.c 28 KB

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