mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
switch rs232 provider to completly async transfer (#255)
This commit is contained in:
parent
f146894799
commit
d1e165a753
@ -13,9 +13,15 @@ ProviderRs232::ProviderRs232(const Json::Value &deviceConfig)
|
|||||||
: _rs232Port(this)
|
: _rs232Port(this)
|
||||||
, _blockedForDelay(false)
|
, _blockedForDelay(false)
|
||||||
, _stateChanged(true)
|
, _stateChanged(true)
|
||||||
|
, _bytesToWrite(0)
|
||||||
|
, _bytesWritten(0)
|
||||||
|
, _frameDropCounter(0)
|
||||||
|
, _lastError(QSerialPort::NoError)
|
||||||
{
|
{
|
||||||
setConfig(deviceConfig);
|
setConfig(deviceConfig);
|
||||||
connect(&_rs232Port, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(error(QSerialPort::SerialPortError)));
|
connect(&_rs232Port, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(error(QSerialPort::SerialPortError)));
|
||||||
|
connect(&_rs232Port, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWritten(qint64)));
|
||||||
|
connect(&_rs232Port, SIGNAL(readyRead()), this, SLOT(readyRead()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProviderRs232::setConfig(const Json::Value &deviceConfig)
|
bool ProviderRs232::setConfig(const Json::Value &deviceConfig)
|
||||||
@ -28,12 +34,33 @@ bool ProviderRs232::setConfig(const Json::Value &deviceConfig)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProviderRs232::bytesWritten(qint64 bytes)
|
||||||
|
{
|
||||||
|
_bytesWritten += bytes;
|
||||||
|
if (_bytesWritten >= _bytesToWrite)
|
||||||
|
{
|
||||||
|
_bytesToWrite = 0;
|
||||||
|
_blockedForDelay = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ProviderRs232::readyRead()
|
||||||
|
{
|
||||||
|
QByteArray data = _rs232Port.readAll();
|
||||||
|
Debug(_log, "received %d bytes data", data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ProviderRs232::error(QSerialPort::SerialPortError error)
|
void ProviderRs232::error(QSerialPort::SerialPortError error)
|
||||||
{
|
{
|
||||||
if ( error != QSerialPort::NoError )
|
if ( error != QSerialPort::NoError )
|
||||||
{
|
{
|
||||||
switch (error)
|
if (_lastError != error)
|
||||||
{
|
{
|
||||||
|
_lastError = error;
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
case QSerialPort::DeviceNotFoundError:
|
case QSerialPort::DeviceNotFoundError:
|
||||||
Error(_log, "An error occurred while attempting to open an non-existing device."); break;
|
Error(_log, "An error occurred while attempting to open an non-existing device."); break;
|
||||||
case QSerialPort::PermissionError:
|
case QSerialPort::PermissionError:
|
||||||
@ -43,11 +70,11 @@ void ProviderRs232::error(QSerialPort::SerialPortError error)
|
|||||||
case QSerialPort::NotOpenError:
|
case QSerialPort::NotOpenError:
|
||||||
Error(_log, "This error occurs when an operation is executed that can only be successfully performed if the device is open."); break;
|
Error(_log, "This error occurs when an operation is executed that can only be successfully performed if the device is open."); break;
|
||||||
case QSerialPort::ParityError:
|
case QSerialPort::ParityError:
|
||||||
Error(_log, "Parity error detected by the hardware while reading data. This value is obsolete. We strongly advise against using it in new code."); break;
|
Error(_log, "Parity error detected by the hardware while reading data."); break;
|
||||||
case QSerialPort::FramingError:
|
case QSerialPort::FramingError:
|
||||||
Error(_log, "Framing error detected by the hardware while reading data. This value is obsolete. We strongly advise against using it in new code."); break;
|
Error(_log, "Framing error detected by the hardware while reading data."); break;
|
||||||
case QSerialPort::BreakConditionError:
|
case QSerialPort::BreakConditionError:
|
||||||
Error(_log, "Break condition detected by the hardware on the input line. This value is obsolete. We strongly advise against using it in new code."); break;
|
Error(_log, "Break condition detected by the hardware on the input line."); break;
|
||||||
case QSerialPort::WriteError:
|
case QSerialPort::WriteError:
|
||||||
Error(_log, "An I/O error occurred while writing the data."); break;
|
Error(_log, "An I/O error occurred while writing the data."); break;
|
||||||
case QSerialPort::ReadError:
|
case QSerialPort::ReadError:
|
||||||
@ -59,8 +86,10 @@ void ProviderRs232::error(QSerialPort::SerialPortError error)
|
|||||||
case QSerialPort::TimeoutError:
|
case QSerialPort::TimeoutError:
|
||||||
Error(_log, "A timeout error occurred."); break;
|
Error(_log, "A timeout error occurred."); break;
|
||||||
default: Error(_log,"An unidentified error occurred. (%d)", error);
|
default: Error(_log,"An unidentified error occurred. (%d)", error);
|
||||||
|
}
|
||||||
|
_rs232Port.clearError();
|
||||||
|
closeDevice();
|
||||||
}
|
}
|
||||||
_rs232Port.clearError();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,15 +113,15 @@ int ProviderRs232::open()
|
|||||||
Info(_log, "Opening UART: %s", _deviceName.c_str());
|
Info(_log, "Opening UART: %s", _deviceName.c_str());
|
||||||
_rs232Port.setPortName(_deviceName.c_str());
|
_rs232Port.setPortName(_deviceName.c_str());
|
||||||
|
|
||||||
return tryOpen() ? 0 : -1;
|
return tryOpen(_delayAfterConnect_ms) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ProviderRs232::tryOpen()
|
bool ProviderRs232::tryOpen(const int delayAfterConnect_ms)
|
||||||
{
|
{
|
||||||
if ( ! _rs232Port.isOpen() )
|
if ( ! _rs232Port.isOpen() )
|
||||||
{
|
{
|
||||||
if ( ! _rs232Port.open(QIODevice::WriteOnly) )
|
if ( ! _rs232Port.open(QIODevice::ReadWrite) )
|
||||||
{
|
{
|
||||||
if ( _stateChanged )
|
if ( _stateChanged )
|
||||||
{
|
{
|
||||||
@ -105,46 +134,52 @@ bool ProviderRs232::tryOpen()
|
|||||||
_stateChanged = true;
|
_stateChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_delayAfterConnect_ms > 0)
|
if (delayAfterConnect_ms > 0)
|
||||||
{
|
{
|
||||||
_blockedForDelay = true;
|
_blockedForDelay = true;
|
||||||
QTimer::singleShot(_delayAfterConnect_ms, this, SLOT(unblockAfterDelay()));
|
QTimer::singleShot(delayAfterConnect_ms, this, SLOT(unblockAfterDelay()));
|
||||||
Debug(_log, "Device blocked for %d ms", _delayAfterConnect_ms);
|
Debug(_log, "Device blocked for %d ms", delayAfterConnect_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _rs232Port.isOpen();
|
return _rs232Port.isOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ProviderRs232::writeBytes(const unsigned size, const uint8_t * data)
|
int ProviderRs232::writeBytes(const qint64 size, const uint8_t * data)
|
||||||
{
|
{
|
||||||
if (_blockedForDelay)
|
if (! _blockedForDelay)
|
||||||
{
|
{
|
||||||
return 0;
|
if (!_rs232Port.isOpen())
|
||||||
}
|
{
|
||||||
|
return tryOpen(3000) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_rs232Port.isOpen())
|
if (_frameDropCounter > 0)
|
||||||
|
{
|
||||||
|
Debug(_log, "%d frames dropped", _frameDropCounter);
|
||||||
|
}
|
||||||
|
_frameDropCounter = 0;
|
||||||
|
_blockedForDelay = true;
|
||||||
|
_bytesToWrite = size;
|
||||||
|
qint64 bytesWritten = _rs232Port.write(reinterpret_cast<const char*>(data), size);
|
||||||
|
if (bytesWritten == -1 || bytesWritten != size)
|
||||||
|
{
|
||||||
|
Warning(_log,"failed writing data");
|
||||||
|
QTimer::singleShot(500, this, SLOT(unblockAfterDelay()));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
QTimer::singleShot(5000, this, SLOT(unblockAfterDelay()));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_delayAfterConnect_ms = 3000;
|
_frameDropCounter++;
|
||||||
return tryOpen() ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_rs232Port.flush();
|
|
||||||
qint64 result = _rs232Port.write(reinterpret_cast<const char*>(data), size);
|
|
||||||
if ( result < 0 || result != size)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug(_log, "write %d ", result);
|
|
||||||
_rs232Port.flush();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ProviderRs232::unblockAfterDelay()
|
void ProviderRs232::unblockAfterDelay()
|
||||||
{
|
{
|
||||||
Debug(_log, "Device unblocked");
|
|
||||||
_blockedForDelay = false;
|
_blockedForDelay = false;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ protected:
|
|||||||
*
|
*
|
||||||
* @return Zero on succes else negative
|
* @return Zero on succes else negative
|
||||||
*/
|
*/
|
||||||
int writeBytes(const unsigned size, const uint8_t *data);
|
int writeBytes(const qint64 size, const uint8_t *data);
|
||||||
|
|
||||||
void closeDevice();
|
void closeDevice();
|
||||||
|
|
||||||
@ -57,10 +57,12 @@ private slots:
|
|||||||
/// Unblock the device after a connection delay
|
/// Unblock the device after a connection delay
|
||||||
void unblockAfterDelay();
|
void unblockAfterDelay();
|
||||||
void error(QSerialPort::SerialPortError error);
|
void error(QSerialPort::SerialPortError error);
|
||||||
|
void bytesWritten(qint64 bytes);
|
||||||
|
void readyRead();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// tries to open device if not opened
|
// tries to open device if not opened
|
||||||
bool tryOpen();
|
bool tryOpen(const int delayAfterConnect_ms);
|
||||||
|
|
||||||
/// The name of the output device
|
/// The name of the output device
|
||||||
std::string _deviceName;
|
std::string _deviceName;
|
||||||
@ -77,4 +79,9 @@ private:
|
|||||||
bool _blockedForDelay;
|
bool _blockedForDelay;
|
||||||
|
|
||||||
bool _stateChanged;
|
bool _stateChanged;
|
||||||
|
|
||||||
|
qint64 _bytesToWrite;
|
||||||
|
qint64 _bytesWritten;
|
||||||
|
qint64 _frameDropCounter;
|
||||||
|
QSerialPort::SerialPortError _lastError;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user