int xbee_ser_open( xbee_serial_t *serial, uint32_t baudrate) { int err; if (serial == NULL) { #ifdef XBEE_SERIAL_VERBOSE printf( "%s: NULL parameter, return -EINVAL\n", __FUNCTION__); #endif return -EINVAL; } // make sure device name is null terminated serial->device[(sizeof serial->device) - 1] = '\0'; serial->fd = open( serial->device, O_RDWR | O_NOCTTY | O_NDELAY); if (serial->fd < 0) { #ifdef XBEE_SERIAL_VERBOSE printf( "%s: open('%s') failed (errno=%d)\n", __FUNCTION__, serial->device, errno); #endif return -errno; } // Configure file descriptor to not block on read() if there aren't // any characters available. fcntl( serial->fd, F_SETFL, FNDELAY); // reset port before setting actual baudrate xbee_ser_baudrate( serial, 0); err = xbee_ser_baudrate( serial, baudrate); if (err) { return err; } return 0; }
void next_baudrate( xbee_serial_t *port) { uint32_t rates[] = { 9600, 19200, 38400, 57600, 115200 }; int i; for (i = 0; i < _TABLE_ENTRIES( rates); ++i) { if (port->baudrate == rates[i]) { ++i; break; } } // At end of loop, if port was using a rate not in the list above, // the code will end up setting the baudrate to 9600. xbee_ser_baudrate( port, rates[i % _TABLE_ENTRIES( rates)]); print_baudrate( port); }
int xbee_ser_open( xbee_serial_t *serial, uint32_t baudrate) { char buffer[sizeof("\\\\.\\COM9999")]; HANDLE hCom; COMMTIMEOUTS timeouts; int err; if (serial == NULL || serial->comport > 9999) { #ifdef XBEE_SERIAL_VERBOSE printf( "%s: -EINVAL (serial=%p)\n", __FUNCTION__, serial); #endif return -EINVAL; } // if XBee's existing hCom handle is not null, need to close it // (unless we're just changing the baud rate?) // Assume serial port has not changed if port is already open, and skip the // CreateFile step. if (serial->hCom) { // serial port is already open hCom = serial->hCom; serial->hCom = NULL; #ifdef XBEE_SERIAL_VERBOSE printf( "%s: port already open (hCom=%p)\n", __FUNCTION__, hCom); #endif } else { snprintf( buffer, sizeof buffer, "\\\\.\\COM%u", serial->comport); hCom = CreateFile( buffer, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hCom == INVALID_HANDLE_VALUE) { #ifdef XBEE_SERIAL_VERBOSE printf( "%s: error %lu opening handle to %s\n", __FUNCTION__, GetLastError(), buffer); #endif return -EIO; } } // set up a transmit and receive buffers SetupComm( hCom, XBEE_SER_RX_BUFSIZE, XBEE_SER_TX_BUFSIZE); /* Set the COMMTIMEOUTS structure. Per MSDN documentation for ReadIntervalTimeout, "A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that the read operation is to return immediately with the bytes that have already been received, even if no bytes have been received." */ if (!GetCommTimeouts( hCom, &timeouts)) { #ifdef XBEE_SERIAL_VERBOSE printf( "%s: %s failed (%lu initializing COM%u)\n", __FUNCTION__, "GetCommTimeouts", GetLastError(), serial->comport); #endif CloseHandle( hCom); return -EIO; } timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; if (!SetCommTimeouts( hCom, &timeouts)) { #ifdef XBEE_SERIAL_VERBOSE printf( "%s: %s failed (%lu initializing COM%u)\n", __FUNCTION__, "SetCommTimeouts", GetLastError(), serial->comport); #endif CloseHandle( hCom); return -EIO; } PurgeComm( hCom, PURGE_TXCLEAR | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_RXABORT); serial->hCom = hCom; err = xbee_ser_baudrate( serial, baudrate); if (err) { serial->hCom = NULL; return err; } #ifdef XBEE_SERIAL_VERBOSE printf( "%s: SUCCESS COM%u opened (hCom=%p, baud=%u)\n", __FUNCTION__, serial->comport, hCom, baudrate); #endif return 0; }