/**
 * Initialize the driver.
 * Open com port and set baud correctly...
 * \param drvthis  Pointer to driver structure.
 * \retval 0       Success.
 * \retval <0      Error.
 */
MODULE_EXPORT int
lcterm_init (Driver *drvthis)
{
  char device[200];
  int speed=B9600;
  struct termios portset;
  PrivateData *p;

  debug(RPT_INFO, "LCTERM: init(%p)", drvthis);

  // Alocate and store private data
  p = (PrivateData *) calloc(1, sizeof(PrivateData));
  if (p == NULL)
    return -1;
  if (drvthis->store_private_ptr(drvthis, p))
    return -1;

  // initialize private data
  p->fd = -1;
  p->ccmode = p->last_ccmode = standard;

  // READ CONFIG FILE:
  // which serial device should be used
  strncpy(device, drvthis->config_get_string(drvthis->name , "Device" , 0 , DEFAULT_DEVICE),
	  sizeof(device));
  device[sizeof(device)-1] = '\0';
  report(RPT_INFO, "%s: using Device %s", drvthis->name, device);

  /* Get and parse size */
  {
    int w, h;
    const char *s = drvthis->config_get_string(drvthis->name, "Size", 0, "16x2");

    debug(RPT_DEBUG, "%s: reading size: %s", __FUNCTION__, s);

    if ((sscanf(s, "%dx%d", &w, &h) != 2)
	|| (w <= 0) || (w > LCD_MAX_WIDTH)
	|| (h <= 0) || (h > LCD_MAX_HEIGHT))
    {
      report(RPT_WARNING, "%s: cannot read Size: %s; using default %s",
		      drvthis->name, s, "16x2");
      sscanf("16x2", "%dx%d", &w, &h);
    }
    p->width  = w;
    p->height = h;
  }
  report(RPT_INFO, "%s: using Size: %dx%d", drvthis->name, p->width, p->height);

  p->framebuf = malloc(p->width * p->height);
  p->last_framebuf = malloc(p->width * p->height);
  if ((p->framebuf == NULL) || (p->last_framebuf == NULL)) {
    report(RPT_ERR, "%s: unable to create framebuffer", drvthis->name);
    return -1;
  }
  memset(p->framebuf, ' ', p->width * p->height);
  memset(p->last_framebuf, ' ', p->width * p->height);

  // Set up io port correctly, and open it...
  debug(RPT_DEBUG, "%s: Opening serial device: %s", drvthis->name, device);
  p->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
  if (p->fd == -1) {
    report(RPT_ERR, "%s: open(%) failed (%s)", drvthis->name, device, strerror(errno));
    if (errno == EACCES)
	report(RPT_ERR, "%s: make sure you have rw access to %s!", drvthis->name, device);
    return -1;
  }
  report(RPT_INFO, "%s: opened display on %s", drvthis->name, device);

  tcgetattr(p->fd, &portset);
#ifdef HAVE_CFMAKERAW
  /* The easy way: */
  cfmakeraw(&portset);
#else
  /* The hard way: */
  portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP
			| INLCR | IGNCR | ICRNL | IXON );
  portset.c_oflag &= ~OPOST;
  portset.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN );
  portset.c_cflag &= ~( CSIZE | PARENB | CRTSCTS );
  portset.c_cflag |= CS8 | CREAD | CLOCAL ;
#endif
  cfsetospeed(&portset, speed);
  cfsetispeed(&portset, speed);
  tcsetattr(p->fd, TCSANOW, &portset);
  tcflush(p->fd, TCIOFLUSH);

  // clear the display, disable cursor, disable key scanning
  write(p->fd, "\x1a\x16\x1bK", 4);

  report(RPT_DEBUG, "%s: init() done", drvthis->name);

  return 0;
}
示例#2
0
EIF_INTEGER posix_cfsetospeed(struct termios *ptr, EIF_INTEGER speed)
{
  return cfsetospeed(ptr, speed);
}
示例#3
0
static int serial_setup(serial_control_t *ctrl)
{
	/* just setup serial at debug level= 0, 1, 4, 
	    for debug level = 2, 3 is reserved for simulation test locally */
	if ((debug <2) || (debug >3)) {
		struct termios newtio, oldtio;

		/*
		 * Here we setup the standard input tty settings. We have to do it here,
		 * because we need to restore them when this application exits (so that the Linux
		 * shell continues to work as expected.)
		 * The tty settings of the external tty are set in the remote build.
		 */
		if (tcgetattr(ctrl->fd, &oldtio) != 0) {
			error_printf("tcgetattr failed: %s\n", strerror(errno));
			return EXIT_FAILURE;
		}

		memset(&newtio, 0, sizeof(newtio));
		memcpy(&newtio, &oldtio, sizeof(struct termios));

		if (ctrl->mode == RAW_MODE) {
			/* Set raw mode: the remote application will handle all terminal characters */
			cfmakeraw(&newtio);
		}

		switch (ctrl->bits) {
		case 7:
			newtio.c_cflag |= CS7;
			break;
		case 8:
			newtio.c_cflag |= CS8;
			break;
		}
		switch (ctrl->parity) {
		case 'O':
			newtio.c_cflag |= PARENB;
			newtio.c_cflag |= PARODD;
			newtio.c_iflag |= (INPCK | ISTRIP);
			break;
		case 'E':
			newtio.c_iflag |= (INPCK | ISTRIP);
			newtio.c_cflag |= PARENB;
			newtio.c_cflag &= ~PARODD;
			break;
		case 'N':
			newtio.c_cflag &= ~PARENB;
			break;
		}
		switch (ctrl->speed) {
		case 2400:
			cfsetispeed(&newtio, B2400);
			cfsetospeed(&newtio, B2400);
			break;
		case 4800:
			cfsetispeed(&newtio, B4800);
			cfsetospeed(&newtio, B4800);
			break;
		case 9600:
			cfsetispeed(&newtio, B9600);
			cfsetospeed(&newtio, B9600);
			break;
		case 115200:
			cfsetispeed(&newtio, B115200);
			cfsetospeed(&newtio, B115200);
			break;
		default:
			cfsetispeed(&newtio, B9600);
			cfsetospeed(&newtio, B9600);
			break;
		}

		if (ctrl->stop == 1)
			newtio.c_cflag &= ~CSTOPB;
		else if (ctrl->stop == 2)
			newtio.c_cflag |= CSTOPB;

		// important
		newtio.c_cflag |= CLOCAL | CREAD;
		newtio.c_cflag &= ~CSIZE;
		if (ctrl->mode == RAW_MODE) {
			newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
			newtio.c_oflag &= ~OPOST;
			newtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
		}

		newtio.c_cc[VTIME] = 0;
		newtio.c_cc[VMIN] = 0;

		tcflush(ctrl->fd, TCIFLUSH);

		if (tcsetattr(ctrl->fd, TCSANOW, &newtio) < 0) {
			error_printf("tcsetattr failed: %s\n", strerror(errno));
			return EXIT_FAILURE;
		}

		debug_printf("serial_control: setting has done!\n");
	}
	return EXIT_SUCCESS;
}
示例#4
0
void serialport_set_baudrate(unsigned int baudrate)
{
    switch(baudrate)
    {
        case 2400:
            cfsetispeed(&term,B2400);
            cfsetospeed(&term,B2400);
            break;
            
        case 4800:
            cfsetispeed(&term,B4800);
            cfsetospeed(&term,B4800);
            break;
            
        case 9600:
            cfsetispeed(&term,B9600);
            cfsetospeed(&term,B9600);
            break;
            
        case 19200:
            cfsetispeed(&term,B19200);
            cfsetospeed(&term,B19200);
            break;
            
        case 38400:
            cfsetispeed(&term,B38400);
            cfsetospeed(&term,B38400);
            break;
            
        case 57600:
            cfsetispeed(&term,B57600);
            cfsetospeed(&term,B57600);
            break;
            
        case 115200:
            cfsetispeed(&term,B115200);
            cfsetospeed(&term,B115200);
            break;
            
        case 230400:
            cfsetispeed(&term,B230400);
            cfsetospeed(&term,B230400);
            break;
#ifndef __APPLE__
        case 460800:
            cfsetispeed(&term,B460800);
            cfsetospeed(&term,B460800);
            break;
            
        case 921600:
            cfsetispeed(&term,B921600);
            cfsetospeed(&term,B921600);
            break;
#endif
        default:
            LOGWARN("serialport_set_baudrate: baud rate %d may not work", baudrate);
            cfsetispeed(&term,baudrate);
            cfsetospeed(&term,baudrate);
            break;
    }
}
示例#5
0
/* Sets up a serial port for RTU communications */
static int _modbus_rtu_connect(modbus_t *ctx)
{
#if defined(_WIN32)
    DCB dcb;
#else
    struct termios tios;
    speed_t speed;
    int flags;
#endif
    modbus_rtu_t *ctx_rtu = ctx->backend_data;

    if (ctx->debug) {
        printf("Opening %s at %d bauds (%c, %d, %d)\n",
               ctx_rtu->device, ctx_rtu->baud, ctx_rtu->parity,
               ctx_rtu->data_bit, ctx_rtu->stop_bit);
    }

#if defined(_WIN32)
    /* Some references here:
     * http://msdn.microsoft.com/en-us/library/aa450602.aspx
     */
    win32_ser_init(&ctx_rtu->w_ser);

    /* ctx_rtu->device should contain a string like "COMxx:" xx being a decimal
     * number */
    ctx_rtu->w_ser.fd = CreateFileA(ctx_rtu->device,
                                    GENERIC_READ | GENERIC_WRITE,
                                    0,
                                    NULL,
                                    OPEN_EXISTING,
                                    0,
                                    NULL);

    /* Error checking */
    if (ctx_rtu->w_ser.fd == INVALID_HANDLE_VALUE) {
        if (ctx->debug) {
            fprintf(stderr, "ERROR Can't open the device %s (LastError %d)\n",
                    ctx_rtu->device, (int)GetLastError());
        }
        return -1;
    }

    /* Save params */
    ctx_rtu->old_dcb.DCBlength = sizeof(DCB);
    if (!GetCommState(ctx_rtu->w_ser.fd, &ctx_rtu->old_dcb)) {
        if (ctx->debug) {
            fprintf(stderr, "ERROR Error getting configuration (LastError %d)\n",
                    (int)GetLastError());
        }
        CloseHandle(ctx_rtu->w_ser.fd);
        ctx_rtu->w_ser.fd = INVALID_HANDLE_VALUE;
        return -1;
    }

    /* Build new configuration (starting from current settings) */
    dcb = ctx_rtu->old_dcb;

    /* Speed setting */
    switch (ctx_rtu->baud) {
    case 110:
        dcb.BaudRate = CBR_110;
        break;
    case 300:
        dcb.BaudRate = CBR_300;
        break;
    case 600:
        dcb.BaudRate = CBR_600;
        break;
    case 1200:
        dcb.BaudRate = CBR_1200;
        break;
    case 2400:
        dcb.BaudRate = CBR_2400;
        break;
    case 4800:
        dcb.BaudRate = CBR_4800;
        break;
    case 9600:
        dcb.BaudRate = CBR_9600;
        break;
    case 14400:
        dcb.BaudRate = CBR_14400;
        break;
    case 19200:
        dcb.BaudRate = CBR_19200;
        break;
    case 38400:
        dcb.BaudRate = CBR_38400;
        break;
    case 57600:
        dcb.BaudRate = CBR_57600;
        break;
    case 115200:
        dcb.BaudRate = CBR_115200;
        break;
    case 230400:
        /* CBR_230400 - not defined */
        dcb.BaudRate = 230400;
        break;
    case 250000:
        dcb.BaudRate = 250000;
        break;
    case 460800:
        dcb.BaudRate = 460800;
        break;
    case 500000:
        dcb.BaudRate = 500000;
        break;
    case 921600:
        dcb.BaudRate = 921600;
        break;
    case 1000000:
        dcb.BaudRate = 1000000;
        break;
    default:
        dcb.BaudRate = CBR_9600;
        if (ctx->debug) {
            fprintf(stderr, "WARNING Unknown baud rate %d for %s (B9600 used)\n",
                    ctx_rtu->baud, ctx_rtu->device);
        }
    }

    /* Data bits */
    switch (ctx_rtu->data_bit) {
    case 5:
        dcb.ByteSize = 5;
        break;
    case 6:
        dcb.ByteSize = 6;
        break;
    case 7:
        dcb.ByteSize = 7;
        break;
    case 8:
    default:
        dcb.ByteSize = 8;
        break;
    }

    /* Stop bits */
    if (ctx_rtu->stop_bit == 1)
        dcb.StopBits = ONESTOPBIT;
    else /* 2 */
        dcb.StopBits = TWOSTOPBITS;

    /* Parity */
    if (ctx_rtu->parity == 'N') {
        dcb.Parity = NOPARITY;
        dcb.fParity = FALSE;
    } else if (ctx_rtu->parity == 'E') {
        dcb.Parity = EVENPARITY;
        dcb.fParity = TRUE;
    } else {
        /* odd */
        dcb.Parity = ODDPARITY;
        dcb.fParity = TRUE;
    }

    /* Hardware handshaking left as default settings retrieved */

    /* No software handshaking */
    dcb.fTXContinueOnXoff = TRUE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;

    /* Binary mode (it's the only supported on Windows anyway) */
    dcb.fBinary = TRUE;

    /* Don't want errors to be blocking */
    dcb.fAbortOnError = FALSE;

    /* Setup port */
    if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) {
        if (ctx->debug) {
            fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n",
                    (int)GetLastError());
        }
        CloseHandle(ctx_rtu->w_ser.fd);
        ctx_rtu->w_ser.fd = INVALID_HANDLE_VALUE;
        return -1;
    }
#else
    /* The O_NOCTTY flag tells UNIX that this program doesn't want
       to be the "controlling terminal" for that port. If you
       don't specify this then any input (such as keyboard abort
       signals and so forth) will affect your process

       Timeouts are ignored in canonical input mode or when the
       NDELAY option is set on the file via open or fcntl */
    flags = O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL;
#ifdef O_CLOEXEC
    flags |= O_CLOEXEC;
