Logo Search packages:      
Sourcecode: hamlib version File versions  Download package

int HAMLIB_API serial_setup ( hamlib_port_t rp  ) 

Set up Serial port according to requests in port.

Parameters:
rp 
Returns:
RIG_OK or < 0

Definition at line 129 of file serial.c.

References hamlib_port_t::fd, hamlib_port_t::parm, rig_debug(), RIG_DEBUG_ERR, RIG_ECONF, RIG_EINVAL, RIG_HANDSHAKE_HARDWARE, RIG_HANDSHAKE_NONE, RIG_HANDSHAKE_XONXOFF, RIG_OK, RIG_PARITY_EVEN, RIG_PARITY_NONE, RIG_PARITY_ODD, and hamlib_port_t::serial.

Referenced by serial_open().

{
  int fd;
  /* There's a lib replacement for termios under Mingw */
#if defined(HAVE_TERMIOS_H)
  speed_t speed;              /* serial comm speed */
  struct termios options;
#elif defined(HAVE_TERMIO_H)
  struct termio options;
#elif defined(HAVE_SGTTY_H)
  struct sgttyb sg;
#else
#error "No term control supported!"
#endif

  if (!rp)
              return -RIG_EINVAL;

  fd = rp->fd;

  /*
   * Get the current options for the port...
   */
  
#if defined(HAVE_TERMIOS_H)
  tcgetattr(fd, &options);
#elif defined(HAVE_TERMIO_H)
  IOCTL (fd, TCGETA, &options);
#else /* sgtty */
  IOCTL (fd, TIOCGETP, &sg);
#endif

#ifdef HAVE_CFMAKERAW
  cfmakeraw(&options); /* Set serial port to RAW mode by default. */
#endif

  /*
   * Set the baud rates to requested values
   */

  switch(rp->parm.serial.rate) {
  case 150:
      speed = B150;           /* yikes... */
    break;
  case 300:
      speed = B300;           /* yikes... */
    break;
  case 600:
        speed = B600;
    break;
  case 1200:
      speed = B1200;
    break;
  case 2400:
      speed = B2400;
    break;
  case 4800:
      speed = B4800;
    break;
  case 9600:
      speed = B9600;
    break;
  case 19200:
      speed = B19200;
    break;
  case 38400:
      speed = B38400;
    break;
  case 57600:
      speed = B57600;         /* cool.. */
    break;
  case 115200:
      speed = B115200;  /* awsome! */
    break;
  default:
    rig_debug(RIG_DEBUG_ERR, "open_serial: unsupported rate specified: %d\n", 
                              rp->parm.serial.rate);
      CLOSE(fd);
    return -RIG_ECONF;
  }
  /* TODO */
  cfsetispeed(&options, speed);
  cfsetospeed(&options, speed);

  /*
   * Enable the receiver and set local mode...
   */
  
  options.c_cflag |= (CLOCAL | CREAD);

/*
 * Set data to requested values.
 *
 */

  switch(rp->parm.serial.data_bits) {
  case 7:
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS7;
    break;
  case 8:
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    break;
  default:
    rig_debug(RIG_DEBUG_ERR,"open_serial: unsupported serial_data_bits "
                              "specified: %d\n", rp->parm.serial.data_bits);
      CLOSE(fd);
    return -RIG_ECONF;
    break;
  }

/*
 * Set stop bits to requested values.
 *
 */  

  switch(rp->parm.serial.stop_bits) {
  case 1:
    options.c_cflag &= ~CSTOPB;
    break;
  case 2:
    options.c_cflag |= CSTOPB;
    break;

  default:
    rig_debug(RIG_DEBUG_ERR, "open_serial: unsupported serial_stop_bits "
                              "specified: %d\n",
                              rp->parm.serial.stop_bits);
      CLOSE(fd);
    return -RIG_ECONF;
    break;
  }

/*
 * Set parity to requested values.
 *
 */  

  switch(rp->parm.serial.parity) {
  case RIG_PARITY_NONE:
    options.c_cflag &= ~PARENB;
    break;
  case RIG_PARITY_EVEN:
    options.c_cflag |= PARENB;
    options.c_cflag &= ~PARODD;
    break;
  case RIG_PARITY_ODD:
    options.c_cflag |= PARENB;
    options.c_cflag |= PARODD;
    break;
  default:
    rig_debug(RIG_DEBUG_ERR, "open_serial: unsupported serial_parity "
                              "specified: %d\n",
                              rp->parm.serial.parity);
      CLOSE(fd);
    return -RIG_ECONF;
    break;
  }


/*
 * Set flow control to requested mode
 *
 */  

  switch(rp->parm.serial.handshake) {
  case RIG_HANDSHAKE_NONE:
    options.c_cflag &= ~CRTSCTS;
    options.c_iflag &= ~IXON;
    break;
  case RIG_HANDSHAKE_XONXOFF:
    options.c_cflag &= ~CRTSCTS;
    options.c_iflag |= IXON;        /* Enable Xon/Xoff software handshaking */
    break;
  case RIG_HANDSHAKE_HARDWARE:
    options.c_cflag |= CRTSCTS;           /* Enable Hardware handshaking */
    options.c_iflag &= ~IXON;
    break;
  default:
    rig_debug(RIG_DEBUG_ERR, "open_serial: unsupported flow_control "
                              "specified: %d\n",
                              rp->parm.serial.handshake);
      CLOSE(fd);
    return -RIG_ECONF;
    break;
  }

  /*
   * Choose raw input, no preprocessing please ..
   */

#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

  /*
   * Choose raw output, no preprocessing please ..
   */

  options.c_oflag &= ~OPOST;

#else /* sgtty */
  sg.sg_flags = RAW;
#endif


  /*
   * Flush serial port
   */

  tcflush(fd, TCIFLUSH);

  /*
   * Finally, set the new options for the port...
   */
  
#if defined(HAVE_TERMIOS_H)
  if (tcsetattr(fd, TCSANOW, &options) == -1) {
            rig_debug(RIG_DEBUG_ERR, "open_serial: tcsetattr failed: %s\n", 
                              strerror(errno));
            CLOSE(fd);
            return -RIG_ECONF;            /* arg, so close! */
  }
#elif defined(HAVE_TERMIO_H)
  if (IOCTL(fd, TCSETA, &options) == -1) {
            rig_debug(RIG_DEBUG_ERR, "open_serial: ioctl(TCSETA) failed: %s\n", 
                              strerror(errno));
            CLOSE(fd);
            return -RIG_ECONF;            /* arg, so close! */
  }
#else /* sgtty */
  if (IOCTL(fd, TIOCSETP, &sg) == -1) {
            rig_debug(RIG_DEBUG_ERR, "open_serial: ioctl(TIOCSETP) failed: %s\n", 
                              strerror(errno));
            CLOSE(fd);
            return -RIG_ECONF;            /* arg, so close! */
  }
#endif

  return RIG_OK;
}


Generated by  Doxygen 1.6.0   Back to index