vfs_uart.c 29 KB

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