#endif

    ctx->s = open(ctx_rtu->device, flags);
    if (ctx->s == -1) {
        if (ctx->debug) {
            fprintf(stderr, "ERROR Can't open the device %s (%s)\n",
                    ctx_rtu->device, strerror(errno));
        }
        return -1;
    }

    /* Save */
    tcgetattr(ctx->s, &(ctx_rtu->old_tios));

    memset(&tios, 0, sizeof(struct termios));

    /* C_ISPEED     Input baud (new interface)
       C_OSPEED     Output baud (new interface)
    */
    switch (ctx_rtu->baud) {
    case 110:
        speed = B110;
        break;
    case 300:
        speed = B300;
        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;
#ifdef B57600
    case 57600:
        speed = B57600;
        break;
#endif
#ifdef B115200
    case 115200:
        speed = B115200;
        break;
#endif
#ifdef B230400
    case 230400:
        speed = B230400;
        break;
#endif
#ifdef B460800
    case 460800:
        speed = B460800;
        break;
#endif
#ifdef B500000
    case 500000:
        speed = B500000;
        break;
#endif
#ifdef B576000
    case 576000:
        speed = B576000;
        break;
#endif
#ifdef B921600
    case 921600:
        speed = B921600;
        break;
#endif
#ifdef B1000000
    case 1000000:
        speed = B1000000;
        break;
#endif
#ifdef B1152000
   case 1152000:
        speed = B1152000;
        break;
#endif
#ifdef B1500000
    case 1500000:
        speed = B1500000;
        break;
#endif
#ifdef B2500000
    case 2500000:
        speed = B2500000;
        break;
#endif
#ifdef B3000000
    case 3000000:
        speed = B3000000;
        break;
#endif
#ifdef B3500000
    case 3500000:
        speed = B3500000;
        break;
#endif
#ifdef B4000000
    case 4000000:
        speed = B4000000;
        break;
#endif
    default:
        speed = B9600;
        if (ctx->debug) {
            fprintf(stderr,
                    "WARNING Unknown baud rate %d for %s (B9600 used)\n",
                    ctx_rtu->baud, ctx_rtu->device);
        }
    }

    /* Set the baud rate */
    if ((cfsetispeed(&tios, speed) < 0) ||
        (cfsetospeed(&tios, speed) < 0)) {
        close(ctx->s);
        ctx->s = -1;
        return -1;
    }

    /* C_CFLAG      Control options
       CLOCAL       Local line - do not change "owner" of port
       CREAD        Enable receiver
    */
    tios.c_cflag |= (CREAD | CLOCAL);
    /* CSIZE, HUPCL, CRTSCTS (hardware flow control) */

    /* Set data bits (5, 6, 7, 8 bits)
       CSIZE        Bit mask for data bits
    */
    tios.c_cflag &= ~CSIZE;
    switch (ctx_rtu->data_bit) {
    case 5:
        tios.c_cflag |= CS5;
        break;
    case 6:
        tios.c_cflag |= CS6;
        break;
    case 7:
        tios.c_cflag |= CS7;
        break;
    case 8:
    default:
        tios.c_cflag |= CS8;
        break;
    }

    /* Stop bit (1 or 2) */
    if (ctx_rtu->stop_bit == 1)
        tios.c_cflag &=~ CSTOPB;
    else /* 2 */
        tios.c_cflag |= CSTOPB;

    /* PARENB       Enable parity bit
       PARODD       Use odd parity instead of even */
    if (ctx_rtu->parity == 'N') {
        /* None */
        tios.c_cflag &=~ PARENB;
    } else if (ctx_rtu->parity == 'E') {
        /* Even */
        tios.c_cflag |= PARENB;
        tios.c_cflag &=~ PARODD;
    } else {
        /* Odd */
        tios.c_cflag |= PARENB;
        tios.c_cflag |= PARODD;
    }

    /* Read the man page of termios if you need more information. */

    /* This field isn't used on POSIX systems
       tios.c_line = 0;
    */

    /* C_LFLAG      Line options

       ISIG Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT signals
       ICANON       Enable canonical input (else raw)
       XCASE        Map uppercase \lowercase (obsolete)
       ECHO Enable echoing of input characters
       ECHOE        Echo erase character as BS-SP-BS
       ECHOK        Echo NL after kill character
       ECHONL       Echo NL
       NOFLSH       Disable flushing of input buffers after
       interrupt or quit characters
       IEXTEN       Enable extended functions
       ECHOCTL      Echo control characters as ^char and delete as ~?
       ECHOPRT      Echo erased character as character erased
       ECHOKE       BS-SP-BS entire line on line kill
       FLUSHO       Output being flushed
       PENDIN       Retype pending input at next read or input char
       TOSTOP       Send SIGTTOU for background output

       Canonical input is line-oriented. Input characters are put
       into a buffer which can be edited interactively by the user
       until a CR (carriage return) or LF (line feed) character is
       received.

       Raw input is unprocessed. Input characters are passed
       through exactly as they are received, when they are
       received. Generally you'll deselect the ICANON, ECHO,
       ECHOE, and ISIG options when using raw input
    */

    /* Raw input */
    tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    /* C_IFLAG      Input options

       Constant     Description
       INPCK        Enable parity check
       IGNPAR       Ignore parity errors
       PARMRK       Mark parity errors
       ISTRIP       Strip parity bits
       IXON Enable software flow control (outgoing)
       IXOFF        Enable software flow control (incoming)
       IXANY        Allow any character to start flow again
       IGNBRK       Ignore break condition
       BRKINT       Send a SIGINT when a break condition is detected
       INLCR        Map NL to CR
       IGNCR        Ignore CR
       ICRNL        Map CR to NL
       IUCLC        Map uppercase to lowercase
       IMAXBEL      Echo BEL on input line too long
    */
    if (ctx_rtu->parity == 'N') {
        /* None */
        tios.c_iflag &= ~INPCK;
    } else {
        tios.c_iflag |= INPCK;
    }

    /* Software flow control is disabled */
    tios.c_iflag &= ~(IXON | IXOFF | IXANY);

    /* C_OFLAG      Output options
       OPOST        Postprocess output (not set = raw output)
       ONLCR        Map NL to CR-NL

       ONCLR ant others needs OPOST to be enabled
    */

    /* Raw ouput */
    tios.c_oflag &=~ OPOST;

    /* C_CC         Control characters
       VMIN         Minimum number of characters to read
       VTIME        Time to wait for data (tenths of seconds)

       UNIX serial interface drivers provide the ability to
       specify character and packet timeouts. Two elements of the
       c_cc array are used for timeouts: VMIN and VTIME. Timeouts
       are ignored in canonical input mode or when the NDELAY
       option is set on the file via open or fcntl.

       VMIN specifies the minimum number of characters to read. If
       it is set to 0, then the VTIME value specifies the time to
       wait for every character read. Note that this does not mean
       that a read call for N bytes will wait for N characters to
       come in. Rather, the timeout will apply to the first
       character and the read call will return the number of
       characters immediately available (up to the number you
       request).

       If VMIN is non-zero, VTIME specifies the time to wait for
       the first character read. If a character is read within the
       time given, any read will block (wait) until all VMIN
       characters are read. That is, once the first character is
       read, the serial interface driver expects to receive an
       entire packet of characters (VMIN bytes total). If no
       character is read within the time allowed, then the call to
       read returns 0. This method allows you to tell the serial
       driver you need exactly N bytes and any read call will
       return 0 or N bytes. However, the timeout only applies to
       the first character read, so if for some reason the driver
       misses one character inside the N byte packet then the read
       call could block forever waiting for additional input
       characters.

       VTIME specifies the amount of time to wait for incoming
       characters in tenths of seconds. If VTIME is set to 0 (the
       default), reads will block (wait) indefinitely unless the
       NDELAY option is set on the port with open or fcntl.
    */
    /* Unused because we use open with the NDELAY option */
    tios.c_cc[VMIN] = 0;
    tios.c_cc[VTIME] = 0;

    if (tcsetattr(ctx->s, TCSANOW, &tios) < 0) {
        close(ctx->s);
        ctx->s = -1;
        return -1;
    }
#endif

    return 0;
}
bool RawChannel::Open()
{
	#ifndef WIN32
		sp = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
		fcntl(sp, F_SETFL, 0);
		//fcntl(sp, F_SETFL, FNDELAY);
		if(sp < 0)
		{
			printf("RawChannel::Open: open(): %s: %d: %s\n", port, errno,  strerror(errno));
			return false;
		}
		if(tcgetattr(sp, &tty) != 0)
		{
			printf("RawChannel::Open: Tcgetattr: %d: %s\n", errno, strerror(errno));
			return false;
		}
		cfsetospeed(&tty, baud_rate);
		cfsetispeed(&tty, baud_rate);
		
		tty.c_oflag &= ~(OCRNL | ONLCR | ONLRET | ONOCR | OFILL | OPOST);

		tty.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
		tty.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK| INPCK| ISTRIP | IXON| IXOFF | IXANY);
		
		tty.c_cflag &= ~(PARENB | CSIZE);
		tty.c_cflag |= CS8;
		
		tty.c_cc[VMIN] = 0;
		tty.c_cc[VTIME] =50;
		if(tcsetattr(sp, TCSANOW, &tty) !=0)
		{
			printf("RawChannel::Open: tcsetattr: %d: %s\n", errno, strerror(errno));
			return false;
		}
		printf("RawChannel::Open: %s opened\n", port);
	#else
		hComm = ::CreateFile(port, GENERIC_READ|GENERIC_WRITE, 0,NULL,OPEN_EXISTING, 0, NULL);
		if(hComm == INVALID_HANDLE_VALUE)
		{
			printf("Error opening serial port: %s\n", port);
			return false;
		}
		if(!::GetCommState(hComm, &dcb))
		{
			printf("Could not setup comm port: %s\n", port);
			return false;
		}
		dcb.BaudRate = CBR_57600;
		dcb.ByteSize = 8;
		dcb.Parity = NOPARITY;
		dcb.fRtsControl = ONESTOPBIT;
		//dcb.EofChar = '\r';
		if(!::SetCommState(hComm, &dcb))
		{
			printf("Could not setup comm port: %s\n", port);
			return false;
		}
		COMMTIMEOUTS cto;
		cto.ReadIntervalTimeout = 100000;
		cto.ReadTotalTimeoutConstant = 100;
		cto.ReadTotalTimeoutMultiplier = 256;
		cto.WriteTotalTimeoutConstant = 0;
		cto.WriteTotalTimeoutMultiplier = 0;
		::SetCommTimeouts(hComm, &cto);
		return true;
	#endif
		return true;
}
示例#7
0
ASerial::ASerial(std::string serialport, int baudrate) throw (std::string){
    std::string exc;
    this->error = 0;
    this->serialport = serialport;
    this->baudrate = baudrate;
    this->fd = open(this->serialport.c_str(), O_RDWR | O_NONBLOCK);
    if(this->fd == -1){
        this->error = 1;
        exc = "ASerial: Could not open serialport: " + serialport + ".";
        throw exc;
    }
    if (tcgetattr(fd, &this->toptions) < 0){
        this->error = 2;
        exc = "ASerial: Could not get term attributes.";
        throw exc;
    }
    speed_t brate = this->baudrate; // let you override switch below if needed
    switch(baudrate) {
        case 4800:
            brate=B4800;
            break;
        case 9600:
            brate=B9600;
            break;
#ifdef B14400
        case 14400:
            brate=B14400;
            break;
#endif
        case 19200:
            brate=B19200;
            break;
#ifdef B28800
        case 28800:
            brate=B28800;
            break;
#endif
        case 38400:
            brate=B38400;
            break;
        case 57600:
            brate=B57600;
            break;
        case 115200:
            brate=B115200;
            break;
#ifdef B230400
        case 230400:
            brate = B230400;
            break;
#endif
    }
    cfsetispeed(&this->toptions, brate);
    cfsetospeed(&this->toptions, brate);
    // 8N1
    toptions.c_cflag &= ~PARENB;
    toptions.c_cflag &= ~CSTOPB;
    toptions.c_cflag &= ~CSIZE;
    toptions.c_cflag |= CS8;
    // no flow control
    toptions.c_cflag &= ~CRTSCTS;
    toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
    toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
    
    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
    toptions.c_oflag &= ~OPOST; // make raw
    toptions.c_cc[VMIN]  = 0;
    toptions.c_cc[VTIME] = 0;
    tcsetattr(fd, TCSANOW, &this->toptions);
    if(tcsetattr(fd, TCSAFLUSH, &this->toptions) < 0){
        this->error = 3;
        exc = "ASerial: Couldn't set term attributes.";
        throw exc;
    }
}
示例#8
0
COMMNG
cmserial_create(UINT port, BYTE param, UINT32 speed)
{
	static const int cmserial_cflag[10] = {
		B110, B300, B1200, B2400, B4800,
		B9600, B19200, B38400, B57600, B115200
	};
	static const int csize[] = { CS5, CS6, CS7, CS8 };
	struct termios options, origopt;
	COMMNG ret;
	CMSER serial;
	int hdl;
	UINT i;

	VERBOSE(("cmserial_create: port = %d, param = %02x, speed = %d", port, param, speed));

	if (port == 0 || port > MAX_SERIAL_PORT_NUM) {
		VERBOSE(("cmserial_create: port is invalid"));
		goto cscre_failure;
	}

	port--;
	if (np2oscfg.com[port].mout[0] == '\0') {
		VERBOSE(("cmserial_create: com device file is disable"));
		goto cscre_failure;
	}

	hdl = open(np2oscfg.com[port].mout, O_RDWR | O_NOCTTY | O_NDELAY);
	if (hdl == -1) {
		VERBOSE(("cmserial_create: open failure %s, %s", np2oscfg.com[port].mout, strerror(errno)));
		goto cscre_failure;
	}

	if (!isatty(hdl)) {
		VERBOSE(("cmserial_create: not terminal file descriptor (%s)", strerror(errno)));
		goto cscre_close;
	}

	/* get current options for the port */
	tcgetattr(hdl, &options);
	origopt = options;

	/* baud rates */
	for (i = 0; i < NELEMENTS(cmserial_speed); i++) {
		if (cmserial_speed[i] >= speed) {
			VERBOSE(("cmserial_create: spped = %d", cmserial_speed[i]));
			break;
		}
	}
	if (i >= NELEMENTS(cmserial_speed)) {
		VERBOSE(("cmserial_create: speed is invaild"));
		goto cscre_close;
	}
	cfsetispeed(&options, cmserial_cflag[i]);
	cfsetospeed(&options, cmserial_cflag[i]);

	/* character size bits */
	options.c_cflag &= ~CSIZE;
	options.c_cflag |= csize[(param >> 2) & 3];
	VERBOSE(("cmserial_create: charactor size = %d", csize[(param >> 2) & 3]));

	/* parity check */
	switch (param & 0x30) {
	case 0x10:
		VERBOSE(("cmserial_create: odd parity"));
		options.c_cflag |= PARENB | PARODD;
		options.c_iflag |= INPCK | ISTRIP;
		break;

	case 0x30:
		VERBOSE(("cmserial_create: even parity"));
		options.c_cflag |= PARENB;
		options.c_cflag &= ~PARODD;
		options.c_iflag |= INPCK | ISTRIP;
		break;

	default:
		VERBOSE(("cmserial_create: non parity"));
		options.c_cflag &= ~PARENB;
		options.c_iflag &= ~(INPCK | ISTRIP);
		break;
	}

	/* stop bits */
	switch (param & 0xc0) {
	case 0x80:
		VERBOSE(("cmserial_create: stop bits: 1.5"));
		break;

	case 0xc0:
		VERBOSE(("cmserial_create: stop bits: 2"));
		options.c_cflag |= CSTOPB;
		break;

	default:
		VERBOSE(("cmserial_create: stop bits: 1"));
		options.c_cflag &= ~CSTOPB;
		break;
	}

	/* set misc flag */
	cfmakeraw(&options);
	options.c_cflag |= CLOCAL | CREAD;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

#if defined(SERIAL_DEBUG)
	print_status(&options);
#endif

	ret = (COMMNG)_MALLOC(sizeof(_COMMNG) + sizeof(_CMSER), "SERIAL");
	if (ret == NULL) {
		VERBOSE(("cmserial_create: memory alloc failure"));
		goto cscre_close;
	}

	/* set the new options for the port */
	tcsetattr(hdl, TCSANOW, &options);

#if 1
	ret->connect = COMCONNECT_MIDI;
#else
	ret->connect = COMCONNECT_SERIAL;
#endif
	ret->read = serialread;
	ret->write = serialwrite;
	ret->getstat = serialgetstat;
	ret->msg = serialmsg;
	ret->release = serialrelease;
	serial = (CMSER)(ret + 1);
	serial->hdl = hdl;
	serial->tio = origopt;
	return ret;

cscre_close:
	close(hdl);
cscre_failure:
	return NULL;
}
示例#9
0
int serialOpen (char *device, 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 ;

    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 | TCSAFLUSH, &options) ;

  ioctl (fd, TIOCMGET, &status);

  status |= TIOCM_DTR ;
  status |= TIOCM_RTS ;

  ioctl (fd, TIOCMSET, &status);

  usleep (10000) ;	// 10mS

  return fd ;
}
示例#10
0
int csr_open_bcsp(char *device)
{
	struct termios ti;
	uint8_t delay, activity = 0x00;
	int timeout = 0;

	if (!device)
		device = "/dev/ttyS0";

	fd = open(device, O_RDWR | O_NOCTTY);
	if (fd < 0) {
		fprintf(stderr, "Can't open serial port: %s (%d)\n",
						strerror(errno), errno);
		return -1;
	}

	tcflush(fd, TCIOFLUSH);

	if (tcgetattr(fd, &ti) < 0) {
		fprintf(stderr, "Can't get port settings: %s (%d)\n",
						strerror(errno), errno);
		close(fd);
		return -1;
	}

	cfmakeraw(&ti);

	ti.c_cflag |=  CLOCAL;
	ti.c_cflag &= ~CRTSCTS;
	ti.c_cflag |=  PARENB;
	ti.c_cflag &= ~PARODD;
	ti.c_cflag &= ~CSIZE;
	ti.c_cflag |=  CS8;
	ti.c_cflag &= ~CSTOPB;

	ti.c_cc[VMIN] = 1;
	ti.c_cc[VTIME] = 0;

	cfsetospeed(&ti, B38400);

	if (tcsetattr(fd, TCSANOW, &ti) < 0) {
		fprintf(stderr, "Can't change port settings: %s (%d)\n",
						strerror(errno), errno);
		close(fd);
		return -1;
	}

	tcflush(fd, TCIOFLUSH);

	if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0) {
		fprintf(stderr, "Can't set non blocking mode: %s (%d)\n",
						strerror(errno), errno);
		close(fd);
		return -1;
	}

	memset(&send_packet, 0, sizeof(send_packet));
	memset(&receive_packet, 0, sizeof(receive_packet));

	ubcsp_initialize();

	send_packet.length = 512;
	send_packet.payload = send_buffer;

	receive_packet.length = 512;
	receive_packet.payload = receive_buffer;

	ubcsp_receive_packet(&receive_packet);

	while (1) {
		delay = ubcsp_poll(&activity);

		if (activity & UBCSP_PACKET_RECEIVED)
			break;

		if (delay) {
			usleep(delay * 100);

			if (timeout++ > 5000) {
				fprintf(stderr, "Initialization timed out\n");
				return -1;
			}
		}
	}

	return 0;
}
示例#11
0
文件: ComDev.cpp 项目: huoyan108/SMS
int CComDev::set_opt(int nSpeed, int nBits, char nEvent, int nStop)
{

	struct termios newtio, oldtio;

	/*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/
	if (tcgetattr(m_nFd, &oldtio) != 0) {
		perror("SetupSerial 1");
		return FALSE;
	}

	bzero(&newtio, sizeof(newtio));
	/*步骤一,设置字符大小*/

	newtio.c_cflag |= CLOCAL | CREAD;
	newtio.c_cflag &= ~CSIZE;

	/*设置停止位*/
	switch (nBits)
	{
	case 7:
		newtio.c_cflag |= CS7;
		break;
	case 8:
		newtio.c_cflag |= CS8;
		break;
	}

	/*设置奇偶校验位*/
	switch (nEvent)
	{
	case 'O': //奇数
		newtio.c_cflag |= PARENB;
		newtio.c_cflag |= PARODD;
		newtio.c_iflag |= (INPCK | ISTRIP);
		break;
	case 'E': //偶数
		newtio.c_iflag |= (INPCK | ISTRIP);
		newtio.c_cflag |= PARENB;
		newtio.c_cflag &= ~PARODD;
		break;
	case 'N':  //无奇偶校验位
		newtio.c_cflag &= ~PARENB;
		break;
	}

	/*设置波特率*/
	switch (nSpeed)
	{
	case 2400:
		cfsetispeed(&newtio, B2400);
		cfsetospeed(&newtio, B2400);
		break;
	case 4800:
		cfsetispeed(&newtio, B4800);
		cfsetospeed(&newtio, B4800);
		break;
	case 9600:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
		break;
	case 115200:
		cfsetispeed(&newtio, B115200);
		cfsetospeed(&newtio, B115200);
		break;
	case 460800:
		cfsetispeed(&newtio, B460800);
		cfsetospeed(&newtio, B460800);
		break;
	default:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
		break;
	}

	/*设置停止位*/
	if (nStop == 1)
		newtio.c_cflag &= ~CSTOPB;
	else if (nStop == 2)
		newtio.c_cflag |= CSTOPB;

	/*设置等待时间和最小接收字符*/
	newtio.c_cc[VTIME] = 0;
	newtio.c_cc[VMIN] = 0;

	/*处理未接收字符*/
	tcflush(m_nFd, TCIFLUSH);

	/*激活新配置*/
	if ((tcsetattr(m_nFd, TCSANOW, &newtio)) != 0)
	{
		perror("Com set error");
		return FALSE;
	}

	printf("Com set done!\n");
	return TRUE;
}
示例#12
0
/*
 * Arguments: fd_udata, [options ...:
 *	reset (string: "reset"),
 *	baud_rate (number),
 *	character_size (string: "cs5".."cs8"),
 *	parity (string: "parno", "parodd", "pareven"),
 *	stop_bits (string: "sb1", "sb2"),
 *	flow_controls (string: "foff", "frtscts", "fxio")]
 * Returns: [fd_udata]
 */
