Ejemplo n.º 1
0
    /** \fn bool Serial::validate_baud_rate(int pbaud_rate)
    *   \brief Validates pbaud_rate.
    *
    *   Description: Sets data members baud_rate, bspeed to valid values.
    *
    *   \param[in] pbaud_rate               baud rate
    *
    *   \return When pbaud_rate is a valid baud rate, data member baud_rate is set to
    *   pbaud_rate. bspeed is set to match the baud rate. Returns true.
    *
    *   When pbaud_rate is not valid, data member baud_rate is set to 57600,
    *   bspeed is set to B57600. Returns false.
    *
    */
    void Serial::validate_baud_rate(int pbaud_rate){
        // set the input/output baud rates
        switch(pbaud_rate)
        {
        case 2400:
        case 9600:
        case 19200:
        case 38400:
        case 57600:
        case 115200:
            baud_rate = pbaud_rate;
            break;
        default:
            baud_rate = DEFAULT_BAUD_RATE;
            LOG_WARN("invalid baud rate: %d, using default: %d", pbaud_rate,
                        DEFAULT_BAUD_RATE);

        } // end switch baud

        bspeed = set_baud_speed(baud_rate);

    }
Ejemplo n.º 2
0
    /** \fn int Serial::initialize(void);
    *   \brief Opens and configures a serial port connection.
    *
    *   The function opens a connection to the pathname stored in the Serial class
    *   data member, serial_device_name_. Returns the file descriptor to that port location.
    *
    *   Configuration:
    *       8 data bits per character
    *       No parity bit
    *       2 stop bits
    *       No hardware flow control
    *       No software flow control
    *
    *
    *   \return success: file descriptor
    *   \return failure: -1
    */
    int Serial::initialize_port(void)
    {
        struct termios oldtio,newtio;

        int serial_speed = set_baud_speed(baud_rate);

        fprintf(stderr, "device name: %s\n", serial_device_name.c_str());


        /** open() system call is used to convert a pathname into a file descriptor
        *   (a small, non-negative integer for use in subsequent I/O).
        *
        *   on success, the file descriptor returned will be the lowest file descriptor
        *   not currently open for the process.
        *
        *   on failure, returns -1
        *
        *   O_RDWR      open for read and write access
        *
        *   O_NDELAY    program doesn't care what state the DCD signal line is at - whether the
        *               other end of the port is up and running. If you do not specify this flag,
        *               your process will be put to sleep until the DCD signal line is set to the
        *               space voltage.
        */
        if( (serial_file_descriptor = open(serial_device_name.c_str(), O_RDWR | O_NDELAY)) == -1 )
        {
            fprintf(stderr, "[ERROR] (%s: %s: %d) errno: %s\n", __FILE__, __FUNCTION__,
                        __LINE__ , strerror(errno));
            return serial_file_descriptor;
        }

         // Get current serial port settings
        if( tcgetattr(serial_file_descriptor, &oldtio) < 0)
        {
            fprintf(stderr, "[ERROR] (%s: %s: %d) errno: %s\n", __FILE__, __FUNCTION__,
                        __LINE__ , strerror(errno));
            close_port();

            return serial_file_descriptor;
        }

        // New port settings
        memset(&newtio, 0, sizeof(newtio));           // set all struct values to zero
        /* Set Control mode
        *  CS8      - 8 data bits, no parity, 1 stop bit
        *  CLOCAL   - local connnection, no modem control
        *  CREAD    - enable receiving characters
        *  IGNBRK   - ignore break condition
        */
        newtio.c_cflag = serial_speed | CS8 | CLOCAL | CREAD | IGNBRK;

        /* IGNPAR - ignore bytes with parity errors
        *  ICRNL -  map CR to NL (otherwise a CR input on the other computer
                        will not terminate input)
        *
        */
        newtio.c_iflag = IGNPAR | ICRNL;
        newtio.c_oflag = 0;                     // raw output
        /*
        * ICANON  : enable canonical input
        *           disable all echo functionality, and don't send signals to calling program
        */
        newtio.c_lflag = ICANON;

        // Empty serial port buffers
        tcflush(serial_file_descriptor, TCIFLUSH);

        // Load new settings
        if( tcsetattr(serial_file_descriptor, TCSANOW, &newtio) , 0)
        {
            fprintf(stderr, "[ERROR] (%s: %s: %d) errno: %s\n", __FILE__, __FUNCTION__,
                        __LINE__ , strerror(errno));
            close(serial_file_descriptor);
            serial_file_descriptor = -1;
            return serial_file_descriptor;
        }

        return serial_file_descriptor;

    }
