vfs_uart.c 28 KB

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