Index: sources/canbus/frameinterface.cpp =================================================================== diff -u -r805119c460b4a266d6401c8705f4427e7fbe270f -r44a85c96ab55e424866ec4cca0270aa218355f82 --- sources/canbus/frameinterface.cpp (.../frameinterface.cpp) (revision 805119c460b4a266d6401c8705f4427e7fbe270f) +++ sources/canbus/frameinterface.cpp (.../frameinterface.cpp) (revision 44a85c96ab55e424866ec4cca0270aa218355f82) @@ -1,21 +1,23 @@ /*! - * + * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. - * copyright - * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, - * IN PART OR IN WHOLE, - * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. - * - * file frameinterface.cpp - * date 10/26/2019 - * author Behrouz NematiPour - * + * \copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * \file frameinterface.cpp + * \author (last) Behrouz NemaiPour + * \date (last) 22-Jun-2020 + * \author (original) Behrouz NematiPour + * \date (original) 18-Dec-2019 + * */ #include "frameinterface.h" // Qt #include #include +#include // Project #include "logger.h" @@ -44,6 +46,8 @@ initConnections(); + startTimer(1, Qt::PreciseTimer); + LOG_EVENT(QObject::tr("%1 Initialized").arg(metaObject()->className())); return true; @@ -73,7 +77,7 @@ { // coco begin validated: Application termination is not correctly done in coco!!! // it has been tested and works perfectly fine in normal run. - quitThread(); + quitThread(); // validated } // coco end @@ -91,6 +95,8 @@ // From CAN connect(&_CanInterface , SIGNAL( didFrameReceive( const QCanBusFrame &)), this , SLOT( onFrameReceive( const QCanBusFrame &))); + connect(&_CanInterface , SIGNAL( didFrameWritten(qint64 )), + this , SLOT( onFrameWritten(qint64 ))); } /*! @@ -124,7 +130,7 @@ if ( ! _thread ) return; // runs in thread - moveToThread(qApp->thread()); + moveToThread(qApp->thread()); // validated } // coco end @@ -138,10 +144,10 @@ * and it can be one of the frames of a message * which has been chopped into frames. */ -void FrameInterface::transmitFrame(Can_Id vFrameId, const QByteArray &vData) +void FrameInterface::transmitFrame(Can_Id vCan_Id, const QByteArray &vData) { QCanBusFrame mFrame; - mFrame.setFrameId(vFrameId); + mFrame.setFrameId(vCan_Id); if (vData.length() > Can::eLenCanFrame) { LOG_ERROR(tr("Payload can't be larger than %1 bytes").arg(Can::eLenCanFrame)); return; @@ -166,48 +172,42 @@ FrameInterface::ChannelGroup channelGroup = ChannelGroup::eChannel_Unknown; switch (vFrameId) { case eChlid_HD_DG : + // coco begin validated: The HD/DG communication has not been defined and implemented yet. case eChlid_DG_HD : + // coco end channelGroup = ChannelGroup::eChannel_Ignores; break; case eChlid_HD_UI : case eChlid_HD_Alarm : - case eChlid_DG_Alarm : case eChlid_HD_Sync : + // coco begin validated: The UI/DG communication has not been defined and implemented yet. + case eChlid_DG_Alarm : case eChlid_DG_Sync : + // coco end //case eChlid_DG_UI : // has duplicate value as eChlid_DG_Alarm channelGroup = ChannelGroup::eChannel_Listens; break; + // coco begin validated: The UI Alarm and Sync messages has not been defined and implemented yet. case eChlid_UI_Alarm : case eChlid_UI_Sync : //case eChlid_UI_DG : channelGroup = ChannelGroup::eChannel_Outputs; break; - + // coco end default: ok = false; break; - } + } + // coco begin validated: manually tested if (vOK) *vOK = ok; + // coco end return channelGroup; } /*! - * \brief FrameInterface::onFrameTransmit - * \details This the slot connected to the MessageDispatcher didFrameTransmit signal. - * When a frame needs to be send to CANBUS, - * this slot will call transmitFrame method to do the job. - * \param vCan_Id - CANBUS Can Id target of the frame. - * \param vData - The data which this frame will carry. - */ -void FrameInterface::onFrameTransmit(Can_Id vCan_Id, const QByteArray &vData) -{ - transmitFrame(vCan_Id, vData); -} - -/*! * \brief FrameInterface::onFrameReceive * \details This the slot connected to the CanInterface didFrameReceive signal. * When a frame received over the CANBUS, @@ -221,7 +221,7 @@ quint32 mFrameId = vFrame.frameId(); ChannelGroup channelGroup = checkChannel(mFrameId, &ok); - if (!ok){ + if (!ok) { LOG_ERROR("Unexpected Channel\r\n" + Format::toHexString(mFrameId, false, eLenChannelDigits) + " -- " + vFrame.payload().toHex(' ')); return; @@ -234,3 +234,102 @@ Can_Id mCan_Id = static_cast(mFrameId); emit didFrameReceive(mCan_Id, vFrame.payload()); } + +/*! + * \brief FrameInterface::onFrameTransmit + * \details This the slot connected to the MessageDispatcher didFrameTransmit signal. + * When a frame needs to be send to CANBUS, + * this slot will call transmitFrame method to do the job. + * \param vCan_Id - CANBUS Can Id target of the frame. + * \param vData - The data which this frame will carry. + */ +void FrameInterface::onFrameTransmit(Can_Id vCan_Id, const QByteArray &vData) +{ + appendHead(vCan_Id, vData); + // Test : qDebug() << _timestamp << "apnd #" << _txFrameList.count(); +} + +/*! + * \brief FrameInterface::onFrameWritten + * \param vCount + */ +void FrameInterface::onFrameWritten(qint64 /*vCount*/) +{ + _transmitted = true; + removeHead(); + // Test : qDebug() << _timestamp << "Sent #" << _txFrameList.count() << vCount; +} + +/*! + * \brief FrameInterface::timerEvent + * \details This event handler is reimplemented in this subclass to receive timer events for this object. + */ +void FrameInterface::timerEvent(QTimerEvent *) +{ + static quint8 count = 0; + // Test : _timestamp = QTime::currentTime().toString("HH:mm:ss.zzz"); + + if (++count != _interval) return; + // Test : qDebug() << _timestamp; + count = 0; + _transmitted = false; + trnsmtHead(); +} + +/*! + * \brief FrameInterface::trnsmtHead + * \details Transmits the head of the trasmit buffer + * Sends an empty frame with lowest prioriority if the transmit buffer is empty + * to keep the UI board CANDriver awake. + */ +void FrameInterface::trnsmtHead() +{ + if ( _txFrameList.isEmpty() ) { + // coco begin validated: This is a fake data generator for CANBus missing/swapped frames Testing + // will never be executed on the product and shall be removed after the CANBus issues has been resolved. + // has been tested manually + if ( gSendEmptyKeepAwake ) { + transmitFrame(eChlid_LOWEST,QByteArray()); // Keep the CANBus awake. + return; + } + } + // coco end + else { + Frame frame = _txFrameList.first(); + transmitFrame(frame.can_Id, frame.data); + // Test : qDebug() << _timestamp << "Tsmt #" << _txFrameList.count(); + } +} + +/*! + * \brief FrameInterface::removeHead + * \details Removes the frame from the head of the transmit buffer + * in case transmission has been confirmed by the CANBus driver + * in the FrameInterface::onFrameWritten slot + * which is connected to CanInterface::didFrameWritten. + */ +void FrameInterface::removeHead() +{ + if ( _txFrameList.isEmpty() ) { + return; + } + _txFrameList.removeFirst(); +} + +/*! + * \brief FrameInterface::appendHead + * \details Appends the frame to the transmit buffer to be sent later + * \param vCan_Id - the canbus id + * \param vData - the data to be sent + */ +void FrameInterface::appendHead(Can_Id vCan_Id, const QByteArray &vData) +{ + Frame frame = Frame(vCan_Id, vData); + // coco begin validated: has been manually tested by sending over 4000 frames and not received by anyother node. + if (_txFrameList.count() >= _txFrameList_Max) { + LOG_ERROR(tr("Transmit buffer overflow of %1").arg(_txFrameList_Max)); + return; + // coco end + } + _txFrameList.append(frame); +}