#include #include #include #include #include #include //Used for UART #include //Used for UART #include //Used for UART #include "serial.h" /* -------------------------------------------------------------------- */ static int baudrate2const(int bauds) { int br; switch (bauds) { case 1200: br = B1200; break; case 2400: br = B2400; break; case 4800: br = B4800; break; case 9600: br = B9600; break; case 19200: br = B19200; break; case 38400: br = B38400; break; case 57600: br = B57600; break; case 115200: br = B115200; break; default: fprintf(stderr, "baudrate %d invalide\n", bauds); exit(1); break; } return br; } /* -------------------------------------------------------------------- */ int prepare_UART(char *port, int baudrate) { int uart0 = -1; int baudbits; struct termios options; #if DEBUG_LEVEL fprintf(stderr, "%s ( %s %d )\n", __func__, port, baudrate); #endif // OPEN THE UART // The flags (defined in fcntl.h): // Access modes (use 1 of these): // O_RDONLY - Open for reading only. // O_RDWR - Open for reading and writing. // O_WRONLY - Open for writing only. // // O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. // When set read requests on the file can return immediately with a // failure status // if there is no input immediately available (instead of blocking). // Likewise, write requests can also return // immediately with a failure status if the output can't be written // immediately. // // O_NOCTTY - When set and path identifies a terminal device, open() // shall not cause the terminal device to become the controlling terminal // for the process. uart0 = open(port, O_RDONLY | O_NOCTTY); if (uart0 < 0) { perror("unable to open uart "); return -1; } // CONFIGURE THE UART // The flags defined in /usr/include/termios.h - // see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html // Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, // B115200, B230400, B460800, B500000, B576000, B921600, B1000000, // B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000 // CSIZE:- CS5, CS6, CS7, CS8 // CLOCAL - Ignore modem status lines // CREAD - Enable receiver // IGNPAR = Ignore characters with parity errors // ICRNL - Map CR to NL on input (Use for ASCII comms where you want // to auto correct end of line characters - don't use for bianry comms!) // PARENB - Parity enable // PARODD - Odd parity (else even) baudbits = baudrate2const(baudrate); #if DEBUG_LEVEL > 1 fprintf(stderr, "%d -> 0x%04x\n", baudrate, baudbits); #endif memset(&options, 0, sizeof(options)); tcgetattr(uart0, &options); options.c_cflag = baudbits | CS8 | CLOCAL | CREAD; options.c_iflag = IGNPAR; options.c_oflag = 0; options.c_lflag = 0; options.c_cc[VMIN] = 1; /* ask for blocking read */ tcflush(uart0, TCIFLUSH); tcsetattr(uart0, TCSANOW, &options); return uart0; } /* -------------------------------------------------------------------- */ /* * this function have NO timeout ! * blocking read is not blocking, wtf ? */ int getbyte(int fd) { unsigned char byte; int foo; byte = 0; foo = read(fd, &byte, 1); if (1 != foo) { fprintf(stderr, "byte %d rd %d errno %d\n", byte, foo, errno); return -1; } return (int)byte; } /* -------------------------------------------------------------------- */ /* timeout is in milliseconds */ int getbyte_to (int fd, int to_ms) { unsigned char byte; struct timeval timeout; fd_set rfds; int retval; timeout.tv_sec = to_ms / 1000; timeout.tv_usec = (to_ms % 1000) * 1000; #if DEBUG_LEVEL > 1 fprintf(stderr, "timeout %6d is %4ld.%6ld\n", to_ms, timeout.tv_sec, timeout.tv_usec); #endif FD_ZERO (&rfds); FD_SET (fd, &rfds); retval = select(1, &rfds, NULL, NULL, &timeout); #if DEBUG_LEVEL fprintf(stderr, "%s : select on fd %d -> %d\n", __func__, fd, retval); #endif switch (retval) { case -1: fprintf(stderr, "omg ?\n"); retval = -1; break; case 0: fprintf(stderr, "timeout %ld.%ld\n", timeout.tv_sec, timeout.tv_usec); retval = -99; break; default: fprintf(stderr, "%s default -> %d\n", __func__, retval); if (retval==fd) { read(fd, &byte, 1); fprintf(stderr, "got 0x%02x\n", byte); retval = byte; } else { fprintf(stderr, "%d bad fd ?\n", retval); retval = -3; } break; } return retval; } /* -------------------------------------------------------------------- */ /* timeout is in milliseconds */ int getline_to(int fd, char *where, int szm, int to_ms) { int curpos, byte, retval; #if DEBUG_LEVEL fprintf(stderr, ">>> %s ( %d %p %d %d )\n", __func__, fd, where, szm, to_ms); #endif curpos = 0; retval = -7; /* magic number powa */ where[0] = '\0'; /* erase all the bs */ for(;;) { if (to_ms) { byte = getbyte_to (fd, to_ms); } else { byte = getbyte(fd); } if (byte < 0) { fprintf(stderr, "%s : somthing is wrong %d\n", __func__, byte); retval = byte; break; } if ('\n' == byte) { /* got an EOL ? */ where[curpos] = '\0'; retval = curpos; break; } if (curpos < szm) { /* ya de la place */ where[curpos] = byte; curpos++; } else { /* oups overflow */ retval = -6; break; } } #if DEBUG_LEVEL fprintf(stderr, "%s -> '%s'\n", __func__, where); #endif return retval; } /* -------------------------------------------------------------------- */