Subversion Repositories Code-Repo

Rev

Rev 364 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "SerialHelper.h"

SerialHelper::SerialHelper(QObject *parent) : QObject(parent)
{
    connected = false;
    speeds << "9600" << "19200" << "38400" << "57600" << "115200" << "230400" << "250000";
    dataBits << "8 Bits" << "7 Bits" << "6 Bits" << "5 Bits";
    stopBits << "1 Bit" << "1.5 Bits" << "2 Bits";
    parity << "None" << "Even" << "Odd" << "Space" << "Mark";
    flowControl << "None" << "Hardware" << "Software";

    serialPort = NULL;
}

SerialHelper::~SerialHelper()
{
    if (serialPort != NULL && serialPort->isOpen())
        serialPort->close();
    delete serialPort;
}

void SerialHelper::QueryParameters()
{
    QList<QSerialPortInfo> portsList = QSerialPortInfo::availablePorts();
    QStringList ports;
    for (int i = 0; i < portsList.size(); i++) {
        ports.append(portsList[i].portName());
    }
    emit UpdateParameters(ports, speeds, dataBits, stopBits, parity, flowControl);
}

void SerialHelper::Connect(QString port, QString speed, QString dataBits,
                            QString stopBits, QString parity, QString flowControl)
{
    if (!connected) {
        emit UpdateStatus("Connecting to " + port);
        serialPort = new QSerialPort();
        connect(serialPort, SIGNAL(readyRead()), this, SLOT(ProcessIncomingData()));
        connect(serialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(ProcessError(QSerialPort::SerialPortError)));
        serialPort->setPortName(port);
        if (serialPort->open(QIODevice::ReadWrite)) {
            connected = true;
            bool ok = false;

            int baud = speed.toInt(&ok);
            if (ok) serialPort->setBaudRate(baud);

            if (dataBits == "5 Bits")
                serialPort->setDataBits(QSerialPort::Data5);
            else if (dataBits == "6 Bits")
                serialPort->setDataBits(QSerialPort::Data6);
            else if (dataBits == "7 Bits")
                serialPort->setDataBits(QSerialPort::Data7);
            else
                serialPort->setDataBits(QSerialPort::Data8);

            if (stopBits == "1.5 Bits")
                serialPort->setStopBits(QSerialPort::OneAndHalfStop);
            else if (stopBits == "2 Bits")
                serialPort->setStopBits(QSerialPort::TwoStop);
            else
                serialPort->setStopBits(QSerialPort::OneStop);

            if (parity == "Even")
                serialPort->setParity(QSerialPort::EvenParity);
            else if (parity == "Odd")
                serialPort->setParity(QSerialPort::OddParity);
            else if (parity == "Space")
                serialPort->setParity(QSerialPort::SpaceParity);
            else if (parity == "Mark")
                serialPort->setParity(QSerialPort::MarkParity);
            else
                serialPort->setParity(QSerialPort::NoParity);

            if (flowControl == "Hardware")
                serialPort->setFlowControl(QSerialPort::HardwareControl);
            else if (flowControl == "Software")
                serialPort->setFlowControl(QSerialPort::SoftwareControl);
            else
                serialPort->setFlowControl(QSerialPort::NoFlowControl);

            // See http://umforum.ultimaker.com/index.php?/topic/5886-um2-controller-resetreboot-when-opening-usb-port-on-linux/
            serialPort->setDataTerminalReady(1);

            if (ok) {
                QString status = "Connected (%1 @ %2 D: %3 S: %4 P: %5 FC: %6)";
                emit UpdateStatus(status.arg(port).arg(speed).arg(dataBits).arg(stopBits).arg(parity).arg(flowControl));
                emit Connected(true);
            } else
                Disconnect();
        }
    }
}

void SerialHelper::Disconnect(bool errored)
{
    serialPort->disconnect();
    serialPort->close();
    delete serialPort;
    connected = false;
    if (!errored)
        emit UpdateStatus("Disconnected");
    emit Connected(false);
}

void SerialHelper::TransmitString(QString string)
{
    serialPort->write(string.toStdString().c_str());
    serialPort->write(SERIAL_NEWLINE_CHAR);
}

void SerialHelper::TransmitByteArray(QByteArray data)
{
    serialPort->write(data);
}

void SerialHelper::ProcessIncomingData()
{
    char tmpBuffer[SERIAL_BUFFER_SIZE];
    int len = serialPort->read(tmpBuffer, sizeof(tmpBuffer));
    while (len > 0) {
        QByteArray data(tmpBuffer, len);
        emit ReceivedByte(data);
        // Check if there is more data to be read from the serial port
        len = serialPort->read(tmpBuffer, sizeof(tmpBuffer));
    }
}

void SerialHelper::ProcessError(QSerialPort::SerialPortError error)
{
    if (error == QSerialPort::NoError) return;

    switch(error) {
        case QSerialPort::DeviceNotFoundError:
            emit UpdateStatus("(Error) Device not found");
            return;
        case QSerialPort::PermissionError:
            emit UpdateStatus("(Error) Device already opened or lacking permission");
            return;
        case QSerialPort::OpenError:
            emit UpdateStatus("(Error) Device already opened");
            return;
        case QSerialPort::NotOpenError:
            emit UpdateStatus("(Error) Device not opened");
            return;
        case QSerialPort::ParityError:
            emit UpdateStatus("(Error) Parity error detected");
            break;
        case QSerialPort::FramingError:
            emit UpdateStatus("(Error) Framing error detected");
            break;
        case QSerialPort::BreakConditionError:
            emit UpdateStatus("(Error) Break condition detected");
            break;
        case QSerialPort::WriteError:
            emit UpdateStatus("(Error) Unable to write to device");
            break;
        case QSerialPort::ReadError:
            emit UpdateStatus("(Error) Unable to read from device");
            break;
        case QSerialPort::ResourceError:
            emit UpdateStatus("(Error) Device missing or disconnected");
            break;
        case QSerialPort::UnsupportedOperationError:
            emit UpdateStatus("(Error) Operation not supported or prohibited");
            break;
        case QSerialPort::TimeoutError:
            emit UpdateStatus("(Error) Connection timeout");
            break;
        case QSerialPort::UnknownError:
            emit UpdateStatus("(Error) Unknown error");
            break;
        default:
            break;
    }

    serialPort->clearError();
    Disconnect(true);
}