/*
* Thanks to Gary Frerking (gary@frerking.org) and Peter Bauman
* for writing the "Serial Programming Howto"
*
*/
#include "serial_low_level.h"
bool wait_flag = true;
void signal_handler_IO (int status);
void signal_handler_IO (int status)
{
Q_UNUSED (status);
//printf("received SIGIO signal.\n");
wait_flag = false;
}
serial_low_level::serial_low_level()
{
file_desc = -1;
}
int serial_low_level
::initialize_serial_port(QString devicename
) {
open_serial_port(devicename);
if (file_desc < 0)
return -1;
install_serial_handler();
//qDebug() << "serial_low_level::initialize_serial_port: file_desc = " << file_desc;
return file_desc;
}
void serial_low_level
::open_serial_port(QString devicename
) {
// convert string to const char*
const char *devname_as_char = tmp_devname.data();
//open the device in non-blocking way (read will return immediately)
file_desc = open(devname_as_char, O_RDWR | O_NOCTTY | O_NONBLOCK);
}
void serial_low_level::install_serial_handler(void)
{
//install the serial handler before making the device asynchronous
saio.sa_handler = &signal_handler_IO;
sigemptyset(&saio.sa_mask); //saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
// allow the process to receive SIGIO
fcntl(file_desc, F_SETOWN, getpid());
// make the file descriptor asynchronous
fcntl(file_desc, F_SETFL, FASYNC);
// set new port settings for canonical input processing
newtio.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VMIN] = 1;
newtio.c_cc[VTIME] = 0;
tcflush(file_desc, TCIFLUSH);
tcsetattr(file_desc,TCSANOW,&newtio);
}
{
char tmp_buffer[255];
int byte_count;
if (wait_flag == true) //if input is available
return result;
byte_count = read(file_desc,tmp_buffer,255);
if (byte_count <= 0)
return result;
// headnut. For some reason get/setRawData doesn't work
for (int i=0; i<byte_count; i++)
result.append(tmp_buffer[i]);
wait_flag = true; /* wait for new input */
//qDebug() << "serial_low_level::read_channel: byte_count = " << result.count() << " " << byte_count;
return result;
}
void serial_low_level::write_channel(char* data, int length)
{
int result = write(file_desc, data, length);
Q_UNUSED(result);
}
void serial_low_level::close_serial_port(void)
{
close(file_desc);
file_desc = -1;
}
bool serial_low_level::isOpen(void)
{
if (file_desc == -1)
return false;
else
return true;
}
/*
* Thanks to Gary Frerking (gary@frerking.org) and Peter Bauman
* for writing the "Serial Programming Howto"
*
*/
#include "serial_low_level.h"
bool wait_flag = true;
void signal_handler_IO (int status);
void signal_handler_IO (int status)
{
Q_UNUSED (status);
//printf("received SIGIO signal.\n");
wait_flag = false;
}
serial_low_level::serial_low_level()
{
file_desc = -1;
}
int serial_low_level::initialize_serial_port(QString devicename)
{
open_serial_port(devicename);
if (file_desc < 0)
return -1;
install_serial_handler();
//qDebug() << "serial_low_level::initialize_serial_port: file_desc = " << file_desc;
return file_desc;
}
void serial_low_level::open_serial_port(QString devicename)
{
// convert string to const char*
QByteArray tmp_devname = devicename.toLatin1();
const char *devname_as_char = tmp_devname.data();
//open the device in non-blocking way (read will return immediately)
file_desc = open(devname_as_char, O_RDWR | O_NOCTTY | O_NONBLOCK);
}
void serial_low_level::install_serial_handler(void)
{
//install the serial handler before making the device asynchronous
saio.sa_handler = &signal_handler_IO;
sigemptyset(&saio.sa_mask); //saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
// allow the process to receive SIGIO
fcntl(file_desc, F_SETOWN, getpid());
// make the file descriptor asynchronous
fcntl(file_desc, F_SETFL, FASYNC);
// set new port settings for canonical input processing
newtio.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VMIN] = 1;
newtio.c_cc[VTIME] = 0;
tcflush(file_desc, TCIFLUSH);
tcsetattr(file_desc,TCSANOW,&newtio);
}
QByteArray serial_low_level::read_channel(void)
{
char tmp_buffer[255];
int byte_count;
QByteArray result;
if (wait_flag == true) //if input is available
return result;
byte_count = read(file_desc,tmp_buffer,255);
if (byte_count <= 0)
return result;
// headnut. For some reason get/setRawData doesn't work
for (int i=0; i<byte_count; i++)
result.append(tmp_buffer[i]);
wait_flag = true; /* wait for new input */
//qDebug() << "serial_low_level::read_channel: byte_count = " << result.count() << " " << byte_count;
return result;
}
void serial_low_level::write_channel(char* data, int length)
{
int result = write(file_desc, data, length);
Q_UNUSED(result);
}
void serial_low_level::close_serial_port(void)
{
close(file_desc);
file_desc = -1;
}
bool serial_low_level::isOpen(void)
{
if (file_desc == -1)
return false;
else
return true;
}
To copy to clipboard, switch view to plain text mode
#ifndef SERIAL_LOW_LEVEL_H
#define SERIAL_LOW_LEVEL_H
#include <QString>
#include <QByteArray>
#include <qdebug.h>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/signal.h>
#include <sys/types.h>
class serial_low_level
{
public:
serial_low_level();
int initialize_serial_port
(QString devicename
);
void write_channel(char* data, int length);
void close_serial_port(void);
bool isOpen(void);
private:
void open_serial_port
(QString devicename
);
void install_serial_handler(void);
int file_desc;
struct termios newtio;
struct sigaction saio;
};
#endif // SERIAL_LOW_LEVEL_H
#ifndef SERIAL_LOW_LEVEL_H
#define SERIAL_LOW_LEVEL_H
#include <QString>
#include <QByteArray>
#include <qdebug.h>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/signal.h>
#include <sys/types.h>
QStringList get_serial_ports(void);
class serial_low_level
{
public:
serial_low_level();
int initialize_serial_port(QString devicename);
QByteArray read_channel(void);
void write_channel(char* data, int length);
void close_serial_port(void);
bool isOpen(void);
private:
void open_serial_port(QString devicename);
void install_serial_handler(void);
int file_desc;
struct termios newtio;
struct sigaction saio;
};
#endif // SERIAL_LOW_LEVEL_H
To copy to clipboard, switch view to plain text mode
Bookmarks