Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rfb20c66bc03db53965d23a4af8ef1b06e88f3a83 -r23ad90c3d5f08e67a1142a68c73d79fedb752da9 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision fb20c66bc03db53965d23a4af8ef1b06e88f3a83) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 23ad90c3d5f08e67a1142a68c73d79fedb752da9) @@ -25,6 +25,7 @@ #include "Dialysis.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "Reservoirs.h" #include "Rinseback.h" @@ -244,6 +245,9 @@ initTreatmentRecirc(); initTreatmentEnd(); + // Started the treatment set the start time in epoch + setTxLastStartTimeEpoch( getRTCTimestamp() ); + return currentTreatmentState; } @@ -822,6 +826,7 @@ static TREATMENT_STATE_T handleTreatmentStopState( void ) { TREATMENT_STATE_T result = TREATMENT_STOP_STATE; + BOOL leavingTreatmentStopState = TRUE; // If user requests resumption of treatment, resume treatment if ( TRUE == resumeTreatmentAlarmResponseRequest ) @@ -857,8 +862,19 @@ { execReservoirs(); execTreatmentStop(); + leavingTreatmentStopState = FALSE; } + // If leaving treatment stop state, zero alarm countdown timer for UI + if ( TRUE == leavingTreatmentStopState ) + { + TREATMENT_STOP_PAYLOAD_T data; + + data.timeout = 0; + data.countdown = 0; + broadcastData( MSG_ID_HD_TREATMENT_STOP_TIMER_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( TREATMENT_STOP_PAYLOAD_T ) ); + } + return result; } Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r623ee38d3e18eb0f400b3070deae21bcade56ec7 -r23ad90c3d5f08e67a1142a68c73d79fedb752da9 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 623ee38d3e18eb0f400b3070deae21bcade56ec7) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 23ad90c3d5f08e67a1142a68c73d79fedb752da9) @@ -63,8 +63,8 @@ #define CLR_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 &= ~BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to disable backup alarm audio. #define ALARM_AUDIO_TEST_TONE 4 ///< Alarm audio state for continuous test tone. -#define ALARM_AUDIO_CURRENT_HG_MIN_MA 20.0 ///< Minimum audio current (high gain) during test tone self-test (in mA). // TODO - Why is HG so low? S/B same as LG I think. -#define ALARM_AUDIO_CURRENT_LG_MIN_MA 60.0 ///< Minimum audio current (low gain) during test tone self-test (in mA). +#define ALARM_AUDIO_CURRENT_HG_MIN_MA 20.0F ///< Minimum audio current (high gain) during test tone self-test (in mA). // TODO - Why is HG so low? S/B same as LG I think. +#define ALARM_AUDIO_CURRENT_LG_MIN_MA 60.0F ///< Minimum audio current (low gain) during test tone self-test (in mA). #define ALARM_AUDIO_MAX_TEST_TIME_MS 1000 ///< Maximum time for audio current to reach threshold in test. #define MAX_ALARM_AUDIO_VOLUME_INDEX (MAX_ALARM_VOLUME_LEVEL - 1 ) ///< Index for maximum alarm audio volume. #define MIN_ALARM_AUDIO_VOLUME_INDEX 0 ///< Index for minimum alarm audio volume. @@ -247,8 +247,10 @@ // Verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { - // No need to do anything if alarm is already active - if ( FALSE == alarmIsActive[ alarm ] ) + // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm + if ( ( FALSE == alarmIsActive[ alarm ] ) || + ( ( FALSE == alarmIsDetected[ alarm ] ) && + ( FALSE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) ) ) { // If alarm status was that no alarms currently active, set this alarm as top alarm until status formally updated later if ( ALARM_ID_NO_ALARM == alarmStatus.alarmTop ) @@ -370,10 +372,12 @@ // Clear alarm condition and broadcast alarm condition clear if not already cleared if ( TRUE == alarmIsDetected[ alarm ] ) { - U32 a = (U32)alarm; + ALARM_ID_DATA_PUBLISH_T data; + data.alarmID = (U32)alarm; + alarmIsDetected[ alarm ] = FALSE; - broadcastData( MSG_ID_ALARM_CONDITION_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&a, sizeof( U32 ) ); + broadcastData( MSG_ID_ALARM_CONDITION_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); } } } @@ -399,9 +403,11 @@ // Clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmIsActive[ alarm ] ) { - U32 a = (U32)alarm; + ALARM_ID_DATA_PUBLISH_T data; + + data.alarmID = (U32) alarm; - broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&a, sizeof( U32 ) ); + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); alarmIsActive[ alarm ] = FALSE; clearAlarmCondition( alarm ); @@ -918,6 +924,7 @@ else { if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) +#ifndef _RELEASE_ { if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ALARM_AUDIO ) != SW_CONFIG_ENABLE_VALUE ) { @@ -927,6 +934,7 @@ } } else +#endif { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, alarmStatus.alarmsState ) setAlarmAudioState( ALARM_PRIORITY_HIGH, @@ -1494,9 +1502,11 @@ { if ( TRUE == alarmIsActive[ a ] ) { - U32 al = (U32)a; + ALARM_ID_DATA_PUBLISH_T data; - broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&al, sizeof( U32 ) ); + data.alarmID = (U32)a; + + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); alarmIsActive[ a ] = FALSE; alarmStartedAt[ a ].data = 0; // Clear FIFO if this alarm was in it Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r623ee38d3e18eb0f400b3070deae21bcade56ec7 -r23ad90c3d5f08e67a1142a68c73d79fedb752da9 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 623ee38d3e18eb0f400b3070deae21bcade56ec7) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 23ad90c3d5f08e67a1142a68c73d79fedb752da9) @@ -75,7 +75,7 @@ BOOL noDialRecirc; ///< No dialysate re-circulation allowed at this time BOOL ok; ///< Display OK button instead of other options BOOL noMinimize; ///< Prevent user from minimizing the alarm window - BOOL lampOn; ///< The alarm lamp is on + BOOL lampOn; ///< The alarm lamp is on } COMP_ALARM_STATUS_T; /// Record structure for unsigned integer alarm data. @@ -153,8 +153,14 @@ U32 silenceExpiresIn; ///< Silencing of alarms expires in this many seconds U16 alarmsFlags; ///< Bit flags: 1 = true, 0 = false for each bit flag } ALARM_COMP_STATUS_PAYLOAD_T; -#pragma pack(pop) +#pragma pack(pop) +/// Alarm ID data publish +typedef struct +{ + U32 alarmID; ///< Alarm ID. +} ALARM_ID_DATA_PUBLISH_T; + // ********** public function prototypes ********** void initAlarmMgmt( void ); Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r571b60526886063837c36da45c6685cdda9483cc -r23ad90c3d5f08e67a1142a68c73d79fedb752da9 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 571b60526886063837c36da45c6685cdda9483cc) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 23ad90c3d5f08e67a1142a68c73d79fedb752da9) @@ -152,7 +152,9 @@ data[ msgSize++ ] = 0; } +#ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ACK_ERRORS ) != SW_CONFIG_ENABLE_VALUE ) +#endif { // If ACK required, add to pending ACK list if ( TRUE == ackReq ) @@ -2324,7 +2326,7 @@ TEMPERATURE_SENSORS_DATA_T payload; memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); - setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); + setDialysateTemperatureReadings( payload.TDi, payload.TRo ); } // TODO - what to do if invalid payload length? // TODO - how to know if DG stops sending these? @@ -3209,7 +3211,7 @@ void handleHDUsageInfoRequest( MESSAGE_T *message ) { MESSAGE_T msg; - U32 payload = getTreatmentTime(); + U32 payload = 0; U08 *payloadPtr = msg.payload; // Create a message record @@ -5150,6 +5152,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 ); @@ -5846,6 +5849,7 @@ TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; BOOL result = FALSE; +#ifndef _RELEASE_ // Verify payload length if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) { @@ -5859,6 +5863,7 @@ result = testResetValvesCurrentOverride( payload.index ); } } +#endif // Respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); @@ -5911,6 +5916,7 @@ TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; BOOL result = FALSE; +#ifndef _RELEASE_ // Verify payload length if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) { @@ -5924,6 +5930,7 @@ result = testResetValvesPositionCountOverride( payload.index ); } } +#endif // Respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); @@ -6808,39 +6815,6 @@ /*********************************************************************//** * @brief - * The handleTestFansRPMAlarmStartTimeOverrideRequest function handles a - * request to override the fan RPM alarm start time. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleTestFansRPMAlarmStartTimeOffsetOverrideRequest( 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 = testSetFanRPMAlarmStartTimeOffsetOverride( payload.state.u32 ); - } - else - { - result = testResetFanRPMAlarmStartTimeOffsetOverride(); - } - } - - // Respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** - * @brief * The handleSetFansDutyCycleOverrideRequest function handles a * request to override the fans duty cycle. * @details Inputs: none @@ -6918,6 +6892,33 @@ /*********************************************************************//** * @brief + * The handleTestFansRPMAlarmStartTimeOffsetRequest function handles a + * request to set the fans RPM alarm start time offset. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestFansRPMAlarmStartTimeOffsetRequest( MESSAGE_T *message ) +{ + U32 rpmTimeOffset; + + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(U32) == message->hdr.payloadLen ) + { + memcpy( &rpmTimeOffset, message->payload, sizeof(U32) ); + + result = testSetFanRPMAlarmStartTimestamp( rpmTimeOffset ); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The sendHDSWConfigRecord function sends out the HD software configuration record. * @details Inputs: none * @details Outputs: HD software configuration record msg constructed and queued @@ -7018,4 +7019,106 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); } +/*********************************************************************//** +* @brief +* The handleGetHDUsageInfoRecord function handles a request to get the HD +* usage information record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetHDUsageInfoRecord( 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 handleSetHDUsageInfoRecord function handles a request to set the HD +* information record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetHDUsageInfoRecord( 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 handleSendHDUsageInfoRecord( 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_HD_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; +} + /**@}*/