Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r5cee5f88d4d3f18b4178621f1ef175b0873d6248 -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 5cee5f88d4d3f18b4178621f1ef175b0873d6248) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -263,10 +263,11 @@ currentDrainPumpRPM = CONVERSION_COEFF / getFPGADrainPumpSpeed(); } + // TODO this is disabled until RPM is calculated propely. // The RPM is only checked in open loop state that the pump is run at a fixed RPM. // The persistent alarm waits for a couple of seconds before raising an alarm, this is supposed to cover // when the pump is turned on and it takes a while to ramp up to target RPM. - if( drainPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) + /*if( drainPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) { U32 targetRPM = getTargetDrainPumpRPM(); F32 threshold = OPEN_LOOP_RPM_OUT_OF_RANGE * targetRPM; @@ -289,7 +290,7 @@ { activateSafetyShutdown(); } - } + }*/ // Publish drain pump data on interval publishDrainPumpData(); Index: firmware/App/Controllers/LoadCell.c =================================================================== diff -u -r06e5fe353de02fbed03e8e0f9b81c41b79e5cf18 -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 06e5fe353de02fbed03e8e0f9b81c41b79e5cf18) +++ firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -15,8 +15,11 @@ * ***************************************************************************/ +#include // For load cells calibration calculations + #include "FPGA.h" #include "LoadCell.h" +#include "NVDataMgmt.h" #include "SystemCommMessages.h" #include "TaskPriority.h" @@ -27,6 +30,9 @@ // ********** private definitions ********** +// TODO check the maximum weight on the load cells in tare. There was 1500 grams limit +// but it has been removed. Check the load cells data sheet. + #define LOAD_CELL_REPORT_PERIOD (100 / TASK_PRIORITY_INTERVAL) ///< Broadcast load cell values message every 100 ms. /// Conversion factor from ADC counts to grams. static const F32 ADC2GRAM = (0.0894 * 1.1338); @@ -62,12 +68,14 @@ static U32 smallReadingsIdx; ///< Index for next sample in load cell small rolling average sample array. static U32 largeReadingsIdx; ///< Index for next sample in load cell large rolling average sample array. +static DG_LOAD_CELLS_CAL_RECORD_T loadCellsCalRecord; ///< Load cells calibration record. // TODO - gain and offset for load cells should be read from NV Data calibration record. // ********** private function prototypes ********** static U32 getLoadCellDataPublishInterval( void ); +static BOOL processCalibrationData( void ); /*********************************************************************//** * @brief @@ -78,6 +86,7 @@ *************************************************************************/ void initLoadCell( void ) { + U32 cell; U32 i; U32 j; @@ -111,6 +120,17 @@ loadcells[ i ].largeFilterReadings[ j ] = 0.0; } } + + // Set all the load cells' calibration values to benign values + for ( cell = CAL_DATA_LOAD_CELL_A1; cell < NUM_OF_CAL_DATA_LOAD_CELLS; cell++ ) + { + // Reset the calibration variables + loadCellsCalRecord.loadCells[ cell ].fourthOrderCoeff = 0.0; + loadCellsCalRecord.loadCells[ cell ].thirdOrderCoeff = 0.0; + loadCellsCalRecord.loadCells[ cell ].secondOrderCoeff = 0.0; + loadCellsCalRecord.loadCells[ cell ].gain = 1.0; + loadCellsCalRecord.loadCells[ cell ].offset = 0.0; + } } /*********************************************************************//** @@ -176,6 +196,33 @@ /*********************************************************************//** * @brief + * The execLoadCellsSelfTest function executes the load cell self test. + * It gets the calibration record from NVDataMgmt and checks whether the + * values have a calibration date. + * @details Inputs: none + * @details Outputs: + * @return result of the load cell self test + *************************************************************************/ +SELF_TEST_STATUS_T execLoadCellsSelfTest ( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + + BOOL calStatus = processCalibrationData(); + + if ( TRUE == calStatus ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + } + + return result; +} + +/*********************************************************************//** + * @brief * The tareLoadCell function sets the load cell auto calibration offset * for a given load cell ID. * @details Inputs: none @@ -302,7 +349,50 @@ return result; } +/*********************************************************************//** + * @brief + * The processCalibrationData function gets the calibration data and makes + * sure it is valid by checking the calibration date. The calibration date + * should not be 0. + * @details Inputs: loadCellsCalRecord + * @details Outputs: loadCellsCalRecord + * @return TRUE if the calibration record is valid, otherwise FALSE + *************************************************************************/ +static BOOL processCalibrationData( void ) +{ + BOOL status = TRUE; + U32 cell; + // Get the calibration record from NVDataMgmt + DG_LOAD_CELLS_CAL_RECORD_T calData = getDGLoadCellsCalibrationRecord(); + + for ( cell = 0; cell < NUM_OF_CAL_DATA_LOAD_CELLS; cell++ ) + { + // Check if the calibration data that was received from NVDataMgmt is legitimate + // The calibration date item should not be zero. If the calibration date is 0, + // then the load cells data is not stored in the NV memory or it was corrupted. + if ( calData.loadCells[ cell ].calibrationTime == 0 ) + { +#ifndef DISABLE_CAL_CHECK + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_LOAD_CELLS_INVALID_CALIBRATION, (U32)cell ); +#endif + status = FALSE; + } + else + { + // The calibration data was valid, update the local copy + loadCellsCalRecord.loadCells[ cell ].fourthOrderCoeff = calData.loadCells[ cell ].fourthOrderCoeff; + loadCellsCalRecord.loadCells[ cell ].thirdOrderCoeff = calData.loadCells[ cell ].thirdOrderCoeff; + loadCellsCalRecord.loadCells[ cell ].secondOrderCoeff = calData.loadCells[ cell ].secondOrderCoeff; + loadCellsCalRecord.loadCells[ cell ].gain = calData.loadCells[ cell ].gain; + loadCellsCalRecord.loadCells[ cell ].offset = calData.loadCells[ cell ].offset; + } + } + + return status; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/DGCommon.h =================================================================== diff -u -ra1b8dbb69c4bd2f0cc22e62bede7015c9307d378 -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/DGCommon.h (.../DGCommon.h) (revision a1b8dbb69c4bd2f0cc22e62bede7015c9307d378) +++ firmware/App/DGCommon.h (.../DGCommon.h) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -32,12 +32,14 @@ #ifndef _RELEASE_ #ifndef _VECTORCAST_ // TODO: Removed debug build flags when release build is ready -// #define RM46_EVAL_BOARD_TARGET 1 + #define BOARD_WITH_NO_HARDWARE 1 + #define DONT_SKIP_NV_POST 1 // #define SIMULATE_UI 1 // #define TASK_TIMING_OUTPUT_ENABLED 1 // re-purposes drain pump enable pin for task timing // #define DISABLE_HEATERS_AND_TEMPS 1 #define DISABLE_ACCELS 1 #define SKIP_POST 1 + //#define DISABLE_CAL_CHECK 1 // #define ENABLE_DIP_SWITCHES 1 // #define EMC_TEST_BUILD 1 #define ALARMS_DEBUG 1 Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -ra1b8dbb69c4bd2f0cc22e62bede7015c9307d378 -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision a1b8dbb69c4bd2f0cc22e62bede7015c9307d378) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -169,6 +169,7 @@ SW_FAULT_ID_DRAIN_MODE_INVALID_EXEC_STATE, SW_FAULT_ID_FILL_MODE_INVALID_EXEC_STATE, SW_FAULT_ID_PRESSURE_INVALID_EXEC_STATE, + SW_FAULT_ID_INVALID_NVDATAMGMT_EXEC_CAL_STATE, // 80 NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r79e9be79f488da3a4aef5d755d359fff91a8db3e -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 79e9be79f488da3a4aef5d755d359fff91a8db3e) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -8,8 +8,8 @@ * * @file FPGA.c * -* @author (last) Quang Nguyen -* @date (last) 18-Sep-2020 +* @author (last) Peman Montazemi +* @date (last) 09-Mar-2021 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -76,6 +76,8 @@ #define DRAIN_PUMP_DAC_SHIFT_BITS 4 ///< Drain pump DAC shift bits. +#define FPGA_FLUIDLEAK_STATE_MASK 0x0004 ///< Bit mask for fluid leak detector. + // FPGA header struct. #pragma pack(push,1) typedef struct @@ -166,7 +168,7 @@ U16 fpgaCP1HallSense; ///< Reg 388. Concentrate pump CP1 hall sensor pulse width. U16 fpgaCP2HallSense; ///< Reg 390. Concentrate pump CP2 hall sensor pulse width. - U08 fpgaGPIOReg; ///< Reg 392. FGPA GPIO register + U08 fpgaGPIO; ///< Reg 392. FGPA GPIO register U08 fpgaDummyByte2Addr; ///< Reg 393. Dummy byte address to maintain an even addressing scheme U16 fpgaADCTemp; ///< Reg 394. Internal FPGA die temperature ADC } DG_FPGA_SENSORS_T; @@ -1778,5 +1780,19 @@ return fpgaSensorReadings.fpgaADC2ErrorCnt; } -/**@}*/ +/*********************************************************************//** + * @brief + * The noFluidLeakDetected function returns TRUE if no fluid leak has been + * detected (dry) and FALSE if a fluid leak has been detected (wet). + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return noFluidLeakDetected + *************************************************************************/ +BOOL noFPGAFluidLeakDetected( void ) +{ + U16 noFluidLeakDetected = fpgaSensorReadings.fpgaGPIO & FPGA_FLUIDLEAK_STATE_MASK; + return ( 0 == noFluidLeakDetected ? FALSE : TRUE ); +} + +/**@}*/ Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -ra3e3feea8cfb6a1e0137bf09031f0484a3c73332 -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision a3e3feea8cfb6a1e0137bf09031f0484a3c73332) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -1209,6 +1209,46 @@ handleTestUVReactorsHealthOverride( message ); break; + case MSG_ID_DG_SET_CALIBRATION_RECORD: + handleSetDGCalibrationRecord( message ); + break; + + case MSG_ID_DG_GET_CALIBRATION_RECORD: + handleGetDGCalibrationRecord( message ); + break; + + case MSG_ID_DG_SET_SYSTEM_RECORD: + handleSetDGSystemRecord( message ); + break; + + case MSG_ID_DG_GET_SYSTEM_RECORD: + handleGetDGSystemRecord( message ); + break; + + case MSG_ID_DG_GET_SERVICE_RECORD: + handleGetDGServiceRecord( message ); + break; + + case MSG_ID_DG_SET_SERVICE_RECORD: + handleSetDGServiceRecord( message ); + break; + + case MSG_ID_DG_GET_SCHEDULED_RUNS_RECORD: + handleGetDGScheduledRunsRecord( message ); + break; + + case MSG_ID_DG_SET_SCHEDULED_RUNS_RECORD: + handleSetDGScheduledRunsRecord( message ); + break; + + case MSG_ID_DG_FLUID_LEAK_SEND_INTERVAL_OVERRIDE: + handleSetFluidLeakBroadcastIntervalOverrideRequest( message ); + break; + + case MSG_ID_DG_FLUID_LEAK_STATE_DETECTOR_OVERRIDE: + handleSetFluidLeakStateDetectorOverrideRequest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r6a78aa774e417565e69c5b5dbc9effa57fea495f -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 6a78aa774e417565e69c5b5dbc9effa57fea495f) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -933,6 +933,192 @@ /*********************************************************************//** * @brief + * The sendDGCalibrationRecord function sends out the DG calibration + * record. + * @details Inputs: none + * @details Outputs: DG calibration record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param calRcrdAddress: start address of the calibration record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGCalibrationRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_SEND_CALIBRATION_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, calRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/***********************************************************************//** + * @brief + * The broadcastFluidLeakState function constructs a DG fluid leak state msg to \n + * be broadcasted and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: fluid leak state msg constructed and queued + * @param state fluid leak state + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastFluidLeakState( FLUID_LEAK_STATES_T state ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + U32 leakState = (U32)state; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_FLUID_LEAK_STATE; + msg.hdr.payloadLen = sizeof( U32 ); + + memcpy( payloadPtr, &leakState, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendDGSystemRecord function sends out the DG system record. + * @details Inputs: none + * @details Outputs: DG system record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param sysRcrdAddress: start address of the system record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGSystemRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* sysRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_SEND_SYSTEM_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, sysRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendDGServiceRecord function sends out the DG service record. + * @details Inputs: none + * @details Outputs: DG system record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param srvcRcrdAddress: start address of the service record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGServiceRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* srvcRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_SEND_SERVICE_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, srvcRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendDGServiceRecord function sends out the DG service record. + * @details Inputs: none + * @details Outputs: DG system record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param scheduledRcrdAddress: start address of the scheduled runs record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGScheduledRunsRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* scheduledRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_SEND_SCHEDULED_RUNS_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, scheduledRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The sendCommandResponseMsg function constructs a command response to HD * and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none @@ -1963,31 +2149,6 @@ /*********************************************************************//** * @brief - * The handleSetAccelCalibration function handles a request to set - * accelerometer calibration factors. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSetAccelCalibration( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( ACCEL_CAL_PAYLOAD_T ) ) - { - ACCEL_CAL_PAYLOAD_T payload; - - memcpy( &payload, message->payload, sizeof( ACCEL_CAL_PAYLOAD_T ) ); - result = setAccelCalibration( payload.xOffset, payload.yOffset, payload.zOffset ); - } - - // respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** - * @brief * The handleTestSetConductivityOverrideRequest function handles a * request to override a conductivity sensor's value * @details Inputs: none @@ -2153,6 +2314,70 @@ /*********************************************************************//** * @brief + * The handleSetFluidLeakBroadcastIntervalOverrideRequest function handles a + * request to override the fluid leak state broadcast interval. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetFluidLeakBroadcastIntervalOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetFluidLeakStatePublishIntervalOverride( (U32)( payload.state.u32 ) ); + } + else + { + result = testResetFluidLeakStatePublishIntervalOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleSetFluidLeakStateDetectorOverrideRequest function handles a request to + * override the fluid leak detector state. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetFluidLeakStateDetectorOverrideRequest( 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 = testSetFluidLeakStateOverride( ( FLUID_LEAK_STATES_T)( payload.state.u32 ) ); + } + else + { + result = testResetFluidLeakStateOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleDGSoftwareResetRequest function handles a request to * perform a software reset on DG. * @details Inputs: none @@ -2475,7 +2700,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -//*******************************************************************/ +/*********************************************************************//** +* @brief +* The handleROPumpTargetPressureOverride function handles a request +* to override the target RO pump pressure. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ void handleROPumpTargetPressureOverride( MESSAGE_T *message ) { BOOL result = FALSE; @@ -2495,4 +2728,240 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** +* @brief +* The handleSetDGCalibrationRecord function handles a request to set the DG +* calibration data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetDGCalibrationRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = setCalibrationRecord( currentMessage, totalMessages, payloadLength, payloadPtr ); + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** +* @brief +* The handleGetDGCalibrationRecord function handles a request to get the DG +* calibration data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetDGCalibrationRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = getCalibrationRecord(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleSetDGSystemRecord function handles a request to set the DG +* system data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetDGSystemRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = setSystemRecord( currentMessage, totalMessages, payloadLength, payloadPtr ); + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** +* @brief +* The handleGetDGSystemRecord function handles a request to get the DG +* system data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetDGSystemRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = getSystemRecord(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleGetDGServiceRecord function handles a request to get the DG +* service data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetDGServiceRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = getServiceRecord(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleSetDGServiceRecord function handles a request to set the DG +* service data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetDGServiceRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = setServiceRecord( currentMessage, totalMessages, payloadLength, payloadPtr ); + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** +* @brief +* The handleGetDGServiceRecord function handles a request to get the DG +* scheduled runs data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetDGScheduledRunsRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = getScheduledRunsRecord(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleSetDGScheduledRunsRecord function handles a request to set the DG +* scheduled runs data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetDGScheduledRunsRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = setScheduledRunsRecord( currentMessage, totalMessages, payloadLength, payloadPtr ); + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r6a78aa774e417565e69c5b5dbc9effa57fea495f -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 6a78aa774e417565e69c5b5dbc9effa57fea495f) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -21,7 +21,9 @@ #include "DGCommon.h" #include "DrainPump.h" #include "Fans.h" +#include "FluidLeak.h" #include "MsgQueues.h" +#include "NVDataMgmt.h" #include "Reservoirs.h" #include "ROPump.h" #include "Thermistors.h" @@ -102,6 +104,9 @@ // MSG_ID_DG_FILTER_FLUSH_PROGRESS BOOL broadcastFilterFlushData( U32 timeout, U32 countdown ); +// MSG_ID_DG_FLUID_LEAK_STATE +BOOL broadcastFluidLeakState( FLUID_LEAK_STATES_T state); + // MSG_ID_DG_COMMAND_RESPONSE void sendCommandResponseMsg( DG_CMD_RESPONSE_T *cmdResponsePtr ); @@ -141,6 +146,21 @@ // MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD void handleStartStopTrimmerHeaterCmd( MESSAGE_T *message ); +// MSG_ID_DG_UV_REACTORS_DATA +BOOL broadcastUVReactorsData( UV_REACTORS_DATA_T *uvReactorsData ); + +// MSG_ID_DG_SEND_CALIBRATION_DATA +BOOL sendDGCalibrationRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress ); + +// MSG_ID_DG_SEND_SYSTEM_RECORD +BOOL sendDGSystemRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* sysRcrdAddress ); + +// MSG_ID_DG_SEND_SERVICE_RECORD +BOOL sendDGServiceRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* srvcRcrdAddress ); + +// MSG_ID_DG_SEND_SCHEDULED_RUNS_RECORD +BOOL sendDGScheduledRunsRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* scheduledRcrdAddress ); + // *********** public test support message functions ********** #ifdef DEBUG_ENABLED @@ -224,15 +244,18 @@ // MSG_ID_DG_ACCEL_SEND_INTERVAL_OVERRIDE: void handleTestDGAccelBroadcastIntervalOverrideRequest( MESSAGE_T *message ); -// MSG_ID_DG_ACCEL_SET_CALIBRATION: -void handleSetAccelCalibration( MESSAGE_T *message ); - // MSG_ID_DG_START_STOP_INLET_UV_REACTOR void handleStartStopUVReactors( MESSAGE_T *message ); -//MSG_ID_UV_REACTORS_DATA_PUBLISH_INTERVAL_OVERRIDE +// MSG_ID_UV_REACTORS_DATA_PUBLISH_INTERVAL_OVERRIDE void handleTestUVReactorsDataPublishIntervalOverride( MESSAGE_T *message ); +// MSG_ID_DG_FLUID_LEAK_SEND_INTERVAL_OVERRIDE +void handleSetFluidLeakBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_FLUID_LEAK_STATE_DETECTOR_OVERRIDE +void handleSetFluidLeakStateDetectorOverrideRequest( MESSAGE_T *message); + // MSG_ID_DG_SOFTWARE_RESET_REQUEST void handleDGSoftwareResetRequest( MESSAGE_T *message); @@ -272,6 +295,30 @@ // MSG_ID_DG_RO_PUMP_TARGET_PRESSURE_OVERRIDE void handleROPumpTargetPressureOverride( MESSAGE_T *message ); +// MSG_ID_DG_SET_CALIBRATION_DATA +void handleSetDGCalibrationRecord( MESSAGE_T *message ); + +// MSG_ID_DG_GET_CALIBRATION_RECORD +void handleGetDGCalibrationRecord( MESSAGE_T *message ); + +// MSG_ID_DG_SET_SYSTEM_DATA +void handleSetDGSystemRecord( MESSAGE_T *message ); + +// MSG_ID_DG_GET_SYSTEM_DATA +void handleGetDGSystemRecord( MESSAGE_T *message ); + +// MSG_ID_DG_GET_SERVICE_RECORD +void handleGetDGServiceRecord( MESSAGE_T *message ); + +// MSG_ID_DG_SET_SERVICE_RECORD +void handleSetDGServiceRecord( MESSAGE_T *message ); + +// MSG_ID_DG_GET_SCHEDULED_RUNS_RECORD +void handleGetDGScheduledRunsRecord( MESSAGE_T *message ); + +// MSG_ID_DG_SET_SCHEDULED_RUNS_RECORD +void handleSetDGScheduledRunsRecord( MESSAGE_T *message ); + /**@}*/ #endif Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -rccf1219089b835ab2f9d401c0be0d2000be9010a -rab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision ccf1219089b835ab2f9d401c0be0d2000be9010a) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision ab447ebbc380f4c7abc2ae283042a5d0c9e1b9cb) @@ -21,10 +21,12 @@ #include "ConcentratePumps.h" #include "DrainPump.h" #include "Fans.h" -#include "Heaters.h" +#include "Heaters.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "Reservoirs.h" -#include "ROPump.h" +#include "ROPump.h" +#include "RTC.h" #include "SystemComm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -71,8 +73,12 @@ checkInWithWatchdogMgmt( TASK_GENERAL ); // do this first to keep timing consistent with watchdog management // manage data received from other sub-systems - execSystemCommRx(); + execSystemCommRx(); + // Control and monitor RTC + execRTC(); + +#ifndef BOARD_WITH_NO_HARDWARE // monitor concentrate pumps execConcentratePumpMonitor(); @@ -95,7 +101,8 @@ execReservoirs(); // Manage UV reactors controller - execUVReactors(); + execUVReactors(); +#endif #ifndef DISABLE_HEATERS_AND_TEMPS // Primary heaters state machine @@ -105,7 +112,11 @@ execTrimmerHeater(); #endif // run operation mode state machine - execOperationModes(); + execOperationModes(); + + // Run non-volatile data management state machine that sends the data record + // to Dialin + execNVDataMgmtProcessRecord(); // manage data to be transmitted to other sub-systems execSystemCommTx();