user_uart.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. //
  2. // The MIT License (MIT)
  3. //
  4. // Copyright (c) 2019 Livox. All rights reserved.
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. // SOFTWARE.
  23. //
  24. #include "user_uart.h"
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <sys/stat.h>
  28. #include <sys/types.h>
  29. #include <termios.h>
  30. #include <unistd.h>
  31. namespace livox_ros {
  32. UserUart::UserUart(uint8_t baudrate_index, uint8_t parity)
  33. : baudrate_(baudrate_index), parity_(parity) {
  34. fd_ = 0;
  35. is_open_ = false;
  36. }
  37. UserUart::~UserUart() {
  38. is_open_ = false;
  39. if (fd_ > 0) {
  40. /** first we flush the port */
  41. tcflush(fd_, TCOFLUSH);
  42. tcflush(fd_, TCIFLUSH);
  43. close(fd_);
  44. }
  45. }
  46. int UserUart::Open(const char *filename) {
  47. fd_ = open(filename, O_RDWR | O_NOCTTY); //| O_NDELAY
  48. if (fd_ < 0) {
  49. printf("Open %s fail!\n", filename);
  50. return -1;
  51. } else {
  52. chmod(filename, S_IRWXU | S_IRWXG | S_IRWXO); /* need add here */
  53. printf("Open %s success!\n", filename);
  54. }
  55. if (fd_ > 0) {
  56. /** set baudrate and parity,etc. */
  57. if (Setup(baudrate_, parity_)) {
  58. return -1;
  59. }
  60. }
  61. is_open_ = true;
  62. return 0;
  63. }
  64. int UserUart::Close() {
  65. is_open_ = false;
  66. if (fd_ > 0) {
  67. /** first we flush the port */
  68. tcflush(fd_, TCOFLUSH);
  69. tcflush(fd_, TCIFLUSH);
  70. return close(fd_);
  71. }
  72. return -1;
  73. }
  74. /** sets up the port parameters */
  75. int UserUart::Setup(uint8_t baudrate_index, uint8_t parity) {
  76. static uint32_t baud_map[19] = {
  77. B2400, B4800, B9600, B19200, B38400, B57600, B115200,
  78. B230400, B460800, B500000, B576000, B921600, B1152000, B1500000,
  79. B2000000, B2500000, B3000000, B3500000, B4000000};
  80. tcflag_t baudrate;
  81. struct termios options;
  82. if ((baudrate_index > BR4000000) || (parity > P_7S1)) {
  83. return -1;
  84. }
  85. /** clear old setting completely,must add here for CDC serial */
  86. tcgetattr(fd_, &options);
  87. memset(&options, 0, sizeof(options));
  88. tcflush(fd_, TCIOFLUSH);
  89. tcsetattr(fd_, TCSANOW, &options);
  90. usleep(10000);
  91. /** Enable the receiver and set local mode... */
  92. options.c_cflag |= (CLOCAL | CREAD);
  93. /** Disable hardware flow */
  94. // options.c_cflag &= ~CRTSCTS;
  95. /** Disable software flow */
  96. // options.c_iflag &= ~(IXON | IXOFF | IXANY);
  97. // options.c_oflag &= ~OPOST;
  98. /** set boadrate */
  99. options.c_cflag &= ~CBAUD;
  100. baudrate = baud_map[baudrate_index];
  101. options.c_cflag |= baudrate;
  102. switch (parity) {
  103. case P_8N1:
  104. /** No parity (8N1) */
  105. options.c_cflag &= ~PARENB;
  106. options.c_cflag &= ~CSTOPB;
  107. options.c_cflag &= ~CSIZE;
  108. options.c_cflag |= CS8;
  109. break;
  110. case P_7E1:
  111. /** Even parity (7E1) */
  112. options.c_cflag |= PARENB;
  113. options.c_cflag &= ~PARODD;
  114. options.c_cflag &= ~CSTOPB;
  115. options.c_cflag &= ~CSIZE;
  116. options.c_cflag |= CS7;
  117. break;
  118. case P_7O1:
  119. /** Odd parity (7O1) */
  120. options.c_cflag |= PARENB;
  121. options.c_cflag |= PARODD;
  122. options.c_cflag &= ~CSTOPB;
  123. options.c_cflag &= ~CSIZE;
  124. options.c_cflag |= CS7;
  125. break;
  126. case P_7S1:
  127. /** Space parity is setup the same as no parity (7S1) */
  128. options.c_cflag &= ~PARENB;
  129. options.c_cflag &= ~CSTOPB;
  130. options.c_cflag &= ~CSIZE;
  131. options.c_cflag |= CS8;
  132. break;
  133. default:
  134. return -1;
  135. }
  136. /** now we setup the values in port's termios */
  137. options.c_iflag &= ~INPCK;
  138. /** Enable non-canonical */
  139. // options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  140. /** Time to wait for data */
  141. options.c_cc[VTIME] = 1;
  142. /** Minimum number of characters to read */
  143. options.c_cc[VMIN] = 1;
  144. /** flush the port */
  145. tcflush(fd_, TCIOFLUSH);
  146. /** send new config to the port */
  147. tcsetattr(fd_, TCSANOW, &options);
  148. return 0;
  149. }
  150. ssize_t UserUart::Write(const char *buffer, size_t size) {
  151. if (fd_ > 0) {
  152. return write(fd_, buffer, size);
  153. } else {
  154. return 0;
  155. }
  156. }
  157. ssize_t UserUart::Read(char *buffer, size_t size) {
  158. if (fd_ > 0) {
  159. return read(fd_, buffer, size);
  160. } else {
  161. return 0;
  162. }
  163. }
  164. } // namespace livox_ros