Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r15919f0c12c0047d3b6331c1f97cdad1dafb3f1b -rb66c3225a5845574b9a4214b391fff4b213e7298 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 15919f0c12c0047d3b6331c1f97cdad1dafb3f1b) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision b66c3225a5845574b9a4214b391fff4b213e7298) @@ -7,8 +7,8 @@ * * @file BloodFlow.c * -* @author (last) Sean Nash -* @date (last) 09-Aug-2022 +* @author (last) Michael Garthwaite +* @date (last) 12-Oct-2022 * * @author (original) Sean Nash * @date (original) 07-Nov-2019 @@ -110,6 +110,8 @@ #define BP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR + BP_PWM_ZERO_OFFSET ) /// Conversion from PWM duty cycle % to commanded pump motor speed. #define BP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - BP_PWM_ZERO_OFFSET) * 4000.0F ) +/// Conversion macro from mL/min to estimated PWM duty cycle %. +#define BP_ML_PER_MIN_FROM_PWM(pwm) ( ( ( pwm - BP_PWM_ZERO_OFFSET ) / ( BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR ) ) ) /// Measured blood flow is filtered w/ moving average. #define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 1 ) @@ -1640,5 +1642,27 @@ return result; } + +/*********************************************************************//** + * @brief + * The testSetBloodPumpTargetDutyCycle function sets the duty cycle of the + * blood pump by calling setBloodPumpTargetFlowRate. + * @details Inputs: none + * @details Outputs: none + * @param value duty cycle of the blood pump (as a percentage). + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testSetBloodPumpTargetDutyCycle( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + setBloodPumpTargetFlowRate( (U32)BP_ML_PER_MIN_FROM_PWM( value ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + result = TRUE; + } + + return result; +} /**@}*/ Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -ra4e044315bbfaaeff11cb9391485897458a48a5f -rb66c3225a5845574b9a4214b391fff4b213e7298 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision a4e044315bbfaaeff11cb9391485897458a48a5f) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision b66c3225a5845574b9a4214b391fff4b213e7298) @@ -77,8 +77,8 @@ static const U32 DIP_OFF_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); /// Persist time (task intervals) motor speed error condition. static const U32 DIP_MOTOR_SPEED_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); -/// Persist time (task intervals) rotor speed error condition. -static const U32 DIP_ROTOR_SPEED_ERROR_PERSIST = ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Rotor speed persist time test needs a minimum number of rotations. +static const U32 DIP_ROTOR_ERROR_PERSIST_ROTATION_MIN = 3; /// Persist time (task intervals) pump direction error condition. static const U32 DIP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); /// Persist time (task intervals) dialysate flow rate out of range error condition. @@ -883,6 +883,28 @@ return result; } +/*********************************************************************//** + * @brief + * The getPumpRotorErrorPersistTime function calculates the Rotor error persist time. + * @details Inputs: none + * @details Outputs: none + * @param mtr_rpm, RPM of the motor. + * gear_ratio, Gear ratio of motor vs motor + * @return Persistent error test time in (ms) + *************************************************************************/ +U32 getPumpRotorErrorPersistTime( F32 mtr_rpm, F32 gear_ratio ) +{ + U32 err_persist_time = HEX_32_BIT_FULL_SCALE; // 49 days + + if ( mtr_rpm > 0 ) + { + /// Calculate persist time for rotor speed error condition. + err_persist_time = ( ( DIP_ROTOR_ERROR_PERSIST_ROTATION_MIN / ( mtr_rpm / gear_ratio / SEC_PER_MIN ) ) * MS_PER_SECOND ); + } + + return err_persist_time; +} + /*********************************************************************//** * @brief * The publishDialInFlowData function publishes dialIn flow data at the set @@ -1133,7 +1155,7 @@ F32 cmdMotorSpeed = DIP_PWM_TO_MOTOR_SPEED_RPM( dialInPumpPWMDutyCyclePctSet ); F32 deltaMotorSpeed = fabs( measMotorSpeed - cmdMotorSpeed ); F32 deltaMCMotorSpeed = fabs( measMCMotorSpeed - cmdMotorSpeed ); - F32 measRotorSpeed = getMeasuredDialInPumpRotorSpeed(); + F32 measRotorSpeed = fabs( getMeasuredDialInPumpRotorSpeed() ); F32 measMotorSpeedInRotorRPM = measMotorSpeed / DIP_GEAR_RATIO; F32 deltaRotorSpeed = fabs( measRotorSpeed - measMotorSpeedInRotorRPM ); @@ -1158,7 +1180,7 @@ // Check measured rotor speed vs. measured motor speed while controlling to target if ( deltaRotorSpeed > DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM ) { - if ( ++errorDialInRotorSpeedPersistTimerCtr >= DIP_ROTOR_SPEED_ERROR_PERSIST ) + if ( ++errorDialInRotorSpeedPersistTimerCtr >= ( getPumpRotorErrorPersistTime( measMotorSpeed, DIP_GEAR_RATIO ) / TASK_PRIORITY_INTERVAL ) ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_SPEED_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) Index: firmware/App/Controllers/DialInFlow.h =================================================================== diff -u -r15919f0c12c0047d3b6331c1f97cdad1dafb3f1b -rb66c3225a5845574b9a4214b391fff4b213e7298 --- firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision 15919f0c12c0047d3b6331c1f97cdad1dafb3f1b) +++ firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision b66c3225a5845574b9a4214b391fff4b213e7298) @@ -7,8 +7,8 @@ * * @file DialInFlow.h * -* @author (last) Darren Cox -* @date (last) 10-Mar-2022 +* @author (last) Michael Garthwaite +* @date (last) 28-Sep-2022 * * @author (original) Sean * @date (original) 16-Dec-2019 @@ -84,7 +84,8 @@ BOOL testSetMeasuredDialInPumpMCSpeedOverride( F32 value ); BOOL testResetMeasuredDialInPumpMCSpeedOverride( void ); BOOL testSetMeasuredDialInPumpMCCurrentOverride( F32 value ); -BOOL testResetMeasuredDialInPumpMCCurrentOverride( void ); +BOOL testResetMeasuredDialInPumpMCCurrentOverride( void ); +BOOL testSetDialInPumpTargetDutyCycle( F32 value ); /**@}*/ Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r15919f0c12c0047d3b6331c1f97cdad1dafb3f1b -rb66c3225a5845574b9a4214b391fff4b213e7298 --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 15919f0c12c0047d3b6331c1f97cdad1dafb3f1b) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision b66c3225a5845574b9a4214b391fff4b213e7298) @@ -7,8 +7,8 @@ * * @file DialOutFlow.c * -* @author (last) Dara Navaei -* @date (last) 01-Sep-2022 +* @author (last) Michael Garthwaite +* @date (last) 12-Oct-2022 * * @author (original) Sean * @date (original) 24-Jan-2020 @@ -103,9 +103,11 @@ #define DOP_PWM_ZERO_OFFSET 0.1F ///< 10% PWM duty cycle = zero speed. /// Macro converts a flow rate to an estimated PWM duty cycle %. -#define DOP_PWM_FROM_ML_PER_MIN(rate) ( ( (rate) * 0.0009 ) + 0.0972 + DOP_PWM_ZERO_OFFSET ) +#define DOP_PWM_FROM_ML_PER_MIN(rate) ( ( ( rate ) * 0.0009F ) + 0.0972F + DOP_PWM_ZERO_OFFSET ) /// Conversion from PWM duty cycle % to commanded pump motor speed. -#define DOP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ((pwm) - DOP_PWM_ZERO_OFFSET) * 4000.0F ) +#define DOP_PWM_TO_MOTOR_SPEED_RPM(pwm) ( ( ( pwm ) - DOP_PWM_ZERO_OFFSET) * 4000.0F ) +/// Macro converts a PWM to an estimated flow rate. +#define DOP_ML_PER_MIN_FROM_PWM(pwm) ( ( ( pwm - DOP_PWM_ZERO_OFFSET ) - 0.0972F ) / 0.0009F ) #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. #define DOP_MIN_DIR_CHECK_SPEED_RPM 10.0F ///< Minimum motor speed before we check pump direction. @@ -1641,4 +1643,32 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetBloodPumpTargetDutyCycle function sets the duty cycle of the + * blood pump by calling setDialOutPumpTargetRate. + * @details Inputs: none + * @details Outputs: none + * @param value duty cycle of the dialysate outlet pump (as a percentage). + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testSetDialOutPumpTargetDutyCycle( F32 value ) +{ + BOOL result = FALSE; + F32 targetPWM = DOP_ML_PER_MIN_FROM_PWM(value) ; + + if ( TRUE == isTestingActivated() ) + { + // currently conversion can create negative values with values <= 10%. + if ( targetPWM < 0 ) + { + targetPWM = 0; + } + setDialOutPumpTargetRate( (U32)targetPWM, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + result = TRUE; + } + + return result; +} + /**@}*/ Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -ra16225ab0fc1c575ad857ccf1dcccdb7a3aa8eef -rb66c3225a5845574b9a4214b391fff4b213e7298 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision a16225ab0fc1c575ad857ccf1dcccdb7a3aa8eef) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision b66c3225a5845574b9a4214b391fff4b213e7298) @@ -7,8 +7,8 @@ * * @file SystemComm.c * -* @author (last) Dara Navaei -* @date (last) 22-Sep-2022 +* @author (last) Michael Garthwaite +* @date (last) 12-Oct-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -55,7 +55,10 @@ #define MSG_NOT_ACKED_MAX_RETRIES 20 ///< Maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm #define PENDING_ACK_LIST_SIZE 25 ///< Maximum number of Denali messages that can be pending ACK at any given time - + +#define MAX_FPGA_CLOCK_SPEED_ERRORS 3 ///< maximum number of FPGA clock speed errors within window period before alarm +#define MAX_FPGA_CLOCK_SPEED_ERROR_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< FPGA clock speed error window + #pragma pack(push, 1) /// Record for transmitted message that is pending acknowledgment from receiver. @@ -142,6 +145,9 @@ // Initialize bad message CRC time windowed count initTimeWindowedCount( TIME_WINDOWED_COUNT_BAD_MSG_CRC, MAX_COMM_CRC_FAILURES, MAX_COMM_CRC_FAILURE_WINDOW_MS ); + + // Initialize FPGA clock speed error time windowed count + initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CLOCK_SPEED_ERROR, MAX_FPGA_CLOCK_SPEED_ERRORS, MAX_FPGA_CLOCK_SPEED_ERROR_WINDOW_MS); // Initialize pending ACK list for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) @@ -256,7 +262,7 @@ * @return none *************************************************************************/ void execSystemCommRx( void ) -{ +{ // Parse messages from comm buffers and queue them processIncomingData(); @@ -698,7 +704,7 @@ { BOOL isThereMsgRcvd = TRUE; // Assume TRUE at first to get into while loop MESSAGE_WRAPPER_T message; - + while ( TRUE == isThereMsgRcvd ) { // See if any messages received @@ -1654,6 +1660,18 @@ handleTestCurrentTreamtmentParametersRequest( message ); break; + case MSG_ID_HD_BLOOD_PUMP_SET_PWM: + handleTestBloodPumpSetPWM( message ); + break; + + case MSG_ID_HD_DIAL_IN_SET_PWM: + handleTestDialInSetPWM( message ); + break; + + case MSG_ID_HD_DIAL_OUT_SET_PWM: + handleTestDialOutSetPWM( message ); + break; + // The default cannot be reached in VectorCAST since the cases are run in a for loop default: // Unrecognized message ID received - ignore Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -ra4e044315bbfaaeff11cb9391485897458a48a5f -rb66c3225a5845574b9a4214b391fff4b213e7298 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a4e044315bbfaaeff11cb9391485897458a48a5f) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision b66c3225a5845574b9a4214b391fff4b213e7298) @@ -36,6 +36,7 @@ #include "SystemComm.h" #include "SystemCommMessages.h" #include "Temperatures.h" +#include "Timers.h" #include "TreatmentEnd.h" #include "TreatmentRecirc.h" #include "TreatmentStop.h" @@ -3235,7 +3236,73 @@ serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); } +/*********************************************************************//** + * @brief + * The handleUIConfirmationResponse function handles a UI response for + * confirmation request. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleUIConfirmationResponse( MESSAGE_T *message ) +{ + BOOL result = FALSE; + U08* payloadPtr = message->payload; + if ( message->hdr.payloadLen == 2 * sizeof(U32) ) + { + U32 request_id; + U32 status; + + memcpy( &request_id, payloadPtr, sizeof(U32) ); + payloadPtr += sizeof(U32); + memcpy( &status, payloadPtr, sizeof(U32) ); + + if ( ( CONFIRMATION_REQUEST_STATUS_REJECTED == status ) || + ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == status ) ) + { + setConfirmationRequestStatus( (GENERIC_CONFIRM_ID_T) request_id, (CONFIRMATION_REQUEST_STATUS_T) status ); + } + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); +} + +/*********************************************************************//** + * @brief + * The sendConfirmationRequest function sends a confirmation request to UI + * @details Inputs: none + * @details Outputs: none + * @param request ID + * @param request type + * @param reject reason + * @return request ID - will be non-zero if sent + *************************************************************************/ +void sendConfirmationRequest( GENERIC_CONFIRM_ID_T request_id, GENERIC_CONFIRM_COMMAND_T request_type, U32 reject_reason ) +{ + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + U32 temp_request = request_id; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_UI_CONFIRMATION; + // The payload length is U32 Request ID, U32 Type, U32 Reject Reason + msg.hdr.payloadLen = 3 * sizeof( U32 ); + + memcpy( payloadPtr, &temp_request, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + temp_request = request_type; + memcpy( payloadPtr, &temp_request, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &reject_reason, 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_NOT_REQUIRED ); +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r6a5da69ce3b1048fbbccb766df391eb6dcc1010c -rb66c3225a5845574b9a4214b391fff4b213e7298 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 6a5da69ce3b1048fbbccb766df391eb6dcc1010c) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision b66c3225a5845574b9a4214b391fff4b213e7298) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.h * -* @author (last) Dara Navaei -* @date (last) 22-Sep-2022 +* @author (last) Michael Garthwaite +* @date (last) 28-Sep-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -815,6 +815,18 @@ // MSG_ID_HD_SEND_BLOOD_LEAK_EMB_MODE_RESPONSE BOOL sendBloodLeakEmbeddedModeCommandResponse( U32 responseLen, U08* response ); +// MSG_ID_HD_SEND_ALARMS_COMMAND +void handleResendAllAlarmsCommand( MESSAGE_T* message ); + +// 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