Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r8fe65bf6222137cc7182ccacff3a5f2fb2f03753 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 8fe65bf6222137cc7182ccacff3a5f2fb2f03753) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -35,6 +35,7 @@ #include "TaskGeneral.h" #include "TaskPriority.h" #include "Timers.h" +#include "Valves.h" #ifdef EMC_TEST_BUILD #include "Heaters.h" #endif @@ -141,6 +142,7 @@ static DG_FLOW_SENSORS_CAL_RECORD_T flowSensorsCalRecord; ///< Flow sensors calibration record. static OVERRIDE_F32_T measuredROFlowRateWithConcPumpsLPM = { 0.0, 0.0, 0.0, 0 }; ///< Measure RO flow rate with concentrate pumps (L/min). static DG_RO_PUMP_CAL_RECORD_T roPumpCalRecord; ///< RO pump calibration record. +static F32 roVolumeL; ///< RO water generated in liters. // ********** private function prototypes ********** @@ -198,6 +200,7 @@ roPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; isROPumpOn = FALSE; roPumpFeedbackDutyCyclePct = 0.0; + roVolumeL = 0.0; } /*********************************************************************//** @@ -379,6 +382,11 @@ flowFilterCounter = 0; } + if ( ( measuredROFlowRateLPM.data > NEARLY_ZERO ) && ( (U32)VALVE_STATE_CLOSED == getValveState( (U32)VBF ) ) ) + { + roVolumeL += ( measuredROFlowRateLPM.data * SEC_PER_MIN ); + } + #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_RO_PUMP_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -574,6 +582,18 @@ /*********************************************************************//** * @brief + * The getROGeneratedVolumeL function returns the RO generated volume in liters. + * @details Inputs: none + * @details Outputs: none + * @return the RO generated volume in liters + *************************************************************************/ +F32 getROGeneratedVolumeL( void ) +{ + return roVolumeL; +} + +/*********************************************************************//** + * @brief * The handleROPumpOffState function handles the RO pump off state of the * controller state machine. * @details Inputs: roPumpControlMode, roPumpPWMDutyCyclePctSet, Index: firmware/App/Controllers/ROPump.h =================================================================== diff -u -r66cc826068b54bc436cde0fae70a05ba6c1ac974 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 66cc826068b54bc436cde0fae70a05ba6c1ac974) +++ firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -67,6 +67,8 @@ F32 getTargetROPumpPressure( void ); +F32 getROGeneratedVolumeL( void ); + BOOL testSetROPumpDataPublishIntervalOverride( U32 value ); BOOL testResetROPumpDataPublishIntervalOverride( void ); Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -r8fe65bf6222137cc7182ccacff3a5f2fb2f03753 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 8fe65bf6222137cc7182ccacff3a5f2fb2f03753) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -24,10 +24,12 @@ #include "ModeChemicalDisinfect.h" #include "ModeFault.h" #include "ModeStandby.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "Pressures.h" #include "Reservoirs.h" #include "ROPump.h" +#include "RTC.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TemperatureSensors.h" @@ -1293,7 +1295,11 @@ // Turn off the heaters stopHeater( DG_PRIMARY_HEATER ); stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_COOL_DOWN_HEATERS; + state = DG_CHEM_DISINFECT_STATE_COOL_DOWN_HEATERS; + + // Set the disinfect flags + setDisinfectStatus( TRUE ); + setLastDisinfectDate( getRTCTimestamp() ); break; } Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -rbb25b54e08fa328452f5d6e3daa2c96578c296bb -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision bb25b54e08fa328452f5d6e3daa2c96578c296bb) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -740,21 +740,26 @@ } } - // SRSDG 400 - if ( FALSE == isValueWithinPercentRange( avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MIXING_IN_FILL ) != SW_CONFIG_ENABLE_VALUE ) +#endif { - setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected - setThisFisrtFillFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 - activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); - } + // SRSDG 400 + if ( FALSE == isValueWithinPercentRange( avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) + { + setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected + setThisFisrtFillFlag( TRUE ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 + activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); + } - if ( FALSE == isValueWithinPercentRange( avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) - { - setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected - setThisFisrtFillFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 then - activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); + if ( FALSE == isValueWithinPercentRange( avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) + { + setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected + setThisFisrtFillFlag( TRUE ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 then + activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); + } } // Done with this fill. Calculate the average fill flow rate and average temperature Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r8fe65bf6222137cc7182ccacff3a5f2fb2f03753 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 8fe65bf6222137cc7182ccacff3a5f2fb2f03753) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -20,6 +20,7 @@ #include "ConductivitySensors.h" #include "DrainPump.h" #include "FPGA.h" +#include "HDDefs.h" #include "Heaters.h" #include "ModeFill.h" #include "ModeGenIdle.h" @@ -53,11 +54,14 @@ // ********** private data ********** static DG_GEN_IDLE_MODE_STATE_T genIdleState; ///< Currently active generation idle state. +// NOTE: the bad fill state must be initialized here and not in the transition function since in case of a bad fill, the transition function is called +// several times to drain and fill and handle a bad fill. static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T badFillState = DG_HANDLE_BAD_FILL_STATE_START; ///< Initialize bad fill sub-state. static U32 hdLostCommStartTime_ms; ///< Lost communication with HD start time in ms. static U32 genIdlePublicationTimerCounter; ///< Used to schedule bad fill sub-states publication to CAN bus. static U32 targetFillVolumeML; ///< Save the target fill volume before calling startFillCmd(). static BOOL handleBadFillFlag; ///< Internal signal flag to handle bad fill. +static HD_OP_MODE_T hdMode; ///< HD operations mode. static OVERRIDE_U32_T badFillSubstatesPublishInterval = { BAD_FILL_SUBSTATES_PUB_INTERVAL, ///< Interval (in ms) at which to publish bad fill sub-states to CAN bus. BAD_FILL_SUBSTATES_PUB_INTERVAL, 0, 0 }; @@ -104,6 +108,12 @@ // Re-initialize each time we transition to generation idle mode initGenIdleMode(); + // TODO should we write to RAM that disinfect has been voided all the time during the treatment? + if ( MODE_TREA == hdMode ) + { + setDisinfectStatus( FALSE ); + } + // Set initial actuator states setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); @@ -163,6 +173,18 @@ /*********************************************************************//** * @brief + * The setHDOperationMode function sets HD operation mode value. + * @details Inputs: none + * @details Outputs: hdMode + * @return none + *************************************************************************/ +void setHDOperationMode( U32 mode ) +{ + hdMode = (HD_OP_MODE_T)mode; +} + +/*********************************************************************//** + * @brief * The setBadAvgConductivityDetectedFlag function sets a flag to indicate * that bad average conductivity is detected. * @details Inputs: none @@ -173,6 +195,7 @@ { handleBadFillFlag = badAvgConducitivyflag; } + /*********************************************************************//** * @brief * The execGenIdleMode function executes the generation idle mode state machine. Index: firmware/App/Modes/ModeGenIdle.h =================================================================== diff -u -r604d8aaceeb8e0b650ac2054644333fc7717bb51 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Modes/ModeGenIdle.h (.../ModeGenIdle.h) (revision 604d8aaceeb8e0b650ac2054644333fc7717bb51) +++ firmware/App/Modes/ModeGenIdle.h (.../ModeGenIdle.h) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -48,6 +48,8 @@ BOOL requestDGStop( void ); // HD requests DG stop (go back to standby mode) +void setHDOperationMode( U32 mode ); + BOOL testSetBadFillSubstatesPublishIntervalOverride( U32 value ); BOOL testResetBadFillSubstatesPublishIntervalOverride( void ); Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r8fe65bf6222137cc7182ccacff3a5f2fb2f03753 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 8fe65bf6222137cc7182ccacff3a5f2fb2f03753) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -25,10 +25,12 @@ #include "MessageSupport.h" #include "ModeFault.h" #include "ModeHeatDisinfect.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "Pressures.h" #include "Reservoirs.h" #include "ROPump.h" +#include "RTC.h" #include "Switches.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -1211,7 +1213,11 @@ stopHeater( DG_PRIMARY_HEATER ); stopHeater( DG_TRIMMER_HEATER ); stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS; + state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS; + + // Set the disinfect flags + setDisinfectStatus( TRUE ); + setLastDisinfectDate( getRTCTimestamp() ); break; case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS: Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -ra9315539f527b92523b1598ff91e47db4d71dae2 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision a9315539f527b92523b1598ff91e47db4d71dae2) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -29,7 +29,9 @@ #include "ModeService.h" #include "ModeSolo.h" #include "ModeStandby.h" +#include "NVDataMgmt.h" #include "OperationModes.h" +#include "ROPump.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -152,6 +154,10 @@ lastMode = currentMode; transitionToNewOperationMode( newMode ); currentMode = newMode; + + // Mode is changing, write the RO generated volume to the RTC RAM and set the service flag to FALSE + // since this is not a from a service change + setROWaterGeneratedL( getROGeneratedVolumeL(), FALSE ); } // mode specific processing to be done continuously Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -re1c23ba7cd93c1d63ffdcbd894aa95ac7c39b584 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e1c23ba7cd93c1d63ffdcbd894aa95ac7c39b584) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -1177,6 +1177,18 @@ handleTestHDCommunicationStatusOverrideRequest( message ); break; + case MSG_ID_DG_GET_USAGE_INFO_RECORD: + handleGetDGUsageInfoRecord( message ); + break; + + case MSG_ID_DG_SET_USAGE_INFO_RECORD: + handleSetDGUsageInfoRecord( message ); + break; + + case MSG_ID_HD_OP_MODE: + handleSetHDOperationMode( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r66cc826068b54bc436cde0fae70a05ba6c1ac974 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 66cc826068b54bc436cde0fae70a05ba6c1ac974) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -3469,4 +3469,136 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** +* @brief +* The handleGetDGUsageInfoRecord function handles a request to get the DG +* usage information record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetDGUsageInfoRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = sendRecordToDialin( NVDATAMGMT_USAGE_INFO_RECORD ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleSetDGUsageInfoRecord function handles a request to set the DG +* information record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetDGUsageInfoRecord( MESSAGE_T *message ) +{ + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + BOOL status = FALSE; + U08* payloadPtr = message->payload; + + if ( message->hdr.payloadLen >= ( sizeof(currentMessage) + sizeof(totalMessages) + sizeof(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 = receiveRecordFromDialin( NVDATAMGMT_USAGE_INFO_RECORD, currentMessage, totalMessages, payloadLength, payloadPtr ); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + +/*********************************************************************//** + * @brief + * The sendDGUsageInfoRecord function sends out the DG usage information record. + * @details Inputs: none + * @details Outputs: DG usage information record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param usageInfoAddress: start address of the susage information record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGUsageInfoRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* usageInfoAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_SEND_USAGE_INFO_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, usageInfoAddress, 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 handleSetHDOperationMode function receives the HD operation modes data + * publish message. + * @details Inputs: none + * @details Outputs: none + * @param message a pointer to the message to handle + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL handleSetHDOperationMode( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + + // HD mode broadcast is operations mode and submode so 8 bytes + if ( message->hdr.payloadLen == sizeof( U32 ) + sizeof( U32 ) ) + { + U32 mode; + + // NOTE: the HD operations modes broadcast message contains the mode and submode states + // In this case, only the mode is needed. The mode is received to check if HD is in treatment + // and therefore, DG can void the last disinfect. + memcpy( payloadPtr, &mode, sizeof( U32 ) ); + setHDOperationMode( mode ); + status = TRUE; + } + + return status; +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r66cc826068b54bc436cde0fae70a05ba6c1ac974 -r1e22b6ff6f42ddc57ad6c17e56057ab8a3765680 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 66cc826068b54bc436cde0fae70a05ba6c1ac974) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 1e22b6ff6f42ddc57ad6c17e56057ab8a3765680) @@ -143,6 +143,9 @@ // MSG_ID_DG_SEND_SW_CONFIG_RECORD BOOL sendDGSWConfigRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* swRcrdAddress ); +// MSG_ID_DG_SEND_USAGE_INFO_RECORD +BOOL sendDGUsageInfoRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* usageInfoAddress ); + // MSG_ID_DG_SCHEDULED_RUNS_INFO void handleDGScheduledRunsRequest( MESSAGE_T *message ); @@ -377,6 +380,15 @@ // MSG_ID_DG_HD_COMMUNICATION_STATUS void handleTestHDCommunicationStatusOverrideRequest(MESSAGE_T *message); +// MSG_ID_DG_GET_USAGE_INFO_RECORD +void handleGetDGUsageInfoRecord( MESSAGE_T *message ); + +// MSG_ID_DG_SET_USAGE_INFO_RECORD +void handleSetDGUsageInfoRecord( MESSAGE_T *message ); + +// MSG_ID_HD_OP_MODE +BOOL handleSetHDOperationMode( MESSAGE_T *message ); + /**@}*/ #endif