示例#1
0
static int ser_setspeed(union filedescriptor *fd, long baud)
{
  int rc;
  struct termios termios;
  speed_t speed = serial_baud_lookup (baud);
  
  if (!isatty(fd->ifd))
    return -ENOTTY;
  
  /*
   * initialize terminal modes
   */
  rc = tcgetattr(fd->ifd, &termios);
  if (rc < 0) {
    avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcgetattr() failed",
            progname);
    return -errno;
  }

  /*
   * copy termios for ser_close if we haven't already
   */
  if (! saved_original_termios++) {
    original_termios = termios;
  }

  termios.c_iflag = IGNBRK;
  termios.c_oflag = 0;
  termios.c_lflag = 0;
  termios.c_cflag = (CS8 | CREAD | CLOCAL);
  termios.c_cc[VMIN]  = 1;
  termios.c_cc[VTIME] = 0;

  cfsetospeed(&termios, speed);
  cfsetispeed(&termios, speed);

  rc = tcsetattr(fd->ifd, TCSANOW, &termios);
  if (rc < 0) {
    avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
            progname);
    return -errno;
  }

  /*
   * Everything is now set up for a local line without modem control
   * or flow control, so clear O_NONBLOCK again.
   */
  rc = fcntl(fd->ifd, F_GETFL, 0);
  if (rc != -1)
    fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);

  return 0;
}
示例#2
0
static int ser_setspeed(union filedescriptor *fd, long baud)
{
	DCB dcb;
	HANDLE hComPort = (HANDLE)fd->pfd;

	ZeroMemory (&dcb, sizeof(DCB));
	dcb.DCBlength = sizeof(DCB);
	dcb.BaudRate = serial_baud_lookup (baud);
	dcb.fBinary = 1;
	dcb.fDtrControl = DTR_CONTROL_DISABLE;
	dcb.fRtsControl = RTS_CONTROL_DISABLE;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;

	if (!SetCommState(hComPort, &dcb))
		return -1;

	return 0;
}
示例#3
0
static int ser_setspeed(union filedescriptor *fd, long baud)
{
  int rc;
  struct termios termios;
#if defined __linux__
  /* for linux no conversion is needed*/
  speed_t speed = baud;
#else
  /* converting the baud rate to the bit set needed by posix way*/
  speed_t speed = serial_baud_lookup (baud);
#endif
  
  if (!isatty(fd->ifd))
    return -ENOTTY;
  
  /*
   * initialize terminal modes
   */
  rc = tcgetattr(fd->ifd, &termios);
  if (rc < 0) {
    avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcgetattr() failed",
            progname);
    return -errno;
  }

  /*
   * copy termios for ser_close if we haven't already
   */
  if (! saved_original_termios++) {
    original_termios = termios;
  }

  termios.c_iflag = IGNBRK;
  termios.c_oflag = 0;
  termios.c_lflag = 0;
  termios.c_cflag = (CS8 | CREAD | CLOCAL);
  termios.c_cc[VMIN]  = 1;
  termios.c_cc[VTIME] = 0;
#ifdef __linux__
  /* Support for custom baud rate for linux is implemented by setting
   * a dummy baud rate of 38400 and manupulating the custom divider of
   * the serial interface*/
  struct serial_struct  ss;
  int ioret = ioctl(fd->ifd, TIOCGSERIAL, &ss);
  if (ioret < 0){
    avrdude_message(MSG_INFO,
		    "%s: Cannot get serial port settings. ioctl returned %d\n",
		    progname, ioret);
    return -errno;
  }
  ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
  ss.custom_divisor = (ss.baud_base + (speed / 2)) / speed;
  unsigned int closestSpeed = ss.baud_base / ss.custom_divisor;

  if (closestSpeed < speed * 98 / 100 || closestSpeed > speed * 102 / 100) {
    avrdude_message(MSG_INFO,
		    "%s: Cannot set serial port speed to %d. Closest possible is %d\n",
		    progname, speed, closestSpeed);
    return -errno;
  }
  ioret= ioctl(fd->ifd, TIOCSSERIAL, &ss);
  if (ioret < 0){
    avrdude_message(MSG_INFO,
		    "%s: Cannot set serial port speed to %d. ioctl returned %d\n",
		    progname, speed, ioret);
    return -errno;
  }
  if (cfsetispeed(&termios, B38400) < 0){
    avrdude_message(MSG_INFO,
		    "%s: cfsetispeed: failed to set dummy baud\n",
		    progname);
    return -errno;
  }
  if (cfsetospeed(&termios, B38400) < 0){
    avrdude_message(MSG_INFO,
		    "%s: cfsetospeed: failed to set dummy baud\n",
		    progname);
    return -errno;
  }
#else  /* !linux */
  if (cfsetospeed(&termios, speed) < 0){
    avrdude_message(MSG_INFO,
		    "%s: cfsetospeed: failed to set speed: %d\n",
		    progname, speed);
    return -errno;
  }
  if (cfsetispeed(&termios, speed) < 0){
    avrdude_message(MSG_INFO,
		    "%s: cfsetispeed: failed to set speed: %d\n",
		    progname, speed);
    return -errno;
  }
#endif	/* linux */
  rc = tcsetattr(fd->ifd, TCSANOW, &termios);
  if (rc < 0) {
    avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
            progname);
    return -errno;
  }
#ifdef __linux__
  /* a bit more linux specific stuff to set custom baud rates*/
  if (ioctl(fd->ifd, TIOCGSERIAL, &ss) < 0){
    avrdude_message(MSG_INFO, "%s: ioctl: failed to get port settins\n", progname);
    return -errno;
  }
  ss.flags &= ~ASYNC_SPD_MASK;
  if (ioctl(fd->ifd, TIOCSSERIAL, &ss) < 0){
    avrdude_message(MSG_INFO, "%s: ioctl: failed to set port settins\n", progname);
    return -errno;
  }
#endif

  /*
   * Everything is now set up for a local line without modem control
   * or flow control, so clear O_NONBLOCK again.
   */
  rc = fcntl(fd->ifd, F_GETFL, 0);
  if (rc != -1)
    fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);

  return 0;
}