Monitoring du Phytotron
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

serial.c 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <sys/select.h>
  5. #include <string.h>
  6. #include <unistd.h> //Used for UART
  7. #include <fcntl.h> //Used for UART
  8. #include <termios.h> //Used for UART
  9. #include "serial.h"
  10. /* -------------------------------------------------------------------- */
  11. static int baudrate2const(int bauds)
  12. {
  13. int br;
  14. switch (bauds)
  15. {
  16. case 1200: br = B1200; break;
  17. case 2400: br = B2400; break;
  18. case 4800: br = B4800; break;
  19. case 9600: br = B9600; break;
  20. case 19200: br = B19200; break;
  21. case 38400: br = B38400; break;
  22. case 57600: br = B57600; break;
  23. case 115200: br = B115200; break;
  24. default:
  25. fprintf(stderr, "baudrate %d invalide\n", bauds);
  26. exit(1);
  27. break;
  28. }
  29. return br;
  30. }
  31. /* -------------------------------------------------------------------- */
  32. int prepare_UART(char *port, int baudrate)
  33. {
  34. int uart0 = -1;
  35. int baudbits;
  36. struct termios options;
  37. #if DEBUG_LEVEL
  38. fprintf(stderr, "%s ( %s %d )\n", __func__, port, baudrate);
  39. #endif
  40. // OPEN THE UART
  41. // The flags (defined in fcntl.h):
  42. // Access modes (use 1 of these):
  43. // O_RDONLY - Open for reading only.
  44. // O_RDWR - Open for reading and writing.
  45. // O_WRONLY - Open for writing only.
  46. //
  47. // O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode.
  48. // When set read requests on the file can return immediately with a
  49. // failure status
  50. // if there is no input immediately available (instead of blocking).
  51. // Likewise, write requests can also return
  52. // immediately with a failure status if the output can't be written
  53. // immediately.
  54. //
  55. // O_NOCTTY - When set and path identifies a terminal device, open()
  56. // shall not cause the terminal device to become the controlling terminal
  57. // for the process.
  58. uart0 = open(port, O_RDONLY | O_NOCTTY);
  59. if (uart0 < 0)
  60. {
  61. perror("unable to open uart ");
  62. return -1;
  63. }
  64. // CONFIGURE THE UART
  65. // The flags defined in /usr/include/termios.h -
  66. // see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html
  67. // Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600,
  68. // B115200, B230400, B460800, B500000, B576000, B921600, B1000000,
  69. // B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
  70. // CSIZE:- CS5, CS6, CS7, CS8
  71. // CLOCAL - Ignore modem status lines
  72. // CREAD - Enable receiver
  73. // IGNPAR = Ignore characters with parity errors
  74. // ICRNL - Map CR to NL on input (Use for ASCII comms where you want
  75. // to auto correct end of line characters - don't use for bianry comms!)
  76. // PARENB - Parity enable
  77. // PARODD - Odd parity (else even)
  78. baudbits = baudrate2const(baudrate);
  79. #if DEBUG_LEVEL > 1
  80. fprintf(stderr, "%d -> 0x%04x\n", baudrate, baudbits);
  81. #endif
  82. memset(&options, 0, sizeof(options));
  83. tcgetattr(uart0, &options);
  84. options.c_cflag = baudbits | CS8 | CLOCAL | CREAD;
  85. options.c_iflag = IGNPAR;
  86. options.c_oflag = 0;
  87. options.c_lflag = 0;
  88. options.c_cc[VMIN] = 1; /* ask for blocking read */
  89. tcflush(uart0, TCIFLUSH);
  90. tcsetattr(uart0, TCSANOW, &options);
  91. return uart0;
  92. }
  93. /* -------------------------------------------------------------------- */
  94. /*
  95. * this function have NO timeout !
  96. * blocking read is not blocking, wtf ?
  97. */
  98. int getbyte(int fd)
  99. {
  100. unsigned char byte;
  101. int foo;
  102. byte = 0;
  103. foo = read(fd, &byte, 1);
  104. if (1 != foo)
  105. {
  106. fprintf(stderr, "byte %d rd %d errno %d\n",
  107. byte, foo, errno);
  108. return -1;
  109. }
  110. return (int)byte;
  111. }
  112. /* -------------------------------------------------------------------- */
  113. /* timeout is in milliseconds */
  114. int getbyte_to (int fd, int to_ms)
  115. {
  116. unsigned char byte;
  117. struct timeval timeout;
  118. fd_set rfds;
  119. int retval;
  120. timeout.tv_sec = to_ms / 1000;
  121. timeout.tv_usec = (to_ms % 1000) * 1000;
  122. #if DEBUG_LEVEL > 1
  123. fprintf(stderr, "timeout %6d is %4ld.%6ld\n", to_ms,
  124. timeout.tv_sec, timeout.tv_usec);
  125. #endif
  126. FD_ZERO (&rfds);
  127. FD_SET (fd, &rfds);
  128. retval = select(1, &rfds, NULL, NULL, &timeout);
  129. #if DEBUG_LEVEL
  130. fprintf(stderr, "%s : select on fd %d -> %d\n", __func__, fd, retval);
  131. #endif
  132. switch (retval) {
  133. case -1:
  134. fprintf(stderr, "omg ?\n");
  135. retval = -1;
  136. break;
  137. case 0:
  138. fprintf(stderr, "timeout %ld.%ld\n",
  139. timeout.tv_sec, timeout.tv_usec);
  140. retval = -99;
  141. break;
  142. default:
  143. fprintf(stderr, "%s default -> %d\n", __func__, retval);
  144. if (retval==fd) {
  145. read(fd, &byte, 1);
  146. fprintf(stderr, "got 0x%02x\n", byte);
  147. retval = byte;
  148. }
  149. else {
  150. fprintf(stderr, "%d bad fd ?\n", retval);
  151. retval = -3;
  152. }
  153. break;
  154. }
  155. return retval;
  156. }
  157. /* -------------------------------------------------------------------- */
  158. /* timeout is in milliseconds */
  159. int getline_to(int fd, char *where, int szm, int to_ms)
  160. {
  161. int curpos, byte, retval;
  162. #if DEBUG_LEVEL
  163. fprintf(stderr, ">>> %s ( %d %p %d %d )\n", __func__,
  164. fd, where, szm, to_ms);
  165. #endif
  166. curpos = 0;
  167. retval = -7; /* magic number powa */
  168. where[0] = '\0'; /* erase all the bs */
  169. for(;;) {
  170. if (to_ms) {
  171. byte = getbyte_to (fd, to_ms);
  172. }
  173. else {
  174. byte = getbyte(fd);
  175. }
  176. if (byte < 0) {
  177. fprintf(stderr, "%s : somthing is wrong %d\n",
  178. __func__, byte);
  179. retval = byte;
  180. break;
  181. }
  182. if ('\n' == byte) { /* got an EOL ? */
  183. where[curpos] = '\0';
  184. retval = curpos;
  185. break;
  186. }
  187. if (curpos < szm) { /* ya de la place */
  188. where[curpos] = byte;
  189. curpos++;
  190. }
  191. else { /* oups overflow */
  192. retval = -6;
  193. break;
  194. }
  195. }
  196. #if DEBUG_LEVEL
  197. fprintf(stderr, "%s -> '%s'\n", __func__, where);
  198. #endif
  199. return retval;
  200. }
  201. /* -------------------------------------------------------------------- */