Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -rdaf8d5b60c753becab80cbaf164aac0e49d533a2 -rab304e2ca6e3e40ed8cb12650e9855ae0b9649d8 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision daf8d5b60c753becab80cbaf164aac0e49d533a2) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision ab304e2ca6e3e40ed8cb12650e9855ae0b9649d8) @@ -7,8 +7,8 @@ * * @file SystemComm.c * -* @author (last) Dara Navaei -* @date (last) 10-Jun-2020 +* @author (last) Quang Nguyen +* @date (last) 26-Aug-2020 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -28,54 +28,64 @@ #include "Utilities.h" #include "SystemCommMessages.h" +/** + * @addtogroup SystemComm + * @{ + */ + // ********** private definitions ********** -#define NUM_OF_CAN_OUT_BUFFERS 4 // # of CAN buffers for transmit -#define NUM_OF_CAN_IN_BUFFERS 6 // # of CAN buffers for receiving +#define NUM_OF_CAN_OUT_BUFFERS 5 ///< Number of CAN buffers for transmit +#define NUM_OF_CAN_IN_BUFFERS 6 ///< Number of CAN buffers for receiving #ifndef DEBUG_ENABLED - #define NUM_OF_MSG_IN_BUFFERS 6 // # of Msg buffers for receiving + #define NUM_OF_MSG_IN_BUFFERS 6 ///< Number of Msg buffers for receiving #else - #define NUM_OF_MSG_IN_BUFFERS 7 // # of Msg buffers for receiving - 1 is UART + #define NUM_OF_MSG_IN_BUFFERS 7 #define SCI1_RECEIVE_DMA_REQUEST 30 #define SCI1_TRANSMIT_DMA_REQUEST 31 #endif -#define CAN_XMIT_PACKET_TIMEOUT_MS 200 ///< if transmitted CAN frame does not cause a transmit complete interrupt within this time, re-send or move on +#define CAN_XMIT_PACKET_TIMEOUT_MS 200 ///< if transmitted CAN frame does not cause a transmit complete interrupt within this time, re-send or move on +#define MAX_XMIT_RETRIES 5 ///< maximum number of retries on no transmit complete interrupt timeout -#define HD_COMM_TIMEOUT_IN_MS 2000 +#define HD_COMM_TIMEOUT_IN_MS 2000 ///< HD has not sent any broadcast messages for this much time -#define MAX_COMM_CRC_FAILURES 5 -#define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) +#define MAX_COMM_CRC_FAILURES 5 ///< maximum number of CRC errors within window period before alarm +#define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window -#define MSG_NOT_ACKED_TIMEOUT_MS ( MS_PER_SECOND * 1 ) -#define MSG_NOT_ACKED_MAX_RETRIES 3 -#define PENDING_ACK_LIST_SIZE 25 +#define MSG_NOT_ACKED_TIMEOUT_MS ( MS_PER_SECOND * 1 ) ///< maximum time for a Denali message that requires ACK to be ACK'd +#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm +#define PENDING_ACK_LIST_SIZE 25 ///< maximum number of Delanli messages that can be pending ACK at any given time #pragma pack(push, 1) +/// Record for transmitted message that is pending acknowledgement from receiver. typedef struct { - BOOL used; - U16 seqNo; - U16 retries; - U32 timeStamp; - COMM_BUFFER_T channel; - U32 msgSize; - U08 msg[ MAX_ACK_MSG_SIZE ]; + BOOL used; ///< Flag indicates whether the pending ACK slot is used or not + U16 seqNo; ///< Sequence number + U16 retries; ///< Retry count + U32 timeStamp; ///< Message time stamp + COMM_BUFFER_T channel; ///< Comm buffer channel + U32 msgSize; ///< Message size + U08 msg[ MAX_ACK_MSG_SIZE ]; ///< Bytes representation of the message } PENDING_ACK_RECORD_T; #pragma pack(pop) // ********** private data ********** +/// Array of out-going CAN buffers. const COMM_BUFFER_T CAN_OUT_BUFFERS[ NUM_OF_CAN_OUT_BUFFERS ] = { COMM_BUFFER_OUT_CAN_DG_ALARM, COMM_BUFFER_OUT_CAN_DG_2_HD, COMM_BUFFER_OUT_CAN_DG_BROADCAST, - COMM_BUFFER_OUT_CAN_PC + COMM_BUFFER_OUT_CAN_PC, + COMM_BUFFER_OUT_CAN_DG_2_UI }; +/// Array of in-coming CAN buffers. const COMM_BUFFER_T MSG_IN_BUFFERS[ NUM_OF_MSG_IN_BUFFERS ] = { COMM_BUFFER_IN_CAN_HD_ALARM, @@ -89,34 +99,29 @@ #endif }; -static U08 lastCANPacketSent[ CAN_MESSAGE_PAYLOAD_SIZE ]; -static CAN_MESSAGE_BOX_T lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0; -static U32 lastCANPacketSentTimeStamp = 0; +static U08 lastCANPacketSent[ CAN_MESSAGE_PAYLOAD_SIZE ]; ///< Keep last packet sent on CAN bus in case we need to re-send. +static CAN_MESSAGE_BOX_T lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0; ///< Keep channel last packet was sent on CAN bus in case we need to re-send. +static U32 lastCANPacketSentTimeStamp = 0; ///< Keep time last packet sent on CAN bus so we can timeout on transmission attempt. +static PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; ///< list of outgoing messages that are awaiting an ACK + +static volatile BOOL dgIsOnlyCANNode = TRUE; ///< flag indicating whether DG is alone on CAN bus. +static U32 canXmitRetryCtr = 0; ///< counter for CAN transmit retries. +static volatile BOOL hdIsCommunicating = FALSE; ///< has HD sent a message since last check +static volatile U32 timeOfLastHDCheckIn = 0; ///< last time we received an HD broadcast + #ifdef DEBUG_ENABLED -static U08 pcXmitPacket[ 1024 ]; -static U08 pcRecvPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + // debug buffers + static U08 pcXmitPacket[ 1024 ]; + static U08 pcRecvPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + // DMA control records + static g_dmaCTRL pcDMAXmitControlRecord; + static g_dmaCTRL pcDMARecvControlRecord; #endif -static PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; // list of outgoing messages that are awaiting an ACK - -// DMA control records -static g_dmaCTRL pcDMAXmitControlRecord; // DMA transmit control record (UART-debug) -static g_dmaCTRL pcDMARecvControlRecord; // DMA receive control record (UART-debug) - -static volatile BOOL hdIsCommunicating = FALSE; // has HD sent a message since last check -static volatile U32 timeOfLastHDCheckIn = 0; // last time we received an HD broadcast - -static U32 badCRCTimeStamps[ MAX_COMM_CRC_FAILURES ]; // time of last five bad message CRCs (wrapping list) -static U32 badCRCListIdx = 0; // where next bad message CRC time stamp will go in list -static U32 badCRCListCount = 0; // # of bad CRCs in the list - // ********** private function prototypes ********** -#ifdef DEBUG_ENABLED - static void initUARTAndDMA( void ); - static U32 transmitNextUARTPacket( void ); -#endif +static void clearCANXmitBuffers( void ); static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void ); static U32 transmitNextCANPacket( void ); @@ -133,13 +138,17 @@ static BOOL matchACKtoPendingACKList( S16 seqNo ); static void checkPendingACKList( void ); -/************************************************************************* - * @brief initSystemComm +#ifdef DEBUG_ENABLED + static void initUARTAndDMA( void ); + static U32 transmitNextUARTPacket( void ); +#endif + +/*********************************************************************//** + * @brief * The initSystemComm function initializes the SystemComm module. * @details * Inputs : none * Outputs : SystemComm module initialized. - * @param none * @return none *************************************************************************/ void initSystemComm( void ) @@ -151,11 +160,8 @@ initUARTAndDMA(); #endif - // initialize bad message CRC list - for ( i = 0; i < MAX_COMM_CRC_FAILURES; i++ ) - { - badCRCTimeStamps[ i ] = 0; - } + // initialize bad message CRC time windowed count + initTimeWindowedCount( TIME_WINDOWED_COUNT_BAD_MSG_CRC, MAX_COMM_CRC_FAILURES, MAX_COMM_CRC_FAILURE_WINDOW_MS ); // initialize pending ACK list for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) @@ -164,32 +170,40 @@ } } -/************************************************************************* +/*********************************************************************//** * @brief - * The isHDCommunicating function determines whether the HD is communicating \n + * The isHDCommunicating function determines whether the HD is communicating * with the DG. * @details * Inputs : hdIsCommunicating * Outputs : none - * @param none * @return TRUE if HD has broadcast since last call, FALSE if not *************************************************************************/ BOOL isHDCommunicating( void ) { - BOOL result = hdIsCommunicating; + return hdIsCommunicating; +} - hdIsCommunicating = FALSE; - - return result; +/*********************************************************************//** + * @brief + * The isDGOnlyCANNode function determines whether the DG is the only node + * currently on the CAN bus. + * @details + * Inputs : dgIsOnlyCANNode + * Outputs : none + * @return TRUE if DG is only node on CAN bus, FALSE if not + *************************************************************************/ +BOOL isDGOnlyCANNode( void ) +{ + return dgIsOnlyCANNode; } -/************************************************************************* - * @brief execSystemCommRx +/*********************************************************************//** + * @brief * The execSystemCommRx function manages received data from other sub-systems. * @details * Inputs : none - * Outputs : none - * @param none + * Outputs : Incoming frames processed. * @return none *************************************************************************/ void execSystemCommRx( void ) @@ -207,32 +221,62 @@ checkPendingACKList(); } -/************************************************************************* - * @brief execSystemCommTx - * The execSystemCommTx function manages data to be transmitted to other \n - * sub-systems. +/*********************************************************************//** + * @brief + * The execSystemCommTx function manages data to be transmitted to other sub-systems. * @details * Inputs : none - * Outputs : none - * @param none + * Outputs : Next outgoing frame transmitted. * @return none *************************************************************************/ void execSystemCommTx( void ) { - // if CAN transmitter is idle, start transmitting any pending packets - if ( FALSE == isCAN1TransmitInProgress() ) + // don't bother with transmitting if no other nodes on CAN bus + if ( FALSE == dgIsOnlyCANNode ) { - transmitNextCANPacket(); - } - else - { // generally, transmitter should not be busy at time of this function call - check timeout just in case so we don't get stuck waiting forever - if ( TRUE == didTimeout( lastCANPacketSentTimeStamp, CAN_XMIT_PACKET_TIMEOUT_MS ) ) + // if CAN transmitter is idle, start transmitting any pending packets + if ( FALSE == isCAN1TransmitInProgress() ) { - // TODO - depending on why we timed out, we may need to reset CAN controller??? - // assume last packet was not successfully transmitted. TODO - Re-send last packet? Or should we move on? - canTransmit( canREG1, lastCANPacketSentChannel, lastCANPacketSent ); + transmitNextCANPacket(); } - } + else + { + // generally, transmitter should not be busy at time of this function call - check timeout just in case so we don't get stuck waiting forever + if ( TRUE == didTimeout( lastCANPacketSentTimeStamp, CAN_XMIT_PACKET_TIMEOUT_MS ) ) + { + // assume last packet was not successfully transmitted. Re-send last packet. + if ( ++canXmitRetryCtr <= MAX_XMIT_RETRIES ) + { + // ensure we have a previous CAN packet/channel to resend - canTransmit() channel param MUST be valid + if ( ( lastCANPacketSentChannel > COMM_BUFFER_NOT_USED ) && ( lastCANPacketSentChannel <= COMM_BUFFER_LAST_CAN_BUFFER ) ) + { + canTransmit( canREG1, lastCANPacketSentChannel, lastCANPacketSent ); + } +#ifdef DEBUG_ENABLED + { + char debugStr[100]; + strcpy( debugStr, "SystemComm-DG resend Last Frame.\n" ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); + } +#endif + } + // we must be only node on CAN bus - nobody is ACKing our transmitted frames + else + { + dgIsOnlyCANNode = TRUE; // set only CAN node flag + canXmitRetryCtr = MAX_XMIT_RETRIES; + signalCANXmitsCompleted(); // clear pending xmit flag + clearCANXmitBuffers(); // clear xmit buffers - nothing is going out right now +#ifdef DEBUG_ENABLED + char debugStr[100]; + strcpy( debugStr, "SystemComm-DG is only node.\n" ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); +#endif + } // end - are we retrying xmit or are we alone on CAN bus + } // end - pending xmit timeout? + } // end - transmit in progress or not + } // end - DG not alone on CAN bus #ifdef DEBUG_ENABLED // if UART transmitter is idle, start transmitting any pending packets @@ -243,16 +287,15 @@ #endif } -/************************************************************************* - * @brief handleCANMsgInterrupt - * The handleCANMsgInterrupt function handles a CAN message interrupt. \n - * This may have occurred because a CAN packet transmission has completed \n - * or because a CAN packet has been received. The appropriate handler is \n - * called. +/*********************************************************************//** + * @brief + * The handleCANMsgInterrupt function handles a CAN message interrupt. This + * may have occurred because a CAN packet transmission has completed or + * because a CAN packet has been received. The appropriate handler is called. * @details * Inputs : none * Outputs : message interrupt handled - * @param srcCANBox : which CAN message box triggered this interrupt + * @param srcCANBox which CAN message box triggered this interrupt * @return none *************************************************************************/ void handleCANMsgInterrupt( CAN_MESSAGE_BOX_T srcCANBox ) @@ -291,14 +334,13 @@ } } -/************************************************************************* - * @brief handleUARTMsgRecvPacketInterrupt - * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive \n +/*********************************************************************//** + * @brief + * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive * packet completed interrupt. * @details * Inputs : none * Outputs : none - * @param none * @return none *************************************************************************/ #ifdef DEBUG_ENABLED @@ -313,14 +355,13 @@ } #endif -/************************************************************************* - * @brief handleUARTMsgXmitPacketInterrupt - * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit \n +/*********************************************************************//** + * @brief + * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit * packet completed interrupt. * @details * Inputs : none * Outputs : none - * @param none * @return none *************************************************************************/ #ifdef DEBUG_ENABLED @@ -335,14 +376,13 @@ } #endif -/************************************************************************* - * @brief initUARTAndDMA - * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA \n +/*********************************************************************//** + * @brief + * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA * to go with it for PC communication. * @details * Inputs : none * Outputs : SCI1 and DMA initialized - * @param none * @return none *************************************************************************/ #ifdef DEBUG_ENABLED @@ -401,14 +441,14 @@ } #endif -/************************************************************************* - * @brief isCANBoxForXmit - * The isCANBoxForXmit function determines whether a given CAN message box \n +/*********************************************************************//** + * @brief + * The isCANBoxForXmit function determines whether a given CAN message box * is configured for transmit. * @details * Inputs : CAN_OUT_BUFFERS[] * Outputs : none - * @param srcCANBox : which CAN message box to check + * @param srcCANBox which CAN message box to check * @return TRUE if the given CAN message box is configured for transmit, FALSE if not. *************************************************************************/ BOOL isCANBoxForXmit( CAN_MESSAGE_BOX_T srcCANBox ) @@ -428,14 +468,14 @@ return result; } -/************************************************************************* - * @brief isCANBoxForRecv - * The isCANBoxForRecv function determines whether a given CAN message box \n +/*********************************************************************//** + * @brief + * The isCANBoxForRecv function determines whether a given CAN message box * is configured for receiving. * @details * Inputs : MSG_IN_BUFFERS[] * Outputs : none - * @param srcCANBox : which CAN message box to check + * @param srcCANBox which CAN message box to check * @return TRUE if the given CAN message box is configured for receiving, FALSE if not. *************************************************************************/ BOOL isCANBoxForRecv( CAN_MESSAGE_BOX_T srcCANBox ) @@ -455,26 +495,37 @@ return result; } -BOOL isDGOnlyCANNode( void ) +/*********************************************************************//** + * @brief + * The clearCANXmitBuffers function clears all CAN transmit buffers. + * @details + * Inputs : CAN_OUT_BUFFERS[] + * Outputs : CAN transmit buffers cleared. + * @return none + *************************************************************************/ +static void clearCANXmitBuffers( void ) { - return FALSE; + U32 i; + + for ( i = 0; i < NUM_OF_CAN_OUT_BUFFERS; i++ ) + { + clearBuffer( CAN_OUT_BUFFERS[ i ] ); + } } /************************************************************************* ********************** TRANSMIT SUPPORT FUNCTIONS ************************ *************************************************************************/ - -/************************************************************************* - * @brief findNextHighestPriorityCANPacketToTransmit - * The findNextHighestPriorityCANPacketToTransmit function gets the next \n - * 8 byte packet and initiates a CAN transmit on the appropriate CAN channel. \n +/*********************************************************************//** + * @brief + * The findNextHighestPriorityCANPacketToTransmit function gets the next + * 8 byte packet and initiates a CAN transmit on the appropriate CAN channel. * @details * Inputs : Output CAN Comm Buffer(s) * Outputs : none - * @param msg : none - * @return buffer with highest priority CAN packet to transmit, \n + * @return buffer with highest priority CAN packet to transmit, * COMM_BUFFER_NOT_USED if not CAN packets pending transmit found *************************************************************************/ static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void ) @@ -495,15 +546,14 @@ return result; } -/************************************************************************* - * @brief transmitNextCANPacket - * The transmitNextCANPacket function gets the next 8 byte packet and initiates \n +/*********************************************************************//** + * @brief + * The transmitNextCANPacket function gets the next 8 byte packet and initiates * a CAN transmit on the appropriate CAN channel. * @details * Inputs : Output CAN Comm Buffers * Outputs : CAN packet transmit initiated. - * @param msg : none - * @return # of bytes transmitted + * @return number of bytes transmitted *************************************************************************/ static U32 transmitNextCANPacket( void ) { @@ -546,15 +596,14 @@ return result; } -/************************************************************************* - * @brief transmitNextUARTPacket - * The transmitNextUARTPacket function sets up and initiates a DMA transmit \n +/*********************************************************************//** + * @brief + * The transmitNextUARTPacket function sets up and initiates a DMA transmit * of the next packet pending transmit (if any) via UART. * @details * Inputs : Output UART Comm Buffer(s) * Outputs : UART DMA transmit initiated. - * @param msg : none - * @return # of bytes transmitted + * @return number of bytes transmitted *************************************************************************/ #ifdef DEBUG_ENABLED static U32 transmitNextUARTPacket( void ) @@ -586,15 +635,13 @@ ********************** RECEIVE SUPPORT FUNCTIONS ************************* *************************************************************************/ - -/************************************************************************* - * @brief processIncomingData - * The processIncomingData function parses out messages from the Input \n - * Comm Buffers and adds them to the Received Message Queue. +/*********************************************************************//** + * @brief + * The processIncomingData function parses out messages from the input + * comm buffers and adds them to the received message queue. * @details * Inputs : Input Comm Buffers - * Outputs : Parsed message(s) added to Received Message Queue - * @param msg : none + * Outputs : Parsed message(s) added to received message queue * @return none *************************************************************************/ static void processIncomingData( void ) @@ -624,6 +671,9 @@ U32 bytesPeeked = peekFromCommBuffer( MSG_IN_BUFFERS[ i ], data, MIN( numOfBytesInBuffer, sizeof( MESSAGE_WRAPPER_T ) + 1 ) ); S32 msgSize = parseMessageFromBuffer( data, bytesPeeked ); + dgIsOnlyCANNode = FALSE; // if we're getting a message, we can't be alone + canXmitRetryCtr = 0; + if ( msgSize > 0 ) // valid, complete message found? { MESSAGE_WRAPPER_T rcvMsg; @@ -669,14 +719,14 @@ } } -/************************************************************************* - * @brief consumeBufferPaddingBeforeSync - * The consumeBufferPaddingBeforeSync function removes any bytes in a given \n +/*********************************************************************//** + * @brief + * The consumeBufferPaddingBeforeSync function removes any bytes in a given * buffer that lie before a sync byte. * @details * Inputs : none - * Outputs : none - * @param msg : buffer : the comm buffer to process + * Outputs : Any padding at front of comm buffer is consumed. + * @param buffer the comm buffer to process * @return none *************************************************************************/ static void consumeBufferPaddingBeforeSync( COMM_BUFFER_T buffer ) @@ -700,16 +750,16 @@ } } -/************************************************************************* - * @brief parseMessageFromBuffer - * The parseMessageFromBuffer function looks for a complete message in a \n - * given buffer. If a message is found, its size is returned. +/*********************************************************************//** + * @brief + * The parseMessageFromBuffer function looks for a complete message in a + * given buffer. If a message is found, its size is returned. * @details * Inputs : none - * Outputs : none - * @param data : pointer to byte array to search for a message - * @param len : # of bytes in the data to search - * @return size of message if found, zero if no complete message found, \n + * Outputs : If a complete message can be found in buffer contents, it is parsed out. + * @param data pointer to byte array to search for a message + * @param len number of bytes in the data to search + * @return size of message if found, zero if no complete message found, * -1 if message found but CRC fails. *************************************************************************/ static S32 parseMessageFromBuffer( U08 *data, U32 len ) @@ -752,14 +802,13 @@ return result; } -/************************************************************************* - * @brief processReceivedMessages - * The processReceivedMessages function processes any messages in the \n +/*********************************************************************//** + * @brief + * The processReceivedMessages function processes any messages in the * received message queues. * @details * Inputs : Received Message Queues * Outputs : Message(s) processed. - * @param msg : none * @return none *************************************************************************/ static void processReceivedMessages( void ) @@ -799,14 +848,12 @@ } } -/************************************************************************* - * @brief checkForCommTimeouts - * The checkForCommTimeouts function checks for sub-system communication \n - * timeout errors. +/*********************************************************************//** + * @brief + * The checkForCommTimeouts function checks for sub-system communication timeout errors. * @details * Inputs : timeOfLastDGCheckIn, timeOfLastUICheckIn * Outputs : possibly a comm t/o alarm - * @param none * @return none *************************************************************************/ static void checkForCommTimeouts( void ) @@ -820,10 +867,10 @@ } } -/************************************************************************* - * @brief checkTooManyBadMsgCRCs - * The checkTooManyBadMsgCRCs function checks for too many bad message CRCs \n - * within a set period of time. Assumed function is being called when a new \n +/*********************************************************************//** + * @brief + * The checkTooManyBadMsgCRCs function checks for too many bad message CRCs + * within a set period of time. Assumed function is being called when a new * bad CRC is detected so a new bad CRC will be added to the list. * @details * Inputs : badCRCTimeStamps[], badCRCListIdx, badCRCListCount @@ -832,33 +879,31 @@ *************************************************************************/ static void checkTooManyBadMsgCRCs( void ) { - U32 listTimeInMS; - - // replace oldest bad CRC in list with this new one - badCRCTimeStamps[ badCRCListIdx ] = getMSTimerCount(); - // move list index to next position (may wrap) - badCRCListIdx = INC_WRAP( badCRCListIdx, 0, MAX_COMM_CRC_FAILURES - 1 ); - // update list count - badCRCListCount = INC_CAP( badCRCListCount, MAX_COMM_CRC_FAILURES ); - // check if too many bad CRCs in window of time - listTimeInMS = calcTimeSince( badCRCTimeStamps[ badCRCListIdx ] ); - if ( ( badCRCListCount >= MAX_COMM_CRC_FAILURES ) && ( listTimeInMS <= MAX_COMM_CRC_FAILURE_WINDOW_MS ) ) + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_BAD_MSG_CRC ) ) { - activateAlarmNoData( ALARM_ID_COMM_TOO_MANY_BAD_CRCS ); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_COMM_TOO_MANY_BAD_CRCS, 2 ); // 2 for DG } +#ifdef DEBUG_ENABLED + { + char debugStr[100]; + + strcpy( debugStr, "SystemComm-DG-Bad Msg CRC.\n" ); + sendDebugDataToUI( (U08*)debugStr ); + } +#endif } -/************************************************************************* - * @brief addMsgToPendingACKList - * The addMsgToPendingACKList function adds a given message to the pending \n - * ACK list. Messages in this list will require receipt of an ACK message \n +/*********************************************************************//** + * @brief + * The addMsgToPendingACKList function adds a given message to the pending + * ACK list. Messages in this list will require receipt of an ACK message * for this particular message within a limited time. * @details * Inputs : pendingAckList[] * Outputs : pendingAckList[] - * @param msg : pointer to msg within the message data - * @param msgData : pointer to message data to add to pending ACK list - * @param len : # of bytes of message data + * @param msg pointer to msg within the message data + * @param msgData pointer to message data to add to pending ACK list + * @param len number of bytes of message data * @return TRUE if message added successfully, FALSE if not *************************************************************************/ BOOL addMsgToPendingACKList( MESSAGE_T *msg, COMM_BUFFER_T channel, U08 *msgData, U32 len ) @@ -894,15 +939,15 @@ return result; } -/************************************************************************* - * @brief matchACKtoPendingACKList - * The matchACKtoPendingACKList function searches the pending ACK list to \n - * see if the sequence # from a received ACK msg matches any. If found, \n +/*********************************************************************//** + * @brief + * The matchACKtoPendingACKList function searches the pending ACK list to + * see if the sequence number from a received ACK msg matches any. If found, * the list entry is removed. * @details * Inputs : pendingAckList[] * Outputs : pendingAckList[] - * @param seqNo : sequence # to match to an entry in the list + * @param seqNo sequence number to match to an entry in the list * @return TRUE if a match was found, FALSE if not *************************************************************************/ static BOOL matchACKtoPendingACKList( S16 seqNo ) @@ -924,15 +969,14 @@ return result; } -/************************************************************************* - * @brief checkPendingACKList - * The checkPendingACKList function searches the pending ACK list to \n - * see if any have expired. Any such messages will be queued for retransmission \n +/*********************************************************************//** + * @brief + * The checkPendingACKList function searches the pending ACK list to see if + * any have expired. Any such messages will be queued for retransmission * and if max retries reached a fault is triggered. * @details * Inputs : pendingAckList[] * Outputs : pendingAckList[] - * @param none * @return none *************************************************************************/ static void checkPendingACKList( void ) @@ -941,198 +985,203 @@ // find expired messages pending ACK for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) - { + { // pending ACK expired? if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, MSG_NOT_ACKED_TIMEOUT_MS ) ) ) - { + { // if retries left, reset and resend pending message if ( pendingAckList[ i ].retries > 0 ) { // re-queue message for transmit pendingAckList[ i ].retries--; pendingAckList[ i ].timeStamp = getMSTimerCount(); addToCommBuffer( pendingAckList[ i ].channel, pendingAckList[ i ].msg, pendingAckList[ i ].msgSize ); } + // if no retries left, alarm else { U16 msgID; memcpy( &msgID, &pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID ); + pendingAckList[ i ].used = FALSE; // take pending message off of list } } } } -/************************************************************************* - * @brief processReceivedMessage +/*********************************************************************//** + * @brief * The processReceivedMessage function processes a given message. * @details * Inputs : none * Outputs : message processed - * @param message : pointer to message to process + * @param message pointer to message to process * @return none *************************************************************************/ static void processReceivedMessage( MESSAGE_T *message ) { U16 msgID = message->hdr.msgID; - // handle any messages from other sub-systems - switch ( msgID ) - { - case MSG_ID_POWER_OFF_WARNING: - handlePowerOffWarning( message ); - break; + // handle any messages from other sub-systems + switch ( msgID ) + { + case MSG_ID_POWER_OFF_WARNING: + handlePowerOffWarning( message ); + break; - case MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS: - handleSetDialysateTemperatureCmd( message ); - break; + case MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS: + handleSetDialysateTemperatureCmd( message ); + break; - case MSG_ID_REQUEST_FW_VERSIONS: - handleFWVersionCmd( message ); - break; + case MSG_ID_REQUEST_FW_VERSIONS: + handleFWVersionCmd( message ); + break; - case MSG_ID_DG_SWITCH_RESERVOIR_CMD: - handleSwitchReservoirCmd( message ); - break; + case MSG_ID_DG_SWITCH_RESERVOIR_CMD: + handleSwitchReservoirCmd( message ); + break; - case MSG_ID_DG_FILL_CMD: - handleFillCmd( message ); - break; + case MSG_ID_DG_FILL_CMD: + handleFillCmd( message ); + break; - case MSG_ID_DG_DRAIN_CMD: - handleDrainCmd( message ); - break; + case MSG_ID_DG_DRAIN_CMD: + handleDrainCmd( message ); + break; - case MSG_ID_STARTING_STOPPING_TREATMENT_CMD: - handleStartStopTreatmentMsg( message ); - break; + case MSG_ID_STARTING_STOPPING_TREATMENT_CMD: + handleStartStopTreatmentMsg( message ); + break; - case MSG_ID_DG_SAMPLE_WATER_CMD: - handleSampleWaterCmd( message ); - break; + case MSG_ID_DG_SAMPLE_WATER_CMD: + handleSampleWaterCmd( message ); + break; - case MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD: - handleStartStopTrimmerHeaterCmd( message ); - break; + case MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD: + handleStartStopTrimmerHeaterCmd( message ); + break; - case MSG_ID_DG_START_STOP_HEAT_DISINFECT: - handleStartStopDGHeatDisinfect( message ); - break; + case MSG_ID_DG_TESTER_LOGIN_REQUEST: + handleTesterLogInRequest( message ); + break; - case MSG_ID_DG_TESTER_LOGIN_REQUEST: - handleTesterLogInRequest( message ); - break; + case MSG_ID_DG_START_STOP_HEAT_DISINFECT: + handleStartStopDGHeatDisinfect( message ); + break; - default: - // unrecognized message ID received - ok, ignore - may be a test message handled below - break; - } + default: + // unrecognized message ID received - ok, ignore - may be a test message handled below + break; + } - // handle any test messages if tester has logged in successfully - if ( ( msgID > MSG_ID_FIRST_DG_TESTER_MESSAGE ) && ( msgID <= END_OF_MSG_IDS ) && ( TRUE == isTestingActivated() ) ) - { - switch ( msgID ) - { - case MSG_ID_DG_ALARM_STATE_OVERRIDE: - handleTestAlarmStateOverrideRequest( message ); - break; + // handle any test messages if tester has logged in successfully + if ( ( msgID > MSG_ID_FIRST_DG_TESTER_MESSAGE ) && ( msgID <= END_OF_MSG_IDS ) && ( TRUE == isTestingActivated() ) ) + { + switch ( msgID ) + { + case MSG_ID_DG_ALARM_STATE_OVERRIDE: + handleTestAlarmStateOverrideRequest( message ); + break; - case MSG_ID_DG_WATCHDOG_TASK_CHECKIN_OVERRIDE: - handleTestWatchdogCheckInStateOverrideRequest( message ); - break; + case MSG_ID_DG_WATCHDOG_TASK_CHECKIN_OVERRIDE: + handleTestWatchdogCheckInStateOverrideRequest( message ); + break; - case MSG_ID_DG_SET_RTC_DATE_TIME: - handleSetRTCTimestamp( message ); - break; + case MSG_ID_DG_SET_RTC_DATE_TIME: + handleSetRTCTimestamp( message ); + break; - case MSG_ID_START_STOP_PRIMARY_HEATER: - handleStartStopPrimaryHeater ( message ); - break; + case MSG_ID_START_STOP_PRIMARY_HEATER: + handleStartStopPrimaryHeater ( message ); + break; - case MSG_ID_LOAD_CELL_OVERRIDE: - handleTestLoadCellOverrideRequest( message ); - break; + case MSG_ID_LOAD_CELL_OVERRIDE: + handleTestLoadCellOverrideRequest( message ); + break; - case MSG_ID_LOAD_CELLL_SEND_INTERVAL_OVERRIDE: - handleTestLoadCellDataBroadcastIntervalOverrideRequest( message ); - break; + case MSG_ID_LOAD_CELLL_SEND_INTERVAL_OVERRIDE: + handleTestLoadCellDataBroadcastIntervalOverrideRequest( message ); + break; - case MSG_ID_PRESSURE_OVERRIDE: - handleTestPressureSensorOverrideRequest( message ); - break; + case MSG_ID_PRESSURE_OVERRIDE: + handleTestPressureSensorOverrideRequest( message ); + break; - case MSG_ID_PRESSURE_SEND_INTERVAL_OVERRIDE: - handleTestPressureDataBroadcastIntervalOverrideRequest( message ); - break; + case MSG_ID_PRESSURE_SEND_INTERVAL_OVERRIDE: + handleTestPressureDataBroadcastIntervalOverrideRequest( message ); + break; - case MSG_ID_RO_PUMP_SET_PT_OVERRIDE: - handleTestROPumpSetPointOverrideRequest( message ); - break; + case MSG_ID_RO_PUMP_SET_PT_OVERRIDE: + handleTestROPumpSetPointOverrideRequest( message ); + break; - case MSG_ID_RO_MEASURED_FLOW_OVERRIDE: - handleTestROMeasuredFlowOverrideRequest( message ); - break; + case MSG_ID_RO_MEASURED_FLOW_OVERRIDE: + handleTestROMeasuredFlowOverrideRequest( message ); + break; - case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: - handleTestROPumpDataBroadcastIntervalOverrideRequest( message ); - break; + case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: + handleTestROPumpDataBroadcastIntervalOverrideRequest( message ); + break; - case MSG_ID_DRAIN_PUMP_SET_RPM_OVERRIDE: - handleTestDrainPumpSetPointOverrideRequest( message ); - break; + case MSG_ID_DRAIN_PUMP_SET_RPM_OVERRIDE: + handleTestDrainPumpSetPointOverrideRequest( message ); + break; - case MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE: - handleTestDrainPumpDataBroadcastIntervalOverrideRequest( message ); - break; + case MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE: + handleTestDrainPumpDataBroadcastIntervalOverrideRequest( message ); + break; - case MSG_ID_VALVE_STATE_OVERRIDE: - handleTestValveStateOverrideRequest( message ); - break; + case MSG_ID_VALVE_STATE_OVERRIDE: + handleTestValveStateOverrideRequest( message ); + break; - case MSG_ID_VALVES_STATES_PUBLISH_INTERVAL_OVERRIDE: - handleTestValvesStatesPublishIntervalOverrideRequest( message ); - break; + case MSG_ID_VALVES_STATES_PUBLISH_INTERVAL_OVERRIDE: + handleTestValvesStatesPublishIntervalOverrideRequest( message ); + break; - case MSG_ID_DG_SAFETY_SHUTDOWN_OVERRIDE: - handleTestDGSafetyShutdownOverrideRequest( message ); + case MSG_ID_DG_SAFETY_SHUTDOWN_OVERRIDE: + handleTestDGSafetyShutdownOverrideRequest( message ); + break; - case MSG_ID_TEMPERATURE_SENSORS_VALUE_OVERRIDE: - handleTestTemperatureSensorsOverrideRequest ( message ); - break; + case MSG_ID_TEMPERATURE_SENSORS_VALUE_OVERRIDE: + handleTestTemperatureSensorsOverrideRequest ( message ); + break; - case MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE: - handleTestTemperatureSensorsDataPublishOverrideRequest ( message ); - break; + case MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE: + handleTestTemperatureSensorsDataPublishOverrideRequest ( message ); + break; - case MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE: - handleTestHeatersDataPublishOverrideRequest ( message ); - break; + case MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE: + handleTestHeatersDataPublishOverrideRequest ( message ); + break; - case MSG_ID_RO_PUMP_SET_PWM: - handleSetROPumpPWM ( message ); - break; + case MSG_ID_CONDUCTIVITY_OVERRIDE: + handleTestSetConductivityOverrideRequest ( message ); + break; - case MSG_ID_DRAIN_PUMP_SET_DELTA_PRESSURE_OVERRIDE: - handleSetDrainPumpDeltaPressureOverrideRequest ( message ); - break; + case MSG_ID_CONDUCTIVITY_PUBLISH_INTERVAL_OVERRIDE: + handleTestSetConductivityDataPublishIntervalOverrideRequest ( message ); + break; - case MSG_ID_HEAT_DISINFECT_RECIRC_PATH_DURATION_MINS: - handleSetHeatDisinfectRecircStateDurationOverrideRequest ( message ); - break; + case MSG_ID_DG_ACCEL_OVERRIDE: + handleTestDGAccelOverrideRequest( message ); + break; - case MSG_ID_HEAT_DISINFECT_RSRVR1_TO_RSRVR2_DURATION_MINS: - handleSetHeatDisinfectRSVR1ToRSVR2StateDurationOverrideRequest ( message ); - break; + case MSG_ID_DG_ACCEL_MAX_OVERRIDE: + handleTestDGAccelMaxOverrideRequest( message ); + break; - case MSG_ID_HEAT_DISINFECT_RSRVR2_TO_RSRVR1_DURATION_MINS: - handleSetHeatDisinfectRSVR2ToRSVR1StateDurationOverrideRequest ( message ); - break; + case MSG_ID_DG_ACCEL_SEND_INTERVAL_OVERRIDE: + handleTestDGAccelBroadcastIntervalOverrideRequest( message ); + break; - case MSG_ID_HEAT_DISINFECT_NO_OF_CYCLES_TO_RUN: - handleSetHeatDisinfectNoOfCyclesStateDurationOverrideRequest ( message ); - break; + case MSG_ID_DG_ACCEL_SET_CALIBRATION: + handleSetAccelCalibration( message ); + break; - default: - // TODO - unrecognized message ID received - ignore - break; - } - } + default: + // TODO - unrecognized message ID received - ignore + break; + } + } } + +/**@}*/