/QMK-Groundstation/branches/own_com_lib/SerialPort/ManageSerialPort.cpp |
---|
0,0 → 1,577 |
/******************************************************************************************************** |
* PROGRAM : QSerialPortTerminal |
* DATE - TIME : vendredi 03 octobre 2008 - 11h15 |
* AUTHOR : VIANNEY-LIAUD Philippe ( philippe.vianney.liaud gmail.com ) |
* FILENAME : ManageSerialPort.cpp |
* LICENSE : GPL |
* COMMENTARY : |
********************************************************************************************************/ |
#include <QtDebug> |
#include "ManageSerialPort.h" |
/******************************************************************************************************** |
* Classe ManageSerialPort |
*****************************************************************************************************/ |
//Constructeur |
ManageSerialPort::ManageSerialPort() |
{ |
//Init pointeur a NULL |
threadSend = NULL; |
threadReceive = NULL; |
//Init des bool |
sendingEnabled = false; |
receivingEnabled = false; |
closeCalled = false; |
saveStateSendEnabled = false; |
saveStateReceivedEnabled = false; |
saveStateReceiveData = false; |
} |
ManageSerialPort::ManageSerialPort(const QString &name, const BaudRateType baudRate, \ |
const DataBitsType dataBits, const ParityType parity, \ |
const StopBitsType stopBits, const FlowType flowControl, \ |
ulong seconds, ulong milliseconds) |
{ |
//Init pointeur a NULL |
threadSend = NULL; |
threadReceive = NULL; |
//Init des bool |
sendingEnabled = false; |
receivingEnabled = false; |
closeCalled = false; |
saveStateSendEnabled = false; |
saveStateReceivedEnabled = false; |
saveStateReceiveData = false; |
setPort(name); |
setBaudRate(baudRate); |
setDataBits(dataBits); |
setParity(parity); |
setStopBits(stopBits); |
setFlowControl(flowControl); |
setTimeout(seconds, milliseconds); |
} |
//Destructeur |
ManageSerialPort::~ManageSerialPort() |
{ |
if (threadSend != NULL) |
{ |
delete threadSend; |
threadSend = NULL; |
} |
if (threadReceive != NULL) |
{ |
delete threadReceive; |
threadReceive = NULL; |
} |
if (isOpen()) |
extSerialPort.close(); |
} |
bool ManageSerialPort::open() |
{ |
bool res = extSerialPort.open(QIODevice::ReadWrite); |
if (closeCalled) |
{ |
if (saveStateSendEnabled) |
enableSending(); |
if (saveStateReceivedEnabled) |
enableReceiving(); |
if (saveStateReceiveData) |
receiveData(); |
closeCalled = false; |
} |
return res; |
} |
bool ManageSerialPort::open(const QString &name, const BaudRateType baudRate, \ |
const DataBitsType dataBits,const ParityType parity, \ |
const StopBitsType stopBits, const FlowType flowControl, \ |
ulong seconds, ulong milliseconds) |
{ |
setPort(name); |
setBaudRate(baudRate); |
setDataBits(dataBits); |
setParity(parity); |
setStopBits(stopBits); |
setFlowControl(flowControl); |
setTimeout(seconds, milliseconds); |
bool res = extSerialPort.open(QIODevice::ReadWrite); |
return res; |
} |
bool ManageSerialPort::isOpen() |
{ |
return extSerialPort.isOpen(); |
} |
void ManageSerialPort::close() |
{ |
closeCalled = true; |
saveStateSendEnabled = isSendingEnabled(); |
saveStateReceivedEnabled = isReceivingEnabled(); |
disableSending(); |
disableReceiving(); |
extSerialPort.close(); |
} |
void ManageSerialPort::setPort(const QString &name) |
{ |
extSerialPort.setPortName(name); |
} |
QString ManageSerialPort::getPort() |
{ |
return extSerialPort.portName(); |
} |
void ManageSerialPort::setBaudRate(const BaudRateType baudRate) |
{ |
extSerialPort.setBaudRate(baudRate); |
} |
QString ManageSerialPort::getBaudRate() |
{ |
switch (extSerialPort.baudRate()) |
{ |
case BAUD50: |
return QString("50"); |
case BAUD75: |
return QString("75"); |
case BAUD110: |
return QString("110"); |
case BAUD134: |
return QString("134"); |
case BAUD150: |
return QString("150"); |
case BAUD200: |
return QString("200"); |
case BAUD300: |
return QString("300"); |
case BAUD600: |
return QString("600"); |
case BAUD1200: |
return QString("1200"); |
case BAUD1800: |
return QString("1800"); |
case BAUD2400: |
return QString("2400"); |
case BAUD4800: |
return QString("4800"); |
case BAUD9600: |
return QString("9600"); |
case BAUD14400: |
return QString("14400"); |
case BAUD19200: |
return QString("19200"); |
case BAUD38400: |
return QString("38400"); |
case BAUD56000: |
return QString("56000"); |
case BAUD57600: |
return QString("57600"); |
case BAUD76800: |
return QString("76800"); |
case BAUD115200: |
return QString("115200"); |
case BAUD128000: |
return QString("128000"); |
case BAUD256000: |
return QString("256000"); |
} |
return 0; |
} |
void ManageSerialPort::setDataBits(const DataBitsType dataBits) |
{ |
extSerialPort.setDataBits(dataBits); |
} |
QChar ManageSerialPort::getDataBits() |
{ |
switch (extSerialPort.dataBits()) |
{ |
case DATA_5: |
return QChar('5'); |
case DATA_6: |
return QChar('6'); |
case DATA_7: |
return QChar('7'); |
case DATA_8: |
return QChar('8'); |
} |
return 0; |
} |
void ManageSerialPort::setParity(const ParityType parity) |
{ |
extSerialPort.setParity(parity); |
} |
QString ManageSerialPort::getParity() |
{ |
switch (extSerialPort.parity()) |
{ |
case PAR_NONE: |
return QString(tr("None")); |
case PAR_ODD: |
return QString(tr("Odd")); |
case PAR_EVEN: |
return QString(tr("Even")); |
case PAR_MARK: |
return QString(tr("Mark")); |
case PAR_SPACE: |
return QString(tr("Space")); |
} |
return 0; |
} |
void ManageSerialPort::setStopBits(const StopBitsType stopBits) |
{ |
extSerialPort.setStopBits(stopBits); |
} |
QString ManageSerialPort::getStopBit() |
{ |
switch (extSerialPort.stopBits()) |
{ |
case STOP_1: |
return QString("1"); |
case STOP_1_5: |
return QString("1.5"); |
case STOP_2: |
return QString("2"); |
} |
return 0; |
} |
void ManageSerialPort::setFlowControl(const FlowType flowControl) |
{ |
extSerialPort.setFlowControl(flowControl); |
} |
QString ManageSerialPort::getFlowControl() |
{ |
switch (extSerialPort.flowControl()) |
{ |
case FLOW_OFF: |
return QString(tr("None")); |
case FLOW_HARDWARE : |
return QString(tr("Hardware")); |
case FLOW_XONXOFF : |
return QString(tr("Xon/Xoff")); |
} |
return 0; |
} |
void ManageSerialPort::setTimeout(ulong seconds, ulong milliseconds) |
{ |
extSerialPort.setTimeout(seconds,milliseconds); |
} |
/* |
QString ManageSerialPort::getLastErrorToString() |
{ |
ulong res = extSerialPort.lastError(); |
switch (res) |
{ |
case E_NO_ERROR: |
return QString(tr("No Error has occured")); |
case E_INVALID_FD: |
return QString(tr("Invalid file descriptor (port was not opened correctly)")); |
case E_NO_MEMORY: |
return QString(tr("Unable to allocate memory tables (POSIX)")); |
case E_CAUGHT_NON_BLOCKED_SIGNAL: |
return QString(tr("Caught a non-blocked signal (POSIX)")); |
case E_PORT_TIMEOUT: |
return QString(tr("Operation timed out (POSIX)")); |
case E_INVALID_DEVICE: |
return QString(tr("The file opened by the port is not a character device (POSIX)")); |
case E_BREAK_CONDITION: |
return QString(tr("The port detected a break condition")); |
case E_FRAMING_ERROR: |
return QString(tr("The port detected a framing error (usually caused by incorrect baud rate settings)")); |
case E_IO_ERROR: |
return QString(tr("There was an I/O error while communicating with the port")); |
case E_BUFFER_OVERRUN: |
return QString(tr("Character buffer overrun")); |
case E_RECEIVE_OVERFLOW: |
return QString(tr("Receive buffer overflow")); |
case E_RECEIVE_PARITY_ERROR: |
return QString(tr("The port detected a parity error in the received data")); |
case E_TRANSMIT_OVERFLOW: |
return QString(tr("Transmit buffer overflow")); |
case E_READ_FAILED: |
return QString(tr("General read operation failure")); |
case E_WRITE_FAILED: |
return QString(tr("General write operation failure")); |
} |
return 0; |
}*/ |
/* |
ulong ManageSerialPort::getLastError() |
{ |
return extSerialPort.lastError(); |
} |
*/ |
void ManageSerialPort::enableSending() |
{ |
if (!sendingEnabled && threadSend == NULL) //Si l'envoi n'est pas active && si threadSend n'est pas alloue |
{ |
threadSend = new ThreadSend(extSerialPort); |
sendingEnabled = true; |
} |
} |
void ManageSerialPort::disableSending() |
{ |
if (sendingEnabled && threadSend != NULL) //Si l'envoi est active && si threadSend est alloue |
{ |
delete (threadSend); |
threadSend = NULL; |
sendingEnabled = false; |
} |
} |
bool ManageSerialPort::isSendingEnabled() |
{ |
return sendingEnabled; |
} |
uchar ManageSerialPort::sendData(QByteArray &dataToSend) |
{ |
if (!isOpen()) //Si le port n'est pas ouvert |
return 2; |
if (!sendingEnabled || threadSend == NULL) //Si l'envoi n'est pas active || si threadSend n'est pas alloue |
return 3; |
threadSend->addDataToSend(dataToSend); //Ajout des donnees a envoyer |
return 1; |
} |
void ManageSerialPort::stopSending() |
{ |
if (!sendingEnabled || threadSend == NULL) //Si l'envoi n'est pas active || si threadSend n'est pas été alloue |
return; |
if (threadSend->isRunning()) //si un envoi est en cour |
{ |
threadSend->stopSending(); //on donne l'ordre d'arreter l'envoi |
long tmp = ULONG_MAX; |
threadSend->wait(tmp); //on attend l'arret |
} |
} |
void ManageSerialPort::enableReceiving() |
{ |
if (!receivingEnabled && threadReceive == NULL) //Si la reception n'est pas active && si threadReceive n'est pas alloue |
{ |
threadReceive = new ThreadReceive(extSerialPort); |
connect(threadReceive, SIGNAL(newDataReceived(const QByteArray &)), this, SIGNAL(newDataReceived(const QByteArray &))); |
receivingEnabled = true; |
} |
} |
void ManageSerialPort::disableReceiving() |
{ |
if (receivingEnabled && threadReceive != NULL) //Si la reception est pas active && si threadReceive est alloue |
{ |
delete (threadReceive); |
threadReceive = NULL; |
receivingEnabled = false; |
} |
} |
bool ManageSerialPort::isReceivingEnabled() |
{ |
return receivingEnabled; |
} |
uchar ManageSerialPort::receiveData() |
{ |
if (!isOpen()) //Si le port n'est pas ouvert |
return 2; |
if (!receivingEnabled || threadReceive == NULL) //Si la reception n'est pas active || si threadReceive n'est pas été alloue |
return 3; |
if (!threadReceive->isRunning()) |
{ |
saveStateReceiveData = true; |
threadReceive->start(); //Demarrage du thread de reception |
} |
return 1; |
} |
void ManageSerialPort::stopReceiving() |
{ |
if (!receivingEnabled || threadReceive == NULL) //Si la reception n'est pas active || si threadReceive n'est pas alloue |
return; |
if (threadReceive->isRunning()) //Si le thread de reception est en fonctionnement |
{ |
saveStateReceiveData = false; |
threadReceive->stopReceiving(); //on donne l'ordre d'arreter la reception |
long tmp = ULONG_MAX; |
threadReceive->wait(tmp); //on attend l'arret |
} |
} |
/******************************************************************************************************** |
* Classe ThreadSend |
*****************************************************************************************************/ |
ThreadSend::ThreadSend(QextSerialPort &addressSerialPort) : extSerialPort(addressSerialPort) |
{ |
dataToSend.clear(); |
stopped=false; |
} |
ThreadSend::~ThreadSend() |
{ |
if (isRunning()) |
{ |
stopSending(); |
wait(); |
} |
} |
void ThreadSend::addDataToSend(QByteArray &dataToAdd) |
{ |
QMutexLocker locker(&mutexSend); |
for (int i=0; i<dataToAdd.size(); i++) |
dataToSend.enqueue(QByteArray(1,dataToAdd.at(i))); |
if (!isRunning()) |
start(); |
} |
void ThreadSend::stopSending() |
{ |
stopped=true; |
} |
void ThreadSend::run() |
{ |
QByteArray byteArray; |
forever |
{ |
if (dataToSend.isEmpty() || stopped) |
{ |
stopped = false; |
break; |
} |
mutexSend.lock(); |
byteArray = dataToSend.dequeue(); |
mutexSend.unlock(); |
extSerialPort.write(byteArray, 1); |
} |
} |
/******************************************************************************************************** |
* Classe ThreadReceive - A TERMINER |
*****************************************************************************************************/ |
ThreadReceive::ThreadReceive(QextSerialPort &addressSerialPort) : extSerialPort(addressSerialPort) |
{ |
stopped=false; |
} |
ThreadReceive::~ThreadReceive() |
{ |
if (isRunning()) |
{ |
stopReceiving(); |
wait(); |
} |
} |
void ThreadReceive::stopReceiving() |
{ |
stopped = true; |
} |
void ThreadReceive::run() |
{ |
int numBytes=0; |
char data[1024]; |
QByteArray dataReceived; |
forever |
{ |
if (stopped) |
{ |
stopped = false; |
break; |
} |
mutexReceive.lock(); |
numBytes = extSerialPort.bytesAvailable(); |
if (numBytes > 0) |
{ |
extSerialPort.read(data, numBytes); |
for (int xy=1; xy < numBytes; xy++) |
{ |
if (data[xy] == 0) |
{ |
data[xy] = 'a'; |
} |
} |
data[numBytes]='\0'; |
dataReceived = data; |
emit newDataReceived(dataReceived); |
} |
mutexReceive.unlock(); |
} |
} |
/QMK-Groundstation/branches/own_com_lib/SerialPort/ManageSerialPort.h |
---|
0,0 → 1,322 |
/******************************************************************************************************** |
* PROGRAM : QSerialPortTerminal |
* DATE - TIME : vendredi 03 octobre 2008 - 11h15 |
* AUTHOR : VIANNEY-LIAUD Philippe ( philippe.vianney.liaud gmail.com ) |
* FILENAME : ManageSerialPort.h |
* LICENSE : GPL |
* COMMENTARY : Manage qExtSerialPort |
********************************************************************************************************/ |
#ifndef MANAGESERIALPORT_H |
#define MANAGESERIALPORT_H |
#include <QThread> |
#include <QQueue> |
#include <QMetaType> |
#include <QMutex> |
#include "qextserialport.h" |
Q_DECLARE_METATYPE(BaudRateType); |
Q_DECLARE_METATYPE(DataBitsType); |
Q_DECLARE_METATYPE(ParityType); |
Q_DECLARE_METATYPE(StopBitsType); |
Q_DECLARE_METATYPE(FlowType); |
class ThreadSend; |
class ThreadReceive; |
class ManageSerialPort : public QObject |
{ |
Q_OBJECT |
public: |
//Constructeurs + destructeur |
ManageSerialPort(); |
ManageSerialPort(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits,\ |
const ParityType parity, const StopBitsType stopBits, \ |
const FlowType flowControl, ulong seconds, ulong milliseconds); |
~ManageSerialPort(); |
//General |
bool open(); |
bool open(const QString &name, const BaudRateType baudRate, const DataBitsType dataBits,\ |
const ParityType parity, const StopBitsType stopBits, \ |
const FlowType flowControl, ulong seconds, ulong milliseconds); |
bool isOpen(); |
void close(); |
//Sets the name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0" |
void setPort(const QString &name); |
QString getPort(); |
/*Most used : '*' (POSTX & Windows) |
RATE Windows Speed POSIX Speed |
----------- ------------- ----------- |
enum BaudRateType{ |
BAUD50 110 50 //POSIX ONLY |
BAUD75 110 75 //POSIX ONLY |
*BAUD110 110 110 |
BAUD134 110 134.5 //POSIX ONLY |
BAUD150 110 150 //POSIX ONLY |
BAUD200 110 200 //POSIX ONLY |
*BAUD300 300 300 |
*BAUD600 600 600 |
*BAUD1200 1200 1200 |
BAUD1800 1200 1800 //POSIX ONLY |
*BAUD2400 2400 2400 |
*BAUD4800 4800 4800 |
*BAUD9600 9600 9600 |
BAUD14400 14400 9600 //WINDOWS ONLY |
*BAUD19200 19200 19200 |
*BAUD38400 38400 38400 |
BAUD56000 56000 38400 //WINDOWS ONLY |
*BAUD57600 57600 57600 |
BAUD76800 57600 76800 //POSIX ONLY |
*BAUD115200 115200 115200 |
BAUD128000 128000 115200 //WINDOWS ONLY |
BAUD256000 256000 115200 //WINDOWS ONLY |
}*/ |
void setBaudRate(const BaudRateType baudRate); |
/*getBaudRate |
return "50"; |
return "75"; |
return "110"; |
return "134"; |
return "150"; |
return "200"; |
return "300"; |
return "600"; |
return "1200"; |
return "1800"; |
return "2400"; |
return "4800"; |
return "9600"; |
return "14400"; |
return "19200"; |
return "38400"; |
return "56000"; |
return "57600"; |
return "76800"; |
return "115200"; |
return "128000"; |
return "256000";*/ |
QString getBaudRate(); |
/*enum DataBitsType { |
DATA_5 |
DATA_6 |
DATA_7 |
DATA_8 |
};*/ |
void setDataBits(const DataBitsType dataBits); |
/*getDataBits |
return '5'; |
return '6'; |
return '7'; |
return '8';*/ |
QChar getDataBits(); |
/*enum ParityType { |
PAR_NONE //None means that no parity bit is sent at all |
PAR_ODD //Odd |
PAR_EVEN //Even |
PAR_MARK //Windows only : Mark parity means that the parity bit is always set to the mark signal condition (logical 1) |
PAR_SPACE //Space parity always sends the parity bit in the space signal condition |
};*/ |
void setParity(const ParityType parity); |
/*getParity |
return "None"; |
return "Odd"; |
return "Even"; |
return "Mark"; Windows only |
return "Space";*/ |
QString getParity(); |
/*enum StopBitsType { |
STOP_1 |
STOP_1_5 //WINDOWS ONLY |
STOP_2 |
};*/ |
void setStopBits(const StopBitsType stopBits); |
/*getStopBit |
return "1" |
return "1.5" |
return "2"*/ |
QString getStopBit(); |
/*enum FlowType { |
FLOW_OFF |
FLOW_HARDWARE |
FLOW_XONXOFF |
};*/ |
void setFlowControl(const FlowType flowControl); |
/*getFlowControl |
return "None" |
return "Hardware" |
return "Xon/Xoff"*/ |
QString getFlowControl(); |
void setTimeout(ulong seconds, ulong milliseconds); |
/*getLastErrorToString |
return "No Error has occured" |
return "Invalid file descriptor (port was not opened correctly)" |
return "Unable to allocate memory tables (POSIX)" |
return "Caught a non-blocked signal (POSIX)" |
return "Operation timed out (POSIX)" |
return "The file opened by the port is not a character device (POSIX)" |
return "The port detected a break condition" |
return "The port detected a framing error (usually caused by incorrect baud rate settings)" |
return "There was an I/O error while communicating with the port" |
return "Character buffer overrun" |
return "Receive buffer overflow" |
return "The port detected a parity error in the received data" |
return "Transmit buffer overflow" |
return "General read operation failure" |
return "General write operation failure"*/ |
/*QString getLastErrorToString();*/ |
/*getLastError |
return 0 : No Error has occured |
return 1 : Invalid file descriptor (port was not opened correctly) |
return 2 : Unable to allocate memory tables (POSIX) |
return 3 : Caught a non-blocked signal (POSIX) |
return 4 : Operation timed out (POSIX) |
return 5 : The file opened by the port is not a character device (POSIX) |
return 6 : The port detected a break condition" |
return 7 : The port detected a framing error (usually caused by incorrect baud rate settings) |
return 8 : There was an I/O error while communicating with the port |
return 9 : Character buffer overrun |
return 10 : Receive buffer overflow |
return 11 : The port detected a parity error in the received data |
return 12 : Transmit buffer overflow |
return 13 : General read operation failure |
return 14 : General write operation failure*/ |
/*ulong getLastError();*/ |
//Emission |
void enableSending(); |
void disableSending(); |
/*isSendingEnabled |
return 0 : sending is not enable |
return 1 : sending is enable*/ |
bool isSendingEnabled(); |
/*sendData |
return 1 : add OK |
return 2 : port is not open |
return 3 : sending is not enable*/ |
uchar sendData(QByteArray &dataToSend); |
void stopSending(); |
//Reception |
void enableReceiving(); |
void disableReceiving(); |
/*isReceivingEnabled |
return 0 : receiving is not enable |
return 1 : receiving is enable*/ |
bool isReceivingEnabled(); |
/*receiveData |
return 1 : start thread OK |
return 2 : port is not open |
return 3 : receiving is not enable*/ |
uchar receiveData(); |
void stopReceiving(); |
signals: |
void newDataReceived(const QByteArray &dataReceived); |
private: |
//Variables privees |
QextSerialPort extSerialPort; |
ThreadSend *threadSend; |
ThreadReceive *threadReceive; |
bool sendingEnabled; |
bool receivingEnabled; |
bool closeCalled; |
bool saveStateSendEnabled; |
bool saveStateReceivedEnabled; |
bool saveStateReceiveData; |
}; |
#endif // MANAGESERIALPORT_H |
class ThreadSend : public QThread |
{ |
Q_OBJECT |
public: |
ThreadSend(QextSerialPort &addressSerialPort); |
~ThreadSend(); |
void addDataToSend(QByteArray &dataToAdd); |
void stopSending(); |
protected: |
void run(); |
private: |
QMutex mutexSend; |
QextSerialPort &extSerialPort; |
QQueue<QByteArray> dataToSend; |
bool stopped; |
}; |
class ThreadReceive : public QThread |
{ |
Q_OBJECT |
public: |
ThreadReceive(QextSerialPort &addressSerialPort); |
~ThreadReceive(); |
void stopReceiving(); |
protected: |
void run(); |
private : |
QMutex mutexReceive; |
QextSerialPort &extSerialPort; |
bool stopped; |
signals: |
void newDataReceived(const QByteArray &dataReceived); |
}; |
/QMK-Groundstation/branches/own_com_lib/SerialPort/posix_qextserialport.cpp |
---|
0,0 → 1,1114 |
/*! |
\class Posix_QextSerialPort |
\version 1.0.0 |
\author Stefan Sander |
A cross-platform serial port class. |
This class encapsulates the POSIX portion of QextSerialPort. The user will be notified of errors |
and possible portability conflicts at run-time by default - this behavior can be turned off by |
defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off portability |
warnings) in the project. Note that _TTY_NOWARN_ will also turn off portability warnings. |
*/ |
#include <stdio.h> |
#include "posix_qextserialport.h" |
/*! |
\fn Posix_QextSerialPort::Posix_QextSerialPort() |
Default constructor. Note that the name of the device used by a QextSerialPort constructed with |
this constructor will be determined by #defined constants, or lack thereof - the default behavior |
is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are: |
\verbatim |
Constant Used By Naming Convention |
---------- ------------- ------------------------ |
_TTY_WIN_ Windows COM1, COM2 |
_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2 |
_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0 |
_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb |
_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02 |
_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1 |
_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1 |
<none> Linux /dev/ttyS0, /dev/ttyS1 |
\endverbatim |
This constructor assigns the device name to the name of the first port on the specified system. |
See the other constructors if you need to open a different port. |
*/ |
Posix_QextSerialPort::Posix_QextSerialPort() |
: QextSerialBase() |
{ |
Posix_File=new QFile(); |
} |
/*! |
\fn Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort&) |
Copy constructor. |
*/ |
Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort& s) |
: QextSerialBase(s.port) |
{ |
setOpenMode(s.openMode()); |
port = s.port; |
Settings.BaudRate=s.Settings.BaudRate; |
Settings.DataBits=s.Settings.DataBits; |
Settings.Parity=s.Settings.Parity; |
Settings.StopBits=s.Settings.StopBits; |
Settings.FlowControl=s.Settings.FlowControl; |
lastErr=s.lastErr; |
Posix_File=new QFile(); |
Posix_File=s.Posix_File; |
memcpy(&Posix_Timeout, &s.Posix_Timeout, sizeof(struct timeval)); |
memcpy(&Posix_Copy_Timeout, &s.Posix_Copy_Timeout, sizeof(struct timeval)); |
memcpy(&Posix_CommConfig, &s.Posix_CommConfig, sizeof(struct termios)); |
} |
/*! |
\fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name) |
Constructs a serial port attached to the port specified by name. |
name is the name of the device, which is windowsystem-specific, |
e.g."COM1" or "/dev/ttyS0". |
*/ |
Posix_QextSerialPort::Posix_QextSerialPort(const QString & name) |
: QextSerialBase(name) |
{ |
Posix_File=new QFile(); |
} |
/*! |
\fn Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings) |
Constructs a port with default name and specified settings. |
*/ |
Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings) |
: QextSerialBase() |
{ |
setBaudRate(settings.BaudRate); |
setDataBits(settings.DataBits); |
setParity(settings.Parity); |
setStopBits(settings.StopBits); |
setFlowControl(settings.FlowControl); |
Posix_File=new QFile(); |
setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); |
} |
/*! |
\fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings) |
Constructs a port with specified name and settings. |
*/ |
Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings) |
: QextSerialBase(name) |
{ |
setBaudRate(settings.BaudRate); |
setDataBits(settings.DataBits); |
setParity(settings.Parity); |
setStopBits(settings.StopBits); |
setFlowControl(settings.FlowControl); |
Posix_File=new QFile(); |
setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); |
} |
/*! |
\fn Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s) |
Override the = operator. |
*/ |
Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s) |
{ |
setOpenMode(s.openMode()); |
port = s.port; |
Settings.BaudRate=s.Settings.BaudRate; |
Settings.DataBits=s.Settings.DataBits; |
Settings.Parity=s.Settings.Parity; |
Settings.StopBits=s.Settings.StopBits; |
Settings.FlowControl=s.Settings.FlowControl; |
lastErr=s.lastErr; |
Posix_File=s.Posix_File; |
memcpy(&Posix_Timeout, &(s.Posix_Timeout), sizeof(struct timeval)); |
memcpy(&Posix_Copy_Timeout, &(s.Posix_Copy_Timeout), sizeof(struct timeval)); |
memcpy(&Posix_CommConfig, &(s.Posix_CommConfig), sizeof(struct termios)); |
return *this; |
} |
/*! |
\fn Posix_QextSerialPort::~Posix_QextSerialPort() |
Standard destructor. |
*/ |
Posix_QextSerialPort::~Posix_QextSerialPort() |
{ |
if (isOpen()) { |
close(); |
} |
Posix_File->close(); |
delete Posix_File; |
} |
/*! |
\fn void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate) |
Sets the baud rate of the serial port. Note that not all rates are applicable on |
all platforms. The following table shows translations of the various baud rate |
constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an * |
are speeds that are usable on both Windows and POSIX. |
\note |
BAUD76800 may not be supported on all POSIX systems. SGI/IRIX systems do not support |
BAUD1800. |
\verbatim |
RATE Windows Speed POSIX Speed |
----------- ------------- ----------- |
BAUD50 110 50 |
BAUD75 110 75 |
*BAUD110 110 110 |
BAUD134 110 134.5 |
BAUD150 110 150 |
BAUD200 110 200 |
*BAUD300 300 300 |
*BAUD600 600 600 |
*BAUD1200 1200 1200 |
BAUD1800 1200 1800 |
*BAUD2400 2400 2400 |
*BAUD4800 4800 4800 |
*BAUD9600 9600 9600 |
BAUD14400 14400 9600 |
*BAUD19200 19200 19200 |
*BAUD38400 38400 38400 |
BAUD56000 56000 38400 |
*BAUD57600 57600 57600 |
BAUD76800 57600 76800 |
*BAUD115200 115200 115200 |
BAUD128000 128000 115200 |
BAUD256000 256000 115200 |
\endverbatim |
*/ |
void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate) |
{ |
LOCK_MUTEX(); |
if (Settings.BaudRate!=baudRate) { |
switch (baudRate) { |
case BAUD14400: |
Settings.BaudRate=BAUD9600; |
break; |
case BAUD56000: |
Settings.BaudRate=BAUD38400; |
break; |
case BAUD76800: |
#ifndef B76800 |
Settings.BaudRate=BAUD57600; |
#else |
Settings.BaudRate=baudRate; |
#endif |
break; |
case BAUD128000: |
case BAUD256000: |
Settings.BaudRate=BAUD115200; |
break; |
default: |
Settings.BaudRate=baudRate; |
break; |
} |
} |
if (isOpen()) { |
switch (baudRate) { |
/*50 baud*/ |
case BAUD50: |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 50 baud operation."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B50; |
#else |
cfsetispeed(&Posix_CommConfig, B50); |
cfsetospeed(&Posix_CommConfig, B50); |
#endif |
break; |
/*75 baud*/ |
case BAUD75: |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 75 baud operation."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B75; |
#else |
cfsetispeed(&Posix_CommConfig, B75); |
cfsetospeed(&Posix_CommConfig, B75); |
#endif |
break; |
/*110 baud*/ |
case BAUD110: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B110; |
#else |
cfsetispeed(&Posix_CommConfig, B110); |
cfsetospeed(&Posix_CommConfig, B110); |
#endif |
break; |
/*134.5 baud*/ |
case BAUD134: |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 134.5 baud operation."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B134; |
#else |
cfsetispeed(&Posix_CommConfig, B134); |
cfsetospeed(&Posix_CommConfig, B134); |
#endif |
break; |
/*150 baud*/ |
case BAUD150: |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 150 baud operation."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B150; |
#else |
cfsetispeed(&Posix_CommConfig, B150); |
cfsetospeed(&Posix_CommConfig, B150); |
#endif |
break; |
/*200 baud*/ |
case BAUD200: |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 200 baud operation."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B200; |
#else |
cfsetispeed(&Posix_CommConfig, B200); |
cfsetospeed(&Posix_CommConfig, B200); |
#endif |
break; |
/*300 baud*/ |
case BAUD300: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B300; |
#else |
cfsetispeed(&Posix_CommConfig, B300); |
cfsetospeed(&Posix_CommConfig, B300); |
#endif |
break; |
/*600 baud*/ |
case BAUD600: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B600; |
#else |
cfsetispeed(&Posix_CommConfig, B600); |
cfsetospeed(&Posix_CommConfig, B600); |
#endif |
break; |
/*1200 baud*/ |
case BAUD1200: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B1200; |
#else |
cfsetispeed(&Posix_CommConfig, B1200); |
cfsetospeed(&Posix_CommConfig, B1200); |
#endif |
break; |
/*1800 baud*/ |
case BAUD1800: |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B1800; |
#else |
cfsetispeed(&Posix_CommConfig, B1800); |
cfsetospeed(&Posix_CommConfig, B1800); |
#endif |
break; |
/*2400 baud*/ |
case BAUD2400: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B2400; |
#else |
cfsetispeed(&Posix_CommConfig, B2400); |
cfsetospeed(&Posix_CommConfig, B2400); |
#endif |
break; |
/*4800 baud*/ |
case BAUD4800: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B4800; |
#else |
cfsetispeed(&Posix_CommConfig, B4800); |
cfsetospeed(&Posix_CommConfig, B4800); |
#endif |
break; |
/*9600 baud*/ |
case BAUD9600: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B9600; |
#else |
cfsetispeed(&Posix_CommConfig, B9600); |
cfsetospeed(&Posix_CommConfig, B9600); |
#endif |
break; |
/*14400 baud*/ |
case BAUD14400: |
TTY_WARNING("Posix_QextSerialPort: POSIX does not support 14400 baud operation. Switching to 9600 baud."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B9600; |
#else |
cfsetispeed(&Posix_CommConfig, B9600); |
cfsetospeed(&Posix_CommConfig, B9600); |
#endif |
break; |
/*19200 baud*/ |
case BAUD19200: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B19200; |
#else |
cfsetispeed(&Posix_CommConfig, B19200); |
cfsetospeed(&Posix_CommConfig, B19200); |
#endif |
break; |
/*38400 baud*/ |
case BAUD38400: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B38400; |
#else |
cfsetispeed(&Posix_CommConfig, B38400); |
cfsetospeed(&Posix_CommConfig, B38400); |
#endif |
break; |
/*56000 baud*/ |
case BAUD56000: |
TTY_WARNING("Posix_QextSerialPort: POSIX does not support 56000 baud operation. Switching to 38400 baud."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B38400; |
#else |
cfsetispeed(&Posix_CommConfig, B38400); |
cfsetospeed(&Posix_CommConfig, B38400); |
#endif |
break; |
/*57600 baud*/ |
case BAUD57600: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B57600; |
#else |
cfsetispeed(&Posix_CommConfig, B57600); |
cfsetospeed(&Posix_CommConfig, B57600); |
#endif |
break; |
/*76800 baud*/ |
case BAUD76800: |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
#ifdef B76800 |
Posix_CommConfig.c_cflag|=B76800; |
#else |
TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); |
Posix_CommConfig.c_cflag|=B57600; |
#endif //B76800 |
#else //CBAUD |
#ifdef B76800 |
cfsetispeed(&Posix_CommConfig, B76800); |
cfsetospeed(&Posix_CommConfig, B76800); |
#else |
TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud."); |
cfsetispeed(&Posix_CommConfig, B57600); |
cfsetospeed(&Posix_CommConfig, B57600); |
#endif //B76800 |
#endif //CBAUD |
break; |
/*115200 baud*/ |
case BAUD115200: |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B115200; |
#else |
cfsetispeed(&Posix_CommConfig, B115200); |
cfsetospeed(&Posix_CommConfig, B115200); |
#endif |
break; |
/*128000 baud*/ |
case BAUD128000: |
TTY_WARNING("Posix_QextSerialPort: POSIX does not support 128000 baud operation. Switching to 115200 baud."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B115200; |
#else |
cfsetispeed(&Posix_CommConfig, B115200); |
cfsetospeed(&Posix_CommConfig, B115200); |
#endif |
break; |
/*256000 baud*/ |
case BAUD256000: |
TTY_WARNING("Posix_QextSerialPort: POSIX does not support 256000 baud operation. Switching to 115200 baud."); |
#ifdef CBAUD |
Posix_CommConfig.c_cflag&=(~CBAUD); |
Posix_CommConfig.c_cflag|=B115200; |
#else |
cfsetispeed(&Posix_CommConfig, B115200); |
cfsetospeed(&Posix_CommConfig, B115200); |
#endif |
break; |
} |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Posix_QextSerialPort::setDataBits(DataBitsType dataBits) |
Sets the number of data bits used by the serial port. Possible values of dataBits are: |
\verbatim |
DATA_5 5 data bits |
DATA_6 6 data bits |
DATA_7 7 data bits |
DATA_8 8 data bits |
\endverbatim |
\note |
This function is subject to the following restrictions: |
\par |
5 data bits cannot be used with 2 stop bits. |
\par |
8 data bits cannot be used with space parity on POSIX systems. |
*/ |
void Posix_QextSerialPort::setDataBits(DataBitsType dataBits) |
{ |
LOCK_MUTEX(); |
if (Settings.DataBits!=dataBits) { |
if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) || |
(Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) || |
(Settings.Parity==PAR_SPACE && dataBits==DATA_8)) { |
} |
else { |
Settings.DataBits=dataBits; |
} |
} |
if (isOpen()) { |
switch(dataBits) { |
/*5 data bits*/ |
case DATA_5: |
if (Settings.StopBits==STOP_2) { |
TTY_WARNING("Posix_QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); |
} |
else { |
Settings.DataBits=dataBits; |
Posix_CommConfig.c_cflag&=(~CSIZE); |
Posix_CommConfig.c_cflag|=CS5; |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
break; |
/*6 data bits*/ |
case DATA_6: |
if (Settings.StopBits==STOP_1_5) { |
TTY_WARNING("Posix_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); |
} |
else { |
Settings.DataBits=dataBits; |
Posix_CommConfig.c_cflag&=(~CSIZE); |
Posix_CommConfig.c_cflag|=CS6; |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
break; |
/*7 data bits*/ |
case DATA_7: |
if (Settings.StopBits==STOP_1_5) { |
TTY_WARNING("Posix_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); |
} |
else { |
Settings.DataBits=dataBits; |
Posix_CommConfig.c_cflag&=(~CSIZE); |
Posix_CommConfig.c_cflag|=CS7; |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
break; |
/*8 data bits*/ |
case DATA_8: |
if (Settings.StopBits==STOP_1_5) { |
TTY_WARNING("Posix_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); |
} |
else { |
Settings.DataBits=dataBits; |
Posix_CommConfig.c_cflag&=(~CSIZE); |
Posix_CommConfig.c_cflag|=CS8; |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
break; |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Posix_QextSerialPort::setParity(ParityType parity) |
Sets the parity associated with the serial port. The possible values of parity are: |
\verbatim |
PAR_SPACE Space Parity |
PAR_MARK Mark Parity |
PAR_NONE No Parity |
PAR_EVEN Even Parity |
PAR_ODD Odd Parity |
\endverbatim |
\note |
This function is subject to the following limitations: |
\par |
POSIX systems do not support mark parity. |
\par |
POSIX systems support space parity only if tricked into doing so, and only with |
fewer than 8 data bits. Use space parity very carefully with POSIX systems. |
*/ |
void Posix_QextSerialPort::setParity(ParityType parity) |
{ |
LOCK_MUTEX(); |
if (Settings.Parity!=parity) { |
if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) { |
} |
else { |
Settings.Parity=parity; |
} |
} |
if (isOpen()) { |
switch (parity) { |
/*space parity*/ |
case PAR_SPACE: |
if (Settings.DataBits==DATA_8) { |
TTY_PORTABILITY_WARNING("Posix_QextSerialPort: Space parity is only supported in POSIX with 7 or fewer data bits"); |
} |
else { |
/*space parity not directly supported - add an extra data bit to simulate it*/ |
Posix_CommConfig.c_cflag&=~(PARENB|CSIZE); |
switch(Settings.DataBits) { |
case DATA_5: |
Settings.DataBits=DATA_6; |
Posix_CommConfig.c_cflag|=CS6; |
break; |
case DATA_6: |
Settings.DataBits=DATA_7; |
Posix_CommConfig.c_cflag|=CS7; |
break; |
case DATA_7: |
Settings.DataBits=DATA_8; |
Posix_CommConfig.c_cflag|=CS8; |
break; |
case DATA_8: |
break; |
} |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
break; |
/*mark parity - WINDOWS ONLY*/ |
case PAR_MARK: |
TTY_WARNING("Posix_QextSerialPort: Mark parity is not supported by POSIX."); |
break; |
/*no parity*/ |
case PAR_NONE: |
Posix_CommConfig.c_cflag&=(~PARENB); |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
break; |
/*even parity*/ |
case PAR_EVEN: |
Posix_CommConfig.c_cflag&=(~PARODD); |
Posix_CommConfig.c_cflag|=PARENB; |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
break; |
/*odd parity*/ |
case PAR_ODD: |
Posix_CommConfig.c_cflag|=(PARENB|PARODD); |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
break; |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Posix_QextSerialPort::setStopBits(StopBitsType stopBits) |
Sets the number of stop bits used by the serial port. Possible values of stopBits are: |
\verbatim |
STOP_1 1 stop bit |
STOP_1_5 1.5 stop bits |
STOP_2 2 stop bits |
\endverbatim |
\note |
This function is subject to the following restrictions: |
\par |
2 stop bits cannot be used with 5 data bits. |
\par |
POSIX does not support 1.5 stop bits. |
*/ |
void Posix_QextSerialPort::setStopBits(StopBitsType stopBits) |
{ |
LOCK_MUTEX(); |
if (Settings.StopBits!=stopBits) { |
if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || stopBits==STOP_1_5) {} |
else { |
Settings.StopBits=stopBits; |
} |
} |
if (isOpen()) { |
switch (stopBits) { |
/*one stop bit*/ |
case STOP_1: |
Settings.StopBits=stopBits; |
Posix_CommConfig.c_cflag&=(~CSTOPB); |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
break; |
/*1.5 stop bits*/ |
case STOP_1_5: |
TTY_WARNING("Posix_QextSerialPort: 1.5 stop bit operation is not supported by POSIX."); |
break; |
/*two stop bits*/ |
case STOP_2: |
if (Settings.DataBits==DATA_5) { |
TTY_WARNING("Posix_QextSerialPort: 2 stop bits cannot be used with 5 data bits"); |
} |
else { |
Settings.StopBits=stopBits; |
Posix_CommConfig.c_cflag|=CSTOPB; |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
break; |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Posix_QextSerialPort::setFlowControl(FlowType flow) |
Sets the flow control used by the port. Possible values of flow are: |
\verbatim |
FLOW_OFF No flow control |
FLOW_HARDWARE Hardware (RTS/CTS) flow control |
FLOW_XONXOFF Software (XON/XOFF) flow control |
\endverbatim |
\note |
FLOW_HARDWARE may not be supported on all versions of UNIX. In cases where it is |
unsupported, FLOW_HARDWARE is the same as FLOW_OFF. |
*/ |
void Posix_QextSerialPort::setFlowControl(FlowType flow) |
{ |
LOCK_MUTEX(); |
if (Settings.FlowControl!=flow) { |
Settings.FlowControl=flow; |
} |
if (isOpen()) { |
switch(flow) { |
/*no flow control*/ |
case FLOW_OFF: |
Posix_CommConfig.c_cflag&=(~CRTSCTS); |
Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
break; |
/*software (XON/XOFF) flow control*/ |
case FLOW_XONXOFF: |
Posix_CommConfig.c_cflag&=(~CRTSCTS); |
Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY); |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
break; |
case FLOW_HARDWARE: |
Posix_CommConfig.c_cflag|=CRTSCTS; |
Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY)); |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
break; |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Posix_QextSerialPort::setTimeout(ulong sec, ulong millisec); |
Sets the read and write timeouts for the port to sec seconds and millisec milliseconds. |
Note that this is a per-character timeout, i.e. the port will wait this long for each |
individual character, not for the whole read operation. This timeout also applies to the |
bytesWaiting() function. |
\note |
POSIX does not support millisecond-level control for I/O timeout values. Any |
timeout set using this function will be set to the next lowest tenth of a second for |
the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds |
will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and |
writing the port. However millisecond-level control is allowed by the select() system call, |
so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for |
the purpose of detecting available bytes in the read buffer. |
*/ |
void Posix_QextSerialPort::setTimeout(ulong sec, ulong millisec) |
{ |
LOCK_MUTEX(); |
Settings.Timeout_Sec=sec; |
Settings.Timeout_Millisec=millisec; |
Posix_Copy_Timeout.tv_sec=sec; |
Posix_Copy_Timeout.tv_usec=millisec; |
if (isOpen()) { |
tcgetattr(Posix_File->handle(), &Posix_CommConfig); |
Posix_CommConfig.c_cc[VTIME]=sec*10+millisec/100; |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn bool Posix_QextSerialPort::open(OpenMode mode) |
Opens the serial port associated to this class. |
This function has no effect if the port associated with the class is already open. |
The port is also configured to the current settings, as stored in the Settings structure. |
*/ |
bool Posix_QextSerialPort::open(OpenMode mode) |
{ |
LOCK_MUTEX(); |
if (mode == QIODevice::NotOpen) |
return isOpen(); |
if (!isOpen()) { |
/*open the port*/ |
Posix_File->setFileName(port); |
if (Posix_File->open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { |
/*set open mode*/ |
QIODevice::open(mode); |
/*configure port settings*/ |
tcgetattr(Posix_File->handle(), &Posix_CommConfig); |
/*set up other port settings*/ |
Posix_CommConfig.c_cflag|=CREAD|CLOCAL; |
Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); |
Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); |
Posix_CommConfig.c_oflag&=(~OPOST); |
Posix_CommConfig.c_cc[VMIN]=0; |
Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE; |
Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE; |
Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE; |
Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE; |
Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE; |
setBaudRate(Settings.BaudRate); |
setDataBits(Settings.DataBits); |
setParity(Settings.Parity); |
setStopBits(Settings.StopBits); |
setFlowControl(Settings.FlowControl); |
setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec); |
tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig); |
} else { |
} |
} |
UNLOCK_MUTEX(); |
return isOpen(); |
} |
/*! |
\fn void Posix_QextSerialPort::close() |
Closes a serial port. This function has no effect if the serial port associated with the class |
is not currently open. |
*/ |
void Posix_QextSerialPort::close() |
{ |
LOCK_MUTEX(); |
Posix_File->close(); |
QIODevice::close(); |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Posix_QextSerialPort::flush() |
Flushes all pending I/O to the serial port. This function has no effect if the serial port |
associated with the class is not currently open. |
*/ |
void Posix_QextSerialPort::flush() |
{ |
LOCK_MUTEX(); |
if (isOpen()) { |
Posix_File->flush(); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn qint64 Posix_QextSerialPort::size() const |
This function will return the number of bytes waiting in the receive queue of the serial port. |
It is included primarily to provide a complete QIODevice interface, and will not record errors |
in the lastErr member (because it is const). This function is also not thread-safe - in |
multithreading situations, use Posix_QextSerialPort::bytesWaiting() instead. |
*/ |
qint64 Posix_QextSerialPort::size() const |
{ |
int numBytes; |
if (ioctl(Posix_File->handle(), FIONREAD, &numBytes)<0) { |
numBytes=0; |
} |
return (qint64)numBytes; |
} |
/*! |
\fn qint64 Posix_QextSerialPort::bytesAvailable() |
Returns the number of bytes waiting in the port's receive queue. This function will return 0 if |
the port is not currently open, or -1 on error. Error information can be retrieved by calling |
Posix_QextSerialPort::getLastError(). |
*/ |
qint64 Posix_QextSerialPort::bytesAvailable() |
{ |
LOCK_MUTEX(); |
if (isOpen()) { |
int bytesQueued; |
fd_set fileSet; |
FD_ZERO(&fileSet); |
FD_SET(Posix_File->handle(), &fileSet); |
/*on Linux systems the Posix_Timeout structure will be altered by the select() call. |
Make sure we use the right timeout values*/ |
//memcpy(&Posix_Timeout, &Posix_Copy_Timeout, sizeof(struct timeval)); |
Posix_Timeout = Posix_Copy_Timeout; |
int n=select(Posix_File->handle()+1, &fileSet, NULL, &fileSet, &Posix_Timeout); |
if (!n) { |
lastErr=E_PORT_TIMEOUT; |
UNLOCK_MUTEX(); |
return -1; |
} |
if (n==-1 || ioctl(Posix_File->handle(), FIONREAD, &bytesQueued)==-1) { |
translateError(errno); |
UNLOCK_MUTEX(); |
return -1; |
} |
lastErr=E_NO_ERROR; |
UNLOCK_MUTEX(); |
return bytesQueued + QIODevice::bytesAvailable(); |
} |
UNLOCK_MUTEX(); |
return 0; |
} |
/*! |
\fn void Posix_QextSerialPort::ungetChar(char) |
This function is included to implement the full QIODevice interface, and currently has no |
purpose within this class. This function is meaningless on an unbuffered device and currently |
only prints a warning message to that effect. |
*/ |
void Posix_QextSerialPort::ungetChar(char) |
{ |
/*meaningless on unbuffered sequential device - return error and print a warning*/ |
TTY_WARNING("Posix_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless"); |
} |
/*! |
\fn void Posix_QextSerialPort::translateError(ulong error) |
Translates a system-specific error code to a QextSerialPort error code. Used internally. |
*/ |
void Posix_QextSerialPort::translateError(ulong error) |
{ |
switch (error) { |
case EBADF: |
case ENOTTY: |
lastErr=E_INVALID_FD; |
break; |
case EINTR: |
lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL; |
break; |
case ENOMEM: |
lastErr=E_NO_MEMORY; |
break; |
} |
} |
/*! |
\fn void Posix_QextSerialPort::setDtr(bool set) |
Sets DTR line to the requested state (high by default). This function will have no effect if |
the port associated with the class is not currently open. |
*/ |
void Posix_QextSerialPort::setDtr(bool set) |
{ |
LOCK_MUTEX(); |
if (isOpen()) { |
int status; |
ioctl(Posix_File->handle(), TIOCMGET, &status); |
if (set) { |
status|=TIOCM_DTR; |
} |
else { |
status&=~TIOCM_DTR; |
} |
ioctl(Posix_File->handle(), TIOCMSET, &status); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Posix_QextSerialPort::setRts(bool set) |
Sets RTS line to the requested state (high by default). This function will have no effect if |
the port associated with the class is not currently open. |
*/ |
void Posix_QextSerialPort::setRts(bool set) |
{ |
LOCK_MUTEX(); |
if (isOpen()) { |
int status; |
ioctl(Posix_File->handle(), TIOCMGET, &status); |
if (set) { |
status|=TIOCM_RTS; |
} |
else { |
status&=~TIOCM_RTS; |
} |
ioctl(Posix_File->handle(), TIOCMSET, &status); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn unsigned long Posix_QextSerialPort::lineStatus() |
returns the line status as stored by the port function. This function will retrieve the states |
of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines |
can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned |
long with specific bits indicating which lines are high. The following constants should be used |
to examine the states of individual lines: |
\verbatim |
Mask Line |
------ ---- |
LS_CTS CTS |
LS_DSR DSR |
LS_DCD DCD |
LS_RI RI |
LS_RTS RTS (POSIX only) |
LS_DTR DTR (POSIX only) |
LS_ST Secondary TXD (POSIX only) |
LS_SR Secondary RXD (POSIX only) |
\endverbatim |
This function will return 0 if the port associated with the class is not currently open. |
*/ |
unsigned long Posix_QextSerialPort::lineStatus() |
{ |
unsigned long Status=0, Temp=0; |
LOCK_MUTEX(); |
if (isOpen()) { |
ioctl(Posix_File->handle(), TIOCMGET, &Temp); |
if (Temp&TIOCM_CTS) { |
Status|=LS_CTS; |
} |
if (Temp&TIOCM_DSR) { |
Status|=LS_DSR; |
} |
if (Temp&TIOCM_RI) { |
Status|=LS_RI; |
} |
if (Temp&TIOCM_CD) { |
Status|=LS_DCD; |
} |
if (Temp&TIOCM_DTR) { |
Status|=LS_DTR; |
} |
if (Temp&TIOCM_RTS) { |
Status|=LS_RTS; |
} |
if (Temp&TIOCM_ST) { |
Status|=LS_ST; |
} |
if (Temp&TIOCM_SR) { |
Status|=LS_SR; |
} |
} |
UNLOCK_MUTEX(); |
return Status; |
} |
/*! |
\fn qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize) |
Reads a block of data from the serial port. This function will read at most maxSize bytes from |
the serial port and place them in the buffer pointed to by data. Return value is the number of |
bytes actually read, or -1 on error. |
\warning before calling this function ensure that serial port associated with this class |
is currently open (use isOpen() function to check if port is open). |
*/ |
qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize) |
{ |
LOCK_MUTEX(); |
int retVal=0; |
retVal=Posix_File->read(data, maxSize); |
if (retVal==-1) |
lastErr=E_READ_FAILED; |
UNLOCK_MUTEX(); |
return retVal; |
} |
/*! |
\fn qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize) |
Writes a block of data to the serial port. This function will write maxSize bytes |
from the buffer pointed to by data to the serial port. Return value is the number |
of bytes actually written, or -1 on error. |
\warning before calling this function ensure that serial port associated with this class |
is currently open (use isOpen() function to check if port is open). |
*/ |
qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize) |
{ |
LOCK_MUTEX(); |
int retVal=0; |
retVal=Posix_File->write(data, maxSize); |
if (retVal==-1) |
lastErr=E_WRITE_FAILED; |
UNLOCK_MUTEX(); |
flush(); |
return retVal; |
} |
/QMK-Groundstation/branches/own_com_lib/SerialPort/posix_qextserialport.h |
---|
0,0 → 1,56 |
#ifndef _POSIX_QEXTSERIALPORT_H_ |
#define _POSIX_QEXTSERIALPORT_H_ |
#include <stdio.h> |
#include <termios.h> |
#include <errno.h> |
#include <unistd.h> |
#include <sys/time.h> |
#include <sys/ioctl.h> |
#include <sys/select.h> |
#include "qextserialbase.h" |
class Posix_QextSerialPort:public QextSerialBase { |
public: |
Posix_QextSerialPort(); |
Posix_QextSerialPort(const Posix_QextSerialPort& s); |
Posix_QextSerialPort(const QString & name); |
Posix_QextSerialPort(const PortSettings& settings); |
Posix_QextSerialPort(const QString & name, const PortSettings& settings); |
Posix_QextSerialPort& operator=(const Posix_QextSerialPort& s); |
virtual ~Posix_QextSerialPort(); |
virtual void setBaudRate(BaudRateType); |
virtual void setDataBits(DataBitsType); |
virtual void setParity(ParityType); |
virtual void setStopBits(StopBitsType); |
virtual void setFlowControl(FlowType); |
virtual void setTimeout(ulong, ulong); |
virtual bool open(OpenMode mode=0); |
virtual void close(); |
virtual void flush(); |
virtual qint64 size() const; |
virtual qint64 bytesAvailable(); |
virtual void ungetChar(char c); |
virtual void translateError(ulong error); |
virtual void setDtr(bool set=true); |
virtual void setRts(bool set=true); |
virtual ulong lineStatus(); |
protected: |
QFile* Posix_File; |
struct termios Posix_CommConfig; |
struct timeval Posix_Timeout; |
struct timeval Posix_Copy_Timeout; |
virtual qint64 readData(char * data, qint64 maxSize); |
virtual qint64 writeData(const char * data, qint64 maxSize); |
}; |
#endif |
/QMK-Groundstation/branches/own_com_lib/SerialPort/qextserialbase.cpp |
---|
0,0 → 1,250 |
#include "qextserialbase.h" |
/*! |
\class QextSerialBase |
\version 1.0.0 |
\author Stefan Sander |
A common base class for Win_QextSerialBase, Posix_QextSerialBase and QextSerialPort. |
*/ |
#ifdef QT_THREAD_SUPPORT |
QMutex* QextSerialBase::mutex=NULL; |
unsigned long QextSerialBase::refCount=0; |
#endif |
/*! |
\fn QextSerialBase::QextSerialBase() |
Default constructor. |
*/ |
QextSerialBase::QextSerialBase() |
: QIODevice() |
{ |
#ifdef _TTY_WIN_ |
setPortName("COM1"); |
#elif defined(_TTY_IRIX_) |
setPortName("/dev/ttyf1"); |
#elif defined(_TTY_HPUX_) |
setPortName("/dev/tty1p0"); |
#elif defined(_TTY_SUN_) |
setPortName("/dev/ttya"); |
#elif defined(_TTY_DIGITAL_) |
setPortName("/dev/tty01"); |
#elif defined(_TTY_FREEBSD_) |
setPortName("/dev/ttyd1"); |
#else |
setPortName("/dev/ttyS0"); |
#endif |
construct(); |
} |
/*! |
\fn QextSerialBase::QextSerialBase(const QString & name) |
Construct a port and assign it to the device specified by the name parameter. |
*/ |
QextSerialBase::QextSerialBase(const QString & name) |
: QIODevice() |
{ |
setPortName(name); |
construct(); |
} |
/*! |
\fn QextSerialBase::~QextSerialBase() |
Standard destructor. |
*/ |
QextSerialBase::~QextSerialBase() |
{ |
#ifdef QT_THREAD_SUPPORT |
refCount--; |
if (mutex && refCount==0) { |
delete mutex; |
mutex=NULL; |
} |
#endif |
} |
/*! |
\fn void QextSerialBase::construct() |
Common constructor function for setting up default port settings. |
(9600 Baud, 8N1, no flow control where supported, otherwise no flow control, and 20 ms timeout). |
*/ |
void QextSerialBase::construct() |
{ |
Settings.BaudRate=BAUD9600; |
Settings.DataBits=DATA_8; |
Settings.Parity=PAR_NONE; |
Settings.StopBits=STOP_1; |
Settings.FlowControl=FLOW_OFF; |
Settings.Timeout_Sec=0; |
Settings.Timeout_Millisec=20; |
#ifdef QT_THREAD_SUPPORT |
if (!mutex) { |
mutex=new QMutex( QMutex::Recursive ); |
} |
refCount++; |
#endif |
setOpenMode(QIODevice::NotOpen); |
} |
/*! |
\fn void QextSerialBase::setPortName(const QString & name) |
Sets the name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0". |
*/ |
void QextSerialBase::setPortName(const QString & name) |
{ |
port = name; |
} |
/*! |
\fn QString QextSerialBase::portName() const |
Returns the name set by setPortName(). |
*/ |
QString QextSerialBase::portName() const |
{ |
return port; |
} |
/*! |
\fn BaudRateType QextSerialBase::baudRate(void) const |
Returns the baud rate of the serial port. For a list of possible return values see |
the definition of the enum BaudRateType. |
*/ |
BaudRateType QextSerialBase::baudRate(void) const |
{ |
return Settings.BaudRate; |
} |
/*! |
\fn DataBitsType QextSerialBase::dataBits() const |
Returns the number of data bits used by the port. For a list of possible values returned by |
this function, see the definition of the enum DataBitsType. |
*/ |
DataBitsType QextSerialBase::dataBits() const |
{ |
return Settings.DataBits; |
} |
/*! |
\fn ParityType QextSerialBase::parity() const |
Returns the type of parity used by the port. For a list of possible values returned by |
this function, see the definition of the enum ParityType. |
*/ |
ParityType QextSerialBase::parity() const |
{ |
return Settings.Parity; |
} |
/*! |
\fn StopBitsType QextSerialBase::stopBits() const |
Returns the number of stop bits used by the port. For a list of possible return values, see |
the definition of the enum StopBitsType. |
*/ |
StopBitsType QextSerialBase::stopBits() const |
{ |
return Settings.StopBits; |
} |
/*! |
\fn FlowType QextSerialBase::flowControl() const |
Returns the type of flow control used by the port. For a list of possible values returned |
by this function, see the definition of the enum FlowType. |
*/ |
FlowType QextSerialBase::flowControl() const |
{ |
return Settings.FlowControl; |
} |
/*! |
\fn bool QextSerialBase::isSequential() const |
Returns true if device is sequential, otherwise returns false. Serial port is sequential device |
so this function always returns true. Check QIODevice::isSequential() documentation for more |
information. |
*/ |
bool QextSerialBase::isSequential() const |
{ |
return true; |
} |
/*! |
\fn bool QextSerialBase::atEnd() const |
This function will return true if the input buffer is empty (or on error), and false otherwise. |
Call QextSerialBase::lastError() for error information. |
*/ |
bool QextSerialBase::atEnd() const |
{ |
if (size()) { |
return true; |
} |
return false; |
} |
/*! |
\fn qint64 QextSerialBase::readLine(char * data, qint64 maxSize) |
This function will read a line of buffered input from the port, stopping when either maxSize bytes |
have been read, the port has no more data available, or a newline is encountered. |
The value returned is the length of the string that was read. |
*/ |
qint64 QextSerialBase::readLine(char * data, qint64 maxSize) |
{ |
qint64 numBytes = bytesAvailable(); |
char* pData = data; |
if (maxSize < 2) //maxSize must be larger than 1 |
return -1; |
/*read a byte at a time for MIN(bytesAvail, maxSize - 1) iterations, or until a newline*/ |
while (pData<(data+numBytes) && --maxSize) { |
readData(pData, 1); |
if (*pData++ == '\n') { |
break; |
} |
} |
*pData='\0'; |
/*return size of data read*/ |
return (pData-data); |
} |
/*! |
\fn ulong QextSerialBase::lastError() const |
Returns the code for the last error encountered by the port, or E_NO_ERROR if the last port |
operation was successful. Possible error codes are: |
\verbatim |
Error Explanation |
--------------------------- ------------------------------------------------------------- |
E_NO_ERROR No Error has occured |
E_INVALID_FD Invalid file descriptor (port was not opened correctly) |
E_NO_MEMORY Unable to allocate memory tables (POSIX) |
E_CAUGHT_NON_BLOCKED_SIGNAL Caught a non-blocked signal (POSIX) |
E_PORT_TIMEOUT Operation timed out (POSIX) |
E_INVALID_DEVICE The file opened by the port is not a character device (POSIX) |
E_BREAK_CONDITION The port detected a break condition |
E_FRAMING_ERROR The port detected a framing error |
(usually caused by incorrect baud rate settings) |
E_IO_ERROR There was an I/O error while communicating with the port |
E_BUFFER_OVERRUN Character buffer overrun |
E_RECEIVE_OVERFLOW Receive buffer overflow |
E_RECEIVE_PARITY_ERROR The port detected a parity error in the received data |
E_TRANSMIT_OVERFLOW Transmit buffer overflow |
E_READ_FAILED General read operation failure |
E_WRITE_FAILED General write operation failure |
\endverbatim |
*/ |
ulong QextSerialBase::lastError() const |
{ |
return lastErr; |
} |
/QMK-Groundstation/branches/own_com_lib/SerialPort/qextserialbase.h |
---|
0,0 → 1,196 |
#ifndef _QEXTSERIALBASE_H_ |
#define _QEXTSERIALBASE_H_ |
#include <QIODevice> |
#include <QFile> |
#ifdef QT_THREAD_SUPPORT |
#include <QThread> |
#include <QMutex> |
#endif |
/*if all warning messages are turned off, flag portability warnings to be turned off as well*/ |
#ifdef _TTY_NOWARN_ |
#define _TTY_NOWARN_PORT_ |
#endif |
/*macros for thread support*/ |
#ifdef QT_THREAD_SUPPORT |
#define LOCK_MUTEX() mutex->lock() |
#define UNLOCK_MUTEX() mutex->unlock() |
#else |
#define LOCK_MUTEX() |
#define UNLOCK_MUTEX() |
#endif |
/*macros for warning messages*/ |
#ifdef _TTY_NOWARN_PORT_ |
#define TTY_PORTABILITY_WARNING(s) |
#else |
#define TTY_PORTABILITY_WARNING(s) qWarning(s) |
#endif |
#ifdef _TTY_NOWARN_ |
#define TTY_WARNING(s) |
#else |
#define TTY_WARNING(s) qWarning(s) |
#endif |
/*line status constants*/ |
#define LS_CTS 0x01 |
#define LS_DSR 0x02 |
#define LS_DCD 0x04 |
#define LS_RI 0x08 |
#define LS_RTS 0x10 |
#define LS_DTR 0x20 |
#define LS_ST 0x40 |
#define LS_SR 0x80 |
/*error constants*/ |
#define E_NO_ERROR 0 |
#define E_INVALID_FD 1 |
#define E_NO_MEMORY 2 |
#define E_CAUGHT_NON_BLOCKED_SIGNAL 3 |
#define E_PORT_TIMEOUT 4 |
#define E_INVALID_DEVICE 5 |
#define E_BREAK_CONDITION 6 |
#define E_FRAMING_ERROR 7 |
#define E_IO_ERROR 8 |
#define E_BUFFER_OVERRUN 9 |
#define E_RECEIVE_OVERFLOW 10 |
#define E_RECEIVE_PARITY_ERROR 11 |
#define E_TRANSMIT_OVERFLOW 12 |
#define E_READ_FAILED 13 |
#define E_WRITE_FAILED 14 |
/*enums for port settings*/ |
enum NamingConvention { |
WIN_NAMES, |
IRIX_NAMES, |
HPUX_NAMES, |
SUN_NAMES, |
DIGITAL_NAMES, |
FREEBSD_NAMES, |
LINUX_NAMES |
}; |
enum BaudRateType { |
BAUD50, //POSIX ONLY |
BAUD75, //POSIX ONLY |
BAUD110, |
BAUD134, //POSIX ONLY |
BAUD150, //POSIX ONLY |
BAUD200, //POSIX ONLY |
BAUD300, |
BAUD600, |
BAUD1200, |
BAUD1800, //POSIX ONLY |
BAUD2400, |
BAUD4800, |
BAUD9600, |
BAUD14400, //WINDOWS ONLY |
BAUD19200, |
BAUD38400, |
BAUD56000, //WINDOWS ONLY |
BAUD57600, |
BAUD76800, //POSIX ONLY |
BAUD115200, |
BAUD128000, //WINDOWS ONLY |
BAUD256000 //WINDOWS ONLY |
}; |
enum DataBitsType { |
DATA_5, |
DATA_6, |
DATA_7, |
DATA_8 |
}; |
enum ParityType { |
PAR_NONE, |
PAR_ODD, |
PAR_EVEN, |
PAR_MARK, //WINDOWS ONLY |
PAR_SPACE |
}; |
enum StopBitsType { |
STOP_1, |
STOP_1_5, //WINDOWS ONLY |
STOP_2 |
}; |
enum FlowType { |
FLOW_OFF, |
FLOW_HARDWARE, |
FLOW_XONXOFF |
}; |
/*structure to contain port settings*/ |
struct PortSettings { |
BaudRateType BaudRate; |
DataBitsType DataBits; |
ParityType Parity; |
StopBitsType StopBits; |
FlowType FlowControl; |
ulong Timeout_Sec; |
ulong Timeout_Millisec; |
}; |
class QextSerialBase : public QIODevice { |
public: |
QextSerialBase(); |
QextSerialBase(const QString & name); |
virtual ~QextSerialBase(); |
virtual void construct(); |
virtual void setPortName(const QString & name); |
virtual QString portName() const; |
virtual void setBaudRate(BaudRateType)=0; |
virtual BaudRateType baudRate() const; |
virtual void setDataBits(DataBitsType)=0; |
virtual DataBitsType dataBits() const; |
virtual void setParity(ParityType)=0; |
virtual ParityType parity() const; |
virtual void setStopBits(StopBitsType)=0; |
virtual StopBitsType stopBits() const; |
virtual void setFlowControl(FlowType)=0; |
virtual FlowType flowControl() const; |
virtual void setTimeout(ulong, ulong)=0; |
virtual bool open(OpenMode mode=0)=0; |
virtual bool isSequential() const; |
virtual void close()=0; |
virtual void flush()=0; |
virtual qint64 size() const=0; |
virtual qint64 bytesAvailable()=0; |
virtual bool atEnd() const; |
virtual void ungetChar(char c)=0; |
virtual qint64 readLine(char * data, qint64 maxSize); |
virtual ulong lastError() const; |
virtual void translateError(ulong error)=0; |
virtual void setDtr(bool set=true)=0; |
virtual void setRts(bool set=true)=0; |
virtual ulong lineStatus()=0; |
protected: |
QString port; |
PortSettings Settings; |
ulong lastErr; |
#ifdef QT_THREAD_SUPPORT |
static QMutex* mutex; |
static ulong refCount; |
#endif |
virtual qint64 readData(char * data, qint64 maxSize)=0; |
virtual qint64 writeData(const char * data, qint64 maxSize)=0; |
}; |
#endif |
/QMK-Groundstation/branches/own_com_lib/SerialPort/qextserialport.cpp |
---|
0,0 → 1,98 |
/*! |
\class QextSerialPort |
\version 1.0.0 |
\author Stefan Sander |
A cross-platform serial port class. |
This class encapsulates a serial port on both POSIX and Windows systems. The user will be |
notified of errors and possible portability conflicts at run-time by default - this behavior can |
be turned off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn |
off portability warnings) in the project. |
\note |
On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may |
select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can |
make no guarantees as to the quality of POSIX support under NT/2000 however. |
*/ |
#include <stdio.h> |
#include "qextserialport.h" |
/*! |
\fn QextSerialPort::QextSerialPort() |
Default constructor. Note that the naming convention used by a QextSerialPort constructed with |
this constructor will be determined by #defined constants, or lack thereof - the default behavior |
is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are: |
\verbatim |
Constant Used By Naming Convention |
---------- ------------- ------------------------ |
_TTY_WIN_ Windows COM1, COM2 |
_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2 |
_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0 |
_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb |
_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02 |
_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1 |
_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1 |
<none> Linux /dev/ttyS0, /dev/ttyS1 |
\endverbatim |
The object will be associated with the first port in the system, e.g. COM1 on Windows systems. |
See the other constructors if you need to use a port other than the first. |
*/ |
QextSerialPort::QextSerialPort() |
: QextBaseType() |
{} |
/*! |
\fn QextSerialPort::QextSerialPort(const QString & name) |
Constructs a serial port attached to the port specified by name. |
name is the name of the device, which is windowsystem-specific, |
e.g."COM1" or "/dev/ttyS0". |
*/ |
QextSerialPort::QextSerialPort(const QString & name) |
: QextBaseType(name) |
{} |
/*! |
\fn QextSerialPort::QextSerialPort(PortSettings const& settings) |
Constructs a port with default name and settings specified by the settings parameter. |
*/ |
QextSerialPort::QextSerialPort(PortSettings const& settings) |
: QextBaseType(settings) |
{} |
/*! |
\fn QextSerialPort::QextSerialPort(const QString & name, PortSettings const& settings) |
Constructs a port with the name and settings specified. |
*/ |
QextSerialPort::QextSerialPort(const QString & name, PortSettings const& settings) |
: QextBaseType(name, settings) |
{} |
/*! |
\fn QextSerialPort::QextSerialPort(const QextSerialPort& s) |
Copy constructor. |
*/ |
QextSerialPort::QextSerialPort(const QextSerialPort& s) |
: QextBaseType(s) |
{} |
/*! |
\fn QextSerialPort& QextSerialPort::operator=(const QextSerialPort& s) |
Overrides the = operator. |
*/ |
QextSerialPort& QextSerialPort::operator=(const QextSerialPort& s) |
{ |
return (QextSerialPort&)QextBaseType::operator=(s); |
} |
/*! |
\fn QextSerialPort::~QextSerialPort() |
Standard destructor. |
*/ |
QextSerialPort::~QextSerialPort() |
{} |
/QMK-Groundstation/branches/own_com_lib/SerialPort/qextserialport.h |
---|
0,0 → 1,27 |
#ifndef _QEXTSERIALPORT_H_ |
#define _QEXTSERIALPORT_H_ |
/*POSIX CODE*/ |
#ifdef _TTY_POSIX_ |
#include "posix_qextserialport.h" |
#define QextBaseType Posix_QextSerialPort |
/*MS WINDOWS CODE*/ |
#else |
#include "win_qextserialport.h" |
#define QextBaseType Win_QextSerialPort |
#endif |
class QextSerialPort: public QextBaseType { |
public: |
QextSerialPort(); |
QextSerialPort(const QString & name); |
QextSerialPort(PortSettings const& s); |
QextSerialPort(const QString & name, PortSettings const& s); |
QextSerialPort(const QextSerialPort& s); |
QextSerialPort& operator=(const QextSerialPort&); |
virtual ~QextSerialPort(); |
}; |
#endif |
/QMK-Groundstation/branches/own_com_lib/SerialPort/win_qextserialport.cpp |
---|
0,0 → 1,877 |
/*! |
\class Win_QextSerialPort |
\version 1.0.0 |
\author Stefan Sander |
A cross-platform serial port class. |
This class encapsulates the Windows portion of QextSerialPort. The user will be notified of |
errors and possible portability conflicts at run-time by default - this behavior can be turned |
off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off |
portability warnings) in the project. Note that defining _TTY_NOWARN_ also defines |
_TTY_NOWARN_PORT_. |
\note |
On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may |
select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can |
make no guarantees as to the quality of POSIX support under NT/2000 however. |
*/ |
#include <stdio.h> |
#include "win_qextserialport.h" |
/*! |
\fn Win_QextSerialPort::Win_QextSerialPort() |
Default constructor. Note that the name of the device used by a Win_QextSerialPort constructed |
with this constructor will be determined by #defined constants, or lack thereof - the default |
behavior is the same as _TTY_LINUX_. Possible naming conventions and their associated constants |
are: |
\verbatim |
Constant Used By Naming Convention |
---------- ------------- ------------------------ |
_TTY_WIN_ Windows COM1, COM2 |
_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2 |
_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0 |
_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb |
_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02 |
_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1 |
_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1 |
<none> Linux /dev/ttyS0, /dev/ttyS1 |
\endverbatim |
This constructor associates the object with the first port on the system, e.g. COM1 for Windows |
platforms. See the other constructor if you need a port other than the first. |
*/ |
Win_QextSerialPort::Win_QextSerialPort():QextSerialBase() { |
Win_Handle=INVALID_HANDLE_VALUE; |
} |
/*!Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort&) |
Copy constructor. |
*/ |
Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort& s):QextSerialBase(s.port) { |
Win_Handle=INVALID_HANDLE_VALUE; |
setOpenMode(s.openMode()); |
lastErr=s.lastErr; |
port = s.port; |
Settings.FlowControl=s.Settings.FlowControl; |
Settings.Parity=s.Settings.Parity; |
Settings.DataBits=s.Settings.DataBits; |
Settings.StopBits=s.Settings.StopBits; |
Settings.BaudRate=s.Settings.BaudRate; |
Win_Handle=s.Win_Handle; |
memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG)); |
memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS)); |
} |
/*! |
\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name) |
Constructs a serial port attached to the port specified by devName. |
devName is the name of the device, which is windowsystem-specific, |
e.g."COM2" or "/dev/ttyS0". |
*/ |
Win_QextSerialPort::Win_QextSerialPort(const QString & name):QextSerialBase(name) { |
Win_Handle=INVALID_HANDLE_VALUE; |
} |
/*! |
\fn Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings) |
Constructs a port with default name and specified settings. |
*/ |
Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings) { |
Win_Handle=INVALID_HANDLE_VALUE; |
setBaudRate(settings.BaudRate); |
setDataBits(settings.DataBits); |
setStopBits(settings.StopBits); |
setParity(settings.Parity); |
setFlowControl(settings.FlowControl); |
setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); |
} |
/*! |
\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings) |
Constructs a port with specified name and settings. |
*/ |
Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings) { |
Win_Handle=INVALID_HANDLE_VALUE; |
setPortName(name); |
setBaudRate(settings.BaudRate); |
setDataBits(settings.DataBits); |
setStopBits(settings.StopBits); |
setParity(settings.Parity); |
setFlowControl(settings.FlowControl); |
setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); |
} |
/*! |
\fn Win_QextSerialPort::~Win_QextSerialPort() |
Standard destructor. |
*/ |
Win_QextSerialPort::~Win_QextSerialPort() { |
if (isOpen()) { |
close(); |
} |
} |
/*! |
\fn Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s) |
overrides the = operator |
*/ |
Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s) { |
setOpenMode(s.openMode()); |
lastErr=s.lastErr; |
port = s.port; |
Settings.FlowControl=s.Settings.FlowControl; |
Settings.Parity=s.Settings.Parity; |
Settings.DataBits=s.Settings.DataBits; |
Settings.StopBits=s.Settings.StopBits; |
Settings.BaudRate=s.Settings.BaudRate; |
Win_Handle=s.Win_Handle; |
memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG)); |
memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS)); |
return *this; |
} |
/*! |
\fn bool Win_QextSerialPort::open(OpenMode mode) |
Opens a serial port. Note that this function does not specify which device to open. If you need |
to open a device by name, see Win_QextSerialPort::open(const char*). This function has no effect |
if the port associated with the class is already open. The port is also configured to the current |
settings, as stored in the Settings structure. |
*/ |
bool Win_QextSerialPort::open(OpenMode mode) { |
unsigned long confSize = sizeof(COMMCONFIG); |
Win_CommConfig.dwSize = confSize; |
LOCK_MUTEX(); |
if (mode == QIODevice::NotOpen) |
return isOpen(); |
if (!isOpen()) { |
/*open the port*/ |
Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE, |
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); |
if (Win_Handle!=INVALID_HANDLE_VALUE) { |
/*set open mode*/ |
QIODevice::open(mode); |
/*configure port settings*/ |
GetCommConfig(Win_Handle, &Win_CommConfig, &confSize); |
GetCommState(Win_Handle, &(Win_CommConfig.dcb)); |
/*set up parameters*/ |
Win_CommConfig.dcb.fBinary=TRUE; |
Win_CommConfig.dcb.fInX=FALSE; |
Win_CommConfig.dcb.fOutX=FALSE; |
Win_CommConfig.dcb.fAbortOnError=FALSE; |
Win_CommConfig.dcb.fNull=FALSE; |
setBaudRate(Settings.BaudRate); |
setDataBits(Settings.DataBits); |
setStopBits(Settings.StopBits); |
setParity(Settings.Parity); |
setFlowControl(Settings.FlowControl); |
setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec); |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
} |
UNLOCK_MUTEX(); |
return isOpen(); |
} |
/*! |
\fn void Win_QextSerialPort::close() |
Closes a serial port. This function has no effect if the serial port associated with the class |
is not currently open. |
*/ |
void Win_QextSerialPort::close() { |
LOCK_MUTEX(); |
CloseHandle(Win_Handle); |
QIODevice::close(); |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Win_QextSerialPort::flush() |
Flushes all pending I/O to the serial port. This function has no effect if the serial port |
associated with the class is not currently open. |
*/ |
void Win_QextSerialPort::flush() { |
LOCK_MUTEX(); |
if (isOpen()) { |
FlushFileBuffers(Win_Handle); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn qint64 Win_QextSerialPort::size() const |
This function will return the number of bytes waiting in the receive queue of the serial port. |
It is included primarily to provide a complete QIODevice interface, and will not record errors |
in the lastErr member (because it is const). This function is also not thread-safe - in |
multithreading situations, use Win_QextSerialPort::bytesAvailable() instead. |
*/ |
qint64 Win_QextSerialPort::size() const { |
int availBytes; |
COMSTAT Win_ComStat; |
DWORD Win_ErrorMask=0; |
ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat); |
availBytes = Win_ComStat.cbInQue; |
return (qint64)availBytes; |
} |
/*! |
\fn qint64 Win_QextSerialPort::bytesAvailable() |
Returns the number of bytes waiting in the port's receive queue. This function will return 0 if |
the port is not currently open, or -1 on error. Error information can be retrieved by calling |
Win_QextSerialPort::getLastError(). |
*/ |
qint64 Win_QextSerialPort::bytesAvailable() { |
LOCK_MUTEX(); |
if (isOpen()) { |
DWORD Errors; |
COMSTAT Status; |
bool success=ClearCommError(Win_Handle, &Errors, &Status); |
translateError(Errors); |
if (success) { |
lastErr=E_NO_ERROR; |
UNLOCK_MUTEX(); |
return Status.cbInQue + QIODevice::bytesAvailable(); |
} |
UNLOCK_MUTEX(); |
return (unsigned int)-1; |
} |
UNLOCK_MUTEX(); |
return 0; |
} |
/*! |
\fn void Win_QextSerialPort::translateError(ulong error) |
Translates a system-specific error code to a QextSerialPort error code. Used internally. |
*/ |
void Win_QextSerialPort::translateError(ulong error) { |
if (error&CE_BREAK) { |
lastErr=E_BREAK_CONDITION; |
} |
else if (error&CE_FRAME) { |
lastErr=E_FRAMING_ERROR; |
} |
else if (error&CE_IOE) { |
lastErr=E_IO_ERROR; |
} |
else if (error&CE_MODE) { |
lastErr=E_INVALID_FD; |
} |
else if (error&CE_OVERRUN) { |
lastErr=E_BUFFER_OVERRUN; |
} |
else if (error&CE_RXPARITY) { |
lastErr=E_RECEIVE_PARITY_ERROR; |
} |
else if (error&CE_RXOVER) { |
lastErr=E_RECEIVE_OVERFLOW; |
} |
else if (error&CE_TXFULL) { |
lastErr=E_TRANSMIT_OVERFLOW; |
} |
} |
/*! |
\fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize) |
Reads a block of data from the serial port. This function will read at most maxlen bytes from |
the serial port and place them in the buffer pointed to by data. Return value is the number of |
bytes actually read, or -1 on error. |
\warning before calling this function ensure that serial port associated with this class |
is currently open (use isOpen() function to check if port is open). |
*/ |
qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize) |
{ |
LOCK_MUTEX(); |
int retVal=0; |
COMSTAT Win_ComStat; |
DWORD Win_BytesRead=0; |
DWORD Win_ErrorMask=0; |
ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat); |
if (Win_ComStat.cbInQue && |
(!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesRead, NULL) |
|| Win_BytesRead==0)) { |
lastErr=E_READ_FAILED; |
retVal=-1; |
} |
else { |
retVal=((int)Win_BytesRead); |
} |
UNLOCK_MUTEX(); |
return retVal; |
} |
/*! |
\fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize) |
Writes a block of data to the serial port. This function will write len bytes |
from the buffer pointed to by data to the serial port. Return value is the number |
of bytes actually written, or -1 on error. |
\warning before calling this function ensure that serial port associated with this class |
is currently open (use isOpen() function to check if port is open). |
*/ |
qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize) |
{ |
LOCK_MUTEX(); |
int retVal=0; |
DWORD Win_BytesWritten; |
if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesWritten, NULL)) { |
lastErr=E_WRITE_FAILED; |
retVal=-1; |
} |
else { |
retVal=((int)Win_BytesWritten); |
} |
UNLOCK_MUTEX(); |
flush(); |
return retVal; |
} |
/*! |
\fn void Win_QextSerialPort::ungetChar(char c) |
This function is included to implement the full QIODevice interface, and currently has no |
purpose within this class. This function is meaningless on an unbuffered device and currently |
only prints a warning message to that effect. |
*/ |
void Win_QextSerialPort::ungetChar(char c) { |
/*meaningless on unbuffered sequential device - return error and print a warning*/ |
TTY_WARNING("Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless"); |
} |
/*! |
\fn void Win_QextSerialPort::setFlowControl(FlowType flow) |
Sets the flow control used by the port. Possible values of flow are: |
\verbatim |
FLOW_OFF No flow control |
FLOW_HARDWARE Hardware (RTS/CTS) flow control |
FLOW_XONXOFF Software (XON/XOFF) flow control |
\endverbatim |
*/ |
void Win_QextSerialPort::setFlowControl(FlowType flow) { |
LOCK_MUTEX(); |
if (Settings.FlowControl!=flow) { |
Settings.FlowControl=flow; |
} |
if (isOpen()) { |
switch(flow) { |
/*no flow control*/ |
case FLOW_OFF: |
Win_CommConfig.dcb.fOutxCtsFlow=FALSE; |
Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE; |
Win_CommConfig.dcb.fInX=FALSE; |
Win_CommConfig.dcb.fOutX=FALSE; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
break; |
/*software (XON/XOFF) flow control*/ |
case FLOW_XONXOFF: |
Win_CommConfig.dcb.fOutxCtsFlow=FALSE; |
Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE; |
Win_CommConfig.dcb.fInX=TRUE; |
Win_CommConfig.dcb.fOutX=TRUE; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
break; |
case FLOW_HARDWARE: |
Win_CommConfig.dcb.fOutxCtsFlow=TRUE; |
Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE; |
Win_CommConfig.dcb.fInX=FALSE; |
Win_CommConfig.dcb.fOutX=FALSE; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
break; |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Win_QextSerialPort::setParity(ParityType parity) |
Sets the parity associated with the serial port. The possible values of parity are: |
\verbatim |
PAR_SPACE Space Parity |
PAR_MARK Mark Parity |
PAR_NONE No Parity |
PAR_EVEN Even Parity |
PAR_ODD Odd Parity |
\endverbatim |
*/ |
void Win_QextSerialPort::setParity(ParityType parity) { |
LOCK_MUTEX(); |
if (Settings.Parity!=parity) { |
Settings.Parity=parity; |
} |
if (isOpen()) { |
Win_CommConfig.dcb.Parity=(unsigned char)parity; |
switch (parity) { |
/*space parity*/ |
case PAR_SPACE: |
if (Settings.DataBits==DATA_8) { |
TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems."); |
} |
Win_CommConfig.dcb.fParity=TRUE; |
break; |
/*mark parity - WINDOWS ONLY*/ |
case PAR_MARK: |
TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems"); |
Win_CommConfig.dcb.fParity=TRUE; |
break; |
/*no parity*/ |
case PAR_NONE: |
Win_CommConfig.dcb.fParity=FALSE; |
break; |
/*even parity*/ |
case PAR_EVEN: |
Win_CommConfig.dcb.fParity=TRUE; |
break; |
/*odd parity*/ |
case PAR_ODD: |
Win_CommConfig.dcb.fParity=TRUE; |
break; |
} |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits) |
Sets the number of data bits used by the serial port. Possible values of dataBits are: |
\verbatim |
DATA_5 5 data bits |
DATA_6 6 data bits |
DATA_7 7 data bits |
DATA_8 8 data bits |
\endverbatim |
\note |
This function is subject to the following restrictions: |
\par |
5 data bits cannot be used with 2 stop bits. |
\par |
1.5 stop bits can only be used with 5 data bits. |
\par |
8 data bits cannot be used with space parity on POSIX systems. |
*/ |
void Win_QextSerialPort::setDataBits(DataBitsType dataBits) { |
LOCK_MUTEX(); |
if (Settings.DataBits!=dataBits) { |
if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) || |
(Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) { |
} |
else { |
Settings.DataBits=dataBits; |
} |
} |
if (isOpen()) { |
switch(dataBits) { |
/*5 data bits*/ |
case DATA_5: |
if (Settings.StopBits==STOP_2) { |
TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); |
} |
else { |
Win_CommConfig.dcb.ByteSize=5; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
break; |
/*6 data bits*/ |
case DATA_6: |
if (Settings.StopBits==STOP_1_5) { |
TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); |
} |
else { |
Win_CommConfig.dcb.ByteSize=6; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
break; |
/*7 data bits*/ |
case DATA_7: |
if (Settings.StopBits==STOP_1_5) { |
TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); |
} |
else { |
Win_CommConfig.dcb.ByteSize=7; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
break; |
/*8 data bits*/ |
case DATA_8: |
if (Settings.StopBits==STOP_1_5) { |
TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); |
} |
else { |
Win_CommConfig.dcb.ByteSize=8; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
break; |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits) |
Sets the number of stop bits used by the serial port. Possible values of stopBits are: |
\verbatim |
STOP_1 1 stop bit |
STOP_1_5 1.5 stop bits |
STOP_2 2 stop bits |
\endverbatim |
\note |
This function is subject to the following restrictions: |
\par |
2 stop bits cannot be used with 5 data bits. |
\par |
1.5 stop bits cannot be used with 6 or more data bits. |
\par |
POSIX does not support 1.5 stop bits. |
*/ |
void Win_QextSerialPort::setStopBits(StopBitsType stopBits) { |
LOCK_MUTEX(); |
if (Settings.StopBits!=stopBits) { |
if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || |
(stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) { |
} |
else { |
Settings.StopBits=stopBits; |
} |
} |
if (isOpen()) { |
switch (stopBits) { |
/*one stop bit*/ |
case STOP_1: |
Win_CommConfig.dcb.StopBits=ONESTOPBIT; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
break; |
/*1.5 stop bits*/ |
case STOP_1_5: |
TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX."); |
if (Settings.DataBits!=DATA_5) { |
TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits"); |
} |
else { |
Win_CommConfig.dcb.StopBits=ONE5STOPBITS; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
break; |
/*two stop bits*/ |
case STOP_2: |
if (Settings.DataBits==DATA_5) { |
TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits"); |
} |
else { |
Win_CommConfig.dcb.StopBits=TWOSTOPBITS; |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
break; |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) |
Sets the baud rate of the serial port. Note that not all rates are applicable on |
all platforms. The following table shows translations of the various baud rate |
constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an * |
are speeds that are usable on both Windows and POSIX. |
\verbatim |
RATE Windows Speed POSIX Speed |
----------- ------------- ----------- |
BAUD50 110 50 |
BAUD75 110 75 |
*BAUD110 110 110 |
BAUD134 110 134.5 |
BAUD150 110 150 |
BAUD200 110 200 |
*BAUD300 300 300 |
*BAUD600 600 600 |
*BAUD1200 1200 1200 |
BAUD1800 1200 1800 |
*BAUD2400 2400 2400 |
*BAUD4800 4800 4800 |
*BAUD9600 9600 9600 |
BAUD14400 14400 9600 |
*BAUD19200 19200 19200 |
*BAUD38400 38400 38400 |
BAUD56000 56000 38400 |
*BAUD57600 57600 57600 |
BAUD76800 57600 76800 |
*BAUD115200 115200 115200 |
BAUD128000 128000 115200 |
BAUD256000 256000 115200 |
\endverbatim |
*/ |
void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) { |
LOCK_MUTEX(); |
if (Settings.BaudRate!=baudRate) { |
switch (baudRate) { |
case BAUD50: |
case BAUD75: |
case BAUD134: |
case BAUD150: |
case BAUD200: |
Settings.BaudRate=BAUD110; |
break; |
case BAUD1800: |
Settings.BaudRate=BAUD1200; |
break; |
case BAUD76800: |
Settings.BaudRate=BAUD57600; |
break; |
default: |
Settings.BaudRate=baudRate; |
break; |
} |
} |
if (isOpen()) { |
switch (baudRate) { |
/*50 baud*/ |
case BAUD50: |
TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation. Switching to 110 baud."); |
Win_CommConfig.dcb.BaudRate=CBR_110; |
break; |
/*75 baud*/ |
case BAUD75: |
TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation. Switching to 110 baud."); |
Win_CommConfig.dcb.BaudRate=CBR_110; |
break; |
/*110 baud*/ |
case BAUD110: |
Win_CommConfig.dcb.BaudRate=CBR_110; |
break; |
/*134.5 baud*/ |
case BAUD134: |
TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation. Switching to 110 baud."); |
Win_CommConfig.dcb.BaudRate=CBR_110; |
break; |
/*150 baud*/ |
case BAUD150: |
TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation. Switching to 110 baud."); |
Win_CommConfig.dcb.BaudRate=CBR_110; |
break; |
/*200 baud*/ |
case BAUD200: |
TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation. Switching to 110 baud."); |
Win_CommConfig.dcb.BaudRate=CBR_110; |
break; |
/*300 baud*/ |
case BAUD300: |
Win_CommConfig.dcb.BaudRate=CBR_300; |
break; |
/*600 baud*/ |
case BAUD600: |
Win_CommConfig.dcb.BaudRate=CBR_600; |
break; |
/*1200 baud*/ |
case BAUD1200: |
Win_CommConfig.dcb.BaudRate=CBR_1200; |
break; |
/*1800 baud*/ |
case BAUD1800: |
TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation. Switching to 1200 baud."); |
Win_CommConfig.dcb.BaudRate=CBR_1200; |
break; |
/*2400 baud*/ |
case BAUD2400: |
Win_CommConfig.dcb.BaudRate=CBR_2400; |
break; |
/*4800 baud*/ |
case BAUD4800: |
Win_CommConfig.dcb.BaudRate=CBR_4800; |
break; |
/*9600 baud*/ |
case BAUD9600: |
Win_CommConfig.dcb.BaudRate=CBR_9600; |
break; |
/*14400 baud*/ |
case BAUD14400: |
TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation."); |
Win_CommConfig.dcb.BaudRate=CBR_14400; |
break; |
/*19200 baud*/ |
case BAUD19200: |
Win_CommConfig.dcb.BaudRate=CBR_19200; |
break; |
/*38400 baud*/ |
case BAUD38400: |
Win_CommConfig.dcb.BaudRate=CBR_38400; |
break; |
/*56000 baud*/ |
case BAUD56000: |
TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation."); |
Win_CommConfig.dcb.BaudRate=CBR_56000; |
break; |
/*57600 baud*/ |
case BAUD57600: |
Win_CommConfig.dcb.BaudRate=CBR_57600; |
break; |
/*76800 baud*/ |
case BAUD76800: |
TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation. Switching to 57600 baud."); |
Win_CommConfig.dcb.BaudRate=CBR_57600; |
break; |
/*115200 baud*/ |
case BAUD115200: |
Win_CommConfig.dcb.BaudRate=CBR_115200; |
break; |
/*128000 baud*/ |
case BAUD128000: |
TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation."); |
Win_CommConfig.dcb.BaudRate=CBR_128000; |
break; |
/*256000 baud*/ |
case BAUD256000: |
TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation."); |
Win_CommConfig.dcb.BaudRate=CBR_256000; |
break; |
} |
SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Win_QextSerialPort::setDtr(bool set) |
Sets DTR line to the requested state (high by default). This function will have no effect if |
the port associated with the class is not currently open. |
*/ |
void Win_QextSerialPort::setDtr(bool set) { |
LOCK_MUTEX(); |
if (isOpen()) { |
if (set) { |
EscapeCommFunction(Win_Handle, SETDTR); |
} |
else { |
EscapeCommFunction(Win_Handle, CLRDTR); |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn void Win_QextSerialPort::setRts(bool set) |
Sets RTS line to the requested state (high by default). This function will have no effect if |
the port associated with the class is not currently open. |
*/ |
void Win_QextSerialPort::setRts(bool set) { |
LOCK_MUTEX(); |
if (isOpen()) { |
if (set) { |
EscapeCommFunction(Win_Handle, SETRTS); |
} |
else { |
EscapeCommFunction(Win_Handle, CLRRTS); |
} |
} |
UNLOCK_MUTEX(); |
} |
/*! |
\fn ulong Win_QextSerialPort::lineStatus(void) |
returns the line status as stored by the port function. This function will retrieve the states |
of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines |
can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned |
long with specific bits indicating which lines are high. The following constants should be used |
to examine the states of individual lines: |
\verbatim |
Mask Line |
------ ---- |
LS_CTS CTS |
LS_DSR DSR |
LS_DCD DCD |
LS_RI RI |
\endverbatim |
This function will return 0 if the port associated with the class is not currently open. |
*/ |
ulong Win_QextSerialPort::lineStatus(void) { |
unsigned long Status=0, Temp=0; |
LOCK_MUTEX(); |
if (isOpen()) { |
GetCommModemStatus(Win_Handle, &Temp); |
if (Temp&MS_CTS_ON) { |
Status|=LS_CTS; |
} |
if (Temp&MS_DSR_ON) { |
Status|=LS_DSR; |
} |
if (Temp&MS_RING_ON) { |
Status|=LS_RI; |
} |
if (Temp&MS_RLSD_ON) { |
Status|=LS_DCD; |
} |
} |
UNLOCK_MUTEX(); |
return Status; |
} |
/*! |
\fn void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec); |
Sets the read and write timeouts for the port to sec seconds and millisec milliseconds. |
*/ |
void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec) { |
LOCK_MUTEX(); |
Settings.Timeout_Sec=sec; |
Settings.Timeout_Millisec=millisec; |
if(isOpen()) { |
Win_CommTimeouts.ReadIntervalTimeout = sec*1000+millisec; |
Win_CommTimeouts.ReadTotalTimeoutMultiplier = sec*1000+millisec; |
Win_CommTimeouts.ReadTotalTimeoutConstant = 0; |
Win_CommTimeouts.WriteTotalTimeoutMultiplier = sec*1000+millisec; |
Win_CommTimeouts.WriteTotalTimeoutConstant = 0; |
SetCommTimeouts(Win_Handle, &Win_CommTimeouts); |
} |
UNLOCK_MUTEX(); |
} |
/QMK-Groundstation/branches/own_com_lib/SerialPort/win_qextserialport.h |
---|
0,0 → 1,48 |
#ifndef _WIN_QEXTSERIALPORT_H_ |
#define _WIN_QEXTSERIALPORT_H_ |
#include "qextserialbase.h" |
/*if all warning messages are turned off, flag portability warnings to be turned off as well*/ |
#ifdef _TTY_NOWARN_ |
#define _TTY_NOWARN_PORT_ |
#endif |
#include <windows.h> |
class Win_QextSerialPort:public QextSerialBase { |
public: |
Win_QextSerialPort(); |
Win_QextSerialPort(Win_QextSerialPort const& s); |
Win_QextSerialPort(const QString & name); |
Win_QextSerialPort(const PortSettings& settings); |
Win_QextSerialPort(const QString & name, const PortSettings& settings); |
Win_QextSerialPort& operator=(const Win_QextSerialPort& s); |
virtual ~Win_QextSerialPort(); |
virtual bool open(OpenMode mode=0); |
virtual void close(); |
virtual void flush(); |
virtual qint64 size() const; |
virtual void ungetChar(char c); |
virtual void setFlowControl(FlowType); |
virtual void setParity(ParityType); |
virtual void setDataBits(DataBitsType); |
virtual void setStopBits(StopBitsType); |
virtual void setBaudRate(BaudRateType); |
virtual void setDtr(bool set=true); |
virtual void setRts(bool set=true); |
virtual ulong lineStatus(void); |
virtual qint64 bytesAvailable(); |
virtual void translateError(ulong); |
virtual void setTimeout(ulong, ulong); |
protected: |
HANDLE Win_Handle; |
COMMCONFIG Win_CommConfig; |
COMMTIMEOUTS Win_CommTimeouts; |
virtual qint64 readData(char *data, qint64 maxSize); |
virtual qint64 writeData(const char *data, qint64 maxSize); |
}; |
#endif |