|
- /*
- * wiringSerial.c:
- * Handle a serial port
- ***********************************************************************
- * This file is part of wiringPi:
- * https://github.com/WiringPi/WiringPi/
- *
- * wiringPi is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * wiringPi is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
- ***********************************************************************
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <stdarg.h>
- #include <string.h>
- #include <termios.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include "wiringSerial.h"
-
- /*
- * serialOpen:
- * Open and initialise the serial port, setting all the right
- * port parameters - or as many as are required - hopefully!
- *********************************************************************************
- */
-
- int serialOpen (const char *device, const int baud)
- {
- struct termios options ;
- speed_t myBaud ;
- int status, fd ;
-
- switch (baud)
- {
- case 50: myBaud = B50 ; break ;
- case 75: myBaud = B75 ; break ;
- case 110: myBaud = B110 ; break ;
- case 134: myBaud = B134 ; break ;
- case 150: myBaud = B150 ; break ;
- case 200: myBaud = B200 ; break ;
- case 300: myBaud = B300 ; break ;
- case 600: myBaud = B600 ; break ;
- case 1200: myBaud = B1200 ; break ;
- case 1800: myBaud = B1800 ; break ;
- case 2400: myBaud = B2400 ; break ;
- case 4800: myBaud = B4800 ; break ;
- case 9600: myBaud = B9600 ; break ;
- case 19200: myBaud = B19200 ; break ;
- case 38400: myBaud = B38400 ; break ;
- case 57600: myBaud = B57600 ; break ;
- case 115200: myBaud = B115200 ; break ;
- case 230400: myBaud = B230400 ; break ;
- case 460800: myBaud = B460800 ; break ;
- case 500000: myBaud = B500000 ; break ;
- case 576000: myBaud = B576000 ; break ;
- case 921600: myBaud = B921600 ; break ;
- case 1000000: myBaud = B1000000 ; break ;
- case 1152000: myBaud = B1152000 ; break ;
- case 1500000: myBaud = B1500000 ; break ;
- case 2000000: myBaud = B2000000 ; break ;
- case 2500000: myBaud = B2500000 ; break ;
- case 3000000: myBaud = B3000000 ; break ;
- case 3500000: myBaud = B3500000 ; break ;
- case 4000000: myBaud = B4000000 ; break ;
-
- default:
- return -2 ;
- }
-
- if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
- return -1 ;
-
- fcntl (fd, F_SETFL, O_RDWR) ;
-
- // Get and modify current options:
-
- tcgetattr (fd, &options) ;
-
- cfmakeraw (&options) ;
- cfsetispeed (&options, myBaud) ;
- cfsetospeed (&options, myBaud) ;
-
- options.c_cflag |= (CLOCAL | CREAD) ;
- options.c_cflag &= ~PARENB ;
- options.c_cflag &= ~CSTOPB ;
- options.c_cflag &= ~CSIZE ;
- options.c_cflag |= CS8 ;
- options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
- options.c_oflag &= ~OPOST ;
-
- options.c_cc [VMIN] = 0 ;
- options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
-
- tcsetattr (fd, TCSANOW, &options) ;
-
- ioctl (fd, TIOCMGET, &status);
-
- status |= TIOCM_DTR ;
- status |= TIOCM_RTS ;
-
- ioctl (fd, TIOCMSET, &status);
-
- usleep (10000) ; // 10mS
-
- return fd ;
- }
-
-
- /*
- * serialFlush:
- * Flush the serial buffers (both tx & rx)
- *********************************************************************************
- */
-
- void serialFlush (const int fd)
- {
- tcflush (fd, TCIOFLUSH) ;
- }
-
-
- /*
- * serialClose:
- * Release the serial port
- *********************************************************************************
- */
-
- void serialClose (const int fd)
- {
- close (fd) ;
- }
-
-
- /*
- * serialPutchar:
- * Send a single character to the serial port
- *********************************************************************************
- */
-
- void serialPutchar(const int fd, const unsigned char c)
- {
- ssize_t bytes_written = write(fd, &c, 1);
- if (bytes_written != 1) {
- perror("Error writing to file descriptor");
- }
- }
-
-
- /*
- * serialPuts:
- * Send a string to the serial port
- *********************************************************************************
- */
-
- void serialPuts(const int fd, const char *s)
- {
- size_t len = strlen(s);
- ssize_t bytes_written = write(fd, s, len);
- if (bytes_written != (ssize_t)len) {
- perror("Error writing to file descriptor");
- }
- }
-
- /*
- * serialPrintf:
- * Printf over Serial
- *********************************************************************************
- */
-
- void serialPrintf (const int fd, const char *message, ...)
- {
- va_list argp ;
- char buffer [1024] ;
-
- va_start (argp, message) ;
- vsnprintf (buffer, 1023, message, argp) ;
- va_end (argp) ;
-
- serialPuts (fd, buffer) ;
- }
-
-
- /*
- * serialDataAvail:
- * Return the number of bytes of data avalable to be read in the serial port
- *********************************************************************************
- */
-
- int serialDataAvail (const int fd)
- {
- int result ;
-
- if (ioctl (fd, FIONREAD, &result) == -1)
- return -1 ;
-
- return result ;
- }
-
-
- /*
- * serialGetchar:
- * Get a single character from the serial device.
- * Note: Zero is a valid character and this function will time-out after
- * 10 seconds.
- *********************************************************************************
- */
-
- int serialGetchar (const int fd)
- {
- uint8_t x ;
-
- if (read (fd, &x, 1) != 1)
- return -1 ;
-
- return ((int)x) & 0xFF ;
- }
|