/********************************************************************* // created: 2013/07/10 // filename: PacpusSerialPort.cpp // // author: Julien Moras // // version: $Id: $ // // purpose: This class defines a Qt 5.1 driver for serial port *********************************************************************/ #include #include #include #include using namespace pacpus; DECLARE_STATIC_LOGGER("pacpus.core.serialport"); static ComponentFactory sFactory("PacpusSerialPort"); PacpusSerialPort::PacpusSerialPort(QString name):ComponentBase(name) { serialPort = new QSerialPort(this); // Default settings #if(Win32) portName = "COM1"; #else portName = "/dev/tty0"; #endif direction = QSerialPort::AllDirections; baudRate = QSerialPort::Baud9600; dataBits = QSerialPort::Data8; parity = QSerialPort::NoParity; stopBits = QSerialPort::OneStop; flowControl = QSerialPort::NoFlowControl; errorPolicy = QSerialPort::SkipPolicy; dataMode = ASCII; sepChar = "\n"; // Or threaded connect(serialPort,SIGNAL(readyRead()),this,SLOT(readData())); } PacpusSerialPort::~PacpusSerialPort() { if(serialPort->isOpen()) serialPort->close(); delete serialPort; } void PacpusSerialPort:: addInput() { ADD_INPUT("inStream",PacpusSerialPort,QByteArray,processInputFrame); } void PacpusSerialPort:: addOutput() { ADD_OUTPUT("outStream",PacpusSerialPort,QByteArray); ADD_OUTPUT("pinOutSignal",PacpusSerialPort,quint16); } ComponentBase::COMPONENT_CONFIGURATION PacpusSerialPort::configureComponent(XmlComponentConfig config) { /// TODO get parameter from xml if(param.hasProperty("portName")) portName = param.getProperty("portName"); if(param.hasProperty("baudRate")) baudRate = (QSerialPort::BaudRate) param.getProperty("baudRate").toInt(); if(param.hasProperty("direction")) direction = (QSerialPort::Direction) param.getProperty("direction").toInt(); if(param.hasProperty("dataBits")) dataBits = (QSerialPort::DataBits) param.getProperty("dataBits").toInt(); if(param.hasProperty("parity")) parity = (QSerialPort::Parity) param.getProperty("parity").toInt(); if(param.hasProperty("stopBits")) stopBits = (QSerialPort::StopBits) param.getProperty("stopBits").toInt(); if(param.hasProperty("flowControl")) flowControl = (QSerialPort::FlowControl) param.getProperty("flowControl").toInt(); if(param.hasProperty("errorPolicy")) errorPolicy = (QSerialPort::DataErrorPolicy) param.getProperty("errorPolicy").toInt(); if(param.hasProperty("dataMode")) dataMode = (DataMode) param.getProperty("dataMode").toInt(); if(param.hasProperty("sepChar")) sepChar = param.getProperty("sepChar"); serialPort->setPortName(portName); if(!serialPort->setBaudRate(baudRate,direction)) LOG_ERROR("n° "<< serialPort->error()); if(!serialPort->setDataBits(dataBits)) LOG_ERROR("n° "<< serialPort->error()); if(!serialPort->setParity(parity)) LOG_ERROR("n° "<< serialPort->error()); if(!serialPort->setStopBits(stopBits)) LOG_ERROR("n° "<< serialPort->error()); if(!serialPort->setFlowControl(flowControl)) LOG_ERROR("n° "<< serialPort->error()); if(!serialPort->setDataErrorPolicy(errorPolicy)) LOG_ERROR("n° "<< serialPort->error()); // For futher developpements // serialPort->setBreakEnabled(); // serialPort->setDataTerminalReady(); // serialPort->setRequestToSend(); return ComponentBase::CONFIGURED_OK; } void PacpusSerialPort::startActivity() { if(!serialPort->open((QSerialPort::OpenModeFlag)direction)) { LOG_FATAL("device "<< serialPort->portName().toStdString() <<" failed to open: " << serialPort->errorString()); } else { LOG_INFO("listening for data on " << serialPort->portName()); } moveToThread(&thread_); thread_.start(); //TODO Remove QThread inheritance if this works fine //THREAD_ALIVE = true; //start(); setState(ComponentBase::MONITOR_OK); } void PacpusSerialPort::stopActivity() { QMetaObject::invokeMethod(&thread_, "quit"); //THREAD_ALIVE = false; //while(!isFinished()); // TODO timeout serialPort->close(); } void PacpusSerialPort::processInputFrame(const QByteArray & inputFrame) { LOG_TRACE("Input frame " << inputFrame.data()); // Write input to serial port if(serialPort->write(inputFrame)>=0) { setState(MONITOR_OK); LOG_DEBUG("Serial write performed") } else { setState(MONITOR_NOK); LOG_WARN("Serial write error") } } void PacpusSerialPort::readData() { int n; buffer.append(serialPort->readAll()); while(true) // loop until no data to send { switch(dataMode) { case ASCII : // Split the first line to send n = buffer.indexOf(sepChar,1) + 1; if(n<=0) return; // end line char not found break; case BINARY : // Get all data n = buffer.size();//serialPort->bytesAvailable(); if(n<=0) return; break; default: LOG_WARN("unknown dataMode") setState(MONITOR_NOK); return; } QByteArray data(buffer.data(),n); buffer.remove(0,n); quint16 pinout = (quint16)serialPort->pinoutSignals(); GET_OUTPUT("outStream",PacpusSerialPort,QByteArray)->send(data); GET_OUTPUT("pinOutSignal",PacpusSerialPort,quint16)->send(pinout); setState(MONITOR_OK); LOG_INFO("Signal Read " << n << " bytes, PinOut : " << pinout); LOG_INFO(QString(data).toStdString()); } //LOG_INFO("Buffer " << buffer.data()); } /*void PacpusSerialPort::run() { while (THREAD_ALIVE) { if (serialPort->waitForReadyRead(timeOut)) { QByteArray data = serialPort->readAll(); GET_OUTPUT("outStream",PacpusSerialPort,QByteArray)->send(data); GET_OUTPUT("pinOutSignal",PacpusSerialPort,quint16)->send((quint16)serialPort->pinoutSignals()); setState(MONITOR_OK); LOG_INFO("Run Read"); LOG_INFO(data.data()); } else { setState(MONITOR_NOK); } } }*/