int SerialPortMacOS::convertBaudRateFlag(int baudrate)
{
    int baudRateFlag = 0;

    // Set termios baudrate flag
    if (baudrate > 0)
    {
        // Try an exact match
        baudRateFlag = rate_to_constant(baudrate);

        if (baudRateFlag != 0)
        {
            TRACE_1(SERIAL, "convertBaudRateFlag(%i) has been set to %i (exact match)\n", baudrate, baudrate);
        }
        else
        {
            int speeds[20] = {2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400,
                              460800, 500000, 576000, 921600, 1000000, 1152000,
                              1500000, 2000000, 2500000, 3000000, 3500000, 4000000};

            // Try a "close enough" match (we allow ±1.5% mismatch)
            for (int i = 0; i < 20; i++)
            {
                if ((baudrate > (static_cast<double>(speeds[i]) * 98.5 / 100.0)) && (baudrate < (static_cast<double>(speeds[i]) * 101.5 / 100.0)))
                {
                    baudRateFlag = rate_to_constant(speeds[i]);
                    TRACE_WARNING(SERIAL, "convertBaudRateFlag(%i) has been set to B%i (close enough match, ±1.5%)\n", baudrate, speeds[i]);
                    break;
                }
            }

            // Try a custom speed
            if (baudRateFlag == 0)
            {
                ttyCustomSpeed = true;
                baudRateFlag = B38400;
                TRACE_WARNING(SERIAL, "convertBaudRateFlag(%i) has been set to B38400 (custom speed will be used)\n", baudrate);
            }
        }
    }
    else
    {
        TRACE_ERROR(SERIAL, "Invalid baudrate, using default value of: B1000000\n");
    }

    // Fallback
    if (baudRateFlag == 0)
    {
        baudRateFlag = B1000000;
        TRACE_ERROR(SERIAL, "Unable to set baud speed at %i: too slow!\n", baudrate);
        TRACE_ERROR(SERIAL, "Invalid baudrate, using default value of: B1000000\n");
    }

    return baudRateFlag;
}
Esempio n. 2
0
/* Open serial port in raw mode, with custom baudrate if necessary */
int serial_open(const char *device, int rate, int stopbits)
{
    struct termios options;
    int fd;
    int speed = 0;

    if ((fd = open(device, O_RDWR | O_NOCTTY)) == -1)
        return -1;

    speed = rate_to_constant(rate);

    if (speed == 0) {
        return -1;
        /* Custom divisor */
        /* struct serial_struct serinfo;
         *
         *
         * serinfo.reserved_char[0] = 0;
        if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
            return -1;
        serinfo.flags &= ~ASYNC_SPD_MASK;
        serinfo.flags |= ASYNC_SPD_CUST;
        serinfo.custom_divisor = (serinfo.baud_base + (rate / 2)) / rate;
        if (serinfo.custom_divisor < 1)
            serinfo.custom_divisor = 1;
        if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0)
            return -1;
        if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
            return -1;
        if (serinfo.custom_divisor * rate != serinfo.baud_base) {
            warnx("actual baudrate is %d / %d = %f",
                  serinfo.baud_base, serinfo.custom_divisor,
                  (float)serinfo.baud_base / serinfo.custom_divisor);
        }*/
    }

    fcntl(fd, F_SETFL, 0);
    tcgetattr(fd, &options);
    cfsetispeed(&options, speed ?: B38400);
    cfsetospeed(&options, speed ?: B38400);
    cfmakeraw(&options);

    options.c_cflag |= (CLOCAL | CREAD);
    // No hardware flow control, no parity, clear size, no hangup on close
    options.c_cflag &= ~(PARENB | CRTSCTS | CSIZE | HUPCL);
    options.c_cflag |= CS8; //8 bits

    if (stopbits >= 2) {
        options.c_cflag |= CSTOPB;
    } else {
        options.c_cflag &= ~CSTOPB;
    }

    if (tcsetattr(fd, TCSANOW, &options) != 0)
        return -1;

    return fd;
}
static int serialOpen(const char *device, int rate)
{
	struct termios options;
	struct serial_struct serinfo;
	int fd;
	int speed = 0;

	/* Open and configure serial port */
	if ((fd = open(device,O_RDWR|O_NOCTTY)) == -1)
		return -1;

	speed = rate_to_constant(rate);

	if (speed == 0) {
		/* Custom divisor */
		serinfo.reserved_char[0] = 0;
		if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
			perror("TIOCGSERIAL");
			return -1;
		}
		serinfo.flags &= ~ASYNC_SPD_MASK;
		serinfo.flags |= ASYNC_SPD_CUST;
		serinfo.custom_divisor = (serinfo.baud_base + (rate / 2)) / rate;
		if (serinfo.custom_divisor < 1) 
			serinfo.custom_divisor = 1;
		if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
			perror("TIOCSSERIAL");
			return -1;
		}
		if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
			perror("TIOCGSERIAL");
			return -1;
		}
		if (1 || serinfo.custom_divisor * rate != serinfo.baud_base) {
			warnx("actual baudrate is %d / %d = %f",
			      serinfo.baud_base, serinfo.custom_divisor,
			      (float)serinfo.baud_base / serinfo.custom_divisor);
		}
	}

	fcntl(fd, F_SETFL, 0);
	tcgetattr(fd, &options);
	cfsetispeed(&options, speed ? speed : B38400);
	cfsetospeed(&options, speed ? speed : B38400);
	cfmakeraw(&options);
	options.c_cflag |= (CLOCAL | CREAD);
	options.c_cflag &= ~CRTSCTS;
	if (tcsetattr(fd, TCSANOW, &options) != 0)
		return -1;

	return fd;
}
Esempio n. 4
0
/* Open serial port in raw mode, with custom baudrate if necessary */
int mmCommInit(const char *device, int rate)
{
	struct termios options;
	struct serial_struct serinfo;
	int fd;
	int speed = 0;

	/* Open and configure serial port */
	if ((fd = open(device,O_RDWR|O_NOCTTY/*|O_NONBLOCK*/)) == -1)
		return -1;
	
	speed = rate_to_constant(rate);

	if (speed == 0) {
		/* Custom divisor */
		serinfo.reserved_char[0] = 0;
		if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
			return -1;
		serinfo.flags &= ~ASYNC_SPD_MASK;
		serinfo.flags |= ASYNC_SPD_CUST;
		serinfo.custom_divisor = (serinfo.baud_base + (rate / 2)) / rate;
		if (serinfo.custom_divisor < 1) 
			serinfo.custom_divisor = 1;
		if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0)
			return -1;
		if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
			return -1;
		if (serinfo.custom_divisor * rate != serinfo.baud_base) {
			warnx("actual baudrate is %d / %d = %f",
			      serinfo.baud_base, serinfo.custom_divisor,
			      (float)serinfo.baud_base / serinfo.custom_divisor);
		}
	}

	//fcntl(fd, F_SETFL, O_NONBLOCK);
	tcgetattr(fd, &options);
	cfsetispeed(&options, speed ?: B38400);
	cfsetospeed(&options, speed ?: B38400);
	cfmakeraw(&options);
	options.c_lflag  &= ~(ICANON|ECHO);
	options.c_cflag |= (CLOCAL | CREAD);
	options.c_cflag &= ~CRTSCTS;
	options.c_cc[VMIN] = 0;
	//options.c_cc[VTIME] = 200;
	if (tcsetattr(fd, TCSANOW, &options) != 0)
		return -1;
	
	tcflush(fd, TCIFLUSH);
	return fd;
}