Index: firmware/App/Controllers/AirPump.c =================================================================== diff -u -r285b5d82539c96524c93703d52a66fff76fb64fc -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 285b5d82539c96524c93703d52a66fff76fb64fc) +++ firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -101,7 +101,7 @@ * @brief * The getAirPumpState function returns the current air pump state machine. * @details \b Inputs: currentAirPumpState - * @details \b Outputs: currentAirPumpState + * @details \b Outputs: none * @return current state of the air pump state machine. *************************************************************************/ AIR_PUMP_STATE_T getAirPumpState( void ) Index: firmware/App/Controllers/AirPump.h =================================================================== diff -u -r552a7de419344b43a3307c61141c99bfbbee7345 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Controllers/AirPump.h (.../AirPump.h) (revision 552a7de419344b43a3307c61141c99bfbbee7345) +++ firmware/App/Controllers/AirPump.h (.../AirPump.h) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -33,12 +33,14 @@ // ********** public definitions ********** +#pragma pack(push, 1) /// Payload record structure for air pump data broadcast message typedef struct { U32 h12State; ///< Air pump state status U32 h12Power; ///< Air pump power level setting } AIR_PUMP_PAYLOAD_T; +#pragma pack(pop) /// Enumeration of air pump states. typedef enum AirPumpControllerStates Index: firmware/App/Controllers/AirTrap.h =================================================================== diff -u -r285b5d82539c96524c93703d52a66fff76fb64fc -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Controllers/AirTrap.h (.../AirTrap.h) (revision 285b5d82539c96524c93703d52a66fff76fb64fc) +++ firmware/App/Controllers/AirTrap.h (.../AirTrap.h) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -33,6 +33,7 @@ // ********** public definitions ********** +#pragma pack(push, 1) /// Payload record structure for air trap data broadcast message typedef struct { @@ -44,6 +45,7 @@ U32 h20State; ///< Is air trap outlet valve open or closed BOOL isAutoControlling; ///< Flag indicates whether air trap level is being auto controlled } AIR_TRAP_PAYLOAD_T; +#pragma pack(pop) // ********** public function prototypes ********** Index: firmware/App/Controllers/BloodFlow.h =================================================================== diff -u -rf3a26c402a2ec88f5ee7dbb8eb7127ab5b4692aa -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision f3a26c402a2ec88f5ee7dbb8eb7127ab5b4692aa) +++ firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -35,6 +35,7 @@ #define MAX_SET_BLOOD_FLOW_RATE 500 ///< Maximum prescribed blood flow rate (in mL/min). #define MIN_SET_BLOOD_FLOW_RATE 100 ///< Minimum prescribed blood flow rate (in mL/min). +#pragma pack(push, 1) /// Payload record structure for a blood pump data message. typedef struct { @@ -48,6 +49,7 @@ U32 h4PresFlow; ///< Prescribed blood flow in mL/min. U32 h4RotorHallState; ///< Rotor hall state (1=home, 0=not home). } BLOOD_PUMP_STATUS_PAYLOAD_T; +#pragma pack(pop) // ********** public function prototypes ********** Index: firmware/App/Controllers/Ejector.c =================================================================== diff -u --- firmware/App/Controllers/Ejector.c (revision 0) +++ firmware/App/Controllers/Ejector.c (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -0,0 +1,452 @@ +/************************************************************************** +* +* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file Ejector.c +* +* @author (last) Sean +* @date (last) 13-May-2025 +* +* @author (original) Sean +* @date (original) 13-May-2025 +* +***************************************************************************/ + +#include "AlarmMgmtTD.h" +#include "Ejector.h" +#include "Messaging.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "TaskGeneral.h" +#include "Timers.h" + +/** + * @addtogroup Ejector + * @{ + */ + +// ********** private definitions ********** + +#define EJECTOR_RETRACT_OP_INTERVAL ( ( MS_PER_SECOND * 5 ) / TASK_GENERAL_INTERVAL ) ///< Ejector retract operation interval. +#define EJECTOR_EXTEND_OP_INTERVAL ( ( MS_PER_SECOND * 5 ) / TASK_GENERAL_INTERVAL ) ///< Ejector extend operation interval. +#define EJECTOR_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Ejector data publish interval. +#define DATA_PUBLISH_COUNTER_START_COUNT 13 ///< Ejector data publish start counter. + +#define EJECTOR_RETRACT_MOTOR_SPEED_RPM -5000.0F ///< Ejector motor retract speed (in RPM). +#define EJECTOR_EXTEND_MOTOR_SPEED_RPM 5000.0F ///< Ejector motor extend speed (in RPM). +#define EJECTOR_OFF_MOTOR_SPEED_RPM 0.0F ///< Ejector motor extend speed (in RPM). + +/// Enumeration of ejector states. +typedef enum EjectorOperations +{ + EJECTOR_OPERATION_HOME = 0, ///< Ejector home operation + EJECTOR_OPERATION_RETRACT, ///< Ejector retract operation + EJECTOR_OPERATION_EXTEND, ///< Ejector extend operation + NUM_OF_EJECTOR_OPERATIONS, ///< Number of ejector operations +} EJECTOR_OPERATION_T; + +// ********** private data ********** + +static EJECTOR_STATE_T currentEjectorState; ///< Current ejector control state. +static F32 currentEjectorSetSpeed; ///< Current ejector set speed (in RPM). +static U32 ejectorOperationTimerCounter; ///< Ejector operation timer counter (in task intervals). +static U32 ejectorDataPublicationTimerCounter; ///< Ejector data broadcast timer counter (in task intervals). +static OVERRIDE_U32_T ejectorDataPublishInterval; ///< Ejector data broadcast interval (in ms). + +static BOOL ejectorHomeRequested; ///< Flag indicating that ejector home operation is requested. +static BOOL ejectorRetractRequested; ///< Flag indicating that ejector retract operation is requested. +static BOOL ejectorExtendRequested; ///< Flag indicating that ejector extend operation is requested. + +// ********** private function prototypes ********** + +static EJECTOR_STATE_T handleEjectorStartState( void ); +static EJECTOR_STATE_T handleEjectorHomingState( void ); +static EJECTOR_STATE_T handleEjectorRetractedState ( void ); +static EJECTOR_STATE_T handleEjectorExtendedState ( void ); +static EJECTOR_STATE_T handleEjectorRetractingState ( void ); +static EJECTOR_STATE_T handleEjectorExtendingState ( void ); +static void resetEjectorFlags( void ); +static void publishEjectorData( void ); + +/*********************************************************************//** + * @brief + * The initEjector function initializes the air pump driver. + * @details \b Inputs: none + * @details \b Outputs: Air pump driver unit initialized + * @return none + *************************************************************************/ +void initEjector(void) +{ + // Initialize driver + initEjectorMotor(); + + // Initialize controller variables + currentEjectorState = EJECTOR_STATE_INIT; + currentEjectorSetSpeed = EJECTOR_OFF_MOTOR_SPEED_RPM; + resetEjectorFlags(); + ejectorOperationTimerCounter = 0; + ejectorDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + ejectorDataPublishInterval.data = EJECTOR_DATA_PUB_INTERVAL; + ejectorDataPublishInterval.ovData = EJECTOR_DATA_PUB_INTERVAL; + ejectorDataPublishInterval.ovInitData = EJECTOR_DATA_PUB_INTERVAL; + ejectorDataPublishInterval.override = OVERRIDE_RESET; +} + +/*********************************************************************//** + * @brief + * The resetEjectorFlags function resets the ejector flags to FALSE. + * @details \b Inputs: none + * @details \b Outputs: ejectorHomeRequested, ejectorRetractRequested, + * ejectorExtendRequested + * @return none + *************************************************************************/ +static void resetEjectorFlags( void ) +{ + ejectorHomeRequested = FALSE; + ejectorRetractRequested = FALSE; + ejectorExtendRequested = FALSE; +} + +/*********************************************************************//** + * @brief + * The homeEjector function requests an ejector home operation. + * @details \b Inputs: currentEjectorState + * @details \b Outputs: ejectorHomeRequested + * @return TRUE if home command accepted, FALSE if not + *************************************************************************/ +BOOL homeEjector( void ) +{ + BOOL result = FALSE; + + if ( currentEjectorState > EJECTOR_STATE_HOMING ) + { + ejectorHomeRequested = TRUE; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The retractEjector function requests an ejector retract operation. + * @details \b Inputs: currentEjectorState + * @details \b Outputs: ejectorRetractRequested + * @return TRUE if retract command accepted, FALSE if not + *************************************************************************/ +BOOL retractEjector( void ) +{ + BOOL result = FALSE; + + if ( EJECTOR_STATE_EXTENDED == currentEjectorState ) + { + ejectorRetractRequested = TRUE; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The extendEjector function requests an ejector extend operation. + * @details \b Inputs: currentEjectorState + * @details \b Outputs: ejectorExtendRequested + * @return TRUE if extend command accepted, FALSE if not + *************************************************************************/ +BOOL extendEjector( void ) +{ + BOOL result = FALSE; + + if ( EJECTOR_STATE_RETRACTED == currentEjectorState ) + { + ejectorExtendRequested = TRUE; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getEjectorState function returns the current ejector control state machine. + * @details \b Inputs: currentEjectorState + * @details \b Outputs: none + * @return current state of the ejector control state machine. + *************************************************************************/ +EJECTOR_STATE_T getEjectorState( void ) +{ + return currentEjectorState; +} + +/*********************************************************************//** + * @brief + * The execEjectorController function executes the ejector control state machine. + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if the current state is invalid. + * @details \b Inputs: currentEjectorState + * @details \b Outputs: currentEjectorState + * @return none + *************************************************************************/ +void execEjectorController( void ) +{ + switch( currentEjectorState ) + { + case EJECTOR_STATE_INIT: + currentEjectorState = handleEjectorStartState(); + break; + + case EJECTOR_STATE_HOMING: + currentEjectorState = handleEjectorHomingState(); + break; + + case EJECTOR_STATE_RETRACTED: + currentEjectorState = handleEjectorRetractedState(); + break; + + case EJECTOR_STATE_EXTENDED: + currentEjectorState = handleEjectorExtendedState(); + break; + + case EJECTOR_STATE_RETRACTING: + currentEjectorState = handleEjectorRetractingState(); + break; + + case EJECTOR_STATE_EXTENDING: + currentEjectorState = handleEjectorExtendingState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_EJECTOR_INVALID_STATE, (U32)currentEjectorState ) + break; + } + + // reset request flags after processing ejector control state machine (they expire) + resetEjectorFlags(); + + // publish ejector data if it's time to publish + publishEjectorData(); +} + +/*********************************************************************//** + * @brief + * The handleEjectorStartState function starts the ejector control state machine. + * @details \b Inputs: ejectorHomeRequested + * @details \b Outputs: ejectorOperationTimerCounter + * @return next state of the ejector control state machine + *************************************************************************/ +static EJECTOR_STATE_T handleEjectorStartState( void ) +{ + EJECTOR_STATE_T state = EJECTOR_STATE_INIT; + + if ( TRUE == ejectorHomeRequested ) + { + ejectorOperationTimerCounter = 0; + setEjectorMotorSpeed( EJECTOR_RETRACT_MOTOR_SPEED_RPM ); + state = EJECTOR_STATE_HOMING; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleEjectorHomingState function handles the homing state of the + * ejector control state machine. + * @details \b Inputs: ejectorOperationTimerCounter + * @details \b Outputs: ejectorOperationTimerCounter + * @return next state of the ejector control state machine + *************************************************************************/ +static EJECTOR_STATE_T handleEjectorHomingState( void ) +{ + EJECTOR_STATE_T state = EJECTOR_STATE_HOMING; + + if ( ++ejectorOperationTimerCounter >= EJECTOR_RETRACT_OP_INTERVAL ) + { + ejectorOperationTimerCounter = 0; + setEjectorMotorSpeed( EJECTOR_OFF_MOTOR_SPEED_RPM ); + state = EJECTOR_STATE_RETRACTED; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleEjectorRetractedState function handles the retracted state of the + * ejector control state machine. + * @details \b Inputs: ejectorExtendRequested + * @details \b Outputs: ejectorOperationTimerCounter + * @return next state of the ejector control state machine + *************************************************************************/ +static EJECTOR_STATE_T handleEjectorRetractedState( void ) +{ + EJECTOR_STATE_T state = EJECTOR_STATE_RETRACTED; + + if ( TRUE == ejectorExtendRequested ) + { + ejectorOperationTimerCounter = 0; + setEjectorMotorSpeed( EJECTOR_EXTEND_MOTOR_SPEED_RPM ); + state = EJECTOR_STATE_EXTENDING; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleEjectorExtendedState function handles the extended state of the + * ejector control state machine. + * @details \b Inputs: ejectorRetractRequested + * @details \b Outputs: ejectorOperationTimerCounter + * @return next state of the ejector control state machine + *************************************************************************/ +static EJECTOR_STATE_T handleEjectorExtendedState ( void ) +{ + EJECTOR_STATE_T state = EJECTOR_STATE_EXTENDED; + + if ( TRUE == ejectorRetractRequested ) + { + ejectorOperationTimerCounter = 0; + setEjectorMotorSpeed( EJECTOR_RETRACT_MOTOR_SPEED_RPM ); + state = EJECTOR_STATE_RETRACTING; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleEjectorRetractingState function handles the retracting state of the + * ejector control state machine. + * @details \b Inputs: ejectorOperationTimerCounter + * @details \b Outputs: ejectorOperationTimerCounter + * @return next state of the ejector control state machine + *************************************************************************/ +static EJECTOR_STATE_T handleEjectorRetractingState ( void ) +{ + EJECTOR_STATE_T state = EJECTOR_STATE_RETRACTING; + + if ( ++ejectorOperationTimerCounter >= EJECTOR_RETRACT_OP_INTERVAL ) + { + ejectorOperationTimerCounter = 0; + setEjectorMotorSpeed( EJECTOR_OFF_MOTOR_SPEED_RPM ); + state = EJECTOR_STATE_RETRACTED; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleEjectorExtendingState function handles the extending state of the + * ejector control state machine. + * @details \b Inputs: ejectorOperationTimerCounter + * @details \b Outputs: ejectorOperationTimerCounter + * @return next state of the ejector control state machine + *************************************************************************/ +static EJECTOR_STATE_T handleEjectorExtendingState ( void ) +{ + EJECTOR_STATE_T state = EJECTOR_STATE_EXTENDING; + + if ( ++ejectorOperationTimerCounter >= EJECTOR_RETRACT_OP_INTERVAL ) + { + ejectorOperationTimerCounter = 0; + setEjectorMotorSpeed( EJECTOR_OFF_MOTOR_SPEED_RPM ); + state = EJECTOR_STATE_EXTENDED; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The publishEjectorData function constructs and sends the air pump data + * broadcast message. + * @details \b Message \b Sent: MSG_ID_TD_AIR_PUMP_DATA + * @details \b Inputs: airPumpDataPublicationTimerCounter, currentEjectorState, + * currentEjectorSetSpeed + * @details \b Outputs: airPumpDataPublicationTimerCounter + * @return none + *************************************************************************/ +static void publishEjectorData( void ) +{ + if ( ++ejectorDataPublicationTimerCounter >= getU32OverrideValue( &ejectorDataPublishInterval ) ) + { + EJECTOR_PAYLOAD_T data; + + data.h5State = getEjectorState(); + data.h5SetSpeed = currentEjectorSetSpeed; + + broadcastData( MSG_ID_TD_EJECTOR_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( EJECTOR_PAYLOAD_T ) ); + ejectorDataPublicationTimerCounter = 0; + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testEjectorDataPublishIntervalOverride function overrides the interval + * at which the ejector data is published. + * @details \b Inputs: none + * @details \b Outputs: ejectorDataPublishInterval + * @param message Override message from Dialin which includes the interval + * (in ms) to override the ejector data broadcast interval to. + * @return TRUE if override request is successful, FALSE if not + *************************************************************************/ +BOOL testEjectorDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = u32BroadcastIntervalOverride( message, &ejectorDataPublishInterval, TASK_GENERAL_INTERVAL ); + + return result; +} + +BOOL testEjectorCommand( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify tester has logged in with TD and override type is valid + if ( TRUE == isTestingActivated() ) + { + // Verify payload length is valid + if ( sizeof( U32 ) == message->hdr.payloadLen ) + { + U32 cmd; + EJECTOR_OPERATION_T op; + + memcpy( &cmd, message->payload, sizeof(U32) ); + op = (EJECTOR_OPERATION_T)cmd; + + switch ( op ) + { + case EJECTOR_OPERATION_HOME: + result = homeEjector(); + break; + + case EJECTOR_OPERATION_RETRACT: + result = retractEjector(); + break; + + case EJECTOR_OPERATION_EXTEND: + result = extendEjector(); + break; + + default: + // no alarm since this is a test function + break; + } + } + } + + return result; +} + +/**@}*/ + Index: firmware/App/Controllers/Ejector.h =================================================================== diff -u --- firmware/App/Controllers/Ejector.h (revision 0) +++ firmware/App/Controllers/Ejector.h (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -0,0 +1,71 @@ +/************************************************************************** +* +* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file Ejector.h +* +* @author (last) Sean +* @date (last) 17-Sep-2024 +* +* @author (original) Sean +* @date (original) 17-Sep-2024 +* +***************************************************************************/ + +#ifndef __EJECTOR_H__ +#define __EJECTOR_H__ + +// ********** public definitions ********** + +#include "TDCommon.h" +#include "EjectorMotor.h" + +/** + * @defgroup Ejector Ejector + * @brief Air Pump controller unit. Provides higher level control of the air pump. + * + * @addtogroup Ejector + * @{ + */ + +// ********** public definitions ********** + +#pragma pack(push, 1) +/// Payload record structure for air pump data broadcast message +typedef struct +{ + U32 h5State; ///< Ejector state + F32 h5SetSpeed; ///< Ejector motor set speed +} EJECTOR_PAYLOAD_T; +#pragma pack(pop) + +/// Enumeration of ejector states. +typedef enum EjectorStates +{ + EJECTOR_STATE_INIT = 0, ///< Ejector Initial (un-homed) state + EJECTOR_STATE_HOMING, ///< Ejector Homing state + EJECTOR_STATE_RETRACTED, ///< Ejector Retracted state + EJECTOR_STATE_EXTENDED, ///< Ejector Extended state + EJECTOR_STATE_RETRACTING, ///< Ejector Retracting state + EJECTOR_STATE_EXTENDING, ///< Ejector Extending state + NUM_OF_EJECTOR_STATES, ///< Number of ejector states +} EJECTOR_STATE_T; + +// ********** public function prototypes ********** + +void initEjector(void); +void execEjectorController(void); +EJECTOR_STATE_T getEjectorState( void ); +BOOL homeEjector( void ); +BOOL retractEjector( void ); +BOOL extendEjector( void ); + +BOOL testEjectorDataPublishIntervalOverride( MESSAGE_T *message ); +BOOL testEjectorCommand( MESSAGE_T *message ); + +/**@}*/ + +#endif Index: firmware/App/Drivers/EjectorMotor.c =================================================================== diff -u --- firmware/App/Drivers/EjectorMotor.c (revision 0) +++ firmware/App/Drivers/EjectorMotor.c (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -0,0 +1,262 @@ +/************************************************************************** +* +* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file EjectorMotor.c +* +* @author (last) Sean +* @date (last) 13-May-2025 +* +* @author (original) Sean +* @date (original) 13-May-2025 +* +***************************************************************************/ + +#include "AlarmMgmtTD.h" +#include "EjectorMotor.h" +#include "FpgaTD.h" +#include "Messaging.h" + +/** + * @addtogroup EjectorMotor + * @{ + */ + +// ********** private definitions ********** + +#define EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP 0xFFFFFFFF ///< Ejector motor microstep toggle time setting to indicate zero speed (stopped). + +#define EJECTOR_STEPS_PER_REV 48.0F ///< Number of steps per revolution (7.5 degrees per step). +#define EJECTOR_MICRO_STEPS_PER_STEP 32.0F ///< Number of micro-steps per step. +#define EJECTOR_TOGGLES_PER_STEP 2.0F ///< Stepper motor driver toggles per step or microstep. + +#define EJECTOR_MOTOR_START_RAMP_SPEED 300000 ///< Starting speed for all ejector operations to ramp up from. +#define EJECTOR_MOTOR_RAMP_DIVISOR 5 ///< Used for ramping profile. + +/// Number of ejector motor micro steps per revolution. +#define EJECTOR_MICRO_STEPS_PER_REV ( EJECTOR_STEPS_PER_REV * EJECTOR_MICRO_STEPS_PER_STEP ) + +// Bit definitions for ejector motor control register +#define EJECTOR_MOTOR_CONTROL_SLEEP_OFF 0x40 ///< Ejector motor control register bit for sleep mode (active low). +#define EJECTOR_MOTOR_CONTROL_NOT_RESET 0x20 ///< Ejector motor control register bit for resetting stepper motor (active low). +#define EJECTOR_MOTOR_CONTROL_ENABLE 0x00 ///< Ejector motor control register bit mask for enable. +#define EJECTOR_MOTOR_CONTROL_DISABLE 0x10 ///< Ejector motor control register bit for enable (active low). +#define EJECTOR_MOTOR_CONTROL_REVERSE_DIR 0x08 ///< Ejector motor control register bit for direction (0=fwd, 1=rev). +#define EJECTOR_MOTOR_CONTROL_FORWARD_DIR 0x00 ///< Ejector motor control register bit mask for forward direction. +#define EJECTOR_MOTOR_CONTROL_32TH_STEP 0x03 ///< Ejector motor control register bits for 1/32 micro-stepping mode. + +/// Control bits to run ejector motor in reverse direction +static const U08 EJECTOR_MOTOR_CONTROL_RUN_REVERSE = EJECTOR_MOTOR_CONTROL_SLEEP_OFF | + EJECTOR_MOTOR_CONTROL_NOT_RESET | + EJECTOR_MOTOR_CONTROL_ENABLE | + EJECTOR_MOTOR_CONTROL_REVERSE_DIR | + EJECTOR_MOTOR_CONTROL_32TH_STEP; +/// Control bits to run ejector motor in forward direction +static const U08 EJECTOR_MOTOR_CONTROL_RUN_FORWARD = EJECTOR_MOTOR_CONTROL_SLEEP_OFF | + EJECTOR_MOTOR_CONTROL_NOT_RESET | + EJECTOR_MOTOR_CONTROL_ENABLE | + EJECTOR_MOTOR_CONTROL_FORWARD_DIR | + EJECTOR_MOTOR_CONTROL_32TH_STEP; + +/// Payload record structure for ejector motor set request +typedef struct +{ + F32 setSpeed; ///< Set speed for ejector motor (in RPM). Negative RPM indicates reverse direction. +} EJECTOR_MOTOR_SET_CMD_PAYLOAD_T; + +// ********** private data ********** + +static F32 currentEjectorMotorSetSpeed; ///< Current air pump motor state: 0=off, 1..255=power level. +static U32 ejectorMotorSetToggleTime; ///< Time (in uSec) between microstep toggles. +static U32 ejectorMotorRampUpToggleTime; ///< Current ramp time (in uSec) between microstep toggles. +static U32 ejectorMotorRampTimerCtr; ///< Used to track ramp up time. +static BOOL ejectorMotorRampUpInProgress; ///< Flag indicating whether a ramp up is in progress. + +// ********** private function prototypes ********** + +static U32 calcEjectorStepToggleTimeFromSetSpeed( F32 rpm ); + +/*********************************************************************//** + * @brief + * The initEjectorMotor function initializes the ejector motor driver unit. + * @details \b Inputs: none + * @details \b Outputs: EjectorMotor unit initialized. + * @return none + *************************************************************************/ +void initEjectorMotor(void) +{ + currentEjectorMotorSetSpeed = 0.0F; + ejectorMotorSetToggleTime = EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP; + ejectorMotorRampUpToggleTime = EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP; + ejectorMotorRampTimerCtr = 0; + ejectorMotorRampUpInProgress = FALSE; + + setH5StepToggleTime( ejectorMotorSetToggleTime ); + setH5ControlFlags( EJECTOR_MOTOR_CONTROL_RUN_FORWARD ); +} + +/*********************************************************************//** + * @brief + * The setEjectorMotorSpeed function sets the ejector motor to the given + * set speed and direction. + * @details \b Inputs: none + * @details \b Outputs: + * @param rpm Speed (rpm) to set the ejector motor to (negative value indicates reverse direction) + * @return TRUE if ejector motor speed set successfully, FALSE if not. + *************************************************************************/ +BOOL setEjectorMotorSpeed( F32 rpm ) +{ + BOOL result = FALSE; + + // if starting motor, motor must be stopped first + if ( ( fabs(rpm) > 0.0F ) && ( currentEjectorMotorSetSpeed < NEARLY_ZERO ) ) + { + U32 stepTime = calcEjectorStepToggleTimeFromSetSpeed( rpm ); + U08 ctrl = EJECTOR_MOTOR_CONTROL_RUN_FORWARD; + + currentEjectorMotorSetSpeed = rpm; + if ( rpm < 0.0F ) + { + ctrl = EJECTOR_MOTOR_CONTROL_RUN_REVERSE; + } + ejectorMotorSetToggleTime = stepTime; + ejectorMotorRampUpToggleTime = EJECTOR_MOTOR_START_RAMP_SPEED; + setH5ControlFlags( ctrl ); + setH5StepToggleTime( ejectorMotorRampUpToggleTime ); + ejectorMotorRampUpInProgress = TRUE; + + result = TRUE; + } + // if stopping motor, motor must be running first + else if ( ( fabs(rpm) < NEARLY_ZERO ) && ( currentEjectorMotorSetSpeed > 0.0F ) ) + { + ejectorMotorRampUpInProgress = FALSE; + ejectorMotorSetToggleTime = EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP; + ejectorMotorRampUpToggleTime = EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP; + currentEjectorMotorSetSpeed = 0.0F; + setH5StepToggleTime( ejectorMotorSetToggleTime ); + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getEjectorMotorSetSpeed function gets the current set ejector motor + * speed (in RPM). If the direction is reverse, the reported speed will be + * negative. + * @details \b Inputs: currentEjectorMotorSetSpeed + * @details \b Outputs: none + * @return currentEjectorMotorSetSpeed + *************************************************************************/ +F32 getEjectorMotorSetSpeed( void ) +{ + return currentEjectorMotorSetSpeed; +} + +/*********************************************************************//** + * @brief + * The execEjectorMotorRamping function manages the ejector motor ramping. + * @note This ramping function is executed within the priority task while + * other ejector related functions occur within the general task. Therefore + * care should be taken when setting the ramp in progress flag. + * @details \b Inputs: ejectorMotorRampUpInProgress + * @details \b Outputs: none + * @return none + *************************************************************************/ +void execEjectorMotorRamping( void ) +{ + if ( TRUE == ejectorMotorRampUpInProgress ) + { + ejectorMotorRampTimerCtr++; + if ( ejectorMotorRampUpToggleTime > ejectorMotorSetToggleTime ) + { + ejectorMotorRampUpToggleTime = (U32)( (F32)EJECTOR_MOTOR_START_RAMP_SPEED / + ( (F32)( ejectorMotorRampTimerCtr * ejectorMotorRampTimerCtr * ejectorMotorRampTimerCtr ) / + (F32)EJECTOR_MOTOR_RAMP_DIVISOR ) ); + if ( ejectorMotorRampUpToggleTime > ejectorMotorSetToggleTime ) + { + setH5StepToggleTime( ejectorMotorRampUpToggleTime ); + } + else + { + setH5StepToggleTime( ejectorMotorSetToggleTime ); + ejectorMotorRampUpInProgress = FALSE; + } + } + } +} + +/*********************************************************************//** + * @brief + * The calcEjectorStepToggleTimeFromSetSpeed function calculates the stepper + * toggle period for a given set speed (in RPM). + * @details Inputs: none + * @details Outputs: none + * @param rpm Speed to convert to step toggle time (in uSec) + * @return toggle time for set speed + *************************************************************************/ +static U32 calcEjectorStepToggleTimeFromSetSpeed( F32 rpm ) +{ + U32 result = EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP; + F64 temp; + F32 conv; + + // Toggle time is direction agnostic, so ignore direction implied by sign. + rpm = fabs( rpm ); + + // Convert given speed to stepper toggle period + temp = (F64)EJECTOR_MICRO_STEPS_PER_REV * (F64)rpm; // = uSteps/min + temp /= (F64)(SEC_PER_MIN); // = uSteps/sec + temp /= (F64)US_PER_SECOND; // = uSteps/uSec + conv = (F32)temp * EJECTOR_TOGGLES_PER_STEP; // = toggles/uSec + conv = 1.0F / conv; // = uSec/toggle + result = (U32)FLOAT_TO_INT_WITH_ROUND( conv ); + + ejectorMotorRampUpToggleTime = EJECTOR_MOTOR_START_RAMP_SPEED; + + return result; +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetEjectorMotorSpeed function sets the ejector motor to a given + * set speed. + * @details \b Inputs: none + * @details \b Outputs: none + * @param message set message from Dialin which includes the set speed being + * requested. + * @return TRUE if set request is successful, FALSE if not + *************************************************************************/ +BOOL testSetEjectorMotorSpeed( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify tester has logged in with TD and override type is valid + if ( TRUE == isTestingActivated() ) + { + // Verify payload length is valid + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + EJECTOR_MOTOR_SET_CMD_PAYLOAD_T payload; + + memcpy( &payload, message->payload, sizeof(EJECTOR_MOTOR_SET_CMD_PAYLOAD_T) ); + result = setEjectorMotorSpeed( payload.setSpeed ); + } + } + + return result; +} + +/**@}*/ + Index: firmware/App/Drivers/EjectorMotor.h =================================================================== diff -u --- firmware/App/Drivers/EjectorMotor.h (revision 0) +++ firmware/App/Drivers/EjectorMotor.h (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -0,0 +1,47 @@ +/************************************************************************** +* +* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file EjectorMotor.h +* +* @author (last) Sean +* @date (last) 13-May-2025 +* +* @author (original) Sean +* @date (original) 13-May-2025 +* +***************************************************************************/ + +#ifndef __EJECTOR_MOTOR_H__ +#define __EJECTOR_MOTOR_H__ + +// ********** public definitions ********** + +#include "TDCommon.h" + +/** + * @defgroup EjectorMotor EjectorMotor + * @brief Ejector motor driver unit. Provides low level functions + * to control an ejector motor. + * + * @addtogroup EjectorMotor + * @{ + */ + +// ********** public definitions ********** + +// ********** public function prototypes ********** + +void initEjectorMotor( void ); +BOOL setEjectorMotorSpeed( F32 rpm ); +F32 getEjectorMotorSetSpeed( void ); +void execEjectorMotor( void ); + +BOOL testSetEjectorMotorSpeed( MESSAGE_T *message ); + +/**@}*/ + +#endif Index: firmware/App/Drivers/PeristalticPump.c =================================================================== diff -u -r52e1d4487a69a1ef0475321084527c0ba86c0892 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Drivers/PeristalticPump.c (.../PeristalticPump.c) (revision 52e1d4487a69a1ef0475321084527c0ba86c0892) +++ firmware/App/Drivers/PeristalticPump.c (.../PeristalticPump.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -38,15 +38,21 @@ #define H4_HZ_TO_RPM(h) ((h) * H4_HZ_TO_RPM_SCALAR) ///< Blood pump Hz to RPM conversion macro. #define H4_ZERO_SPEED_PERIOD 0xFFFF ///< Blood pump period reported when pump is stopped. +#define H4_ROT_GEAR_RATIO 64.0F ///< Blood pump rotor to motor gear ratio. +#define H4_ROT_PERIOD_SEC 0.001F ///< Blood pump rotor feedback period in seconds. +#define H4_ROT_PERIOD_TO_HZ(p) ( 1.0F / (F32)((S32)(p) * H4_ROT_PERIOD_SEC) ) ///< Blood pump rotor period to Hz conversion macro. +#define H4_ROT_PERIOD_TO_RPM(p) ((H4_ROT_PERIOD_TO_HZ(p)) * (F32)SEC_PER_MIN) ///< Blood pump rotor period to RPM conversion macro. + #define H4_HOME_SPEED_RPM 400 ///< Blood pump set speed for rotor homing operation. #define H6_STATUS_HOME_BIT_POS 0x1 ///< Bit position in H6 status register that indicates whether rotor is in home position. // ********** private data ********** static S32 pumpSetSpeedRPM; ///< Current set speed for the pump (in RPM). Negative indicates reverse direction. -static OVERRIDE_F32_T pumpMeasSpeedRPM; ///< Latest measured pump speed (in RPM). -static BOOL pumpHomeRequested; ///< Flag indicates a pump home operation has been requested. +static F32 pumpMeasSpeedRPM; ///< Latest measured pump speed (in RPM). +static F32 pumpMeasRotSpeedRPM; ///< Latest measured pump rotor speed (in RPM). +static BOOL pumpHomeInProgress; ///< Flag indicates a pump home operation is in progress. // ********** private function prototypes ********** @@ -60,12 +66,10 @@ *************************************************************************/ void initPeristalticPumpDriver(void) { - pumpHomeRequested = FALSE; + pumpHomeInProgress = FALSE; pumpSetSpeedRPM = 0; - pumpMeasSpeedRPM.data = 0.0F; - pumpMeasSpeedRPM.ovData = 0.0F; - pumpMeasSpeedRPM.ovInitData = 0.0F; - pumpMeasSpeedRPM.override = OVERRIDE_RESET; + pumpMeasSpeedRPM = 0.0F; + pumpMeasRotSpeedRPM = 0.0F; setH4Direction( MOTOR_DIR_FORWARD ); setH4SetSpeed( 0 ); @@ -78,37 +82,49 @@ * peristaltic pump from the FPGA. * @note This function should be called periodically to maintain fresh * sensor readings for the pump. - * @details \b Inputs: pumpSetSpeedRPM, pumpHomeRequested, FPGA - * @details \b Outputs: pumpMeasSpeedRPM, pumpHomeRequested + * @details \b Inputs: pumpSetSpeedRPM, pumpHomeInProgress, FPGA + * @details \b Outputs: pumpMeasSpeedRPM, pumpHomeInProgress * @return none *************************************************************************/ void readPeristalticPumps( void ) { U16 period = getH4Period(); - F32 Hz = H4_PERIOD_TO_HZ(period); - F32 rpm = H4_HZ_TO_RPM(Hz); + S16 rotPer = getH4RotorCount(); - // update measured pump speed + // update measured pump motor speed if ( period != H4_ZERO_SPEED_PERIOD ) { + F32 Hz = H4_PERIOD_TO_HZ( period ); + F32 rpm = H4_HZ_TO_RPM( Hz ); + if ( pumpSetSpeedRPM < 0 ) // TODO - can we get a real measured direction to base measured speed sign on? { - pumpMeasSpeedRPM.data = rpm * -1.0F; + pumpMeasSpeedRPM = rpm * -1.0F; } else { - pumpMeasSpeedRPM.data = rpm; + pumpMeasSpeedRPM = rpm; } } else { - pumpMeasSpeedRPM.data = 0.0F; + pumpMeasSpeedRPM = 0.0F; } - // monitor home command status if in progress, stop pump if rotor in home position - if ( ( TRUE == pumpHomeRequested ) && ( TRUE == isPeristalticPumpHome() ) ) + // update measured pump rotor speed + if ( rotPer != 0 ) { - pumpHomeRequested = FALSE; + pumpMeasRotSpeedRPM = H4_ROT_PERIOD_TO_RPM( rotPer ); + } + else + { + pumpMeasRotSpeedRPM = 0.0F; + } + + // monitor home command status if in progress, stop pump if rotor is in home position + if ( ( TRUE == pumpHomeInProgress ) && ( TRUE == isPeristalticPumpHome() ) ) + { + pumpHomeInProgress = FALSE; setPeristalticPumpSetSpeed( 0 ); } } @@ -117,17 +133,18 @@ * @brief * The cmdPeristalticPumpHome function initiates a pump home operation. * @details \b Inputs: none - * @details \b Outputs: pumpHomeRequested, FPGA + * @details \b Outputs: pumpHomeInProgress, FPGA * @return TRUE if home operation is initiated, FALSE if not *************************************************************************/ BOOL cmdPeristalticPumpHome( void ) { BOOL result = FALSE; - if ( ( 0 == pumpSetSpeedRPM ) && ( pumpHomeRequested != TRUE ) ) + // Pump must be stopped before homing + if ( ( 0 == pumpSetSpeedRPM ) && ( pumpHomeInProgress != TRUE ) ) { result = TRUE; - pumpHomeRequested = TRUE; + pumpHomeInProgress = TRUE; setPeristalticPumpSetSpeed( H4_HOME_SPEED_RPM ); } @@ -213,9 +230,21 @@ *************************************************************************/ F32 getPeristalticPumpMeasSpeed( void ) { - F32 result = getF32OverrideValue( &pumpMeasSpeedRPM ); + return pumpMeasSpeedRPM; +} - return result; +/*********************************************************************//** + * @brief + * The getPeristalticPumpMeasRotorSpeed function gets the latest measured pump + * rotor speed in RPM. + * @note A negative speed indicates reverse direction. + * @details \b Inputs: pumpMeasRotSpeedRPM + * @details \b Outputs: none + * @return Latest measured pump rotor speed in RPM. + *************************************************************************/ +F32 getPeristalticPumpMeasRotorSpeed( void ) +{ + return pumpMeasRotSpeedRPM; } /**@}*/ Index: firmware/App/Drivers/PeristalticPump.h =================================================================== diff -u -r52e1d4487a69a1ef0475321084527c0ba86c0892 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Drivers/PeristalticPump.h (.../PeristalticPump.h) (revision 52e1d4487a69a1ef0475321084527c0ba86c0892) +++ firmware/App/Drivers/PeristalticPump.h (.../PeristalticPump.h) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -42,12 +42,11 @@ BOOL setPeristalticPumpSetSpeed( S32 rpm ); S32 getPeristalticPumpSetSpeed( void ); F32 getPeristalticPumpMeasSpeed( void ); +F32 getPeristalticPumpMeasRotorSpeed( void ); BOOL cmdPeristalticPumpHome( void ); BOOL isPeristalticPumpHome( void ); -BOOL testSetPeristalticPumpSetSpeed( MESSAGE_T *message ); - /**@}*/ #endif Index: firmware/App/Modes/ModeTxParams.c =================================================================== diff -u -r52e1d4487a69a1ef0475321084527c0ba86c0892 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Modes/ModeTxParams.c (.../ModeTxParams.c) (revision 52e1d4487a69a1ef0475321084527c0ba86c0892) +++ firmware/App/Modes/ModeTxParams.c (.../ModeTxParams.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -38,14 +38,15 @@ // ********** private definitions ********** -#define MAX_DIALYSATE_VOLUME_ML ( 150 * ML_PER_LITER ) ///< Maximum dialysate volume (in mL) -#define MAX_HEPARIN_VOLUME_ML 10 ///< Maximum heparin volume ( in mL ) - +#define MAX_HEPARIN_VOLUME_ML 10.0F ///< Maximum heparin volume ( in mL ) #define NO_HEPARIN_PRE_STOP_TIME_SET 0 ///< Zero value indicates no Heparin pre-stop time was set by user - #define NO_HEPARIN_TYPE_SET 0xFFFFFFFF ///< UI will send this value for Heparin type if Heparin not used + #define INSTIT_CHEM_DISINFECT_ENABLE_RANGE 1 ///< Institutional record chemical disinfect enable/disable allowable range +#define SYRINGE_PUMP_PRIME_VOLUME_ML 0.353F ///< Target syringe prime volume (in mL). TODO- move these to syringe pump controller when implemented +#define SYRINGE_PUMP_FILL_VOLUME_OFFSET_ML 0.8F ///< Advised fill volume offset due to HW variance. + /// Record for range and default of treatment parameters. typedef struct { @@ -588,19 +589,30 @@ static BOOL checkTreatmentParamsDependencies( U32 *reasons ) { BOOL result = TRUE; + U32 txDur = stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt; + U32 hepST = stagedParams[ TREATMENT_PARAM_HEPARIN_STOP_TIME ].uInt; + F32 hepDR = stagedParams[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].sFlt; + F32 hepBV = stagedParams[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].sFlt; + F32 txVol = hepBV + ( hepDR * ( hepST / (F32)SEC_PER_MIN ) ) + SYRINGE_PUMP_PRIME_VOLUME_ML + SYRINGE_PUMP_FILL_VOLUME_OFFSET_ML; // Verify Heparin stop time is only set if Heparin dispense rate is set - if ( ( stagedParams[ TREATMENT_PARAM_HEPARIN_STOP_TIME ].uInt > 0 ) && ( stagedParams[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].sFlt < NEARLY_ZERO ) ) + if ( ( hepST > 0 ) && ( hepDR < NEARLY_ZERO ) ) { reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_STOP_TIME_WITH_NO_DISPENSE; result = FALSE; } // Verify Heparin stop time does not exceed Tx duration - else if ( stagedParams[ TREATMENT_PARAM_HEPARIN_STOP_TIME ].uInt > stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt ) + else if ( hepST > txDur ) { reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_STOP_TIME_EXCEEDS_DURATION; result = FALSE; } + // Verify Heparin stop time does not exceed max 10 mL Heparin volume + else if ( txVol > MAX_HEPARIN_VOLUME_ML ) + { + reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_VOLUME_EXCEEDS_10_ML; + result = FALSE; + } return result; } Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r52e1d4487a69a1ef0475321084527c0ba86c0892 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 52e1d4487a69a1ef0475321084527c0ba86c0892) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -164,6 +164,7 @@ SW_FAULT_ID_TX_DIALYSIS_INVALID_STATE2 = 133, SW_FAULT_ID_DIALYZER_TYPE_INVALID1 = 134, SW_FAULT_ID_DIALYZER_TYPE_INVALID2 = 135, + SW_FAULT_ID_TD_EJECTOR_INVALID_STATE = 136, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/FpgaTD.c =================================================================== diff -u -r52e1d4487a69a1ef0475321084527c0ba86c0892 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision 52e1d4487a69a1ef0475321084527c0ba86c0892) +++ firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -68,6 +68,19 @@ #define FPGA_H18_BUBBLE_STATUS_MASK 0x0002 ///< Bit mask for venous air bubble detector input status. #define FPGA_H18_BUBBLE_SELF_TEST_CMD 0x08 ///< Bit for venous air bubble detector self-test command. +/// Control bits to run syringe pump in reverse direction // TODO - move to syringe pump controller unit when implemented. +static const U08 SYRINGE_PUMP_CONTROL_RUN_REVERSE = SYRINGE_PUMP_CONTROL_SLEEP_OFF | + SYRINGE_PUMP_CONTROL_NOT_RESET | + SYRINGE_PUMP_CONTROL_ENABLE | + SYRINGE_PUMP_CONTROL_REVERSE_DIR | + SYRINGE_PUMP_CONTROL_32TH_STEP; +/// Control bits to run syringe pump in forward direction // TODO - move to syringe pump controller unit when implemented. +static const U08 SYRINGE_PUMP_CONTROL_RUN_FORWARD = SYRINGE_PUMP_CONTROL_SLEEP_OFF | + SYRINGE_PUMP_CONTROL_NOT_RESET | + SYRINGE_PUMP_CONTROL_ENABLE | + SYRINGE_PUMP_CONTROL_FORWARD_DIR | + SYRINGE_PUMP_CONTROL_32TH_STEP; + // FPGA Sensors Record #pragma pack(push,1) @@ -477,7 +490,7 @@ * The setH4SetSpeed function sets the fpga blood pump set speed * to the given speed (0..3000 RPM). * @details \b Inputs: none - * @details \b Outputs: H4 set speed is set + * @details \b Outputs: fpgaActuatorSetPoints * @param rpm the set point for the H4 pump speed (in RPM). * @return none *************************************************************************/ @@ -531,6 +544,41 @@ /*********************************************************************//** * @brief + * The setH5ControlFlags function sets the control flags for the H5 ejector + * stepper motor. + * @note Bit 0 - MS1 (bit 1 of microstepping configuration setting) + * Bit 1 - MS2 (bit 2 of microstepping configuration setting) + * Bit 2 - MS3 (bit 3 of microstepping configuration setting) + * Bit 3 - Direction (0=forward, 1=reverse) + * Bit 4 - Disable (0=enabled, 1=disabled) + * Bit 5 - Reset (0=reset, 1=not reset) + * Bit 6 - Sleep (0=sleep, 1=not sleep) + * Bit 7 - Reserved + * @details \b Inputs: none + * @details \b Outputs: fpgaActuatorSetPoints.h5Control + * @param ctrl Bit flags for H5 stepper motor control + * @return none + *************************************************************************/ +void setH5ControlFlags( U08 ctrl ) +{ + fpgaActuatorSetPoints.h5Control = ctrl; +} + +/*********************************************************************//** + * @brief + * The setH5StepToggleTime function sets the ejector motor set speed step + * toggle time (in uSec). + * @details \b Inputs: none + * @details \b Outputs: fpgaActuatorSetPoints.h5SetSpeed + * @return latest arterial pressure reading + *************************************************************************/ +void setH5StepToggleTime( U32 microSeconds ) +{ + fpgaActuatorSetPoints.h5SetSpeed = microSeconds; +} + +/*********************************************************************//** + * @brief * The getH2Pressure function gets the latest arterial pressure reading. * The high 2 bits are status bits: 00=ok, 01=cmd mode, 10=stale data, 11=diag * The low 14 bits are data. Zero is at 1638. Values above are positive, Index: firmware/App/Services/FpgaTD.h =================================================================== diff -u -r52e1d4487a69a1ef0475321084527c0ba86c0892 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Services/FpgaTD.h (.../FpgaTD.h) (revision 52e1d4487a69a1ef0475321084527c0ba86c0892) +++ firmware/App/Services/FpgaTD.h (.../FpgaTD.h) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -31,13 +31,23 @@ // ********** public definitions ********** -#define FPGA_PINCH_VALVES_1_32_STEP 0x03 ///< Bit mask for configuring pinch valve for 1/32 step. -#define FPGA_PINCH_VALVES_REVERSE 0x08 ///< Bit mask for configuring pinch valve for reverse direction. -#define FPGA_PINCH_VALVES_DISABLE 0x10 ///< Bit mask for configuring pinch valve to be disabled. -#define FPGA_PINCH_VALVES_NOT_RESET 0x20 ///< Bit mask for configuring pinch valve to not be in reset. -#define FPGA_PINCH_VALVES_NOT_SLEEP 0x40 ///< Bit mask for configuring pinch valve to not be in sleep mode. -#define FPGA_PINCH_VALVES_NEW_POS_CMD 0x80 ///< Bit mask for configuring pinch valve to accept a new position command. +// Bit definitions for pinch valve control register +#define FPGA_PINCH_VALVES_1_32_STEP 0x03 ///< Bit mask for configuring pinch valve for 1/32 step. +#define FPGA_PINCH_VALVES_REVERSE 0x08 ///< Bit mask for configuring pinch valve for reverse direction. +#define FPGA_PINCH_VALVES_DISABLE 0x10 ///< Bit mask for configuring pinch valve to be disabled. +#define FPGA_PINCH_VALVES_NOT_RESET 0x20 ///< Bit mask for configuring pinch valve to not be in reset. +#define FPGA_PINCH_VALVES_NOT_SLEEP 0x40 ///< Bit mask for configuring pinch valve to not be in sleep mode. +#define FPGA_PINCH_VALVES_NEW_POS_CMD 0x80 ///< Bit mask for configuring pinch valve to accept a new position command. +// Bit definitions for syringe pump control register +#define SYRINGE_PUMP_CONTROL_SLEEP_OFF 0x40 ///< Syringe pump control register bit for sleep mode (active low). +#define SYRINGE_PUMP_CONTROL_NOT_RESET 0x20 ///< Syringe pump control register bit for resetting stepper motor (active low). +#define SYRINGE_PUMP_CONTROL_ENABLE 0x00 ///< Syringe pump control register bit mask for enable. +#define SYRINGE_PUMP_CONTROL_DISABLE 0x10 ///< Syringe pump control register bit for enable (active low). +#define SYRINGE_PUMP_CONTROL_REVERSE_DIR 0x08 ///< Syringe pump control register bit for direction (0=fwd, 1=rev). +#define SYRINGE_PUMP_CONTROL_FORWARD_DIR 0x00 ///< Syringe pump control register bit mask for forward direction. +#define SYRINGE_PUMP_CONTROL_32TH_STEP 0x03 ///< Syringe pump control register bits for 1/32 micro-stepping mode. + // ********** public function prototypes ********** void initFpgaTD( void ); @@ -64,6 +74,9 @@ S16 getH4RotorCount( void ); U08 getH6Status( void ); +void setH5ControlFlags( U08 ctrl ); +void setH5StepToggleTime( U32 microSeconds ); + U16 getH2Pressure( void ); S16 getH2Temperature( void ); U08 getH2ReadCounter( void ); Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rc8a6bfae0f88b45e3783632c868235077e4cbeec -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision c8a6bfae0f88b45e3783632c868235077e4cbeec) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -26,6 +26,7 @@ #include "Compatible.h" #include "CpldInterface.h" #include "DDInterface.h" +#include "Ejector.h" #include "FpgaTD.h" #include "LevelSensors.h" #include "Messaging.h" @@ -143,7 +144,9 @@ MSG_ID_TD_REQ_CURRENT_TREATMENT_PARAMETERS, MSG_ID_TD_SET_TREATMENT_PARAMETER, MSG_ID_TD_OP_MODE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, - MSG_ID_TD_OP_MODE_OVERRIDE_REQUEST + MSG_ID_TD_OP_MODE_OVERRIDE_REQUEST, + MSG_ID_TD_EJECTOR_MOTOR_SET_SPEED_REQUEST, + MSG_ID_TD_EJECTOR_COMMAND }; /// Message handling function table @@ -203,7 +206,9 @@ &testTxParamsRequest, &testSetTreatmentParameter, &testSetOpModePublishIntervalOverride, - &testSetOperationMode + &testSetOperationMode, + &testSetEjectorMotorSpeed, + &testEjectorCommand }; #define NUM_OF_FUNCTION_HANDLERS (sizeof(MSG_FUNCTION_HANDLERS) / sizeof(MsgFuncPtr)) Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -r036a75d76ab01912646a480b935d97187a231a19 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 036a75d76ab01912646a480b935d97187a231a19) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -18,6 +18,7 @@ #include "AirPump.h" #include "AirTrap.h" #include "BloodFlow.h" +#include "Ejector.h" #include "Messaging.h" #include "OperationModes.h" #include "Pressures.h" @@ -108,6 +109,9 @@ // Control pinch valves execValvesController(); + // Control ejector + execEjectorController(); + // Control blood pump execBloodFlowController(); Index: firmware/App/Tasks/TaskPriority.c =================================================================== diff -u -r036a75d76ab01912646a480b935d97187a231a19 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision 036a75d76ab01912646a480b935d97187a231a19) +++ firmware/App/Tasks/TaskPriority.c (.../TaskPriority.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -18,6 +18,7 @@ #include "AirTrap.h" #include "Bubbles.h" #include "Buttons.h" +#include "EjectorMotor.h" #include "FPGA.h" #include "InternalADC.h" #include "SystemCommTD.h" @@ -72,6 +73,9 @@ // Monitor air bubble detectors execBubbles(); + // Control ejector motor ramping + execEjectorMotorRamping(); + // 2nd pass for FPGA execFPGA( FALSE ); } Index: firmware/source/sys_main.c =================================================================== diff -u -r051326e2671e8d5b3e99eaa109ea549e94a929f3 -raa6d45143096dfab776ce2ed7c775cfe2dd6db18 --- firmware/source/sys_main.c (.../sys_main.c) (revision 051326e2671e8d5b3e99eaa109ea549e94a929f3) +++ firmware/source/sys_main.c (.../sys_main.c) (revision aa6d45143096dfab776ce2ed7c775cfe2dd6db18) @@ -70,6 +70,7 @@ #include "Buttons.h" #include "CpldInterface.h" #include "DDInterface.h" +#include "Ejector.h" #include "FpgaTD.h" #include "InternalADC.h" #include "Interrupts.h" @@ -200,6 +201,7 @@ initAirPump(); initAirTrap(); initBloodFlow(); + initEjector(); initValves(); // Initialize modes initOperationModes();