223 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			223 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| #include <stdio.h>
 | |
| #include  <stdlib.h>
 | |
| #include  <errno.h>
 | |
| #include  <sys/select.h>
 | |
| #include  <string.h>
 | |
| #include <unistd.h>			//Used for UART
 | |
| #include <fcntl.h>			//Used for UART
 | |
| #include <termios.h>		//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
 | |
| 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;
 | |
| 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
 | |
| 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 -> %d\n", __func__, retval);
 | |
| #endif
 | |
| 
 | |
| switch (retval) {
 | |
| 
 | |
| 	case -1:
 | |
| 		fprintf(stderr, "omg ?\n");
 | |
| 		retval = -1;
 | |
| 		break;
 | |
| 
 | |
| 	case 0:
 | |
| 		fprintf(stderr, "timeout\n");
 | |
| 		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;
 | |
| 
 | |
| curpos = 0;
 | |
| retval = -7;					/* magic number powa */
 | |
| where[0] = '\0';				/* erase all the bs  */
 | |
| 
 | |
| for(;;)	{
 | |
| 	byte = getbyte_to (fd, to_ms);
 | |
| 
 | |
| 	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;
 | |
| 		}
 | |
| 
 | |
| 	if (curpos < szm) {			/* ya de la place */
 | |
| 		where[curpos] = byte;
 | |
| 		curpos++;
 | |
| 		}
 | |
| 	else	{				/* oups overflow */
 | |
| 		retval = -6;
 | |
| 		break;
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| fprintf(stderr, "%s -> '%s'\n", __func__, where);
 | |
| 
 | |
| 
 | |
| return retval;
 | |
| }
 | |
| /* -------------------------------------------------------------------- */
 | |
| 
 |