示例#1
0
// Return a list of all serial ports
wxArrayString Serial::port_list()
{
	wxArrayString list;
#if defined(LINUX)
	// This is ugly guessing, but Linux doesn't seem to provide anything else.
	// If there really is an API to discover serial devices on Linux, please
	// email [email protected] with the info.  Please?
	// The really BAD aspect is all ports get DTR raised briefly, because linux
	// has no way to open the port without raising DTR, and there isn't any way
	// to tell if the device file really represents hardware without opening it.
	// maybe sysfs or udev provides a useful API??
	DIR *dir;
	struct dirent *f;
	struct stat st;
	unsigned int i, len[NUM_DEVNAMES];
	char s[512];
	int fd, bits;
	termios mytios;

	dir = opendir("/dev/");
	if (dir == NULL) return list;
	for (i=0; i<NUM_DEVNAMES; i++) len[i] = strlen(devnames[i]);
	// Read all the filenames from the /dev directory...
	while ((f = readdir(dir)) != NULL) {
		// ignore everything that doesn't begin with "tty"
		if (strncmp(f->d_name, "tty", 3)) continue;
		// ignore anything that's not a known serial device name
		for (i=0; i<NUM_DEVNAMES; i++) {
			if (!strncmp(f->d_name + 3, devnames[i], len[i])) break;
		}
		if (i >= NUM_DEVNAMES) continue;
		snprintf(s, sizeof(s), "/dev/%s", f->d_name);
		// check if it's a character type device (almost certainly is)
		if (stat(s, &st) != 0 || !(st.st_mode & S_IFCHR)) continue;
		// now see if we can open the file - if the device file is
		// populating /dev but doesn't actually represent a loaded
		// driver, this is where we will detect it.
		fd = open(s, O_RDONLY | O_NOCTTY | O_NONBLOCK);
		if (fd < 0) {
			// if permission denied, give benefit of the doubt
			// (otherwise the port will be invisible to the user
			// and we won't have a to alert them to the permssion
			// problem)
		  if (errno == EACCES) list.Add(wxString(s,wxConvUTF8));
			// any other error, assume it's not a real device
			continue;
		}
		// does it respond to termios requests? (probably will since
		// the name began with tty).  Some devices where a single
		// driver exports multiple names will open but this is where
		// we can really tell if they work with real hardare.
		if (tcgetattr(fd, &mytios) != 0) {
			close(fd);
			continue;
		}
		// does it respond to reading the control signals?  If it's
		// some sort of non-serial terminal (eg, pseudo terminals)
		// this is where we will detect it's not really a serial port
		if (ioctl(fd, TIOCMGET, &bits) < 0) {
			close(fd);
			continue;
		}
		// it passed all the tests, it's a serial port, or some sort
		// of "terminal" that looks exactly like a real serial port!
		close(fd);
		// unfortunately, Linux always raises DTR when open is called.
		// not nice!  Every serial port is going to get DTR raised
		// and then lowered.  I wish there were a way to prevent this,
		// but it seems impossible.
		list.Add(wxString(s,wxConvUTF8));
	}
	closedir(dir);
#elif defined(MACOSX)
	// adapted from SerialPortSample.c, by Apple
	// http://developer.apple.com/samplecode/SerialPortSample/listing2.html
	// and also testserial.c, by Keyspan
	// http://www.keyspan.com/downloads-files/developer/macosx/KesypanTestSerial.c
	// www.rxtx.org, src/SerialImp.c seems to be based on Keyspan's testserial.c
	// neither keyspan nor rxtx properly release memory allocated.
	// more documentation at:
	// http://developer.apple.com/documentation/DeviceDrivers/Conceptual/WorkingWSerial/WWSerial_SerialDevs/chapter_2_section_6.html
	mach_port_t masterPort;
	CFMutableDictionaryRef classesToMatch;
	io_iterator_t serialPortIterator;
	if (IOMasterPort(NULL, &masterPort) != KERN_SUCCESS) return list;
	// a usb-serial adaptor is usually considered a "modem",
	// especially when it implements the CDC class spec
	classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
	if (!classesToMatch) return list;
	CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
	   CFSTR(kIOSerialBSDModemType));
	if (IOServiceGetMatchingServices(masterPort, classesToMatch,
	   &serialPortIterator) != KERN_SUCCESS) return list;
	macos_ports(&serialPortIterator, list);
	IOObjectRelease(serialPortIterator);
	// but it might be considered a "rs232 port", so repeat this
	// search for rs232 ports
	classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
	if (!classesToMatch) return list;
	CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
	   CFSTR(kIOSerialBSDRS232Type));
	if (IOServiceGetMatchingServices(masterPort, classesToMatch,
	   &serialPortIterator) != KERN_SUCCESS) return list;
	macos_ports(&serialPortIterator, list);
	IOObjectRelease(serialPortIterator);
