Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r1c80d60fe6a95297a8a8033a3c7eade53e72779a -r94895e32fe18e78b98fe3bb7786838cf00afdbfa --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 1c80d60fe6a95297a8a8033a3c7eade53e72779a) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 94895e32fe18e78b98fe3bb7786838cf00afdbfa) @@ -37,11 +37,17 @@ #define NUM_OF_CAN_OUT_BUFFERS 5 // # of CAN buffers for transmit #define NUM_OF_CAN_IN_BUFFERS 7 // # of CAN buffers for receiving -#define NUM_OF_MSG_IN_BUFFERS 8 // # of Msg buffers for receiving - 1 is UART +#ifdef DEBUG_ENABLED + #define NUM_OF_MSG_IN_BUFFERS 8 // # of Msg buffers for receiving - 1 is UART +#else + #define NUM_OF_MSG_IN_BUFFERS 7 // # of Msg buffers for receiving +#endif #define SCI1_RECEIVE_DMA_REQUEST 30 #define SCI1_TRANSMIT_DMA_REQUEST 31 +#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 UI_COMM_TIMEOUT_IN_MS 5000 #define DG_COMM_TIMEOUT_IN_MS 2000 @@ -52,7 +58,7 @@ #define MSG_NOT_ACKED_MAX_RETRIES 3 #define PENDING_ACK_LIST_SIZE 25 -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { @@ -87,19 +93,28 @@ COMM_BUFFER_IN_CAN_UI_2_HD, COMM_BUFFER_IN_CAN_UI_BROADCAST, COMM_BUFFER_IN_CAN_PC, +#ifdef DEBUG_ENABLED COMM_BUFFER_IN_UART_PC +#endif }; -static U08 pcXmitPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static U08 pcRecvPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static U08 lastCANPacketSent[ CAN_MESSAGE_PAYLOAD_SIZE ]; +static CAN_MESSAGE_BOX_T lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0; +static U32 lastCANPacketSentTimeStamp = 0; -#ifndef ACK_NOT_IMPLEMENTED -static PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; // list of outgoing messages that are awaiting an ACK +#ifdef DEBUG_ENABLED + static U08 pcXmitPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + static U08 pcRecvPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + // DMA control records + static g_dmaCTRL pcDMAXmitControlRecord; // DMA transmit control record (UART-debug) + static g_dmaCTRL pcDMARecvControlRecord; // DMA receive control record (UART-debug) + + //static U08 dbgRcvFromDialin[2048]; + //static U32 dbgRcvFromDialinIdx = 0; #endif -// DMA control records -static g_dmaCTRL pcDMAXmitControlRecord; // DMA transmit control record (UART-debug) -static g_dmaCTRL pcDMARecvControlRecord; // DMA receive control record (UART-debug) +static PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; // list of outgoing messages that are awaiting an ACK static volatile BOOL dgIsCommunicating = FALSE; // has DG sent a message since last check static U32 timeOfLastDGCheckIn = 0; // last time DG checked in @@ -113,27 +128,28 @@ // ********** private function prototypes ********** -static void initUARTAndDMA( void ); +#ifdef DEBUG_ENABLED + static void initUARTAndDMA( void ); + static U32 transmitNextUARTPacket( void ); +#endif + static BOOL isCANBoxForXmit( CAN_MESSAGE_BOX_T srcCANBox ); static BOOL isCANBoxForRecv( CAN_MESSAGE_BOX_T srcCANBox ); static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void ); static U32 transmitNextCANPacket( void ); -static U32 transmitNextUARTPacket( void ); static void processIncomingData( void ); -static U32 parseMessageFromBuffer( U08 *data, U32 len ); +static S32 parseMessageFromBuffer( U08 *data, U32 len ); static void consumeBufferPaddingBeforeSync( COMM_BUFFER_T buffer ); static void processReceivedMessages( void ); static void processReceivedMessage( MESSAGE_T *message ); static void checkForCommTimeouts( void ); -static void checkTooManyBadMsgCRCs( U16 msgID ); +static void checkTooManyBadMsgCRCs( void ); -#ifndef ACK_NOT_IMPLEMENTED static BOOL matchACKtoPendingACKList( S16 seqNo ); static void checkPendingACKList( void ); -#endif /************************************************************************* * @brief initSystemComm @@ -148,22 +164,22 @@ { U32 i; +#ifdef DEBUG_ENABLED // initialize UART and DMA for PC communication initUARTAndDMA(); +#endif // initialize bad message CRC list for ( i = 0; i < MAX_COMM_CRC_FAILURES; i++ ) { badCRCTimeStamps[ i ] = 0; } -#ifndef ACK_NOT_IMPLEMENTED // initialize pending ACK list for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) { pendingAckList[ i ].used = FALSE; } -#endif } /************************************************************************* @@ -271,10 +287,8 @@ // check for sub-system comm timeouts checkForCommTimeouts(); -#ifndef ACK_NOT_IMPLEMENTED // check ACK list for messages that need to be re-sent because they haven't been ACK'd checkPendingACKList(); -#endif } /************************************************************************* @@ -294,12 +308,23 @@ { 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 ) ) + { + // 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 ); + } + } +#ifdef DEBUG_ENABLED // if UART transmitter is idle, start transmitting any pending packets if ( FALSE == isSCI1DMATransmitInProgress() ) { transmitNextUARTPacket(); } +#endif } /************************************************************************* @@ -321,6 +346,7 @@ { U32 bytesXmitted = transmitNextCANPacket(); + // if nothing more to send, signal that transmitter is available if ( 0 == bytesXmitted ) { signalCANXmitsCompleted(); @@ -333,9 +359,21 @@ // get CAN packet received on given CAN message box if ( FALSE != canIsRxMessageArrived( canREG1, srcCANBox ) ) { - canGetData( canREG1, srcCANBox, data ); - // add CAN packet to appropriate comm buffer based on the message box it came in on (s/b same #) - addToCommBuffer( srcCANBox, data, CAN_MESSAGE_PAYLOAD_SIZE ); + U32 result = canGetData( canREG1, srcCANBox, data ); + + // if packet retrieved, add to buffer + if ( result != 0 ) + { +//#ifdef DEBUG_ENABLED +// if ( srcCANBox == COMM_BUFFER_IN_CAN_PC ) +// { +// memcpy( &dbgRcvFromDialin[dbgRcvFromDialinIdx], data, CAN_MESSAGE_PAYLOAD_SIZE); +// dbgRcvFromDialinIdx += CAN_MESSAGE_PAYLOAD_SIZE; +// } +//#endif + // add CAN packet to appropriate comm buffer based on the message box it came in on (s/b same #) + addToCommBuffer( srcCANBox, data, CAN_MESSAGE_PAYLOAD_SIZE ); + } } } else @@ -355,6 +393,7 @@ * @param none * @return none *************************************************************************/ +#ifdef DEBUG_ENABLED void handleUARTMsgRecvPacketInterrupt( void ) { // buffer received packet @@ -364,6 +403,7 @@ dmaSetChEnable( DMA_CH1, DMA_HW ); setSCI1DMAReceiveInterrupt(); } +#endif /************************************************************************* * @brief handleUARTMsgXmitPacketInterrupt @@ -375,6 +415,7 @@ * @param none * @return none *************************************************************************/ +#ifdef DEBUG_ENABLED void handleUARTMsgXmitPacketInterrupt( void ) { U32 bytesXmitted = transmitNextUARTPacket(); @@ -384,6 +425,7 @@ signalSCI1XmitsCompleted(); } } +#endif /************************************************************************* * @brief initUARTAndDMA @@ -395,11 +437,13 @@ * @param none * @return none *************************************************************************/ +#ifdef DEBUG_ENABLED static void initUARTAndDMA( void ) { // Enable DMA block transfer complete interrupts dmaEnableInterrupt( DMA_CH1, BTC ); dmaEnableInterrupt( DMA_CH3, BTC ); + // assign DMA channels to h/w DMA requests dmaReqAssign( DMA_CH1, SCI1_RECEIVE_DMA_REQUEST ); dmaReqAssign( DMA_CH3, SCI1_TRANSMIT_DMA_REQUEST ); @@ -448,6 +492,7 @@ dmaSetChEnable( DMA_CH1, DMA_HW ); setSCI1DMAReceiveInterrupt(); } +#endif /************************************************************************* * @brief isCANBoxForXmit @@ -563,7 +608,12 @@ // if there's another CAN packet to send, send it if ( dataSize == CAN_MESSAGE_PAYLOAD_SIZE ) { + // we're transmitting another packet - signal transmitter is busy signalCANXmitsInitiated(); + // remember packet data being transmitted here in case transmission fails and we need to re-send + memcpy( lastCANPacketSent, data, CAN_MESSAGE_PAYLOAD_SIZE ); + lastCANPacketSentChannel = mBox; + lastCANPacketSentTimeStamp = getMSTimerCount(); if ( 0 != canTransmit( canREG1, mBox, data ) ) { result = CAN_MESSAGE_PAYLOAD_SIZE; @@ -594,6 +644,7 @@ * @param msg : none * @return # of bytes transmitted *************************************************************************/ +#ifdef DEBUG_ENABLED static U32 transmitNextUARTPacket( void ) { U32 result = 0; @@ -617,8 +668,8 @@ return result; } +#endif - /************************************************************************* ********************** RECEIVE SUPPORT FUNCTIONS ************************* *************************************************************************/ @@ -636,8 +687,9 @@ *************************************************************************/ static void processIncomingData( void ) { - U08 data[ sizeof( MESSAGE_WRAPPER_T ) + 1 ]; + U08 data[ 512 ]; // message work space U32 i; + BOOL badCRCDetected = FALSE; // queue any received messages for ( i = 0; i < NUM_OF_MSG_IN_BUFFERS; i++ ) @@ -658,17 +710,17 @@ if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE ) { // peek at minimum of all bytes available or max message size (+1 for sync byte) U32 bytesPeeked = peekFromCommBuffer( MSG_IN_BUFFERS[ i ], data, MIN( numOfBytesInBuffer, sizeof( MESSAGE_WRAPPER_T ) + 1 ) ); - U32 msgSize = parseMessageFromBuffer( data, bytesPeeked ); + S32 msgSize = parseMessageFromBuffer( data, bytesPeeked ); - if ( msgSize > 0 ) + if ( msgSize > 0 ) // valid, complete message found? { MESSAGE_WRAPPER_T rcvMsg; U08 *dataPtr = data+1; // skip over sync byte // consume message (+sync byte) msgSize = getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, msgSize + 1 ); // convert received message data to a message and add to message queue - messagesInBuffer = TRUE; + messagesInBuffer = TRUE; // keep processing this buffer // blank the new message record blankMessageInWrapper( &rcvMsg ); // copy message header portion of message data to the new message @@ -681,10 +733,31 @@ rcvMsg.crc = *dataPtr; // add new message to queue for later processing addToMsgQueue( MSG_Q_IN, &rcvMsg ); + } + else if ( -1 == msgSize ) // candidate message with bad CRC found? + { + badCRCDetected = TRUE; + getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, 1 ); // consume sync byte so we can re-sync +//#ifdef DEBUG_ENABLED +//{ +// // TODO - temporary debug code - remove later +// char debugStr[ 20 ]; +// +// sprintf( debugStr, "%02X", (S32)data[0] ); +// sendDebugData( (U08*)debugStr, strlen(debugStr) ); +//} +//#endif + messagesInBuffer = TRUE; // keep processing this buffer } // looks like there is a complete message in the comm buffer } // enough data left in comm buffer to possibly be a complete message } // while loop to get all complete messages for each comm buffer } // for loop to check all comm buffers for messages + + // if any bad CRCs detected, see if too many + if ( TRUE == badCRCDetected ) + { + checkTooManyBadMsgCRCs(); + } } /************************************************************************* @@ -708,11 +781,27 @@ peekFromCommBuffer( buffer, &data, 1 ); if ( MESSAGE_SYNC_BYTE == data ) { +//#ifdef DEBUG_ENABLED +//{ +// // TODO - temporary debug code - remove later +// char debugStr[ 3 ] = "\n"; +// sendDebugData( (U08*)debugStr, strlen(debugStr) ); +//} +//#endif break; // we found a sync - we're done } else // not a sync byte, so consume it { getFromCommBuffer( buffer, &data, 1 ); +//#ifdef DEBUG_ENABLED +//{ +// // TODO - temporary debug code - remove later +// char debugStr[ 20 ]; +// +// sprintf( debugStr, "%02X ", (U32)data ); +// sendDebugData( (U08*)debugStr, strlen(debugStr) ); +//} +//#endif numOfBytesInBuffer = numberOfBytesInCommBuffer( buffer ); } } @@ -727,14 +816,15 @@ * 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. + * @return size of message if found, zero if no complete message found, \n + * -1 if message found but CRC fails. *************************************************************************/ -static U32 parseMessageFromBuffer( U08 *data, U32 len ) +static S32 parseMessageFromBuffer( U08 *data, U32 len ) { U32 i; U32 payloadSize; U32 msgSize; - U32 result = 0; + S32 result = 0; for ( i = 0; i < len; i++ ) { @@ -751,11 +841,17 @@ msgSize = MESSAGE_OVERHEAD_SIZE + payloadSize; // we now know the size of the message - we can now know if full message is contained in buffer if ( msgSize <= remSize ) - { - result = msgSize; // we found a complete message of this size + { // check CRC to make sure it's a valid message + if ( data[i+msgSize] == crc8( &data[pos], msgSize - 1 ) ) + { + result = msgSize; // we found a complete, valid message of this size + } + else // CRC failed + { + result = -1; // we found a complete, invalid message + } } } - break; } } @@ -783,35 +879,30 @@ // see if any messages received isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN, &message ); if ( TRUE == isThereMsgRcvd ) - { - // TODO - check CRC before processing a message + { // CRC should be good because we checked it during parsing before adding to queue - but check it again for good measure if ( message.crc == crc8( (U08*)(&message), sizeof(MESSAGE_HEADER_T) + message.msg.hdr.payloadLen ) ) { -#ifndef ACK_NOT_IMPLEMENTED // if ACK, mark pending message ACK'd if ( MSG_ID_ACK == message.msg.hdr.msgID ) { matchACKtoPendingACKList( message.msg.hdr.seqNo ); } else -#endif { -#ifndef ACK_NOT_IMPLEMENTED // if received message requires ACK, queue one up if ( message.msg.hdr.seqNo < 0 ) { sendACKMsg( &message.msg ); } else -#endif { // otherwise, process the received message processReceivedMessage( &message.msg ); } } } else // CRC failed { - checkTooManyBadMsgCRCs( message.msg.hdr.msgID ); + checkTooManyBadMsgCRCs(); } } } @@ -847,10 +938,9 @@ * @details * Inputs : badCRCTimeStamps[], badCRCListIdx, badCRCListCount * Outputs : possibly a "too many bad CRCs" alarm - * @param msgID : the message ID from the recevied msg that failed CRC check. * @return none *************************************************************************/ -static void checkTooManyBadMsgCRCs( U16 msgID ) +static void checkTooManyBadMsgCRCs( void ) { U32 listTimeInMS; @@ -862,13 +952,14 @@ badCRCListCount = INC_CAP( badCRCListCount, MAX_COMM_CRC_FAILURES ); // check if too many bad CRCs in window of time listTimeInMS = calcTimeSince( badCRCTimeStamps[ badCRCListIdx ] ); - if ( listTimeInMS <= MAX_COMM_CRC_FAILURE_WINDOW_MS ) + if ( ( badCRCListCount >= MAX_COMM_CRC_FAILURES ) && ( listTimeInMS <= MAX_COMM_CRC_FAILURE_WINDOW_MS ) ) { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_COMM_TOO_MANY_BAD_CRCS, (U32)msgID ); +#ifndef DISABLE_CRC_ERROR + activateAlarmNoData( ALARM_ID_COMM_TOO_MANY_BAD_CRCS ); +#endif } } -#ifndef ACK_NOT_IMPLEMENTED /************************************************************************* * @brief addMsgToPendingACKList * The addMsgToPendingACKList function adds a given message to the pending \n @@ -981,7 +1072,6 @@ } } } -#endif /************************************************************************* * @brief processReceivedMessage @@ -1014,6 +1104,26 @@ handleUICheckIn( message ); break; + case MSG_ID_LOAD_CELL_READINGS: + handleLoadCellReadingsFromDG( message ); + break; + + case MSG_ID_USER_UF_PAUSE_RESUME_REQUEST: + handleUFPauseResumeRequest( message ); + break; + + case MSG_ID_USER_UF_SETTINGS_CHANGE_REQUEST: + handleChangeUFSettingsRequest( message ); + break; + + case MSG_ID_USER_CONFIRM_UF_SETTINGS_CHANGE: + handleChangeUFSettingsConfirmation( message ); + break; + + case MSG_ID_USER_TREATMENT_TIME_CHANGE_REQUEST: + handleChangeTreatmentDurationRequest( message ); + break; + case MSG_ID_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); break; @@ -1144,6 +1254,38 @@ handleSetRTCTimestamp( message ); break; + case MSG_ID_DIAL_OUT_FLOW_SEND_INTERVAL_OVERRIDE: + handleTestDialOutFlowBroadcastIntervalOverrideRequest( message ); + break; + + case MSG_ID_DIAL_OUT_UF_REF_VOLUME_OVERRIDE: + handleTestDialOutUFReferenceVolumeOverrideRequest( message ); + break; + + case MSG_ID_DIAL_OUT_UF_MEAS_VOLUME_OVERRIDE: + handleTestDialOutUFMeasuredVolumeOverrideRequest( message ); + break; + + case MSG_ID_DIAL_OUT_PUMP_MC_MEAS_SPEED_OVERRIDE: + handleTestDialOutPumpMCMeasuredSpeedOverrideRequest( message ); + break; + + case MSG_ID_DIAL_OUT_PUMP_MC_MEAS_CURR_OVERRIDE: + handleTestDialOutPumpMCMeasuredCurrentOverrideRequest( message ); + break; + + case MSG_ID_DIAL_OUT_PUMP_MEAS_SPEED_OVERRIDE: + handleTestDialOutPumpMeasuredSpeedOverrideRequest( message ); + break; + + case MSG_ID_DIAL_OUT_PUMP_MEAS_ROTOR_SPEED_OVERRIDE: + handleTestDialOutPumpMeasuredRotorSpeedOverrideRequest( message ); + break; + + case MSG_ID_DIAL_OUT_LOAD_CELL_WEIGHT_OVERRIDE: + handleTestDialOutLoadCellWeightOverrideRequest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break;