Ejemplo n.º 3
0
/**
* NAME : int serial_init(const char *serial_device_name, int baud_rate)
*
* DESCRIPTION: opens serial port
*
* INPUTS: 
*   Parameters:
*       const char*     serial_device_name              serial device path name
                                                        example: "/dev/ttyUSB0"
*       int             baud_rate                       baud rate 
*   Globals:
*       none
*
* OUTPUTS:
*   Return:
*       Type: int
*       Values:            
*           success     serial port file descriptor.
*           failure     -1
*
* PROCESS:
*       [1] open serial port connection 
*       [2] sets speed to specified baud rate
*           If baud rate is not valid, sets to default rate 9600
*       [3] 8 data bits, No parity, 1 stop bit
*       [4] Raw mode, so binary data can be sent
*       [5] minimum characters to read: 0
*       [6] time to wait for data: 0
*       [7] flushes data from input & output lines
*       [8] returns valid file descriptor or -1 on error
*      
* NOTES:
*       Error messages are sent to stderr stream
*
*/
int serial_init(const char *serial_device_name, int baud_rate)
{
    int serial_port_fd;
    int bspeed; 
    struct termios terminalSettings;

    // Open the serial port nonblocking (read returns immediately)
    serial_port_fd = open(serial_device_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if(serial_port_fd < 0)             // open returns -1 on error
    {
        fprintf(stderr, "error: %s, serial port not open, errno -%s\n", 
                    __FUNCTION__, strerror(errno));

        fprintf(stderr, "serial device name: %s\n", serial_device_name);
        return -1;
    }

    else    fprintf(stderr, "serial port fd = %d\n", serial_port_fd);


    // Get current serial port settings
    if(tcgetattr(serial_port_fd, &terminalSettings) < 0){
        perror("initialize_serial: could not get current serial port settings");
        return -1;
    }


    // set baud rate
    bspeed = set_baud_speed(baud_rate);
    if(bspeed != -1){
        cfsetispeed(&terminalSettings, bspeed);
        cfsetospeed(&terminalSettings, bspeed);
    }
    else{
        return -1;
    }


    // set control flags
    terminalSettings.c_cflag &= ~PARENB;            // no parity
    terminalSettings.c_cflag &= ~CSTOPB;            // 1 stop bit
    terminalSettings.c_cflag &= ~CSIZE;             // reset character size bits
    terminalSettings.c_cflag |= CS8;                // data size 8 bit
  
    terminalSettings.c_cflag &= ~CRTSCTS;           // no flow control

    /* CREAD - enable receiver
       CLOCAL should be enabled to ensure that your program does not become 
       the 'owner' of the port subject to sporatic job control and hangup signals
    */
    terminalSettings.c_cflag |= CREAD | CLOCAL;     // enable receiver, ignore ctrl lines

    /** turn off software flow control (outgoing, incoming)
        allow any character to start flow again
    */
    terminalSettings.c_iflag &= ~(IXON | IXOFF | IXANY);    


    // configure for raw input
    terminalSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 

    // configure for raw output
    terminalSettings.c_oflag &= ~OPOST; 

    // VMIN sets minimum characters to read
    terminalSettings.c_cc[VMIN]  = 0;

    // time to wait for data (tenths of seconds)
    terminalSettings.c_cc[VTIME] = 0;


    // Load new settings
    if( tcsetattr(serial_port_fd, TCSAFLUSH, &terminalSettings) < 0){
        perror("init_serialport: Couldn't set term attributes");
        return -1;
    }

    // clear data from both input/output buffers
    /* When using a usb serial port, the USB driver does not
       know if there is data in the internal shift register, FIFO
       or USB subsystem. As a workaround, to ensure the data
       is flushed, add a sleep delay here to suspend program
       execution. This allows time for data to arrive and be
       stored in the buffers. A call to flush will then work.

       May need to experiment with sleep time.
    */
    usleep(10000);                                  // 10 ms
    tcflush(serial_port_fd, TCIOFLUSH);

    return serial_port_fd;
}