#elif defined(WINDOWS)
	// http://msdn.microsoft.com/en-us/library/aa365461(VS.85).aspx
	// page with 7 ways - not all of them work!
	// http://www.naughter.com/enumser.html
	// may be possible to just query the windows registary
	// http://it.gps678.com/2/ca9c8631868fdd65.html
	// search in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
	// Vista has some special new way, vista-only
	// http://msdn2.microsoft.com/en-us/library/aa814070(VS.85).aspx
	char *buffer, *p;
	//DWORD size = QUERYDOSDEVICE_BUFFER_SIZE;
	DWORD ret;

	buffer = (char *)malloc(QUERYDOSDEVICE_BUFFER_SIZE);
	if (buffer == NULL) return list;
	memset(buffer, 0, QUERYDOSDEVICE_BUFFER_SIZE);
	ret = QueryDosDeviceA(NULL, buffer, QUERYDOSDEVICE_BUFFER_SIZE);
	if (ret) {
		printf("Detect Serial using QueryDosDeviceA: ");
		for (p = buffer; *p; p += strlen(p) + 1) {
			printf(":  %s", p);
			if (strncmp(p, "COM", 3)) continue;
			list.Add(wxString(p) + ":");
		}
	} else {
		char buf[1024];
		win32_err(buf);
		printf("QueryDosDeviceA failed, error \"%s\"\n", buf);
		printf("Detect Serial using brute force GetDefaultCommConfig probing: ");
		for (int i=1; i<=32; i++) {
			printf("try  %s", buf);
			COMMCONFIG cfg;
			DWORD len;
			snprintf(buf, sizeof(buf), "COM%d", i);
			if (GetDefaultCommConfig(buf, &cfg, &len)) {
				wxString name;
				name.Printf("COM%d:", i);
				list.Add(name);
				printf(":  %s", buf);
			}
		}
	}
	free(buffer);
