Logo Search packages:      
Sourcecode: qmk-groundstation version File versions  Download package

ManageSerialPort.cpp

/********************************************************************************************************
            * 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();
      }
}


Generated by  Doxygen 1.6.0   Back to index