GophHub - go4retro/tcpser/src/serial.c


Raw File

    1	#include <sys/file.h>
    2	#include <unistd.h>
    3	#include <termios.h>
    4	#include <stdio.h>
    5	#include <fcntl.h>
    6	#include <sys/ioctl.h>
    7	#include "dce.h"
    8	#include "debug.h"
    9	
   10	#include "serial.h"
   11	
   12	int ser_get_bps_const(int speed) {
   13	  int bps_rate = 0;
   14	
   15	  LOG_ENTER();
   16	  
   17	  LOG(LOG_DEBUG,"Checking speed: %d",speed);
   18	
   19	  switch (speed) {
   20	#if defined (B921600)
   21	    case 921600:
   22	      bps_rate = B921600;
   23	      break;
   24	#endif /* B921600 */
   25	#if defined (B460800)
   26	    case 460800:
   27	      bps_rate = B460800;
   28	      break;
   29	#endif /* B460800 */
   30	#if defined (B230400)
   31	    case 230400:
   32	      bps_rate = B230400;
   33	      break;
   34	#endif /* B230400 */
   35	#if defined (B115200)
   36	    case 115200:
   37	      bps_rate = B115200;
   38	      break;
   39	#endif /* B115200 */
   40	#if defined (B57600)
   41	    case 57600:
   42	      bps_rate = B57600;
   43	      break;
   44	#endif /* B57600 */
   45	#if defined (B38400)
   46	    case 38400:
   47	      bps_rate = B38400;
   48	      break;
   49	#endif /* B38400 */
   50	#if defined (B19200)
   51	    case 19200:
   52	      bps_rate = B19200;
   53	      break;
   54	#endif /* B19200 */
   55	#if defined (B9600)
   56	    case 9600:
   57	      bps_rate = B9600;
   58	      break;
   59	#endif /* B9600 */
   60	#if defined (B4800)
   61	    case 4800:
   62	      bps_rate = B4800;
   63	      break;
   64	#endif /* B4800 */
   65	#if defined (B2400)
   66	    case 2400:
   67	      bps_rate = B2400;
   68	      break;
   69	#endif /* B2400 */
   70	#if defined (B1200)
   71	    case 1200:
   72	      bps_rate = B1200;
   73	      break;
   74	#endif /* B1200 */
   75	#if defined (B600)
   76	    case 600:
   77	      bps_rate = B600;
   78	      break;
   79	#endif /* B600 */
   80	#if defined (B300)
   81	    case 300:
   82	      bps_rate = B300;
   83	      break;
   84	#endif /* B300 */
   85	#if defined (B150)
   86	    case 150:
   87	      bps_rate = B150;
   88	      break;
   89	#endif /* B150 */
   90	#if defined (B134)
   91	    case 134:
   92	      bps_rate = B134;
   93	      break;
   94	#endif /* B134 */
   95	#if defined (B110)
   96	    case 110:
   97	      bps_rate = B110;
   98	      break;
   99	#endif /* B110 */
  100	#if defined (B75)
  101	    case 75:
  102	      bps_rate = B75;
  103	      break;
  104	#endif /* B75 */
  105	#if defined (B50)
  106	    case 50:
  107	      bps_rate = B50;
  108	      break;
  109	#endif /* B50 */
  110	#if defined (B0)
  111	    case 0:
  112	      bps_rate = B0;
  113	      break;
  114	#endif /* B0 */
  115	    default:
  116	      ELOG(LOG_FATAL, "Unknown baud rate"); 
  117	      bps_rate = -1;
  118	  }
  119	  LOG_EXIT();
  120	  return bps_rate;
  121	
  122	}
  123	
  124	int ser_init_conn(char *tty, int speed) {
  125	  int fd = -1;
  126	  struct termios tio;
  127	  int bps_rate = 0;
  128	
  129	  LOG_ENTER();
  130	
  131	  bps_rate = ser_get_bps_const(speed);
  132	
  133	  if(bps_rate > -1) {
  134	    /* open the device to be non-blocking (read will return immediatly) */
  135	    LOG(LOG_INFO, "Opening serial device %s at speed %d", tty, speed);
  136	
  137	    fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK);
  138	
  139	    if (fd <0) {
  140	      ELOG(LOG_FATAL, "TTY %s could not be opened", tty); 
  141	    } else {
  142	      LOG(LOG_INFO, "Opened serial device %s at speed %d as fd %d", tty, speed, fd);
  143	
  144	      /* Make the file descriptor asynchronous (the manual page says only 
  145	         O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
  146	      fcntl(fd, F_SETFL, FASYNC);
  147	
  148	      if (0 != tcgetattr(fd, &tio)) {
  149	        ELOG(LOG_FATAL, "Could not get serial port attributes");
  150	        return -1;
  151	      }
  152	
  153	      // leave CRTSCTS off when building for Windows on Rapsberry Pi...
  154	      // https://github.com/driver1998/tcpser
  155	#ifdef WIN_RPI
  156	      tio.c_cflag = CS8 | CLOCAL | CREAD;
  157	#else
  158	      tio.c_cflag = CS8 | CLOCAL | CREAD | CRTSCTS;
  159	#endif
  160	      tio.c_iflag = IGNBRK;
  161	      tio.c_oflag = 0;
  162	      tio.c_lflag = 0;
  163	      cfsetispeed(&tio, bps_rate);
  164	      cfsetospeed(&tio, bps_rate);
  165	
  166	      tio.c_cc[VMIN] = 1;
  167	      tio.c_cc[VTIME] = 0;
  168	
  169	      tcflush(fd, TCIFLUSH);
  170	      tcsetattr(fd, TCSANOW, &tio);
  171	      LOG(LOG_INFO, "serial device configured");
  172	    }
  173	  }
  174	
  175	  LOG_EXIT();
  176	  return fd;
  177	}
  178	
  179	int ser_set_flow_control(int fd, int status) {
  180	  struct termios tio;
  181	  if(0 != tcgetattr(fd, &tio)) {
  182	    ELOG(LOG_FATAL, "Could not get serial port attributes");
  183	    return -1;
  184	  }
  185	  // turn all off.
  186	  tio.c_cflag &= ~(IXON | IXOFF | CRTSCTS);
  187	  tio.c_cflag |= status;
  188	  if(0 != tcsetattr(fd, TCSANOW, &tio)) {
  189	    ELOG(LOG_FATAL,"Could not set serial port attributes");
  190	    return -1;
  191	  }
  192	  return 0;
  193	}
  194	
  195	int ser_get_control_lines(int fd) {
  196	  int status;
  197	
  198	  if(0 > ioctl(fd, TIOCMGET, &status)) {
  199	    ELOG(LOG_FATAL, "Could not obtain serial port status");
  200	    return -1;
  201	  }
  202	
  203	  return (DCE_CL_LE           // RS232 link is always up.
  204	          | ((status & TIOCM_DSR) ? DCE_CL_DTR : 0)
  205	          //| ((status & TIOCM_CTS) ? DCE_CL_RTS : 0)
  206	         );
  207	}
  208	
  209	int ser_set_control_lines(int fd, int state) {
  210	  int status;
  211	
  212	  if(0 > ioctl(fd, TIOCMGET, &status)) {
  213	    ELOG(LOG_FATAL, "Could not obtain serial port status");
  214	    return -1;
  215	  }
  216	
  217	  status &= ~(TIOCM_DTR);
  218	  //status &= ~(TIOCM_RTS | TIOCM_DTR);
  219	  status |= (state & DCE_CL_DCD ? TIOCM_DTR : 0);
  220	  //status |= (state & DCE_CL_CTS ? TIOCM_RTS : 0);
  221	  if(0 > ioctl(fd, TIOCMSET, &status)) {
  222	    ELOG(LOG_WARN, "Could not set serial port status");
  223	  }
  224	  return 0;
  225	}
  226	
  227	int ser_write(int fd, unsigned char* data, int len) {
  228	  log_trace(TRACE_MODEM_OUT, data, len);
  229	  return write(fd, data, len);
  230	}
  231	
  232	int ser_read(int fd, unsigned char* data, int len) {
  233	  int res;
  234	
  235	  res = read(fd, data, len);
  236	  log_trace(TRACE_MODEM_IN, data, res);
  237	  return res;
  238	}
  239	

Generated by GNU Enscript 1.6.6, and GophHub 1.3.