#endif
	list.Sort();
	return list;
}
示例#2
0
// Open a port, by name.  Return 0 on success, non-zero for error
int Serial::Open(const wxString& name)
{
	Close();
#if defined(LINUX)
	struct serial_struct kernel_serial_settings;
	int bits;
	port_fd = open(name.mb_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
	if (port_fd < 0) {
		if (errno == EACCES) {
		  error_msg = _("Unable to access ") + wxString(name,wxConvUTF8) + _(", insufficient permission");
			// TODO: we could look at the permission bits and owner
			// to make a better message here
		} else if (errno == EISDIR) {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", Object is a directory, not a serial port");
		} else if (errno == ENODEV || errno == ENXIO) {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", Serial port hardware not installed");
		} else if (errno == ENOENT) {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", Device name does not exist");
		} else {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", ") + wxString(strerror(errno),wxConvUTF8);
		}
		return -1;
	}
	if (ioctl(port_fd, TIOCMGET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to query serial port signals");
		return -1;
	}
	bits &= ~(TIOCM_DTR | TIOCM_RTS);
	if (ioctl(port_fd, TIOCMSET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to control serial port signals");
		return -1;
	}
	if (tcgetattr(port_fd, &settings_orig) != 0) {
		close(port_fd);
		error_msg = _("Unable to query serial port settings (perhaps not a serial port)");
		return -1;
	}
	memset(&settings, 0, sizeof(settings));
	settings.c_iflag = IGNBRK | IGNPAR;
	settings.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
	Set_baud(baud_rate);
	if (ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings) == 0) {
		kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
		ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
	}
	tcflush(port_fd, TCIFLUSH);
#elif defined(MACOSX)
	int bits;
	port_fd = open(name.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
	if (port_fd < 0) {
	  error_msg = _("Unable to open ") + name + _(", ") + strerror(errno);
		return -1;
	}
	if (ioctl(port_fd, TIOCEXCL) == -1) {
		close(port_fd);
		error_msg = _("Unable to get exclussive access to port ") + name;
		return -1;
	}
	if (ioctl(port_fd, TIOCMGET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to query serial port signals on ") + name;
		return -1;
	}
	bits &= ~(TIOCM_DTR | TIOCM_RTS);
	if (ioctl(port_fd, TIOCMSET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to control serial port signals on ") + name;
		return -1;
	}
	if (tcgetattr(port_fd, &settings_orig) < 0) {
		close(port_fd);
		error_msg = _("Unable to access baud rate on port ") + name;
		return -1;
	}
	memset(&settings, 0, sizeof(settings));
	settings.c_cflag = CS8 | CLOCAL | CREAD | HUPCL;
	settings.c_iflag = IGNBRK | IGNPAR;
	Set_baud(baud_rate);
	tcflush(port_fd, TCIFLUSH);
#elif defined(WINDOWS)
	COMMCONFIG cfg;
	COMMTIMEOUTS timeouts;
	int got_default_cfg=0, port_num;
	char buf[1024], name_createfile[64], name_commconfig[64], *p;
	DWORD len;

	snprintf(buf, sizeof(buf), _("%s"), name.c_str());
	p = strstr(buf, _("COM"));
	if (p && sscanf(p + 3, _("%d"), &port_num) == 1) {
	  printf(_("port_num = %d\n"), port_num);
	  snprintf(name_createfile, sizeof(name_createfile), _("\\\\.\\COM%d"), port_num);
	  snprintf(name_commconfig, sizeof(name_commconfig), _("COM%d"), port_num);
	} else {
	  snprintf(name_createfile, sizeof(name_createfile), _("%s"), name.c_str());
	  snprintf(name_commconfig, sizeof(name_commconfig), _("%s"), name.c_str());
	}
	len = sizeof(COMMCONFIG);
	if (GetDefaultCommConfig(name_commconfig, &cfg, &len)) {
		// this prevents unintentionally raising DTR when opening
		// might only work on COM1 to COM9
		got_default_cfg = 1;
		memcpy(&port_cfg_orig, &cfg, sizeof(COMMCONFIG));
		cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
		cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
		SetDefaultCommConfig(name_commconfig, &cfg, sizeof(COMMCONFIG));
	} else {
	  printf(_("error with GetDefaultCommConfig\n"));
	}
	port_handle = CreateFile(name_createfile, GENERIC_READ | GENERIC_WRITE,
	   0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	if (port_handle == INVALID_HANDLE_VALUE) {
		win32_err(buf);
		error_msg =  _("Unable to open ") + name + _(", ") + buf;
		return -1;
	}
	len = sizeof(COMMCONFIG);
	if (!GetCommConfig(port_handle, &port_cfg, &len)) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to read communication config on ") + name + _(", ") + buf;
		return -1;
	}
	if (!got_default_cfg) {
		memcpy(&port_cfg_orig, &port_cfg, sizeof(COMMCONFIG));
	}
	// http://msdn2.microsoft.com/en-us/library/aa363188(VS.85).aspx
	port_cfg.dcb.BaudRate = baud_rate;
	port_cfg.dcb.fBinary = TRUE;
	port_cfg.dcb.fParity = FALSE;
	port_cfg.dcb.fOutxCtsFlow = FALSE;
	port_cfg.dcb.fOutxDsrFlow = FALSE;
	port_cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
	port_cfg.dcb.fDsrSensitivity = FALSE;
	port_cfg.dcb.fTXContinueOnXoff = TRUE;	// ???
	port_cfg.dcb.fOutX = FALSE;
	port_cfg.dcb.fInX = FALSE;
	port_cfg.dcb.fErrorChar = FALSE;
	port_cfg.dcb.fNull = FALSE;
	port_cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
	port_cfg.dcb.fAbortOnError = FALSE;
	port_cfg.dcb.ByteSize = 8;
	port_cfg.dcb.Parity = NOPARITY;
	port_cfg.dcb.StopBits = ONESTOPBIT;
	if (!SetCommConfig(port_handle, &port_cfg, sizeof(COMMCONFIG))) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to write communication config to ") + name + _(", ") + buf;
		return -1;
	}
	if (!EscapeCommFunction(port_handle, CLRDTR | CLRRTS)) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to control serial port signals on ") + name + _(", ") + buf;
		return -1;
	}
	// http://msdn2.microsoft.com/en-us/library/aa363190(VS.85).aspx
	// setting to all zeros means timeouts are not used
	//timeouts.ReadIntervalTimeout		= 0;
	timeouts.ReadIntervalTimeout		= MAXDWORD;
	timeouts.ReadTotalTimeoutMultiplier	= 0;
	timeouts.ReadTotalTimeoutConstant	= 0;
	timeouts.WriteTotalTimeoutMultiplier	= 0;
	timeouts.WriteTotalTimeoutConstant	= 0;
	if (!SetCommTimeouts(port_handle, &timeouts)) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to write timeout settings to ") + name + _(", ") + buf;
		return -1;
	}
#endif
	port_name = name;
	port_is_open = 1;
	return 0;
}
    int ArduinoSerial::openPort(const char *portName)
    {


        _portName = std::string(portName);
        _portOpened = false;
        triedToConfigureAgain = false;
        closeSerial();
        fd = 0;
        _numberOfChannels = 1;
#if defined(__APPLE__) || defined(__linux__)
        struct termios options;

        fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY);//O_SHLOCK
        sleep(2);
        int bits;
