Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rc6d4cd2dbaac8a68be80b047f8fb0a33133576af -rf7292cd3376119210980f14e8bdb0ec5e0cf5df5 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision c6d4cd2dbaac8a68be80b047f8fb0a33133576af) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision f7292cd3376119210980f14e8bdb0ec5e0cf5df5) @@ -57,6 +57,99 @@ #ifdef DEBUG_ENABLED #define DEBUG_EVENT_MAX_TEXT_LEN 40 #endif + +// ********** private data ********** + +static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. +static volatile U16 nextSeqNo = 1; ///< Next sequence number. + +// ********** private function prototypes ********** + +static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ); +static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); +static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); + +/*********************************************************************//** + * @brief + * The serializeMessage function serializes a given message into a given + * array of bytes. A sequence # is added to the message here and the ACK + * bit of the sequence # is set if ACK is required per parameter. A sync byte + * is inserted at the beginning of the message and an 8-bit CRC is appended to + * the end of the message. The message is queued for transmission in the given buffer. + * @details Inputs: none + * @details Outputs: given data array populated with serialized message data and queued for transmit. + * @param msg message to serialize + * @param buffer outgoing buffer that message should be queued in + * @param ackReq is an acknowledgement from receiver required? + * @return size (in bytes) of serialized message populated in given data array. + *************************************************************************/ +static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) +{ + BOOL result = FALSE; + BOOL error = FALSE; + U32 msgSize = 0; + U32 sizeMod, sizePad; + U32 i; + U08 crc; + U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data + + // prefix data with message sync byte + data[ msgSize++ ] = MESSAGE_SYNC_BYTE; + + // set sequence # and ACK bit (unless this is an ACK to a received message) + if ( msg.hdr.msgID != MSG_ID_ACK ) + { + // thread protect next sequence # access & increment + _disable_IRQ(); + msg.hdr.seqNo = nextSeqNo; + nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); + _enable_IRQ(); + if ( TRUE == ackReq ) + { + msg.hdr.seqNo *= -1; + } + } + + // calculate message CRC + crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); + + // serialize message header data + memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); + msgSize += sizeof( MESSAGE_HEADER_T ); + + // serialize message payload (only used bytes per payloadLen field) + memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); + msgSize += msg.hdr.payloadLen; + + // add 8-bit CRC + data[ msgSize++ ] = crc; + + // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) + sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; + sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); + for ( i = 0; i < sizePad; i++ ) + { + data[ msgSize++ ] = 0; + } + + // if ACK required, add to pending ACK list + if ( TRUE == ackReq ) + { + if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) + { + error = TRUE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + } + } + + if ( FALSE == error ) + { + // add serialized message data to appropriate out-going comm buffer + result = addToCommBuffer( buffer, data, msgSize ); + } + + return result; +} // ********** private data ********** @@ -324,7 +417,6 @@ /*********************************************************************//** * @brief * The broadcastRTCEpoch function constructs an epoch msg to be broadcast -<<<<<<< HEAD * and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none * @details Outputs: RTC time and date in epoch @@ -516,22 +608,17 @@ * @param setPWM set PWM duty cycle in % * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL broadcastROPumpData( U32 tgtPressure, F32 measFlow, F32 setPWM ) +BOOL broadcastROPumpData( RO_PUMP_DATA_T *pumpData ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; - RO_PUMP_DATA_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_RO_PUMP_DATA; msg.hdr.payloadLen = sizeof( RO_PUMP_DATA_T ); - payload.setROPumpPressure = tgtPressure; - payload.measROFlowRate = measFlow; - payload.roPumpPWM = setPWM; - memcpy( payloadPtr, &payload, sizeof( RO_PUMP_DATA_T ) ); // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer @@ -1496,15 +1583,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestROMeasuredFlowOverrideRequest function handles a request to - * override the RO flow rate. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestROMeasuredFlowOverrideRequest function handles a request to + * override the RO flow rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -2104,8 +2191,58 @@ { result = testResetThermistorPublishIntervalOverride(); } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +} +void handleTestROPumpDutyCycleOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( F32 ) ); + + result = testSetTargetDutyCycle( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleTestROFlowRateOverride function handles a request to override +* the RO flow rate. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*******************************************************************/ +void handleTestMeasuredROFlowRateOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetMeasuredROFlowRateOverride( payload.state.f32 ); + } + else + { + result = testResetMeasuredROFlowRateOverride(); + } + } + // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } @@ -2137,7 +2274,22 @@ result = testResetMeasuredThermistorOverride( payload.index ); } } +} +//*******************************************************************/ +void handleTestROPumpTargetFlowOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payload; + + memcpy( &payload, message->payload, sizeof( F32 ) ); + result = testSetTargetROPumpFlow( payload ); + } + // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } @@ -2169,7 +2321,24 @@ result = testResetFanPublishIntervalOverride(); } } +} +//*******************************************************************/ +void handleROPumpTargetPressureOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( U32 ) == message->hdr.payloadLen ) + { + U32 payload; + + memcpy( &payload, message->payload, sizeof( U32 ) ); + + result = testSetTargetROPumpPressure( payload ); + + } + // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); }