Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r549fea9aba0bc5bc03d195d1a5659261e3ace9d0 -r0589eeee132373075cccc56eab04db2b5160ae81 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 549fea9aba0bc5bc03d195d1a5659261e3ace9d0) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 0589eeee132373075cccc56eab04db2b5160ae81) @@ -30,6 +30,7 @@ #include "ModeTreatment.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" +#include "RTC.h" #include "Switches.h" #include "SyringePump.h" #include "SystemComm.h" @@ -46,7 +47,7 @@ // ********** private definitions ********** #define DISINFECTS_DATA_PUB_INTERVAL ( 1 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Disinfects data publish interval in counts. -#define SERVICE_TIME_INTERVAL_MS ( 6 * 30 * SECONDS_IN_A_DAY * MS_PER_SECOND ) ///< HD/DG 6-month service interval in milliseconds. +#define DISINFECTS_TIME_INTERVAL_S ( 2 * SECONDS_IN_A_DAY ) ///< HD/DG 2-day service interval in seconds. // ********** private data ********** @@ -63,6 +64,9 @@ /// Interval (in task intervals) at which to publish standby mode data to CAN bus. static OVERRIDE_U32_T standbyModePublishInterval = { DISINFECTS_DATA_PUB_INTERVAL, DISINFECTS_DATA_PUB_INTERVAL, DISINFECTS_DATA_PUB_INTERVAL, 0 }; +static const U32 SERVICE_TIME_INTERVAL_S = (U32)( 365 * 0.5 * SECONDS_IN_A_DAY ); ///< HD/DG 6-month service interval in seconds. +static BOOL homingInitiated; ///< Flag indicates actuator homing has been initiated from standby mode. + // ********** private function prototypes ********** static void handleDisinfectCancel( BOOL stop ); @@ -83,6 +87,8 @@ static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectStartState( void ); static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectInProgressState( void ); +static BOOL isDGDisinfectValid( void ); +static BOOL haveHDDGServicesBeenExpired( REQUEST_REJECT_REASON_CODE_T* rejReason ); static void publishDisinfectData( void ); /*********************************************************************//** @@ -103,6 +109,7 @@ heatDisinfectStartReqReceived = FALSE; chemDisinfectStartReqReceived = FALSE; disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; + homingInitiated = FALSE; dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; } @@ -149,6 +156,9 @@ { currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; } + // Request DG service record and usage information from DG + sendDGServiceRequestToDG(); + sendDGUsageInfoRequestToDG(); return currentStandbyState; } @@ -171,7 +181,7 @@ switch ( currentStandbyState ) { case STANDBY_START_STATE: - currentStandbyState = handleStandbyModeStartState();; + currentStandbyState = handleStandbyModeStartState(); break; case STANDBY_WAIT_FOR_TREATMENT_STATE: @@ -286,9 +296,22 @@ rejReason = REQUEST_REJECT_REASON_BATTERY_IS_NOT_CHARGED; } +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SERVICE_AND_DISINFECT_CHECK ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + // This function checks both HD and DG service records and if any of them has failed, it fills the provided reject reason buffer + haveHDDGServicesBeenExpired( &rejReason ); + + if ( FALSE == isDGDisinfectValid() ) + { + rejReason = REQUEST_REJECT_REASON_DG_DISINFECT_HAS_BEEN_EXPIRED; + } + } + if ( REQUEST_REJECT_REASON_NONE == rejReason ) { - result = TRUE; + result = TRUE; treatStartReqReceived = TRUE; } @@ -569,31 +592,33 @@ *************************************************************************/ static HD_STANDBY_STATE_T handleStandbyModeStartState( void ) { - static BOOL homingInitiated = FALSE; HD_STANDBY_STATE_T state = STANDBY_START_STATE; // Wait for door to be closed so we can home actuators - if ( ( homingInitiated != TRUE ) && ( STATE_CLOSED == getSwitchStatus( FRONT_DOOR ) ) ) + if ( STATE_CLOSED == getSwitchStatus( FRONT_DOOR ) ) { - VALVE_T valve; - - // Home pumps and valves - for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) + // If we haven't alreadyy initiated homing of actuators, initiate now + if ( homingInitiated != TRUE ) { - homeValve( valve ); - } - homeBloodPump(); - homeDialInPump(); - homeDialOutPump(); - retractSyringePump(); + VALVE_T valve; - homingInitiated = TRUE; + // Home pumps and valves + for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) + { + homeValve( valve ); + } + homeBloodPump(); + homeDialInPump(); + homeDialOutPump(); + retractSyringePump(); + + homingInitiated = TRUE; + } } else { // Trigger door open alarm to prompt user to close the door activateAlarmNoData( ALARM_ID_CARTRIDGE_DOOR_OPENED ); - homingInitiated = FALSE; } // If homing has been initiated, wait for syringe pump to home and the verify force sensor calibration @@ -619,7 +644,7 @@ *************************************************************************/ static HD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ) { - HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; DG_OP_MODE_T dgOperationMode = getDGOpMode(); // If DG is filling while we are in standby mode, abort the fill @@ -634,17 +659,22 @@ cmdStopDG(); } - // If treatment start is requested by user, initiate treatment workflow (transition to treatment params mode). TODO - check required conditions before allowing treatment start, reject if necessary. + // If treatment start is requested by user, initiate treatment workflow (transition to treatment params mode). if ( TRUE == treatStartReqReceived ) { - // Initialize treatment modes before starting a new treatment - initTreatParamsMode(); - initPreTreatmentMode(); - initTreatmentMode(); - initPostTreatmentMode(); - // Start treatment workflow with treatment parameters mode - requestNewOperationMode( MODE_TPAR ); - treatStartReqReceived = FALSE; + BOOL startTreatment = TRUE; + + if ( TRUE == startTreatment ) + { + // Initialize treatment modes before starting a new treatment + initTreatParamsMode(); + initPreTreatmentMode(); + initTreatmentMode(); + initPostTreatmentMode(); + // Start treatment workflow with treatment parameters mode + requestNewOperationMode( MODE_TPAR ); + treatStartReqReceived = FALSE; + } } return state; @@ -922,6 +952,85 @@ /*********************************************************************//** * @brief + * The isDGDisinfectValid function checks whether the DG disinfects is + * acceptable to start another treatment. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if the disinfect is valid otherwise, FALSE + ***********************************************************************/ +static BOOL isDGDisinfectValid( void ) +{ + DG_SERVICE_AND_USAGE_DATA_T data; + BOOL status = TRUE; + + getHDVersionDGServiceAndUsageData( &data ); + + if ( TRUE == data.isDGUsageInfoAviable ) + { + if ( TRUE == data.dgUsageInfo.isDisinfected ) + { + U32 chemDisElapsedTimeS = getRTCTimestamp() - data.dgUsageInfo.lastChemicalDisDateEpoch; + BOOL hasChemDisBeenExpired = ( chemDisElapsedTimeS > DISINFECTS_TIME_INTERVAL_S ? TRUE : FALSE ); + U32 heatDisElapsedTimeS = getRTCTimestamp() - data.dgUsageInfo.lastHeatDisDateEpoch; + BOOL hasHeatDisBeenExpired = ( heatDisElapsedTimeS > DISINFECTS_TIME_INTERVAL_S ? TRUE : FALSE ); + + if ( ( TRUE == hasChemDisBeenExpired ) && ( TRUE == hasHeatDisBeenExpired ) ) + { + status = FALSE; + } + } + else + { + status = FALSE; + } + } + + return status; +} + +/*********************************************************************//** + * @brief + * The haveHDDGServicesBeenExpired function checks whether the last DG/HD + * service time is still within the interval or not. + * @details Inputs: none + * @details Outputs: none + * @param rejReason pointer to the provided reject reason buffer to be send to UI + * @return TRUE if the service time is still valid otherwise, FALSE + ***********************************************************************/ +static BOOL haveHDDGServicesBeenExpired( REQUEST_REJECT_REASON_CODE_T* rejReason ) +{ + BOOL status = TRUE; + DG_SERVICE_AND_USAGE_DATA_T dgData; + HD_SERVICE_RECORD_T hdServiceRecord; + + getHDVersionDGServiceAndUsageData( &dgData ); + getNVRecord2Driver( GET_SRV_RECORD, (U08*)&hdServiceRecord, sizeof( HD_SERVICE_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + + if ( TRUE == dgData.isDGServiceRecordAvailable ) + { + U32 dgSrvcElapsedTimeS = getRTCTimestamp() - dgData.dgServiceRecord.lastServiceDateEpoch; + BOOL hasDGSrvcBeenExpired = ( dgSrvcElapsedTimeS > SERVICE_TIME_INTERVAL_S ? TRUE : FALSE ); + U32 hdSrvcElapsedTimeS = getRTCTimestamp() - hdServiceRecord.lastServiceEpochDate; + BOOL hasHDSrvcBeenExpied = ( hdSrvcElapsedTimeS > SERVICE_TIME_INTERVAL_S ? TRUE : FALSE ); + + if ( TRUE == hasDGSrvcBeenExpired ) + { + status = FALSE; + *rejReason = REQUEST_REJECT_REASON_DG_SERVICE_IS_DUE; + } + + if ( TRUE == hasHDSrvcBeenExpied ) + { + status = FALSE; + *rejReason = REQUEST_REJECT_REASON_HD_SERVICE_IS_DUE; + } + } + + return status; +} + +/*********************************************************************//** + * @brief * The publishDisinfectData function publishes disinfects data at * the set interval. * @details Inputs: dataPublishCounter Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -r402885eda2ed755a079c854d1228ac5f76cbec7c -r0589eeee132373075cccc56eab04db2b5160ae81 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 402885eda2ed755a079c854d1228ac5f76cbec7c) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 0589eeee132373075cccc56eab04db2b5160ae81) @@ -42,7 +42,19 @@ #define BROADCAST_HD_OP_MODE_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< HD operation mode broadcast interval (in task interval/sec). #define DATA_PUBLISH_COUNTER_START_COUNT 11 ///< Data publish counter start count. +#define NUM_CONFIRM_REQUESTS 4 ///< Number of available confirmation requests. +#define CONFIRMATION_REQUEST_TIMEOUT_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Confirmation response timeout in ms +/// Structure for confirmation request. +typedef struct +{ + GENERIC_CONFIRM_ID_T requestID; ///< Request ID + GENERIC_CONFIRM_COMMAND_T requestType; ///< Request Type + U32 timeStamp; ///< Timestamp for request + CONFIRMATION_REQUEST_STATUS_T status; ///< Request status (pending, accepted, rejected) +} CONFIRMATION_REQUEST_T; + + // ********** private data ********** static volatile BOOL modeRequest[ NUM_OF_MODES - 1 ]; ///< Pending operation mode change requests. @@ -53,6 +65,11 @@ /// Interval (in task intervals) at which to publish operation mode data to CAN bus. static OVERRIDE_U32_T opModePublishInterval = { BROADCAST_HD_OP_MODE_INTERVAL, BROADCAST_HD_OP_MODE_INTERVAL, BROADCAST_HD_OP_MODE_INTERVAL, 0 }; static U32 priorSubMode = 0; ///< The prior submode state. +static CONFIRMATION_REQUEST_T confirmRequests[NUM_CONFIRM_REQUESTS] = + { GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, }; /// This matrix determines legal transitions from one mode to another static const HD_OP_MODE_T MODE_TRANSITION_TABLE[ NUM_OF_MODES - 1 ][ NUM_OF_MODES - 1 ] = { @@ -71,6 +88,7 @@ static HD_OP_MODE_T arbitrateModeRequest( void ); static void transitionToNewOperationMode( HD_OP_MODE_T newMode ); static void broadcastOperationMode( void ); +static void updateConfirmationRequestTimeouts( void ); /*********************************************************************//** * @brief @@ -200,6 +218,8 @@ } priorSubMode = currentSubMode; + updateConfirmationRequestTimeouts( ); + // Broadcast current operation mode on interval broadcastOperationMode(); } @@ -415,7 +435,154 @@ } } +/*********************************************************************//** + * @brief + * The updateConfirmationRequestTimeouts function checks the status of + * all active confirmation requests and updates the timeout. + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] status updated if timeout. + * @param none + * @return none + *************************************************************************/ +void updateConfirmationRequestTimeouts( void ) +{ + U08 i; + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( CONFIRMATION_REQUEST_STATUS_PENDING == confirmRequests[ i ].status ) + { + if ( TRUE == didTimeout( confirmRequests[ i ].timeStamp, CONFIRMATION_REQUEST_TIMEOUT_MS ) ) + { + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_TIMEOUT; + } + } + } +} + +/*********************************************************************//** + * @brief + * The getConfirmationRequestStatus function returns the status of a confirmation request + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] cleared if completed. + * @param request ID + * @return CONFIRMATION_REQUEST_STATUS_T + *************************************************************************/ +CONFIRMATION_REQUEST_STATUS_T getConfirmationRequestStatus( GENERIC_CONFIRM_ID_T request_id ) +{ + U08 i; + CONFIRMATION_REQUEST_STATUS_T status = CONFIRMATION_REQUEST_STATUS_PENDING; + BOOL pending = FALSE; + U08 pending_index = 0; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].requestID == request_id ) + { + status = confirmRequests[ i ].status; + if ( CONFIRMATION_REQUEST_STATUS_PENDING != status) + { + // Send UI clear + if ( CONFIRMATION_REQUEST_STATUS_TIMEOUT == confirmRequests[ i ].status ) + { + sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_TIMEOUT_CLOSE, 0 ); + } + else + { + sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_ACCEPT_CLOSE, 0 ); + } + + // Clear the confirmation request, it is done and consumed + confirmRequests[ i ].requestID = GENERIC_CONFIRM_ID_NONE; + confirmRequests[ i ].requestType = GENERIC_CONFIRM_CMD_REQUEST_OPEN; + confirmRequests[ i ].timeStamp = 0; + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_UNUSED; + } + } + else if ( CONFIRMATION_REQUEST_STATUS_PENDING == confirmRequests[ i ].status ) + { + if ( TRUE == pending ) + { + // Is this newer than other pending request? + if ( confirmRequests[ i ].timeStamp > confirmRequests[ pending_index ].timeStamp ) + { + pending_index = i; + pending = TRUE; + } + } + else + { + pending_index = i; + pending = TRUE; + } + } + } + if ( ( CONFIRMATION_REQUEST_STATUS_PENDING != status ) && ( TRUE == pending ) ) + { + // Last confirmation cleared, pending request must be resent to UI + sendConfirmationRequest( confirmRequests[ pending_index ].requestID, confirmRequests[ pending_index ].requestType, 0 ); + } + + return status; +} + +/*********************************************************************//** + * @brief + * The setConfirmationRequestStatus function sets the status of a confirmation request + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] status. + * @param request ID + * @param new status + * @return CONFIRMATION_REQUEST_STATUS_T + *************************************************************************/ +void setConfirmationRequestStatus( GENERIC_CONFIRM_ID_T request_id, CONFIRMATION_REQUEST_STATUS_T status ) +{ + U08 i; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].requestID == request_id ) + { + confirmRequests[ i ].status = status; + break; + } + } +} + +/*********************************************************************//** + * @brief + * The addConfirmationRequest function sends a confirmation request to UI + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] new added. + * @param request_id - confirm id / type + * @param request_type - confirm command + * @return request ID - will be non-zero if added + *************************************************************************/ +GENERIC_CONFIRM_ID_T addConfirmationRequest( GENERIC_CONFIRM_ID_T request_id, GENERIC_CONFIRM_COMMAND_T request_type, U32 reject_reason ) +{ + U08 i; + GENERIC_CONFIRM_ID_T new_id = GENERIC_CONFIRM_ID_NONE; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].status == CONFIRMATION_REQUEST_STATUS_UNUSED ) + { + // Save the confirmation request info + confirmRequests[ i ].requestID = request_id; + confirmRequests[ i ].requestType = request_type; + confirmRequests[ i ].timeStamp = getMSTimerCount(); + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_PENDING; + new_id = request_id; + sendConfirmationRequest( request_id, request_type, reject_reason ); + + break; + } + } + + return new_id; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r549fea9aba0bc5bc03d195d1a5659261e3ace9d0 -r0589eeee132373075cccc56eab04db2b5160ae81 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 549fea9aba0bc5bc03d195d1a5659261e3ace9d0) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 0589eeee132373075cccc56eab04db2b5160ae81) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.c * -* @author (last) Dara Navaei -* @date (last) 22-Sep-2022 +* @author (last) Dong Nguyen +* @date (last) 27-Sep-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -44,6 +44,7 @@ #include "Valves.h" #include "WatchdogMgmt.h" #include "HDDefs.h" +#include "TaskPriority.h" /** * @addtogroup SystemCommMessages @@ -63,9 +64,9 @@ #pragma pack(pop) // ********** private data ********** - static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether an external tester (connected PC) has sent a valid login message. static volatile U16 nextSeqNo = 1; ///< Value of sequence number to use for next transmitted message. + /// List of message IDs that are requested not to be transmitted. static BLOCKED_MSGS_DATA_T blockedMessagesForXmit = { 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -2309,17 +2310,36 @@ *************************************************************************/ void handleLoadCellReadingsFromDG( MESSAGE_T *message ) { - if ( message->hdr.payloadLen == sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ) + if ( message->hdr.payloadLen == sizeof( LOAD_CELL_DATA_T ) ) { - LOAD_CELL_READINGS_PAYLOAD_T payload; + LOAD_CELL_DATA_T payload; - memcpy( &payload, message->payload, sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ); - setNewLoadCellReadings( payload.res1PrimaryLoadCell, payload.res1BackupLoadCell, payload.res2PrimaryLoadCell, payload.res2BackupLoadCell ); + memcpy( &payload, message->payload, sizeof( LOAD_CELL_DATA_T ) ); + setNewLoadCellReadings( payload.loadCellA1inGram, payload.loadCellA2inGram, payload.loadCellB1inGram, payload.loadCellB2inGram ); } } /*********************************************************************//** * @brief + * The handleDGHeatersData function handles the heaters data reading from DG. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGHeatersData( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof( HEATERS_DATA_T ) ) + { + HEATERS_DATA_T payload; + + memcpy( &payload, message->payload, sizeof( HEATERS_DATA_T ) ); + setDGHeatersData( &payload ); + } +} + +/*********************************************************************//** + * @brief * The handleDGTemperatureData function handles a temperature readings * broadcast message from the DG. * @details Inputs: none @@ -2336,8 +2356,6 @@ memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); } - // TODO - what to do if invalid payload length? - // TODO - how to know if DG stops sending these? } /*********************************************************************//** @@ -2351,12 +2369,12 @@ *************************************************************************/ void handleDialysateFlowData( MESSAGE_T *message ) { - if ( message->hdr.payloadLen == sizeof( DIALYSATE_FLOW_METER_DATA_T ) ) + if ( message->hdr.payloadLen == sizeof( FLOW_SENSORS_DATA_T ) ) { - DIALYSATE_FLOW_METER_DATA_T payload; + FLOW_SENSORS_DATA_T payload; - memcpy( &payload, message->payload, sizeof( DIALYSATE_FLOW_METER_DATA_T ) ); - setDialysateFlowData( payload.measuredDialysateFlowRate ); + memcpy( &payload, message->payload, sizeof( FLOW_SENSORS_DATA_T ) ); + setDialysateFlowData( payload.dialysateFlowRateLPM ); } } @@ -3187,23 +3205,26 @@ { MESSAGE_T msg; HD_SERVICE_RECORD_T service; + DG_SERVICE_AND_USAGE_DATA_T dgData; getNVRecord2Driver( GET_SRV_RECORD, (U08*)&service, sizeof( HD_SERVICE_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + getHDVersionDGServiceAndUsageData( &dgData ); U08 *payloadPtr = msg.payload; - if ( message->hdr.payloadLen == sizeof( U32 ) + sizeof( U32 ) ) - { - // Create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_HD_SERVICE_SCHEDULE_DATA; - msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SERVICE_SCHEDULE_DATA; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); - // Fill message payload - memcpy( payloadPtr, &service.lastServiceEpochDate, sizeof( U32 ) ); - payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, &service.serviceIntervalSeconds, sizeof( U32 ) ); - } + // Fill message payload + memcpy( payloadPtr, &service.lastServiceEpochDate, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &service.serviceIntervalSeconds, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &dgData.dgServiceRecord.lastServiceDateEpoch, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &dgData.dgServiceRecord.serviceIntervalSeconds, sizeof( U32 ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); @@ -5129,6 +5150,7 @@ if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) { result = testSetBatteryRemainingPercentOverride( payload.state.u32 ); @@ -7093,6 +7115,96 @@ } /*********************************************************************//** + * @brief + * The sendDGUsageInfoRequestToDG function constructs a request msg + * to the DG to request the DG usage info and queues the msg for transmit + * on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG usage info result request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGUsageInfoRequestToDG( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_USAGE_INFO; + msg.hdr.payloadLen = 0; + + // 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_HD_2_DG, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendDGServiceRequestToDG function constructs a request msg + * to the DG to request the DG service record and queues the msg for transmit + * on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG usage info result request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGServiceRequestToDG( void ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_SERVICE_RECORD; + msg.hdr.payloadLen = 0; + + // 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_HD_2_DG, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleDGServiceScheduleData function receives the HD version of the + * DG service record. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGServiceScheduleData( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof( HD_VERSION_DG_SERVICE_RECORD_T ) ) + { + HD_VERSION_DG_SERVICE_RECORD_T payload; + + memcpy( &payload, message->payload, sizeof( HD_VERSION_DG_SERVICE_RECORD_T ) ); + setHDVersionDGServiceRecord( &payload ); + } +} + +/*********************************************************************//** + * @brief + * The handleDGUsageInfoData function receives the HD version of the + * DG usage info. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGUsageInfoData( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof( HD_VERSION_DG_USAGE_INFO_T ) ) + { + HD_VERSION_DG_USAGE_INFO_T payload; + + memcpy( &payload, message->payload, sizeof( HD_VERSION_DG_USAGE_INFO_T ) ); + setHDVersionDGUsageInfo( &payload ); + } +} + +/*********************************************************************//** * @brief * The handleGetHDUsageInfoRecord function handles a request to get the HD * usage information record. @@ -7326,6 +7438,88 @@ } /*********************************************************************//** +* @brief +* The handleTestBloodPumpSetPWM function handles a request to override +* the Blood pumps duty cycle. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleTestBloodPumpSetPWM( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( F32 ) ); + + result = testSetBloodPumpTargetDutyCycle( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleTestDialInSetPWM function handles a request to override +* the Dialysate Inlet pumps duty cycle. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleTestDialInSetPWM( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( F32 ) ); + + result = testSetDialInPumpTargetDutyCycle( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleTestDialOutSetPWM function handles a request to override +* the Dialysate Outlet pumps duty cycle. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleTestDialOutSetPWM( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + F32 payLoad; + + memcpy( &payLoad, message->payload, sizeof( F32 ) ); + + result = testSetDialOutPumpTargetDutyCycle( payLoad ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + + +/*********************************************************************//** * @brief * The handleUIConfirmationResponse function handles a UI response for * confirmation request. Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r549fea9aba0bc5bc03d195d1a5659261e3ace9d0 -r0589eeee132373075cccc56eab04db2b5160ae81 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 549fea9aba0bc5bc03d195d1a5659261e3ace9d0) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 0589eeee132373075cccc56eab04db2b5160ae81) @@ -136,15 +136,18 @@ void handleUIPOSTFinalResult( MESSAGE_T *message ); // MSG_ID_LOAD_CELL_READINGS -void handleLoadCellReadingsFromDG( MESSAGE_T *message ); +void handleLoadCellReadingsFromDG( MESSAGE_T *message ); + +// MSG_ID_DG_HEATERS_DATA +void handleDGHeatersData( MESSAGE_T *message ); // MSG_ID_DG_TEMPERATURE_DATA: void handleDGTemperatureData( MESSAGE_T *message ); // MSG_ID_RO_PUMP_DATA: void handleROPumpData( MESSAGE_T *message ); -// MSG_ID_DG_DIALYSATE_FLOW_METER_DATA: +// MSG_ID_DG_FLOW_SENSORS_DATA void handleDialysateFlowData( MESSAGE_T *message ); // MSG_ID_DRAIN_PUMP_DATA: @@ -439,6 +442,18 @@ // MSG_ID_HD_REQUEST_DG_ALARMS BOOL sendRequestForDGResendAlarms( void ); +// MSG_ID_HD_REQUEST_DG_USAGE_INFO +BOOL sendDGUsageInfoRequestToDG( void ); + +// MSG_ID_HD_REQUEST_DG_SERVICE_INFO +BOOL sendDGServiceRequestToDG( void ); + +// MSG_ID_DG_SERVICE_SCHEDULE_DATA +void handleDGServiceScheduleData( MESSAGE_T *message ); + +// MSG_ID_DG_USAGE_DATA +void handleDGUsageInfoData( MESSAGE_T *message ); + // *********** public test support message functions ********** // MSG_TESTER_LOG_IN @@ -814,6 +829,15 @@ // MSG_ID_HD_SEND_BLOOD_LEAK_EMB_MODE_RESPONSE BOOL sendBloodLeakEmbeddedModeCommandResponse( U32 responseLen, U08* response ); +// MSG_ID_HD_BLOOD_PUMP_SET_PWM +void handleTestBloodPumpSetPWM( MESSAGE_T* message ); + +// MSG_ID_HD_DIAL_IN_SET_PWM +void handleTestDialInSetPWM( MESSAGE_T* message ); + +// MSG_ID_HD_DIAL_OUT_SET_PWM +void handleTestDialOutSetPWM( MESSAGE_T* message ); + /**@}*/ #endif