#endif
#ifdef __APPLE__
        std::stringstream sstm;

        if (fd < 0) {
            sstm << "Unable to open " << portName << ", " << strerror(errno);
            errorString = sstm.str();
            std::cout<<"Unable to open "<<portName<<", "<<strerror(errno)<<"\n";
            return -1;
        }
        if (ioctl(fd, TIOCEXCL) == -1) {
            close(fd);
            sstm << "Unable to get exclussive access to port " << portName;;
            errorString = sstm.str();
            std::cout<<"Unable to get exclussive access to port "<<portName<<"\n";
            return -1;
        }
        if (ioctl(fd, TIOCMGET, &bits) < 0) {
            close(fd);
            sstm <<"Unable to query serial port signals on " << portName;
            errorString = sstm.str();
            std::cout<<"Unable to query serial port signals on "<<portName<<"\n";
            return -1;
        }
        bits &= ~(TIOCM_DTR | TIOCM_RTS);
        if (ioctl(fd, TIOCMSET, &bits) < 0) {
            close(fd);
            sstm <<"Unable to control serial port signals on " << portName;
            errorString = sstm.str();
            std::cout<<"Unable to control serial port signals on "<<portName<<"\n";
            return -1;
        }
        struct termios settings_orig;
        if (tcgetattr(fd, &settings_orig) < 0) {
            close(fd);
            sstm <<"Unable to access baud rate on port " << portName;
            errorString = sstm.str();
            std::cout<<"Unable to access baud rate on port "<<portName<<"\n";
            return -1;
        }
#endif
#ifdef __linux__
 // struct serial_struct kernel_serial_settings;
    struct termios settings_orig;
    //struct termios settings;
    if (fd < 0)
    {
        if (errno == EACCES)
        {
            std::cout<<"Unable to access "<< portName<< ", insufficient permission";
            // TODO: we could look at the permission bits and owner
            // to make a better message here
        }
        else if (errno == EISDIR)
        {
            std::cout<< "Unable to open " << portName <<
                     ", Object is a directory, not a serial port";
        }
        else if (errno == ENODEV || errno == ENXIO)
        {
            std::cout<< "Unable to open " << portName <<
                     ", Serial port hardware not installed";
        }
        else if (errno == ENOENT)
        {
            std::cout<< "Unable to open " << portName <<
                     ", Device name does not exist";
        }
        else
        {
            std::cout<< "Unable to open " << portName; //<<

        }
        return -1;
    }
    if (ioctl(fd, TIOCMGET, &bits) < 0)
    {
        close(fd);
        std::cout<< "Unable to query serial port signals";
        return -1;
    }
    bits &= ~(TIOCM_DTR | TIOCM_RTS);
    if (ioctl(fd, TIOCMSET, &bits) < 0)
    {
        close(fd);
        std::cout<< "Unable to control serial port signals";
        return -1;
    }
    if (tcgetattr(fd, &settings_orig) != 0)
    {
        close(fd);
        std::cout<< "Unable to query serial port settings (perhaps not a serial port)";
        return -1;
    }
    /*memset(&settings, 0, sizeof(settings));
    settings.c_iflag = IGNBRK | IGNPAR;
    settings.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
    Set_baud(baud_rate);
    if (ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings) == 0) {
    	kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
    	ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
    }
    tcflush(port_fd, TCIFLUSH);*/
#endif
#if defined(__APPLE__) || defined(__linux__)
        if (fd == -1)
        {
            std::cout<<"Can't open serial port\n";
            return -1;
        }
        fcntl(fd, F_SETFL, 0);    // clear all flags on descriptor, enable direct I/O
        tcgetattr(fd, &options);   // read serial port options
        // enable receiver, set 8 bit data, ignore control lines
        options.c_cflag |= (CLOCAL | CREAD | CS8);
        // disable parity generation and 2 stop bits
        options.c_cflag &= ~(PARENB | CSTOPB);

        //cfsetispeed(&options, B9600);
        //cfsetospeed(&options, B9600);

        cfsetispeed(&options, B230400);
        cfsetospeed(&options, B230400);

        // set the new port options
        tcsetattr(fd, TCSANOW, &options);