static int
comm_init (lua_State *L)
{
  const fd_t fd = (fd_t) lua_unboxinteger(L, 1, FD_TYPENAME);
  const int narg = lua_gettop(L);
  int i;

#ifndef _WIN32
  struct termios tio;

  if (tcgetattr(fd, &tio) == -1) goto err;
#else
  DCB dcb;

  dcb.DCBlength = sizeof(DCB);
  if (!GetCommState(fd, &dcb)) goto err;
#endif

  for (i = 2; i <= narg; ++i) {
#ifndef _WIN32
    tcflag_t mask = 0, flag = 0;
#endif

    if (lua_isnumber(L, i)) {
      const int baud_rate = lua_tointeger(L, i);
#ifndef _WIN32
      switch (baud_rate) {
      case 9600: flag = B9600; break;
      case 19200: flag = B19200; break;
      case 38400: flag = B38400; break;
      case 57600: flag = B57600; break;
      case 115200: flag = B115200; break;
      }
      if (cfsetispeed(&tio, flag) == -1
       || cfsetospeed(&tio, flag) == -1)
        goto err;
#else
      dcb.BaudRate = baud_rate;
#endif
    } else {
      const char *opt = lua_tostring(L, i);
      const char *endp = opt + lua_rawlen(L, i) - 1;

      if (!opt) continue;
      switch (*opt) {
      case 'r':  /* reset */
#ifndef _WIN32
        memset(&tio, 0, sizeof(struct termios));
#else
        memset(&dcb, 0, sizeof(DCB));
#endif
        continue;
      case 'c':  /* character size */
#ifndef _WIN32
        switch (*endp) {
        case '5': flag = CS5; break;
        case '6': flag = CS6; break;
        case '7': flag = CS7; break;
        default: flag = CS8;
        }
        mask = CSIZE;
#else
        dcb.ByteSize = (char) (*endp - '0');
#endif
        break;
      case 'p':  /* parity */
#ifndef _WIN32
        switch (*endp) {
        case 'd': flag = PARODD;
        case 'n': flag |= PARENB; break;
        default: flag = 0;  /* no parity */
        }
        mask = PARENB | PARODD;
#else
        {
          int parity;
          switch (*endp) {
          case 'd': parity = ODDPARITY; break;
          case 'n': parity = EVENPARITY; break;
          default: parity = 0;  /* no parity */
          }
          dcb.Parity = (char) parity;
          dcb.fParity = (parity != 0);
        }
#endif
        break;
      case 's':  /* stop bits */
#ifndef _WIN32
        if (*endp == '2') flag = CSTOPB;  /* else: one stop bit */
        mask = CSTOPB;
#else
        dcb.StopBits = (char) (*endp == '2' ? TWOSTOPBITS
         : ONESTOPBIT);
#endif
        break;
      case 'f':  /* flow controls */
        /* off */
#ifndef _WIN32
        mask = CRTSCTS;
        tio.c_iflag &= ~(IXON | IXOFF | IXANY);
#else
        dcb.fOutX = dcb.fInX = 0;
        dcb.fRtsControl = RTS_CONTROL_DISABLE;
        dcb.fOutxCtsFlow = 0;
#endif
        switch (opt[1]) {
        case 'x':  /* XON/XOFF */
#ifndef _WIN32
          tio.c_iflag |= (IXON | IXOFF | IXANY);
#else
          dcb.fOutX = dcb.fInX = 1;
#endif
          break;
        case 'r':  /* RTS/CTS */
#ifndef _WIN32
          flag = CRTSCTS;
#else
          dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
          dcb.fOutxCtsFlow = 1;
#endif
          break;
        }
        break;
      }
    }
#ifndef _WIN32
    tio.c_cflag &= ~mask;
    tio.c_cflag |= flag;
#endif
  }
#ifndef _WIN32
  tio.c_cflag |= CLOCAL | CREAD;

  if (!tcsetattr(fd, TCSANOW, &tio)) {
#else
  if (SetCommState(fd, &dcb)) {
#endif
    lua_settop(L, 1);
    return 1;
  }
 err:
  return sys_seterror(L, 0);
}

/*
 * Arguments: fd_udata, [controls (string: "dtr", "dsr", "rts", "cts") ...]
 * Returns: [fd_udata]
 */
static int
comm_control (lua_State *L)
{
  const fd_t fd = (fd_t) lua_unboxinteger(L, 1, FD_TYPENAME);
  const int narg = lua_gettop(L);
  int i;

#ifndef _WIN32
  int flags;

  if (ioctl(fd, TIOCMGET, &flags) == -1) goto err;
  flags &= ~(TIOCM_DTR | TIOCM_DSR | TIOCM_RTS | TIOCM_CTS
   | TIOCM_ST | TIOCM_SR | TIOCM_CAR | TIOCM_RNG);
#else
  DCB dcb;

  dcb.DCBlength = sizeof(DCB);
  if (!GetCommState(fd, &dcb)) goto err;
  dcb.fDtrControl = dcb.fOutxDsrFlow
   = dcb.fRtsControl = dcb.fOutxCtsFlow = 0;
#endif

  for (i = 2; i <= narg; ++i) {
    const char *s = lua_tostring(L, i);

    if (!s) continue;
    switch (*s) {
    case 'd':  /* DTR/DSR */
#ifndef _WIN32
      flags |= (s[1] == 't') ? TIOCM_DTR : TIOCM_DSR;
#else
      if (s[1] == 't') dcb.fDtrControl = 1;
      else dcb.fOutxDsrFlow = 1;
#endif
      break;
    case 'r':  /* RTS */
#ifndef _WIN32
      flags |= TIOCM_RTS;
#else
      dcb.fRtsControl = 1;
#endif
      break;
    case 'c':  /* CTS */
#ifndef _WIN32
      flags |= TIOCM_CTS;
#else
      dcb.fOutxCtsFlow = 1;
#endif
      break;
    }
  }
#ifndef _WIN32
  if (!ioctl(fd, TIOCMSET, &flags)) {
#else
  if (SetCommState(fd, &dcb)) {
#endif
    lua_settop(L, 1);
    return 1;
  }
 err:
  return sys_seterror(L, 0);
}

/*
 * Arguments: fd_udata, [read_timeout (milliseconds)]
 * Returns: [fd_udata]
 */
static int
comm_timeout (lua_State *L)
{
  const fd_t fd = (fd_t) lua_unboxinteger(L, 1, FD_TYPENAME);
  const int rtime = lua_tointeger(L, 2);

#ifndef _WIN32
  struct termios tio;

  if (tcgetattr(fd, &tio) == -1) goto err;
  tio.c_cc[VTIME] = rtime / 100;
  tio.c_cc[VMIN] = 0;

  if (!tcsetattr(fd, TCSANOW, &tio)) {
#else
  COMMTIMEOUTS timeouts;

  memset(&timeouts, 0, sizeof(COMMTIMEOUTS));
  timeouts.ReadIntervalTimeout = rtime ? (DWORD) rtime : MAXDWORD;
  timeouts.ReadTotalTimeoutMultiplier =
   timeouts.ReadTotalTimeoutConstant = rtime;

  if (SetCommTimeouts(fd, &timeouts)) {
#endif
    lua_settop(L, 1);
    return 1;
  }
#ifndef _WIN32
 err:
#endif
  return sys_seterror(L, 0);
}

/*
 * Arguments: fd_udata, in_buffer_size (number), out_buffer_size (number)
 * Returns: [fd_udata]
 */
static int
comm_queues (lua_State *L)
{
#ifndef _WIN32
  if (1) {
#else
  const fd_t fd = (fd_t) lua_unboxinteger(L, 1, FD_TYPENAME);
  const int rqueue = lua_tointeger(L, 2);
  const int wqueue = lua_tointeger(L, 3);

  if (SetupComm(fd, rqueue, wqueue)) {
#endif
    lua_settop(L, 1);
    return 1;
  }
#ifdef _WIN32
  return sys_seterror(L, 0);
#endif
}

/*
 * Arguments: fd_udata, [mode (string: "rw", "r", "w")]
 * Returns: [fd_udata]
 */
static int
comm_purge (lua_State *L)
{
  const fd_t fd = (fd_t) lua_unboxinteger(L, 1, FD_TYPENAME);
  const char *mode = lua_tostring(L, 2);
  int flags;

  flags = TCIOFLUSH;
  if (mode)
    switch (mode[0]) {
    case 'w': flags = TCOFLUSH; break;
    case 'r': if (!mode[1]) flags = TCIFLUSH;
    }
#ifndef _WIN32
  if (!tcflush(fd, flags)) {
#else
  if (PurgeComm(fd, flags)) {
#endif
    lua_settop(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}

/*
 * Arguments: fd_udata, options (string: "car", "cts", "dsr", "ring") ...
 * Returns: [boolean ...]
 */
static int
comm_wait (lua_State *L)
{
  const fd_t fd = (fd_t) lua_unboxinteger(L, 1, FD_TYPENAME);
  const int narg = lua_gettop(L);
  unsigned long status = 0;
  int flags = 0;
  int i, res;

  for (i = 2; i <= narg; ++i) {
    const char *s = lua_tostring(L, i);

    if (!s) continue;
    switch (*s) {
    case 'c':  /* CAR/CTS */
      flags |= (s[1] == 'a') ? TIOCM_CAR : TIOCM_CTS;
      break;
    case 'd':  /* DSR */
      flags |= TIOCM_DSR;
      break;
    case 'r':  /* RING */
      flags |= TIOCM_RNG;
      break;
    }
  }

  sys_vm_leave();
#ifndef _WIN32
  do {
#ifdef TIOCMIWAIT
    res = !(ioctl(fd, TIOCMIWAIT, flags) || ioctl(fd, TIOCMGET, &status));
#else
    while ((res = !ioctl(fd, TIOCMGET, &status)) && !(status & flags))
      usleep(10000);  /* 10 msec polling */
#endif
  } while (!res && sys_eintr());
#else
  res = SetCommMask(fd, flags) && WaitCommEvent(fd, &status, NULL);
#endif
  sys_vm_enter();

  if (res) {
    if (flags & TIOCM_CAR)
      lua_pushboolean(L, status & TIOCM_CAR);
    if (flags & TIOCM_CTS)
      lua_pushboolean(L, status & TIOCM_CTS);
    if (flags & TIOCM_DSR)
      lua_pushboolean(L, status & TIOCM_DSR);
    if (flags & TIOCM_RNG)
      lua_pushboolean(L, status & TIOCM_RNG);
    return narg - 1;
  }
  return sys_seterror(L, 0);
}
示例#13
0
/*
 * Decodes terminal modes for the terminal referenced by fd in a portable
 * manner from a packet being read.
 */
void
ssh_tty_parse_modes(struct ssh *ssh, int fd)
{
	struct termios tio;
	struct sshbuf *buf;
	const u_char *data;
	u_char opcode;
	u_int baud, u;
	int r, failure = 0;
	size_t len;

	if ((r = sshpkt_get_string_direct(ssh, &data, &len)) != 0)
		fatal("%s: packet error: %s", __func__, ssh_err(r));
	if (len == 0)
		return;
	if ((buf = sshbuf_from(data, len)) == NULL) {
		error("%s: sshbuf_from failed", __func__);
		return;
	}

	/*
	 * Get old attributes for the terminal.  We will modify these
	 * flags. I am hoping that if there are any machine-specific
	 * modes, they will initially have reasonable values.
	 */
	if (tcgetattr(fd, &tio) == -1) {
		logit("tcgetattr: %.100s", strerror(errno));
		failure = -1;
	}

	while (sshbuf_len(buf) > 0) {
		if ((r = sshbuf_get_u8(buf, &opcode)) != 0)
			fatal("%s: packet error: %s", __func__, ssh_err(r));
		switch (opcode) {
		case TTY_OP_END:
			goto set;

		case TTY_OP_ISPEED:
			if ((r = sshbuf_get_u32(buf, &baud)) != 0)
				fatal("%s: packet error: %s",
				    __func__, ssh_err(r));
			if (failure != -1 &&
			    cfsetispeed(&tio, baud_to_speed(baud)) == -1)
				error("cfsetispeed failed for %d", baud);
			break;

		case TTY_OP_OSPEED:
			if ((r = sshbuf_get_u32(buf, &baud)) != 0)
				fatal("%s: packet error: %s",
				    __func__, ssh_err(r));
			if (failure != -1 &&
			    cfsetospeed(&tio, baud_to_speed(baud)) == -1)
				error("cfsetospeed failed for %d", baud);
			break;

#define TTYCHAR(NAME, OP) \
		case OP: \
			if ((r = sshbuf_get_u32(buf, &u)) != 0) \
				fatal("%s: packet error: %s", __func__, \
				    ssh_err(r)); \
			tio.c_cc[NAME] = u; \
			break;
#define TTYMODE(NAME, FIELD, OP) \
		case OP: \
			if ((r = sshbuf_get_u32(buf, &u)) != 0) \
				fatal("%s: packet error: %s", __func__, \
				    ssh_err(r)); \
			if (u) \
				tio.FIELD |= NAME; \
			else \
				tio.FIELD &= ~NAME; \
			break;

#include "ttymodes.h"

#undef TTYCHAR
#undef TTYMODE

		default:
			debug("Ignoring unsupported tty mode opcode %d (0x%x)",
			    opcode, opcode);
			/*
			 * SSH2:
			 * Opcodes 1 to 159 are defined to have a uint32
			 * argument.
			 * Opcodes 160 to 255 are undefined and cause parsing
			 * to stop.
			 */
			if (opcode > 0 && opcode < 160) {
				if ((r = sshbuf_get_u32(buf, NULL)) != 0)
					fatal("%s: packet error: %s", __func__,
					    ssh_err(r));
				break;
			} else {
				logit("%s: unknown opcode %d", __func__,
				    opcode);
				goto set;
			}
		}
	}

set:
	len = sshbuf_len(buf);
	sshbuf_free(buf);
	if (len > 0) {
		logit("%s: %zu bytes left", __func__, len);
		return;		/* Don't process bytes passed */
	}
	if (failure == -1)
		return;		/* Packet parsed ok but tcgetattr() failed */

	/* Set the new modes for the terminal. */
	if (tcsetattr(fd, TCSANOW, &tio) == -1)
		logit("Setting tty modes failed: %.100s", strerror(errno));
}
示例#14
0
int OpenConnection(void)
{
  /*
    UART_Start();
  */
  int speed;
  if (serial_port == NULL)
    {
      if ((serial_port = strdup(MODEMDEV)) == NULL) {
	printf("[ERROR] malloc failed\n");
	return(CYRET_ERR_FILE);
      }
    }
  // tty_fd=open(argv[1], O_RDWR | O_NONBLOCK);      
  tty_fd=open(serial_port, O_RDWR | O_NOCTTY | O_SYNC); 
  if ( tty_fd == -1) {
    printf("[ERROR] opening %s : %s\n",serial_port,strerror(errno));
    exit(1);
    // return (CYRET_ERR_FILE);
  }
  memset(&tio,0,sizeof(tio));
  tio.c_iflag=0;
  tio.c_oflag=0;
  tio.c_cflag=CS8|CREAD|CLOCAL;           // 8n1, see termios.h for more information
  tio.c_lflag=0;
  tio.c_cc[VMIN]=1;
  tio.c_cc[VTIME]=5;


  switch(serial_speed) {
  case 9600:
    speed = B9600;
    break;
  case 19200:
    speed = B19200;
    break;
  case 38400:
    speed = B38400;
    break;
  case 57600:
    speed = B57600;
    break;
  case 115200:
    speed = B115200;
    break;    
  default:
    speed = COMSPEED;
    printf("[INFO] unsupported speed %d, defaulting to %d\n",serial_speed,speed);
    break;
  }
  if ( cfsetospeed(&tio,speed) == -1) {            // 115200 baud
    printf("[ERROR] %s\n",strerror(errno));
    return (CYRET_ERR_FILE);    
  }
  if (cfsetispeed(&tio,speed) == -1) {            // 115200 baud
    printf("[ERROR] %s\n",strerror(errno));
    return (CYRET_ERR_FILE);     
  }
  if (tcsetattr(tty_fd,TCSANOW,&tio) == -1) {
    printf("[ERROR] %s\n",strerror(errno));
    return (CYRET_ERR_FILE);    
  }
  return(CYRET_SUCCESS);
}
示例#15
0
// ------------------------------------------------------------------------------
//   Helper Function - Setup Serial Port
// ------------------------------------------------------------------------------
// Sets configuration, flags, and baud rate
bool
Serial_Port::
_setup_port(int baud, int data_bits, int stop_bits, bool parity, bool hardware_control)
{
	// Check file descriptor
	if(!isatty(fd))
	{
		fprintf(stderr, "\nERROR: file descriptor %d is NOT a serial port\n", fd);
		return false;
	}

	// Read file descritor configuration
	struct termios  config;
	if(tcgetattr(fd, &config) < 0)
	{
		fprintf(stderr, "\nERROR: could not read configuration of fd %d\n", fd);
		return false;
	}

	// Input flags - Turn off input processing
	// convert break to null byte, no CR to NL translation,
	// no NL to CR translation, don't mark parity errors or breaks
	// no input parity check, don't strip high bit off,
	// no XON/XOFF software flow control
	config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
						INLCR | PARMRK | INPCK | ISTRIP | IXON);

	// Output flags - Turn off output processing
	// no CR to NL translation, no NL to CR-NL translation,
	// no NL to CR translation, no column 0 CR suppression,
	// no Ctrl-D suppression, no fill characters, no case mapping,
	// no local output processing
	config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
						 ONOCR | OFILL | OPOST);

	#ifdef OLCUC
		config.c_oflag &= ~OLCUC;
	#endif

	#ifdef ONOEOT
		config.c_oflag &= ~ONOEOT;
	#endif

	// No line processing:
	// echo off, echo newline off, canonical mode off,
	// extended input processing off, signal chars off
	config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);

	// Turn off character processing
	// clear current char size mask, no parity checking,
	// no output processing, force 8 bit input
	config.c_cflag &= ~(CSIZE | PARENB);
	config.c_cflag |= CS8;

	// One input byte is enough to return from read()
	// Inter-character timer off
	config.c_cc[VMIN]  = 1;
	config.c_cc[VTIME] = 10; // was 0

	// Get the current options for the port
	////struct termios options;
	////tcgetattr(fd, &options);

	// Apply baudrate
	switch (baud)
	{
		case 1200:
			if (cfsetispeed(&config, B1200) < 0 || cfsetospeed(&config, B1200) < 0)
			{
				fprintf(stderr, "\nERROR: Could not set desired baud rate of %d Baud\n", baud);
				return false;
			}
			break;
		case 1800:
			cfsetispeed(&config, B1800);
			cfsetospeed(&config, B1800);
			break;
		case 9600:
			cfsetispeed(&config, B9600);
			cfsetospeed(&config, B9600);
			break;
		case 19200:
			cfsetispeed(&config, B19200);
			cfsetospeed(&config, B19200);
			break;
		case 38400:
			if (cfsetispeed(&config, B38400) < 0 || cfsetospeed(&config, B38400) < 0)
			{
				fprintf(stderr, "\nERROR: Could not set desired baud rate of %d Baud\n", baud);
				return false;
			}
			break;
		case 57600:
			if (cfsetispeed(&config, B57600) < 0 || cfsetospeed(&config, B57600) < 0)
			{
				fprintf(stderr, "\nERROR: Could not set desired baud rate of %d Baud\n", baud);
				return false;
			}
			break;
		case 115200:
			if (cfsetispeed(&config, B115200) < 0 || cfsetospeed(&config, B115200) < 0)
			{
				fprintf(stderr, "\nERROR: Could not set desired baud rate of %d Baud\n", baud);
				return false;
			}
			break;

		// These two non-standard (by the 70'ties ) rates are fully supported on
		// current Debian and Mac OS versions (tested since 2010).
		case 460800:
			if (cfsetispeed(&config, B460800) < 0 || cfsetospeed(&config, B460800) < 0)
			{
				fprintf(stderr, "\nERROR: Could not set desired baud rate of %d Baud\n", baud);
				return false;
			}
			break;
		case 921600:
			if (cfsetispeed(&config, B921600) < 0 || cfsetospeed(&config, B921600) < 0)
			{
				fprintf(stderr, "\nERROR: Could not set desired baud rate of %d Baud\n", baud);
				return false;
			}
			break;
		default:
			fprintf(stderr, "ERROR: Desired baud rate %d could not be set, aborting.\n", baud);
			return false;

			break;
	}

	// Finally, apply the configuration
	if(tcsetattr(fd, TCSAFLUSH, &config) < 0)
	{
		fprintf(stderr, "\nERROR: could not set configuration of fd %d\n", fd);
		return false;
	}

	// Done!
	return true;
}
示例#16
0
int GPS::setBaudrate(unsigned baud)
{

#if __PX4_QURT
	// TODO: currently QURT does not support configuration with termios.
	dspal_serial_ioctl_data_rate data_rate;

	switch (baud) {
	case 9600: data_rate.bit_rate = DSPAL_SIO_BITRATE_9600; break;

	case 19200: data_rate.bit_rate = DSPAL_SIO_BITRATE_19200; break;

	case 38400: data_rate.bit_rate = DSPAL_SIO_BITRATE_38400; break;

	case 57600: data_rate.bit_rate = DSPAL_SIO_BITRATE_57600; break;

	case 115200: data_rate.bit_rate = DSPAL_SIO_BITRATE_115200; break;

	default:
		PX4_ERR("ERR: unknown baudrate: %d", baud);
		return -EINVAL;
	}

	int ret = ::ioctl(_serial_fd, SERIAL_IOCTL_SET_DATA_RATE, (void *)&data_rate);

	if (ret != 0) {

		return ret;
	}

#else
	/* process baud rate */
	int speed;

	switch (baud) {
	case 9600:   speed = B9600;   break;

	case 19200:  speed = B19200;  break;

	case 38400:  speed = B38400;  break;

	case 57600:  speed = B57600;  break;

	case 115200: speed = B115200; break;

	default:
		PX4_ERR("ERR: unknown baudrate: %d", baud);
		return -EINVAL;
	}

	struct termios uart_config;

	int termios_state;

	/* fill the struct for the new configuration */
	tcgetattr(_serial_fd, &uart_config);

	/* properly configure the terminal (see also https://en.wikibooks.org/wiki/Serial_Programming/termios ) */

	//
	// Input flags - Turn off input processing
	//
	// convert break to null byte, no CR to NL translation,
	// no NL to CR translation, don't mark parity errors or breaks
	// no input parity check, don't strip high bit off,
	// no XON/XOFF software flow control
	//
	uart_config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
				 INLCR | PARMRK | INPCK | ISTRIP | IXON);
	//
	// Output flags - Turn off output processing
	//
	// no CR to NL translation, no NL to CR-NL translation,
	// no NL to CR translation, no column 0 CR suppression,
	// no Ctrl-D suppression, no fill characters, no case mapping,
	// no local output processing
	//
	// config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
	//                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
	uart_config.c_oflag = 0;

	//
	// No line processing
	//
	// echo off, echo newline off, canonical mode off,
	// extended input processing off, signal chars off
	//
	uart_config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);

	/* no parity, one stop bit */
	uart_config.c_cflag &= ~(CSTOPB | PARENB);

	/* set baud rate */
	if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) {
		GPS_ERR("ERR: %d (cfsetispeed)", termios_state);
		return -1;
	}

	if ((termios_state = cfsetospeed(&uart_config, speed)) < 0) {
		GPS_ERR("ERR: %d (cfsetospeed)", termios_state);
		return -1;
	}

	if ((termios_state = tcsetattr(_serial_fd, TCSANOW, &uart_config)) < 0) {
		GPS_ERR("ERR: %d (tcsetattr)", termios_state);
		return -1;
	}

#endif
	return 0;
}
示例#17
0
/* 
 * Class:     cedric_serial_SerialPort 
 * Method:    open 
 * Signature: (Ljava/lang/String;)V 
 */  
JNIEXPORT jobject JNICALL Java_com_erobbing_mcutool_SerialPort_open(JNIEnv *env, jobject thiz, jstring path,jint baudrate) {  
    int fd;  
    speed_t speed;  
    jobject mFileDescriptor;  
  
    LOGD("init native Check arguments");  
    /* Check arguments */  
    {  
        speed = getBaudrate(baudrate);  
        if (speed == -1) {  
            /* TODO: throw an exception */  
            LOGE("Invalid baudrate");  
            return NULL;  
        }  
    }  
  
    LOGD("init native Opening device!");  
    /* Opening device */  
    {  
        jboolean iscopy;  
        const char *path_utf = env->GetStringUTFChars(path, &iscopy);  
        LOGD("Opening serial port %s", path_utf);  
//      fd = open(path_utf, O_RDWR | O_DIRECT | O_SYNC);  
        fd = open(path_utf, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);  
        LOGD("open() fd = %d", fd);  
        env->ReleaseStringUTFChars(path, path_utf);  
        if (fd == -1) {  
            /* Throw an exception */  
            LOGE("Cannot open port %d",baudrate);  
            /* TODO: throw an exception */  
            return NULL;  
        }  
    }  
  
    LOGD("init native Configure device!");  
    /* Configure device */  
    {  
        struct termios cfg;  
        if (tcgetattr(fd, &cfg)) {  
            LOGE("Configure device tcgetattr() failed 1");  
            close(fd);  
            return NULL;  
        }  
  
        cfmakeraw(&cfg);  
        cfsetispeed(&cfg, speed);  
        cfsetospeed(&cfg, speed);  
  
        if (tcsetattr(fd, TCSANOW, &cfg)) {  
            LOGE("Configure device tcsetattr() failed 2");  
            close(fd);  
            /* TODO: throw an exception */  
            return NULL;  
        }  
    }  
  
    /* Create a corresponding file descriptor */  
    {  
        jclass cFileDescriptor = env->FindClass("java/io/FileDescriptor");  
        jmethodID iFileDescriptor = env->GetMethodID(cFileDescriptor,"<init>", "()V");  
        jfieldID descriptorID = env->GetFieldID(cFileDescriptor,"descriptor", "I");  
        mFileDescriptor = env->NewObject(cFileDescriptor,iFileDescriptor);  
        env->SetIntField(mFileDescriptor, descriptorID, (jint) fd);  
    }  
  
    return mFileDescriptor;  
}  
示例#18
0
int
main(int argc, char *argv[])
{
	struct info i;
	enum FMT fmt;
	int ch;
	const char *file;

	fmt = NOTSET;
	i.fd = STDIN_FILENO;
	file = "stdin";

	opterr = 0;
	while (optind < argc &&
	    strspn(argv[optind], "-aefg") == strlen(argv[optind]) &&
	    (ch = getopt(argc, argv, "aef:g")) != -1)
		switch(ch) {
		case 'a':		/* undocumented: POSIX compatibility */
			fmt = POSIX;
			break;
		case 'e':
			fmt = BSD;
			break;
		case 'f':
			if ((i.fd = open(optarg, O_RDONLY | O_NONBLOCK)) < 0)
				err(1, "%s", optarg);
			file = optarg;
			break;
		case 'g':
			fmt = GFLAG;
			break;
		case '?':
		default:
			goto args;
		}

args:	argc -= optind;
	argv += optind;

	if (tcgetattr(i.fd, &i.t) < 0)
		errx(1, "%s isn't a terminal", file);
	if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0)
		err(1, "TIOCGETD");
	if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0)
		warn("TIOCGWINSZ");

	checkredirect();			/* conversion aid */

	switch(fmt) {
	case NOTSET:
		if (*argv)
			break;
		/* FALLTHROUGH */
	case BSD:
	case POSIX:
		print(&i.t, &i.win, i.ldisc, fmt);
		break;
	case GFLAG:
		gprint(&i.t, &i.win, i.ldisc);
		break;
	}

	for (i.set = i.wset = 0; *argv; ++argv) {
		if (ksearch(&argv, &i))
			continue;

		if (csearch(&argv, &i))
			continue;

		if (msearch(&argv, &i))
			continue;

		if (isdigit(**argv)) {
			speed_t speed;

			speed = atoi(*argv);
			cfsetospeed(&i.t, speed);
			cfsetispeed(&i.t, speed);
			i.set = 1;
			continue;
		}

		if (!strncmp(*argv, "gfmt1", sizeof("gfmt1") - 1)) {
			gread(&i.t, *argv + sizeof("gfmt1") - 1);
			i.set = 1;
			continue;
		}

		warnx("illegal option -- %s", *argv);
		usage();
	}

	if (i.set && tcsetattr(i.fd, 0, &i.t) < 0)
		err(1, "tcsetattr");
	if (i.wset && ioctl(i.fd, TIOCSWINSZ, &i.win) < 0)
		warn("TIOCSWINSZ");
	exit(0);
}
/***@brief  设置串口通信速率
*param  fd     类型 int  打开串口的文件句柄
*param  speed  类型 int  串口速度,波特率
*param nEvent :奇偶校验设置,0:无校验,1:奇校验,2:偶校验
*param nStop : 停止位,设置为0,或者1
*return  void*/
int set_opt(int fd,int nSpeed,int nBits,int nEvent,int nStop)
{
    struct termios newtio,oldtio;

    if(tcgetattr(fd,&oldtio))
    {
        printf("tcgetattr in set_opt");
        return -1;
    }

    bzero(&newtio,sizeof(newtio));
    newtio.c_cflag |= CLOCAL|CREAD;
    newtio.c_cflag &= ~CSIZE;

    //newtio.c_oflag |= OPOST;

    switch(nBits)
    {
        case 0:
            newtio.c_cflag |= CS5;
            break;
        case 1:
            newtio.c_cflag |= CS6;
            break;
        case 2:
            newtio.c_cflag |= CS7;
            break;
        case 3:
            newtio.c_cflag |= CS8;
            break;
        default:
            break;
    }

    switch(nEvent)
    {
        case 0:
            newtio.c_cflag &= ~PARENB;
            break;
        case 1:   //奇校验。  // odd
            newtio.c_cflag |= PARENB;
            newtio.c_cflag |= PARODD;
            //newtio.c_iflag |= (INPCK|ISTRIP);
            newtio.c_iflag |= (INPCK);
            break;
        case 2:   //偶校验。  // even
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;
            //newtio.c_iflag |= (INPCK|ISTRIP);
            newtio.c_iflag |= (INPCK);
            break;
    }
    //newtio.c_iflag |= (IGNPAR);
    //newtio.c_iflag |= (PARMRK | IGNPAR);
    //newtio.c_iflag |= (PARMRK);

    switch(nSpeed)
    {
        case 1200:
            cfsetispeed(&newtio,B1200);
            cfsetospeed(&newtio,B1200);
            break;
        case 2400:
            cfsetispeed(&newtio,B2400);
            cfsetospeed(&newtio,B2400);
            break;
        case 4800:
            cfsetispeed(&newtio,B4800);
            cfsetospeed(&newtio,B4800);
            break;
        case 9600:
            cfsetispeed(&newtio,B9600);
            cfsetospeed(&newtio,B9600);
            break;
        case 19200:
            cfsetispeed(&newtio,B19200);
            cfsetospeed(&newtio,B19200);
            break;
        case 38400:
            cfsetispeed(&newtio,B38400);
            cfsetospeed(&newtio,B38400);
            break;
        case 57600:
            cfsetispeed(&newtio,B57600);
            cfsetospeed(&newtio,B57600);
            break;
        case 115200:
            cfsetispeed(&newtio,B115200);
            cfsetospeed(&newtio,B115200);
            break;
        default:
            break;
    }

    //停止位:1,2。
    if(nStop==0)
    {
        newtio.c_cflag &=~CSTOPB;
    }
    else if(nStop==1) 
    {
        newtio.c_cflag |=CSTOPB;
    }


    //navy add
    //newtio.c_oflag &= ~OPOST;
    //newtio.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
    //tcflush(fd, TCIOFLUSH);  //navy add
    //end navy

    newtio.c_cc[VTIME]=0;
    newtio.c_cc[VMIN]=0;

    if(0!=(tcsetattr(fd,TCSANOW,&newtio)))
    {
        printf("com set error\n");
        return -1;
    }
    return 0;
}
int init_uart (const char *port)
{
    int r;

    info ("Opening serial device: %s\n",
          port);
    tty_file_desc = open (port, O_RDWR | /*O_NONBLOCK | */O_NOCTTY,
                          0);
    if (tty_file_desc < 1) {
        error ("FATAL: Could not open serial device\n");
        goto serial_device_open_fail;
    }

    printf ("File descriptor :: %d\n", tty_file_desc);

    // get the current attributes
    memset (&termios, 0, sizeof(struct termios));
    r = tcgetattr (tty_file_desc, &termios);
    if (r != 0) {
        error ("Failed to get attribute");
        goto attribute_change_fail;
    }

    /*
      termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
      | INLCR | IGNCR | ICRNL | IXON);
      termios.c_oflag &= ~OPOST;
      termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
      termios.c_cflag &= ~(CSIZE | PARENB);
      termios.c_cflag |= CS8;
    */
    /* makeraw does this
       termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
       | INLCR | IGNCR | ICRNL | IXON);
       termios_p->c_oflag &= ~OPOST;
       termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
       termios_p->c_cflag &= ~(CSIZE | PARENB);
       termios_p->c_cflag |= CS8;
    */


    // set the attributes
    //termios.c_iflag &=
    //~(IGNBRK | /* ignore break */
    //  INPCK  | /* enable input parity check */


    //	termios.c_oflag = 0;
    //	termios.c_cflag = B115200 | CS8 | CLOCAL | CREAD;

    cfmakeraw (&termios);
    // set the baud rate
    cfsetispeed (&termios, B115200);
    cfsetospeed (&termios, B115200);

    termios.c_cflag |= B115200 |  CS8 | CLOCAL | CREAD;
    // additional for hawkboard
    termios.c_iflag |= IGNPAR;
    termios.c_iflag &= ~INPCK;
    // ~hawkboard

    r = tcsetattr (tty_file_desc, TCSANOW, &termios);
    if (r != 0) {
        error ("Failed to set attribute");
        goto attribute_change_fail;
    }

    if (verify_settingschange (tty_file_desc, &termios) != 0)
        goto attribute_change_fail;


#if 0
    char uc = 'X', rc = 'Y';
    const char string[]="Kaustubh Satish Ashtekar";
    char readstring[sizeof(string)+10];
    int wi,ri, t;


#if 1
    ri = 0;
    while (1) {
        //		write (tty_file_desc, &uc, 1);
        if (read (tty_file_desc, &rc, 1) == 1) {
            printf ("%c\n", rc);
        }

    }
#endif


    for (t = sizeof(string), ri = 0, wi = 0;;) {
        if (wi < (sizeof(string)-1)) {
            write (tty_file_desc, &string[wi], 1);
            wi++;
        }
        if (ri < sizeof(string)) {
            1	    if (read (tty_file_desc, &rc, 1) == 1) {
                printf ("%c", rc);
                readstring[ri]=rc;
                ri++;
            }
        }
        if (ri == (sizeof(string)-1))
            break;
    }
示例#21
0
bool MLTTYDevice::open(QIODevice::OpenMode mode)
{
  int flags=O_NONBLOCK|O_NOCTTY;
  struct termios term;

  tty_mode=mode;
  if((mode&QIODevice::ReadWrite)==QIODevice::ReadWrite) {
    flags|=O_RDWR;
  }
  else {
    if(((mode&QIODevice::WriteOnly)!=0)) {
      flags|=O_WRONLY;
    }
    if(((mode&QIODevice::ReadOnly)!=0)) {
      flags|=O_RDONLY;
    }
  }
  if((mode&QIODevice::Append)!=0) {
    flags|=O_APPEND;
  }
  if((mode&QIODevice::Truncate)!=0) {
    flags|=O_TRUNC;
  }

  if((tty_fd=::open(tty_name.toAscii(),flags))<0) {
    return false;
  }
  tty_open=true;

  tcgetattr(tty_fd,&term);

  //
  // Set Speed
  //
  //cfsetispeed(&term,B0);
  cfsetispeed(&term,tty_speed);
  cfsetospeed(&term,tty_speed);

  //
  // Set Mode
  //
  cfmakeraw(&term);
  term.c_iflag |= IGNBRK; 

  //
  // Set Parity
  //
  switch(tty_parity) {
  case MLTTYDevice::None:
    term.c_iflag |= IGNPAR;
    break;

  case MLTTYDevice::Even:
    term.c_cflag |= PARENB;
    break;

  case MLTTYDevice::Odd:
    term.c_cflag |= PARENB|PARODD;
    break;
  }

  //
  // Set Word Length
  //
  //term.c_cflag &= ~CSIZE;
  switch(tty_length) {
  case 5:
    term.c_cflag |= CS5;
    break;

  case 6:
    term.c_cflag |= CS6;
    break;

  case 7:
    term.c_cflag |= CS7;
    break;

  case 8:
    term.c_cflag |= CS8;
    break;
  }

  //
  // Set Flow Control
  //
  switch(tty_flow_control) {
  case MLTTYDevice::FlowNone:
    term.c_cflag &= ~CRTSCTS;
    term.c_iflag &= ~IXON;
    term.c_iflag &= ~IXOFF;
    break;

  case MLTTYDevice::FlowRtsCts:
    term.c_cflag |= CRTSCTS;
    term.c_iflag &= ~IXON;
    term.c_iflag &= ~IXOFF;
    break;

  case MLTTYDevice::FlowXonXoff:
    term.c_cflag &= ~CRTSCTS;
    term.c_iflag |= IXON;
    term.c_iflag |= IXOFF;
    break;
  }

  tcsetattr(tty_fd,TCSADRAIN,&term);

  tty_notifier=new QSocketNotifier(tty_fd,QSocketNotifier::Read,this);
  connect(tty_notifier,SIGNAL(activated(int)),this,SLOT(readTtyData(int)));

  tty_write_timer->start(10);

  return true;
}
示例#22
0
文件: sio.c 项目: boris-r-v/RIO
/**********************************************************************
 *  sio_open
 *
 *  Open and initiate serial port
 *  default open port in noncanonical mode
 *
 *  Arguments:
 *    port    a string point to the name of serial device,
 *				such as "/dev/ttyS0"
 *    baud    B0, B50... B9600, B19200, B38400...
 *    data    Data bit(s), unsigned char
 *    parity  Parity, unsigned char
 *    stop    Stop bit(s), unsigned char
 *
 *  Returned:
 *    This function returns int port descriptor for the port opened
 *    successfully. Return value ERR_PORT_OPEN if failed.
 *
 **********************************************************************/
int
sio_open(const char *port, speed_t baud, tcflag_t data, tcflag_t parity,
		 tcflag_t stop)
{
	struct sio *sio;			/* point to current sio structure */

	int fd;						/* file descriptor for current port */
	int r;

	struct termios *options;	/* options for current port */

	PDEBUG("sio_open: start\n");

  /***************
   *  open port  *
   ***************/
	fd = _sio_device(port);
	if (fd == 0) {				/* device is not yet opened, so, open it */
		// fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
		//printf("%s ... open %s\n",__FUNCTION__, port);
		fd = open(port, O_RDWR | O_NOCTTY);
	}
	PDEBUG("          fd = %u\n", fd);

	if (fd == -1) {				/* Could not open the port */
		PDEBUG("sio_open: Unable to open %s - %s\n", strerror(errno),
			   port);
		return (ERR_PORT_OPEN);
	}

  /********************************
   *  allocate new sio structure  *
   ********************************/
	sio = _sio_follow(fd);
	if (!sio) {					/* out of memory */
		close(fd);
		return (ERR_PORT_OPEN);
	}

	sio->fd = fd;
	sio->name = port;

	// fcntl(fd, F_SETFL, FNDELAY); /* nonblocking */

	tcgetattr(fd, sio->old_options);	/* save the original options */
	tcgetattr(fd, sio->options);	/* Get the current options */

	options = sio->options;

	/*
	 * printf("\nsio_open\n"); printf("name : %s\n", sio->name);
	 * printf("fd : %d\n", fd); printf("sio : %lx\n", sio);
	 * printf("sio->options : %lx\n", sio->options);
	 * printf("sio->old_options : %lx\n", sio->old_options);
	 * printf("options : %lx\n", options); printf("\n"); 
	 */

  /*********************
   *  select Baudrate  *
   *********************/
	r = cfsetispeed(options, baud);	/* input */
	if (r) {
		PDEBUG("sio_open: fails to set input baudrate!\n", r);
		close(fd);
		return (r);
	}
	r = cfsetospeed(options, baud);	/* output */
	if (r) {
		PDEBUG("sio_open: fails to set output baudrate!\n", r);
		close(fd);
		return (r);
	}

  /**********************
   *  select data bits  *
   **********************/
	options->c_cflag &= ~CSIZE;	/* bit mask for data bits */
	options->c_cflag |= data;
	/*
	 * close(fd); PDEBUG("undefined data bits number %d, port %s
	 * closed.\n", data, port); return (ERR_PORT_OPEN); 
	 */

  /*******************
   *  select parity  *
   *******************/
	switch (parity) {
	case NO_PARITY:
		options->c_cflag &= ~(PARENB | PARODD);
		break;
	case ODD_PARITY:
		options->c_cflag |= PARODD;
		break;
	case EVEN_PARITY:
		options->c_cflag |= PARENB;
		break;
	default:
		tcsetattr(fd, TCSANOW, sio->old_options);
		close(fd);
		_sio_trim(fd);
		PDEBUG("undefined parity code %d, port %s closed.\n", parity,
			   port);
		return (ERR_PORT_OPEN);
	}

  /************************
   *  select stop bit(s)  *
   ************************/
	switch (stop) {
	case ONE_STOP_BIT:
		options->c_cflag &= ~CSTOPB;
		break;
	case TWO_STOP_BITS:
		options->c_cflag |= CSTOPB;
		break;
	default:
		tcsetattr(fd, TCSANOW, sio->old_options);
		close(fd);
		_sio_trim(fd);
		PDEBUG("undefined stop bits code %d, port %s closed.\n", stop,
			   port);
		return (ERR_PORT_OPEN);
	}

  /**********************
   *  other parameterm  *
   **********************/
	/*
	 * posix input mode flags 
	 */
	options->c_iflag &= ~ICRNL;	/* disable map CR to NL for noncanonical */
	options->c_iflag &= ~INLCR;
	options->c_iflag &= ~IXON;	/* disable software flow control
								   * (outgoing) */
	options->c_iflag &= ~IXOFF;	/* disable software flow control
								   * (incoming) */

	/*
	 * posix output mode flags 
	 */
	options->c_oflag &= ~OPOST;	/* raw output */
	options->c_oflag &= ~OLCUC;	/* do not transfer the case */
	options->c_oflag &= ~ONLCR;	/* do not translate the CR and NL */
	options->c_oflag &= ~OCRNL;
	options->c_oflag &= ~NLDLY;	/* no delay for NL */
	options->c_oflag &= ~CRDLY;	/* no delay for CR */
	options->c_oflag &= ~TABDLY;	/* no delay for TAB */
	options->c_oflag &= ~BSDLY;	/* no delay for BS */
	options->c_oflag &= ~VTDLY;	/* no delay for VT */
	options->c_oflag &= ~FFDLY;	/* no delay for FF */

	/*
	 * posix control mode flags 
	 */
	options->c_cflag |= CLOCAL;	/* Local line */
	/*
	 * do not change "owner" of port 
	 */
	options->c_cflag |= CREAD;	/* Enable receiver */

	options->c_cflag &= ~CRTSCTS;	/* Disable hardware flow control */

	/*
	 * posix local mode flags 
	 */
	options->c_lflag &= ~ICANON;	/* default for noncanonical mode */
	options->c_lflag &= ~ECHO;	/* Disable echoing of input characters */
	options->c_lflag &= ~ISIG;	/* disable signals */

	/*
	 * posix control characters 
	 */
	options->c_cc[VINTR] = 0;
	options->c_cc[VQUIT] = 0;
	options->c_cc[VERASE] = 0;
	options->c_cc[VKILL] = 0;
	options->c_cc[VEOF] = 4;
	options->c_cc[VTIME] = 0;	/* Time to wait for data (tenths of
								   * seconds) */
	options->c_cc[VMIN] = 1;
	options->c_cc[VSWTC] = 0;
	options->c_cc[VSTART] = 0;
	options->c_cc[VSTOP] = 0;
	options->c_cc[VSUSP] = 0;
	options->c_cc[VEOL] = 0;
	options->c_cc[VREPRINT] = 0;
	options->c_cc[VDISCARD] = 0;
	options->c_cc[VWERASE] = 0;
	options->c_cc[VLNEXT] = 0;
	options->c_cc[VEOL2] = 0;

  /**************************************
   *  set the new options for the port  *
   **************************************/
	// tcsetattr(fd, TCSANOW, options);
	tcsetattr(fd, TCSAFLUSH, options);	/* flush input and output buffers,
										   * and make the change */
# ifdef I7K_DEBUG
	_sio_poptions(fd);
# endif							/* I7K_DEBUG */

	return (fd);
}
示例#23
0
int Mavlink::mavlink_open_uart(int baud, const char *uart_name, struct termios *uart_config_original, bool *is_usb)
{
	/* process baud rate */
	int speed;

	switch (baud) {
	case 0:      speed = B0;      break;

	case 50:     speed = B50;     break;

	case 75:     speed = B75;     break;

	case 110:    speed = B110;    break;

	case 134:    speed = B134;    break;

	case 150:    speed = B150;    break;

	case 200:    speed = B200;    break;

	case 300:    speed = B300;    break;

	case 600:    speed = B600;    break;

	case 1200:   speed = B1200;   break;

	case 1800:   speed = B1800;   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;  break;

	case 115200: speed = B115200; break;

	case 230400: speed = B230400; break;

	case 460800: speed = B460800; break;

	case 921600: speed = B921600; break;

	default:
		warnx("ERROR: Unsupported baudrate: %d\n\tsupported examples:\n\t9600, 19200, 38400, 57600\t\n115200\n230400\n460800\n921600\n",
		      baud);
		return -EINVAL;
	}

	/* open uart */
	_uart_fd = ::open(uart_name, O_RDWR | O_NOCTTY);

	if (_uart_fd < 0) {
		return _uart_fd;
	}


	/* Try to set baud rate */
	struct termios uart_config;
	int termios_state;
	*is_usb = false;

	/* Back up the original uart configuration to restore it after exit */
	if ((termios_state = tcgetattr(_uart_fd, uart_config_original)) < 0) {
		warnx("ERR GET CONF %s: %d\n", uart_name, termios_state);
		::close(_uart_fd);
		return -1;
	}

	/* Fill the struct for the new configuration */
	tcgetattr(_uart_fd, &uart_config);

	/* Clear ONLCR flag (which appends a CR for every LF) */
	uart_config.c_oflag &= ~ONLCR;

	/* USB serial is indicated by /dev/ttyACM0*/
	if (strcmp(uart_name, "/dev/ttyACM0") != OK && strcmp(uart_name, "/dev/ttyACM1") != OK) {

		/* Set baud rate */
		if (cfsetispeed(&uart_config, speed) < 0 || cfsetospeed(&uart_config, speed) < 0) {
			warnx("ERR SET BAUD %s: %d\n", uart_name, termios_state);
			::close(_uart_fd);
			return -1;
		}

	}

	if ((termios_state = tcsetattr(_uart_fd, TCSANOW, &uart_config)) < 0) {
		warnx("ERR SET CONF %s\n", uart_name);
		::close(_uart_fd);
		return -1;
	}

	if (!_is_usb_uart) {
		/*
		 * Setup hardware flow control. If the port has no RTS pin this call will fail,
		 * which is not an issue, but requires a separate call so we can fail silently.
		 */
		(void)tcgetattr(_uart_fd, &uart_config);
#ifdef CRTS_IFLOW
		uart_config.c_cflag |= CRTS_IFLOW;
#else
		uart_config.c_cflag |= CRTSCTS;
#endif
		(void)tcsetattr(_uart_fd, TCSANOW, &uart_config);

		/* setup output flow control */
		if (enable_flow_control(true)) {
			warnx("hardware flow control not supported");
		}

	} else {
		_flow_control_enabled = false;
	}

	return _uart_fd;
}
示例#24
0
/*
 * Open the serial port.
 * Return -1 on error.
 */
dyio_t *_dyio_serial_open(const char *devname, int baud_rate)
{
#if defined(__WIN32__) || defined(WIN32)
    DCB new_mode;
    COMMTIMEOUTS ctmo;
#else
    struct termios new_mode;
#endif
    dyio_serial_t *s;

    s = calloc(1, sizeof(dyio_serial_t));
    if (! s) {
        fprintf(stderr, "dyio: Out of memory\n");
        return 0;
    }

#if defined(__WIN32__) || defined(WIN32)
    /* Open port */
    s->fd = CreateFile(devname, GENERIC_READ | GENERIC_WRITE,
        0, 0, OPEN_EXISTING, 0, 0);
    if (s->fd == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "%s: Cannot open\n", devname);
        free(s);
        return 0;
    }

    /* Set serial attributes */
    memset(&s->saved_mode, 0, sizeof(s->saved_mode));
    if (! GetCommState(s->fd, &s->saved_mode)) {
        fprintf(stderr, "%s: Cannot get state\n", devname);
        CloseHandle(s->fd);
        free(s);
        return 0;
    }

    new_mode = s->saved_mode;
    new_mode.BaudRate = baud_encode(baud_rate);
    new_mode.ByteSize = 8;
    new_mode.StopBits = ONESTOPBIT;
    new_mode.Parity = 0;
    new_mode.fParity = FALSE;
    new_mode.fOutX = FALSE;
    new_mode.fInX = FALSE;
    new_mode.fOutxCtsFlow = FALSE;
    new_mode.fOutxDsrFlow = FALSE;
    new_mode.fRtsControl = RTS_CONTROL_ENABLE;
    new_mode.fNull = FALSE;
    new_mode.fAbortOnError = FALSE;
    new_mode.fBinary = TRUE;
    if (! SetCommState(s->fd, &new_mode)) {
        fprintf(stderr, "%s: Cannot set state\n", devname);
        CloseHandle(s->fd);
        free(s);
        return 0;
    }

    memset(&ctmo, 0, sizeof(ctmo));
    ctmo.ReadIntervalTimeout = 0;
    ctmo.ReadTotalTimeoutMultiplier = 0;
    ctmo.ReadTotalTimeoutConstant = 5000;
    if (! SetCommTimeouts(s->fd, &ctmo)) {
        fprintf(stderr, "%s: Cannot set timeouts\n", devname);
        CloseHandle(s->fd);
        free(s);
        return 0;
    }
#else
    /* Encode baud rate. */
    int baud_code = baud_encode(baud_rate);
    if (baud_code < 0) {
        fprintf(stderr, "%s: Bad baud rate %d\n", devname, baud_rate);
        free(s);
        return 0;
    }

    /* Open port */
    s->fd = open(devname, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (s->fd < 0) {
        perror(devname);
        free(s);
        return 0;
    }

    /* Set serial attributes */
    memset(&s->saved_mode, 0, sizeof(s->saved_mode));
    tcgetattr(s->fd, &s->saved_mode);

    /* 8n1, ignore parity */
    memset(&new_mode, 0, sizeof(new_mode));
    new_mode.c_cflag = CS8 | CLOCAL | CREAD;
    new_mode.c_iflag = IGNBRK;
    new_mode.c_oflag = 0;
    new_mode.c_lflag = 0;
    new_mode.c_cc[VTIME] = 0;
    new_mode.c_cc[VMIN]  = 1;
    cfsetispeed(&new_mode, baud_code);
    cfsetospeed(&new_mode, baud_code);
    tcflush(s->fd, TCIFLUSH);
    tcsetattr(s->fd, TCSANOW, &new_mode);

    /* Clear O_NONBLOCK flag. */
    int flags = fcntl(s->fd, F_GETFL, 0);
    if (flags >= 0)
        fcntl(s->fd, F_SETFL, flags & ~O_NONBLOCK);
#endif
    return &s->generic;
}
示例#25
0
/*!
\fn void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
Sets the baud rate of the serial port.  Note that not all rates are applicable on
all platforms.  The following table shows translations of the various baud rate
constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
are speeds that are usable on both Windows and POSIX.

\note
BAUD76800 may not be supported on all POSIX systems.  SGI/IRIX systems do not support
BAUD1800.

\verbatim

  RATE          Windows Speed   POSIX Speed
  -----------   -------------   -----------
   BAUD50                 110          50
   BAUD75                 110          75
  *BAUD110                110         110
   BAUD134                110         134.5
   BAUD150                110         150
   BAUD200                110         200
  *BAUD300                300         300
  *BAUD600                600         600
  *BAUD1200              1200        1200
   BAUD1800              1200        1800
  *BAUD2400              2400        2400
  *BAUD4800              4800        4800
  *BAUD9600              9600        9600
   BAUD14400            14400        9600
  *BAUD19200            19200       19200
  *BAUD38400            38400       38400
   BAUD56000            56000       38400
  *BAUD57600            57600       57600
   BAUD76800            57600       76800
  *BAUD115200          115200      115200
   BAUD128000          128000      115200
   BAUD256000          256000      115200
\endverbatim
*/
void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
{
    LOCK_MUTEX();
    if (Settings.BaudRate!=baudRate) {
        switch (baudRate) {
            case BAUD14400:
                Settings.BaudRate=BAUD9600;
                break;

            case BAUD56000:
                Settings.BaudRate=BAUD38400;
                break;

            case BAUD76800:

#ifndef B76800
                Settings.BaudRate=BAUD57600;
#else
                Settings.BaudRate=baudRate;
#endif
                break;

            case BAUD128000:
            case BAUD256000:
                Settings.BaudRate=BAUD115200;
                break;

            default:
                Settings.BaudRate=baudRate;
                break;
        }
    }
    if (isOpen()) {
        switch (baudRate) {

            /*50 baud*/
            case BAUD50:
                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 50 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B50;
#else
                cfsetispeed(&Posix_CommConfig, B50);
                cfsetospeed(&Posix_CommConfig, B50);
#endif
                break;

            /*75 baud*/
            case BAUD75:
                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 75 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B75;
#else
                cfsetispeed(&Posix_CommConfig, B75);
                cfsetospeed(&Posix_CommConfig, B75);
#endif
                break;

            /*110 baud*/
            case BAUD110:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B110;
#else
                cfsetispeed(&Posix_CommConfig, B110);
                cfsetospeed(&Posix_CommConfig, B110);
#endif
                break;

            /*134.5 baud*/
            case BAUD134:
                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 134.5 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B134;
#else
                cfsetispeed(&Posix_CommConfig, B134);
                cfsetospeed(&Posix_CommConfig, B134);
#endif
                break;

            /*150 baud*/
            case BAUD150:
                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 150 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B150;
#else
                cfsetispeed(&Posix_CommConfig, B150);
                cfsetospeed(&Posix_CommConfig, B150);
#endif
                break;

            /*200 baud*/
            case BAUD200:
                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 200 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B200;
#else
                cfsetispeed(&Posix_CommConfig, B200);
                cfsetospeed(&Posix_CommConfig, B200);
#endif
                break;

            /*300 baud*/
            case BAUD300:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B300;
#else
                cfsetispeed(&Posix_CommConfig, B300);
                cfsetospeed(&Posix_CommConfig, B300);
#endif
                break;

            /*600 baud*/
            case BAUD600:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B600;
#else
                cfsetispeed(&Posix_CommConfig, B600);
                cfsetospeed(&Posix_CommConfig, B600);
#endif
                break;

            /*1200 baud*/
            case BAUD1200:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B1200;
#else
                cfsetispeed(&Posix_CommConfig, B1200);
                cfsetospeed(&Posix_CommConfig, B1200);
#endif
                break;

            /*1800 baud*/
            case BAUD1800:
                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B1800;
#else
                cfsetispeed(&Posix_CommConfig, B1800);
                cfsetospeed(&Posix_CommConfig, B1800);
#endif
                break;

            /*2400 baud*/
            case BAUD2400:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B2400;
#else
                cfsetispeed(&Posix_CommConfig, B2400);
                cfsetospeed(&Posix_CommConfig, B2400);
#endif
                break;

            /*4800 baud*/
            case BAUD4800:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B4800;
#else
                cfsetispeed(&Posix_CommConfig, B4800);
                cfsetospeed(&Posix_CommConfig, B4800);
#endif
                break;

            /*9600 baud*/
            case BAUD9600:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B9600;
#else
                cfsetispeed(&Posix_CommConfig, B9600);
                cfsetospeed(&Posix_CommConfig, B9600);
#endif
                break;

            /*14400 baud*/
            case BAUD14400:
                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 14400 baud operation.  Switching to 9600 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B9600;
#else
                cfsetispeed(&Posix_CommConfig, B9600);
                cfsetospeed(&Posix_CommConfig, B9600);
#endif
                break;

            /*19200 baud*/
            case BAUD19200:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B19200;
#else
                cfsetispeed(&Posix_CommConfig, B19200);
                cfsetospeed(&Posix_CommConfig, B19200);
#endif
                break;

            /*38400 baud*/
            case BAUD38400:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B38400;
#else
                cfsetispeed(&Posix_CommConfig, B38400);
                cfsetospeed(&Posix_CommConfig, B38400);
#endif
                break;

            /*56000 baud*/
            case BAUD56000:
                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 56000 baud operation.  Switching to 38400 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B38400;
#else
                cfsetispeed(&Posix_CommConfig, B38400);
                cfsetospeed(&Posix_CommConfig, B38400);
#endif
                break;

            /*57600 baud*/
            case BAUD57600:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B57600;
#else
                cfsetispeed(&Posix_CommConfig, B57600);
                cfsetospeed(&Posix_CommConfig, B57600);
#endif
                break;

            /*76800 baud*/
            case BAUD76800:
                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);

#ifdef B76800
                Posix_CommConfig.c_cflag|=B76800;
#else
                TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support.  Switching to 57600 baud.");
                Posix_CommConfig.c_cflag|=B57600;
#endif //B76800
#else  //CBAUD
#ifdef B76800
                cfsetispeed(&Posix_CommConfig, B76800);
                cfsetospeed(&Posix_CommConfig, B76800);
#else
                TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support.  Switching to 57600 baud.");
                cfsetispeed(&Posix_CommConfig, B57600);
                cfsetospeed(&Posix_CommConfig, B57600);
#endif //B76800
#endif //CBAUD
                break;

            /*115200 baud*/
            case BAUD115200:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B115200;
#else
                cfsetispeed(&Posix_CommConfig, B115200);
                cfsetospeed(&Posix_CommConfig, B115200);
#endif
                break;

            /*128000 baud*/
            case BAUD128000:
                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 128000 baud operation.  Switching to 115200 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B115200;
#else
                cfsetispeed(&Posix_CommConfig, B115200);
                cfsetospeed(&Posix_CommConfig, B115200);
#endif
                break;

            /*256000 baud*/
            case BAUD256000:
                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 256000 baud operation.  Switching to 115200 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B115200;
#else
                cfsetispeed(&Posix_CommConfig, B115200);
                cfsetospeed(&Posix_CommConfig, B115200);
#endif
                break;
        }
        tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
    }
    UNLOCK_MUTEX();
}
示例#26
0
文件: lnx_init.c 项目: Agnarr/xserver
void
xf86OpenConsole(void)
{
    int i, fd = -1;
    struct vt_mode VT;
    struct vt_stat vts;
    MessageType from = X_PROBED;
    char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
    char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };

    if (serverGeneration == 1) {

	/* when KeepTty check if we're run with euid==0 */
	if (KeepTty && geteuid() != 0) 
	    FatalError("xf86OpenConsole:"
		       " Server must be suid root for option \"KeepTTY\"\n");

	/*
	 * setup the virtual terminal manager
	 */
	if (VTnum != -1) {
	    xf86Info.vtno = VTnum;
	    from = X_CMDLINE;
	} else {

	    i=0;
	    while (tty0[i] != NULL) {
		if ((fd = open(tty0[i],O_WRONLY,0)) >= 0)
		  break;
		i++;
	    }
	    
	    if (fd < 0)
		FatalError(
		    "xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
		    strerror(errno));

            if (ShareVTs)
            {
                if (ioctl(fd, VT_GETSTATE, &vts) == 0)
                    xf86Info.vtno = vts.v_active;
                else
                    FatalError("xf86OpenConsole: Cannot find the current"
                               " VT (%s)\n", strerror(errno));
            } else {
	        if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
		    (xf86Info.vtno == -1))
		    FatalError("xf86OpenConsole: Cannot find a free VT: %s\n",
                               strerror(errno));
            }
	    close(fd);
	}

	xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);

	if (!KeepTty) {
	    pid_t ppid = getppid();
	    pid_t ppgid;
	    ppgid = getpgid(ppid);

	    /*
	     * change to parent process group that pgid != pid so
	     * that setsid() doesn't fail and we become process
	     * group leader
	     */
	    if (setpgid(0,ppgid) < 0)
		xf86Msg(X_WARNING, "xf86OpenConsole: setpgid failed: %s\n",
			strerror(errno));

	    /* become process group leader */
	    if ((setsid() < 0))
		xf86Msg(X_WARNING, "xf86OpenConsole: setsid failed: %s\n",
			strerror(errno));
	}

        i=0;
        while (vcs[i] != NULL) {
            sprintf(vtname, vcs[i], xf86Info.vtno); /* /dev/tty1-64 */
     	    if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) >= 0)
		break;
            i++;
        }

	if (xf86Info.consoleFd < 0)
	    FatalError("xf86OpenConsole: Cannot open virtual console"
		       " %d (%s)\n", xf86Info.vtno, strerror(errno));

        if (!ShareVTs)
        {
	    /*
	     * Grab the vt ownership before we overwrite it.
	     * Hard coded /dev/tty0 into this function as well for below.
	     */
	    if (!saveVtPerms())
	        xf86Msg(X_WARNING,
		        "xf86OpenConsole: Could not save ownership of VT\n");

	    if (geteuid() == 0) {
		    /* change ownership of the vt */
		    if (chown(vtname, getuid(), getgid()) < 0)
			    xf86Msg(X_WARNING,"xf86OpenConsole: chown %s failed: %s\n",
				    vtname, strerror(errno));

		    /*
		     * the current VT device we're running on is not
		     * "console", we want to grab all consoles too
		     *
		     * Why is this needed??
		     */
		    if (chown("/dev/tty0", getuid(), getgid()) < 0)
			    xf86Msg(X_WARNING,"xf86OpenConsole: chown /dev/tty0 failed: %s\n",
				    strerror(errno));
	    }
        }

	/*
	 * Linux doesn't switch to an active vt after the last close of a vt,
	 * so we do this ourselves by remembering which is active now.
	 */
	if (ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts) < 0)
	    xf86Msg(X_WARNING,"xf86OpenConsole: VT_GETSTATE failed: %s\n",
		    strerror(errno));
	else
	    activeVT = vts.v_active;

