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.9KB

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