#endif

#ifdef _WIN32

	COMMCONFIG cfg;
	COMMTIMEOUTS timeouts;
	int got_default_cfg=0, port_num;
	char buf[1024], name_createfile[64], name_commconfig[64], *p;
	DWORD len;

	snprintf(buf, sizeof(buf), "%s", _portName.c_str());
	p = strstr(buf, "COM");
	if (p && sscanf(p + 3, "%d", &port_num) == 1) {
		printf("port_num = %d\n", port_num);
		snprintf(name_createfile, sizeof(name_createfile), "\\\\.\\COM%d", port_num);
		snprintf(name_commconfig, sizeof(name_commconfig), "COM%d", port_num);
	} else {
		snprintf(name_createfile, sizeof(name_createfile), "%s", _portName.c_str());
		snprintf(name_commconfig, sizeof(name_commconfig), "%s", _portName.c_str());
	}
	len = sizeof(COMMCONFIG);
	if (GetDefaultCommConfig(name_commconfig, &cfg, &len)) {
		// this prevents unintentionally raising DTR when opening
		// might only work on COM1 to COM9
		got_default_cfg = 1;
		memcpy(&port_cfg_orig, &cfg, sizeof(COMMCONFIG));
		cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
		cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
		SetDefaultCommConfig(name_commconfig, &cfg, sizeof(COMMCONFIG));
	} else {
		printf("error with GetDefaultCommConfig\n");
	}
	port_handle = CreateFile(name_createfile, GENERIC_READ | GENERIC_WRITE,
	   0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	if (port_handle == INVALID_HANDLE_VALUE) {
		win32_err(buf);
		//error_msg =  "Unable to open " + _portName + ", " + buf;
		return -1;
	}
	len = sizeof(COMMCONFIG);
	if (!GetCommConfig(port_handle, &port_cfg, &len)) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to read communication config on " + _portName + ", " + buf;
		return -1;
	}
	if (!got_default_cfg) {
		memcpy(&port_cfg_orig, &port_cfg, sizeof(COMMCONFIG));
	}
	// http://msdn2.microsoft.com/en-us/library/aa363188(VS.85).aspx
	port_cfg.dcb.BaudRate = 230400;
	port_cfg.dcb.fBinary = TRUE;
	port_cfg.dcb.fParity = FALSE;
	port_cfg.dcb.fOutxCtsFlow = FALSE;
	port_cfg.dcb.fOutxDsrFlow = FALSE;
	port_cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
	port_cfg.dcb.fDsrSensitivity = FALSE;
	port_cfg.dcb.fTXContinueOnXoff = TRUE;	// ???
	port_cfg.dcb.fOutX = FALSE;
	port_cfg.dcb.fInX = FALSE;
	port_cfg.dcb.fErrorChar = FALSE;
	port_cfg.dcb.fNull = FALSE;
	port_cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
	port_cfg.dcb.fAbortOnError = FALSE;
	port_cfg.dcb.ByteSize = 8;
	port_cfg.dcb.Parity = NOPARITY;
	port_cfg.dcb.StopBits = ONESTOPBIT;
	if (!SetCommConfig(port_handle, &port_cfg, sizeof(COMMCONFIG))) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to write communication config to " + name + ", " + buf;
		return -1;
	}
	if (!EscapeCommFunction(port_handle, CLRDTR | CLRRTS)) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to control serial port signals on " + name + ", " + buf;
		return -1;
	}
	// http://msdn2.microsoft.com/en-us/library/aa363190(VS.85).aspx
	// setting to all zeros means timeouts are not used
	//timeouts.ReadIntervalTimeout		= 0;
	timeouts.ReadIntervalTimeout		= MAXDWORD;
	timeouts.ReadTotalTimeoutMultiplier	= 0;
	timeouts.ReadTotalTimeoutConstant	= 0;
	timeouts.WriteTotalTimeoutMultiplier	= 0;
	timeouts.WriteTotalTimeoutConstant	= 0;
	if (!SetCommTimeouts(port_handle, &timeouts)) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to write timeout settings to " + name + ", " + buf;
		return -1;
	}

#endif // _WIN32

        circularBuffer[0] = '\n';

        cBufHead = 0;
        cBufTail = 0;

        serialCounter = 0;

        _portOpened = true;


        setNumberOfChannelsAndSamplingRate(1, maxSamplingRate());


        return fd;
    }