Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r9df8618dfd95d3af354e6cbb590ebe6f6fd7ccdd -r6e07046677cba738be6f78b155f4f23120a43081 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 9df8618dfd95d3af354e6cbb590ebe6f6fd7ccdd) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 6e07046677cba738be6f78b155f4f23120a43081) @@ -14,8 +14,9 @@ * @date (original) 08-Apr-2020 * ***************************************************************************/ - + #include "DialInFlow.h" +#include "DGDefs.h" #include "ModeTreatment.h" #include "OperationModes.h" #include "SystemCommMessages.h" @@ -105,6 +106,9 @@ static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. static U32 resUseTimer = 0; ///< Used to track time pumping from active reservoir (for volume used calculation). static F32 resUseVolumeMl = 0.0; ///< Accumulated volume used from active reservoir. + +// DG command response +static DG_CMD_RESPONSE_T dgCmdResp; ///< Used to keep the latest DG command response. // ********** private function prototypes ********** @@ -151,6 +155,11 @@ lgLoadCellReadings[ i ][ j ] = 0.0; } } + + dgCmdResp.commandID = DG_CMD_NONE; + dgCmdResp.rejected = TRUE; + dgCmdResp.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; + smLoadCellReadingsIdx = 0; smLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; smLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; @@ -735,7 +744,8 @@ *************************************************************************/ void cmdStartDGTrimmerHeater( void ) { - dgTrimmerHeaterOn = TRUE; + dgTrimmerHeaterOn = TRUE; + dgCmdResp.commandID = DG_CMD_NONE; sendDGStartStopTrimmerHeaterCommand( START_DG_CMD ); } @@ -749,7 +759,8 @@ *************************************************************************/ void cmdStopDGTrimmerHeater( void ) { - dgTrimmerHeaterOn = FALSE; + dgTrimmerHeaterOn = FALSE; + dgCmdResp.commandID = DG_CMD_NONE; sendDGStartStopTrimmerHeaterCommand( STOP_DG_CMD ); } @@ -766,7 +777,8 @@ { if ( resID < NUM_OF_DG_RESERVOIRS ) { - dgActiveReservoirSet = resID; + dgActiveReservoirSet = resID; + dgCmdResp.commandID = DG_CMD_NONE; sendDGSwitchReservoirCommand( (U32)resID ); } else @@ -784,7 +796,8 @@ * @return none *************************************************************************/ void cmdStartDGFill( U32 fillToVolMl ) -{ +{ + dgCmdResp.commandID = DG_CMD_NONE; dgReservoirFillVolumeTargetSet = fillToVolMl; sendDGFillCommand( fillToVolMl ); } @@ -802,6 +815,7 @@ { DRAIN_RESERVOIR_CMD_PAYLOAD_T payload; + dgCmdResp.commandID = DG_CMD_NONE; payload.drainToVolumeML = drainToVolMl; payload.tareLoadCells = tareLoadCell; dgReservoirDrainVolumeTargetSet = drainToVolMl; @@ -821,7 +835,38 @@ sendDGSampleWaterCommand(); } +/*********************************************************************//** + * @brief + * The handleDGCommandResponse function processes the latest DG command response. + * @details Inputs: none + * @details Outputs: process command response from DG + * @param cmdRespPtr pointer to DG command response data record + * @return none + *************************************************************************/ +void handleDGCommandResponse( U08 *cmdRespPtr ) +{ + memcpy( &dgCmdResp, cmdRespPtr, sizeof( DG_CMD_RESPONSE_T ) ); + if ( ( TRUE == dgCmdResp.rejected ) && ( DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER == dgCmdResp.rejectCode ) ) + { + activateAlarmNoData( ALARM_ID_DG_COMMAND_INVALID_PARAMETER_FAULT ); + } +} + +/*********************************************************************//** + * @brief + * The getDGCommandResponse function gets the latest command response from DG. + * @details Inputs: dgCmdResp + * @details Outputs: none + * @param cmdRespPtr pointer to data record to copy DG command response to + * @return none + *************************************************************************/ +void getDGCommandResponse( DG_CMD_RESPONSE_T *cmdRespPtr ) +{ + memcpy( &cmdRespPtr, &dgCmdResp, sizeof( DG_CMD_RESPONSE_T ) ); +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -rf3680ff380d9543102406833a48da5a2d20e6029 -r6e07046677cba738be6f78b155f4f23120a43081 --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision f3680ff380d9543102406833a48da5a2d20e6029) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 6e07046677cba738be6f78b155f4f23120a43081) @@ -123,6 +123,14 @@ BOOL tareLoadCells; } DRAIN_RESERVOIR_CMD_PAYLOAD_T; +/// DG command response data record structure. +typedef struct +{ + U32 commandID; ///< The command DG is responding to + BOOL rejected; ///< Flag indicates if the command has been rejected + U32 rejectCode; ///< Reason code for rejecting the command +} DG_CMD_RESPONSE_T; + // ********** public function prototypes ********** void initDGInterface( void ); @@ -163,6 +171,9 @@ void cmdStopDGTrimmerHeater( void ); void cmdDGSampleWater( void ); +void handleDGCommandResponse( U08 *cmdRespPtr ); +void getDGCommandResponse( DG_CMD_RESPONSE_T *cmdRespPtr ); + BOOL testSetDialOutLoadCellWeightOverride( U32 sensor, F32 value ); BOOL testResetDialOutLoadCellWeightOverride( U32 sensor ); Index: firmware/App/Modes/Prime.c =================================================================== diff -u -rfee71ca73745dad573b28acd13b66624cceeabc0 -r6e07046677cba738be6f78b155f4f23120a43081 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision fee71ca73745dad573b28acd13b66624cceeabc0) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 6e07046677cba738be6f78b155f4f23120a43081) @@ -59,8 +59,10 @@ { PRIME_RESERVOIR_MGMT_START_STATE = 0, ///< If DG not already in re-circ mode, try to get it there. PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE, ///< In DG re-circ, wait for lines to flush - then start draining inactive reservoir. + PRIME_RESERVOIR_MGMT_WAIT_FOR_DRAIN_CMD_RESP, ///< After sending drain command, wait for DG to response back. PRIME_RESERVOIR_MGMT_DRAIN_STATE, ///< Wait for drain to complete. PRIME_RESERVOIR_MGMT_START_FILL_STATE, ///< Command DG to start filling reservoir. + PRIME_RESERVOIR_MGMT_WAIT_FOR_FILL_CMD_RESP, ///< After sending fill command, wait for DG to response back. PRIME_RESERVOIR_MGMT_FILL_STATE, ///< Wait for fill to complete. PRIME_RESERVOIR_MGMT_FILL_COMPLETE_STATE, ///< Reservoir fill has completed. PRIME_RESERVOIR_MGMT_WAIT_RESERVOIR_TWO_INACTIVE, ///< Wait for reservoir 2 become inactive. @@ -89,7 +91,7 @@ // ********** private function prototypes ********** static void broadcastPrimingStatus( void ); -static void execPreTreatmentReservoirMgmt( void ); +static void execPrimeReservoirMgmt( void ); static void purgeAirValvesBloodPumpControl( void ); static HD_PRE_TREATMENT_PRIME_STATE_T handlePrimeSalineSetupState( void ); @@ -196,7 +198,7 @@ broadcastPrimingStatus(); // Exec reservoir management for priming - execPreTreatmentReservoirMgmt(); + execPrimeReservoirMgmt(); } /*********************************************************************//** @@ -243,41 +245,55 @@ /*********************************************************************//** * @brief - * The execPreTreatmentReservoirMgmt function executes the state machine for the - * reservoir management during pre-treatment mode. + * The execPrimeReservoirMgmt function executes the state machine for the + * reservoir management during pre-treatment prime sub-mode. * @details Inputs: currentReservoirMgmtState * @details Outputs: DG reservoirs' fills managed. * @return none *************************************************************************/ -static void execPreTreatmentReservoirMgmt( void ) +static void execPrimeReservoirMgmt( void ) { + DG_CMD_RESPONSE_T dgCmdResp; + + getDGCommandResponse( &dgCmdResp ); DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); + // treatment reservoir mgmt. state machine switch ( currentReservoirMgmtState ) { case PRIME_RESERVOIR_MGMT_START_STATE: + currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE; + break; + + case PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE: if ( DG_MODE_CIRC == dgOpMode ) { - currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE; + if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) + { + currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_WAIT_FOR_DRAIN_CMD_RESP; + cmdStartDGDrain( PRIME_DRAIN_RESERVOIR_TO_VOLUME_ML, TRUE ); + } } else { - cmdStartDG(); + // TODO Handle when DG mode is out of sync } break; - case PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE: - if ( ( DG_MODE_CIRC == dgOpMode ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) ) + case PRIME_RESERVOIR_MGMT_WAIT_FOR_DRAIN_CMD_RESP: + if ( DG_CMD_START_DRAIN == dgCmdResp.commandID ) { - cmdStartDGDrain( PRIME_DRAIN_RESERVOIR_TO_VOLUME_ML, TRUE ); + if ( FALSE == dgCmdResp.rejected ) + { + currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_DRAIN_STATE; + } + else if ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejected ) + { + currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE; + } } - - if ( DG_MODE_DRAI == dgOpMode ) - { - currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_DRAIN_STATE; - } break; case PRIME_RESERVOIR_MGMT_DRAIN_STATE: @@ -290,11 +306,22 @@ case PRIME_RESERVOIR_MGMT_START_FILL_STATE: if ( ( DG_MODE_CIRC == dgOpMode ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) ) { + currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_WAIT_FOR_FILL_CMD_RESP; cmdStartDGFill( PRIME_FILL_RESERVOIR_TO_VOLUME_ML ); } - if ( DG_MODE_FILL == dgOpMode ) + break; + + case PRIME_RESERVOIR_MGMT_WAIT_FOR_FILL_CMD_RESP: + if ( DG_CMD_START_FILL == dgCmdResp.commandID ) { - currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_FILL_STATE; + if ( FALSE == dgCmdResp.rejected ) + { + currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_FILL_STATE; + } + else if ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejected ) + { + currentReservoirMgmtState = PRIME_RESERVOIR_MGMT_START_FILL_STATE; + } } break; Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r911f6526ec3ba03ba0131681c7fb371c0abda6bb -r6e07046677cba738be6f78b155f4f23120a43081 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 911f6526ec3ba03ba0131681c7fb371c0abda6bb) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 6e07046677cba738be6f78b155f4f23120a43081) @@ -1199,6 +1199,10 @@ handleUFVolumeSetRequest( message ); break; + case MSG_ID_DG_COMMAND_RESPONSE: + handleDGCommandResponse( message ); + break; + case MSG_ID_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -re65a2e67337ef5fff12de02db85ba101305fb006 -r6e07046677cba738be6f78b155f4f23120a43081 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision e65a2e67337ef5fff12de02db85ba101305fb006) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 6e07046677cba738be6f78b155f4f23120a43081) @@ -667,10 +667,55 @@ result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_DG, ACK_REQUIRED ); return result; -} +} + +/*********************************************************************//** + * @brief + * The handleDGCmdResp function handles a DG command response message. + * @details Inputs: none + * @details Outputs: message handled, response constructed and queued for transmit. + * @param messagePtr pointer to the message to handle. + * @return none + *************************************************************************/ +void handleDGCmdResp( MESSAGE_T *messagePtr ) +{ + BOOL result = FALSE; + if ( messagePtr->hdr.payloadLen == sizeof( DG_CMD_RESPONSE_T ) ) + { + result = TRUE; + handleDGCommandResponse( &messagePtr->payload ); + } + + sendAckResponseMsg( (MSG_ID_T)messagePtr->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_DG, result ); +} + /*********************************************************************//** * @brief + * The handleDGOpMode function handles a DG broadcast of its current mode. + * @details Inputs: none + * @details Outputs: message handled, response constructed and queued for transmit. + * @param message pointer to the message to handle. + * @return none + *************************************************************************/ +void handleDGOpMode( MESSAGE_T *message ) +{ + U32 payloadSize = sizeof(U32) + sizeof(U32); + + if ( message->hdr.payloadLen == payloadSize ) + { + U32 mode, subMode; + + memcpy( &mode, message->payload, sizeof(U32) ); + memcpy( &subMode, &message->payload[sizeof(U32)], sizeof(U32) ); + + setDGOpMode( mode, subMode ); + checkInFromDG(); // TODO - here until we implement DG check-in w/ HD broadcast + } +} + +/*********************************************************************//** + * @brief * The broadcastAccelData function constructs an accelerometer data msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none @@ -2078,30 +2123,6 @@ /*********************************************************************//** * @brief - * The handleDGOpMode function handles a DG broadcast of its current mode. - * @details Inputs: none - * @details Outputs: message handled, response constructed and queued for transmit. - * @param message a pointer to the message to handle. - * @return none - *************************************************************************/ -void handleDGOpMode( MESSAGE_T *message ) -{ - U32 payloadSize = sizeof(U32) + sizeof(U32); - - if ( message->hdr.payloadLen == payloadSize ) - { - U32 mode, subMode; - - memcpy( &mode, message->payload, sizeof(U32) ); - memcpy( &subMode, &message->payload[sizeof(U32)], sizeof(U32) ); - - setDGOpMode( mode, subMode ); - checkInFromDG(); // TODO - here until we implement DG check-in w/ HD broadcast - } -} - -/*********************************************************************//** - * @brief * The handleFWVersionRequest function handles a request for HD f/w version. * @details Inputs: none * @details Outputs: message handled, response constructed and queued for transmit. Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -re65a2e67337ef5fff12de02db85ba101305fb006 -r6e07046677cba738be6f78b155f4f23120a43081 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision e65a2e67337ef5fff12de02db85ba101305fb006) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 6e07046677cba738be6f78b155f4f23120a43081) @@ -178,13 +178,16 @@ // MSG_ID_STARTING_STOPPING_TREATMENT_CMD BOOL sendDGStartStopCommand( BOOL start ); -// MSG_ID_DG_SAMPLE_WATER_CMD -BOOL sendDGSampleWaterCommand( void ); - // MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD BOOL sendDGStartStopTrimmerHeaterCommand( BOOL start ); -// MSG_ID_DG_OP_MODE: +// MSG_ID_DG_SAMPLE_WATER_CMD +BOOL sendDGSampleWaterCommand( void ); + +// MSG_ID_DG_COMMAND_RESPONSE +void handleDGCmdResp( MESSAGE_T *messagePtr ); + +// MSG_ID_DG_OP_MODE void handleDGOpMode( MESSAGE_T *message ); // MSG_ID_HD_ACCELEROMETER_DATA