#if 0
	if (!KeepTty) {
	    /*
	     * Detach from the controlling tty to avoid char loss
	     */
	    if ((i = open("/dev/tty",O_RDWR)) >= 0) {
		ioctl(i, TIOCNOTTY, 0);
		close(i);
	    }
	}
#endif

        if (!ShareVTs)
        {
            struct termios nTty;

	    /*
	     * now get the VT.  This _must_ succeed, or else fail completely.
	     */
	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
	        FatalError("xf86OpenConsole: VT_ACTIVATE failed: %s\n",
		           strerror(errno));

	    if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
	        FatalError("xf86OpenConsole: VT_WAITACTIVE failed: %s\n",
			   strerror(errno));

	    if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
	        FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
		           strerror(errno));

	    signal(SIGUSR1, xf86VTRequest);

	    VT.mode = VT_PROCESS;
	    VT.relsig = SIGUSR1;
	    VT.acqsig = SIGUSR1;

	    if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
	        FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
		    strerror(errno));
	
	    if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
	        FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
		           strerror(errno));

            tcgetattr(xf86Info.consoleFd, &tty_attr);
            ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode);

            if (ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW) < 0)
                FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n",
                        strerror(errno));

            nTty = tty_attr;
            nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
            nTty.c_oflag = 0;
            nTty.c_cflag = CREAD | CS8;
            nTty.c_lflag = 0;
            nTty.c_cc[VTIME]=0;
            nTty.c_cc[VMIN]=1;
            cfsetispeed(&nTty, 9600);
            cfsetospeed(&nTty, 9600);
            tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);

            /* need to keep the buffer clean, else the kernel gets angry */
	    if (xf86Info.allowEmptyInput)
		console_handler = xf86AddGeneralHandler(xf86Info.consoleFd,
							drain_console, NULL);

	    /* we really should have a InitOSInputDevices() function instead
	     * of Init?$#*&Device(). So I just place it here */
        }
    } else { 	/* serverGeneration != 1 */
        if (!ShareVTs && VTSwitch)
        {
	    /*
	     * now get the VT
	     */
	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
	        xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed %s\n",
		        strerror(errno));

	    if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
	        xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed %s\n",
		        strerror(errno));
        }
    }
}
示例#27
0
int main( int argc, char **argv )
{
    int         sig;
    int         rc;
    int         opt;
    char        devName[ 40 ];
    const char *baudStr = NULL;
    const char *portStr = "ttyS2";
    speed_t     baudRate;
    sigset_t    termSig;
    pthread_t   readSerialThreadId;
    pthread_t   readStdinThreadId;
    struct termios stdin_tio;
    struct termios stdin_tio_org;

    struct termios attr;

    // Parse the command line options

    while (( opt = getopt_long( argc, argv, "b:dhp:v", gLongOption, NULL )) > 0 )
    {
        switch ( opt )
        {
            case 'b':
            {
                baudStr = optarg;
                break;
            }

            case 'd':
            {
                gDebug = 1;
                break;
            }

            case 'p':
            {
                portStr = optarg;
                break;
            }

            case 'v':
            {
                gVerbose = 1;
                break;
            }
            case '?':
            case 'h':
            {
                Usage();
                return 1;
            }
        }
    }

    devName[ 0 ] = '\0';
    if ( portStr[ 0 ] != '/' )
    {
        StrMaxCpy( devName, "/dev/", sizeof( devName ));
    }
    StrMaxCat( devName, portStr, sizeof( devName ));


    baudRate = B0;
    if ( baudStr == NULL )
    {
        baudRate = B9600;
    }
    else
    {
        int baudIdx;
        int testBaud = atoi( baudStr );

        for ( baudIdx = 0; baudIdx < ARRAY_LEN( gBaudTable ); baudIdx++ ) 
        {
            if ( gBaudTable[ baudIdx ].baudRate == testBaud )
            {
                baudRate = gBaudTable[ baudIdx ].speed;
                break;
            }
        }

        if ( baudRate == B0 )
        {
            fprintf( stderr, "Unrecognized baud rate: '%s'\n", baudStr );
            exit( 1 );
        }
    }

    if (( gPortFd = open( devName, O_RDWR | O_EXCL )) < 0 )
    {
        fprintf( stderr, "Unable to open serial port '%s': %s\n", devName, strerror( errno ));
        exit( 2 );
    }

    if ( tcgetattr( gPortFd, &attr ) < 0 )
    {
        fprintf( stderr, "Call to tcgetattr failed: %s\n", strerror( errno ));
        exit( 3 );
    }

    cfmakeraw( &attr );

    // CLOCAL - Disable modem control lines
    // CREAD  - Enable Receiver

    attr.c_cflag |= ( CLOCAL | CREAD );

    cfsetispeed( &attr, baudRate );
    cfsetospeed( &attr, baudRate );

    if ( tcsetattr( gPortFd, TCSAFLUSH, &attr ) < 0 )
    {
        fprintf( stderr, "Call to tcsetattr failed: %s\n", strerror( errno ));
        exit( 4 );
    }

    // Put stdin & stdout in unbuffered mode.

    setbuf( stdin, NULL );
    setbuf( stdout, NULL );

    sigemptyset( &termSig );
    sigaddset( &termSig, SIGINT );
    sigaddset( &termSig, SIGTERM );

    pthread_sigmask( SIG_BLOCK, &termSig, NULL );

    // Put stdin in raw mode (i.e. turn off canonical mode). Canonical mode
    // causes the driver to wait for the RETURN character so that line editing
    // can take place. We also want to turn off ECHO.

    if ( tcgetattr( fileno( stdin ), &stdin_tio_org ) < 0 )
    {
        fprintf( stderr, "Unable to retrieve terminal settings: %s\n", strerror( errno ));
        exit( 5 );
    }

    stdin_tio = stdin_tio_org;
    stdin_tio.c_lflag &= ~( ICANON | ECHO );
    stdin_tio.c_cc[VTIME] = 0;
    stdin_tio.c_cc[VMIN] = 1;

    if ( tcsetattr( fileno( stdin ), TCSANOW, &stdin_tio ) < 0 )
    {
        fprintf( stderr, "Unable to update terminal settings: %s\n", strerror( errno ));
        exit( 6 );
    }

    // Kick off the serial port reader thread.

    rc = pthread_create( &readSerialThreadId, NULL, ReadSerialThread, NULL );
    if ( rc != 0 )
    {
        fprintf( stderr, "Error creating ReadSerialThread: %s\n", strerror( rc ));
        exit( 7 );
    }

    // Kick off the stdin reader thread

    rc = pthread_create( &readStdinThreadId, NULL, ReadStdinThread, NULL );
    if ( rc != 0 )
    {
        fprintf( stderr, "Error creating ReadStdinThread: %s\n", strerror( rc ));
        exit( 7 );
    }

    // Wait for a termmination signal

    if (( rc = sigwait( &termSig, &sig )) != 0 )
    {
        fprintf( stderr, "sigwait failed\n" );
    }
    else
    {
        fprintf( stderr, "Exiting...\n" );
    }

    pthread_cancel( readSerialThreadId );
    pthread_cancel( readStdinThreadId );

    // Restore stdin back to the way it was when we started

    if ( tcsetattr( fileno( stdin ), TCSANOW, &stdin_tio_org ) < 0 )
    {
        fprintf( stderr, "Unable to update terminal settings: %s\n", strerror( errno ));
        exit( 6 );
    }

    // Unblock the termination signals so the user can kill us if we hang up
    // waiting for the reader threads to exit.

    pthread_sigmask( SIG_UNBLOCK, &termSig, NULL );

    pthread_join( readSerialThreadId, NULL );
    pthread_join( readStdinThreadId, NULL );

    close( gPortFd );

    if ( gVerbose )
    {
        fprintf( stderr, "Done\n" );
    }

    exit( 0 );
    return 0;   // Get rid of warning about not returning anything
}
示例#28
0
//---------------------------------------------------------------------------
void OpenComms(void)
{
	const char *device = CommPortString.c_str();
	fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
	if (fd == -1) {
		LoggingFile.mLogFile << "failed to open port:" << endl;
		ShowMessage(device);
		CloseComms();
		return;
	}
	
	if (!isatty(fd)) {
		LoggingFile.mLogFile << "not a tty:" << endl;
		ShowMessage(device);
		CloseComms();
		return;
	}
	
	if (tcgetattr(fd, &config) < 0) {
		LoggingFile.mLogFile << "failed to get port info" << endl;
		CloseComms();
		return;
	}
	
	//
	// Input flags - Turn off input processing
	// convert break to null byte, no CR to NL translation,
	// no NL to CR translation, don't mark parity errors or breaks
	// no input parity check, don't strip high bit off,
	// no XON/XOFF software flow control
	//
	config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | 
						INLCR | PARMRK | INPCK | ISTRIP | IXON);
	//
	// Output flags - Turn off output processing
	// no CR to NL translation, no NL to CR-NL translation,
	// no NL to CR translation, no column 0 CR suppression,
	// no Ctrl-D suppression, no fill characters, no case mapping,
	// no local output processing
	//
	// config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
	//                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
	config.c_oflag = 0;
	
	//
	// No line processing:
	// echo off, echo newline off, canonical mode off, 
	// extended input processing off, signal chars off
	//
	config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
	
	//
	// Turn off character processing
	// clear current char size mask, no parity checking,
	// no output processing, force 8 bit input
	//
	config.c_cflag &= ~(CSIZE | PARENB | CSTOPB);
	config.c_cflag |= CS8;
	
	//
	// One input byte is enough to return from read()
	// Inter-character timer off
	//
	config.c_cc[VMIN]  = 1;
	config.c_cc[VTIME] = 0;
	
	//
	// Communication speed (simple version, using the predefined
	// constants)
	//
	if (cfsetispeed(&config, B19200) < 0 || cfsetospeed(&config, B19200) < 0) {
		LoggingFile.mLogFile << "failed to set port speed" << endl;
		CloseComms();
		return;
	}
	
	//
	// Finally, apply the configuration
	//
	if (tcsetattr(fd, TCSAFLUSH, &config) < 0) {
		LoggingFile.mLogFile << "failed to configure port" << endl;
		CloseComms();
		return;
	}
	
	LoggingFile.mLogFile << "Opened port " << device << endl;
}
示例#29
0
int set_baudrate_length_parity_stopbits(int fd, unsigned int new_baudrate, int length, char parity_c, int stopbits)
{
    struct termios uart_cfg_opt;
	speed_t speed;
	struct serial_struct ss;
	char  using_custom_speed = 0;
	
	if(-1==fd)
		return -1;

	/* Get current uart configure option */
	if(-1 == tcgetattr(fd, &uart_cfg_opt))
		return -1;

	tcflush(fd, TCIOFLUSH);

	/* Baud rate setting section */
	speed = get_speed(new_baudrate);
	if(CBAUDEX != speed){
		/*set standard buadrate setting*/
		cfsetospeed(&uart_cfg_opt, speed);
		cfsetispeed(&uart_cfg_opt, speed);
		printf("Standard baud\r\n");
	}else{
		printf("Custom baud\r\n");
		using_custom_speed = 1;
	}
	/* Apply baudrate settings */
	if(-1==tcsetattr(fd, TCSANOW, &uart_cfg_opt))
		return -1;
    
	/* Set time out */
	uart_cfg_opt.c_cc[VTIME] = 1;
	uart_cfg_opt.c_cc[VMIN] = 0;

	/*if((ioctl(fd,TIOCGSERIAL,&ss)) < 0)
		return -1;

	if(using_custom_speed){
		ss.flags |= ASYNC_SPD_CUST;  
        	ss.custom_divisor = 1<<31|new_baudrate;
        }else
        	ss.flags &= ~ASYNC_SPD_CUST;    

	if((ioctl(fd, TIOCSSERIAL, &ss)) < 0)
		return -1;//*/

	/* Data length setting section */
	uart_cfg_opt.c_cflag &= ~CSIZE;
	switch(length)
	{
	default:
	case 8:
		uart_cfg_opt.c_cflag |= CS8;
		break;
	case 5:
		uart_cfg_opt.c_cflag |= CS5;
		break;
	case 6:
		uart_cfg_opt.c_cflag |= CS6;
		break;
	case 7:
		uart_cfg_opt.c_cflag |= CS7;
		break;
	}

	/* Parity setting section */
	uart_cfg_opt.c_cflag &= ~(PARENB|PARODD);
	switch(parity_c)
	{
	default:
	case 'N':
	case 'n':
		uart_cfg_opt.c_iflag &= ~INPCK;
		break;
	case 'O':
	case 'o':
		uart_cfg_opt.c_cflag |= (PARENB|PARODD);
		uart_cfg_opt.c_iflag |= INPCK;
		break;
	case 'E':
	case 'e':
		uart_cfg_opt.c_cflag |= PARENB;
		uart_cfg_opt.c_iflag |= INPCK;
		break;
	}

	/* Stop bits setting section */
	if(2==stopbits)
		uart_cfg_opt.c_cflag |= CSTOPB;
	else
		uart_cfg_opt.c_cflag &= ~CSTOPB;

	/* Using raw data mode */
	uart_cfg_opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	uart_cfg_opt.c_iflag &= ~(INLCR | IGNCR | ICRNL | IXON | IXOFF);
	uart_cfg_opt.c_oflag &=~(INLCR|IGNCR|ICRNL);
	uart_cfg_opt.c_oflag &=~(ONLCR|OCRNL);

	/* Apply new settings */
	if(-1==tcsetattr(fd, TCSANOW, &uart_cfg_opt))
		return -1;

	tcflush(fd,TCIOFLUSH);

	/* All setting applied successful */
	printf("setting apply done\r\n");
	return 0;
}
示例#30
0
//----------------------------------------------------------------
bool ofSerial::setup(string portName, int baud){

	bInited = false;

	//---------------------------------------------
	#if defined( TARGET_OSX ) || defined( TARGET_LINUX )
	//---------------------------------------------

	    ofLog(OF_NOTICE,"ofSerialInit: opening port %s @ %d bps", portName.c_str(), baud);
		fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
		if(fd == -1){
			ofLog(OF_ERROR,"ofSerial: unable to open port");
			return false;
		}

		struct termios options;
		tcgetattr(fd,&oldoptions);
		options = oldoptions;
		switch(baud){
		   case 300: 	cfsetispeed(&options,B300);
						cfsetospeed(&options,B300);
						break;
		   case 1200: 	cfsetispeed(&options,B1200);
						cfsetospeed(&options,B1200);
						break;
		   case 2400: 	cfsetispeed(&options,B2400);
						cfsetospeed(&options,B2400);
						break;
		   case 4800: 	cfsetispeed(&options,B4800);
						cfsetospeed(&options,B4800);
						break;
		   case 9600: 	cfsetispeed(&options,B9600);
						cfsetospeed(&options,B9600);
						break;
		   case 14400: 	cfsetispeed(&options,B14400);
						cfsetospeed(&options,B14400);
						break;
		   case 19200: 	cfsetispeed(&options,B19200);
						cfsetospeed(&options,B19200);
						break;
		   case 28800: 	cfsetispeed(&options,B28800);
						cfsetospeed(&options,B28800);
						break;
		   case 38400: 	cfsetispeed(&options,B38400);
						cfsetospeed(&options,B38400);
						break;
		   case 57600:  cfsetispeed(&options,B57600);
						cfsetospeed(&options,B57600);
						break;
		   case 115200: cfsetispeed(&options,B115200);
						cfsetospeed(&options,B115200);
						break;

			default:	cfsetispeed(&options,B9600);
						cfsetospeed(&options,B9600);
						ofLog(OF_ERROR,"ofSerialInit: cannot set %i baud setting baud to 9600\n", baud);
						break;
		}

		options.c_cflag |= (CLOCAL | CREAD);
		options.c_cflag &= ~PARENB;
		options.c_cflag &= ~CSTOPB;
		options.c_cflag &= ~CSIZE;
		options.c_cflag |= CS8;
		tcsetattr(fd,TCSANOW,&options);

		bInited = true;
		ofLog(OF_NOTICE,"sucess in opening serial connection");

	    return true;
	//---------------------------------------------
    #endif
    //---------------------------------------------


    //---------------------------------------------
	#ifdef TARGET_WIN32
	//---------------------------------------------

	// open the serial port:
	// "COM4", etc...

	hComm=CreateFileA(portName.c_str(),GENERIC_READ|GENERIC_WRITE,0,0,
					OPEN_EXISTING,0,0);

	if(hComm==INVALID_HANDLE_VALUE){
		ofLog(OF_ERROR,"ofSerial: unable to open port");
		return false;
	}


	// now try the settings:
	COMMCONFIG cfg;
	DWORD cfgSize;
	char  buf[80];

	cfgSize=sizeof(cfg);
	GetCommConfig(hComm,&cfg,&cfgSize);
	int bps = baud;
	sprintf(buf,"baud=%d parity=N data=8 stop=1",bps);

	#if (_MSC_VER)       // microsoft visual studio
		// msvc doesn't like BuildCommDCB,
		//so we need to use this version: BuildCommDCBA
		if(!BuildCommDCBA(buf,&cfg.dcb)){
			ofLog(OF_ERROR,"ofSerial: unable to build comm dcb; (%s)",buf);
		}
	#else
		if(!BuildCommDCB(buf,&cfg.dcb)){
			ofLog(OF_ERROR,"ofSerial: Can't build comm dcb; %s",buf);
		}
	#endif


	// Set baudrate and bits etc.
	// Note that BuildCommDCB() clears XON/XOFF and hardware control by default

	if(!SetCommState(hComm,&cfg.dcb)){
		ofLog(OF_ERROR,"ofSerial: Can't set comm state");
	}
	//ofLog(OF_NOTICE,buf,"bps=%d, xio=%d/%d",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX);

	// Set communication timeouts (NT)
	COMMTIMEOUTS tOut;
	GetCommTimeouts(hComm,&oldTimeout);
	tOut = oldTimeout;
	// Make timeout so that:
	// - return immediately with buffered characters
	tOut.ReadIntervalTimeout=MAXDWORD;
	tOut.ReadTotalTimeoutMultiplier=0;
	tOut.ReadTotalTimeoutConstant=0;
	SetCommTimeouts(hComm,&tOut);

	bInited = true;
	return true;
	//---------------------------------------------
	#endif
	//---------------------------------------------
}