Index: firmware/.launches/DG.launch
===================================================================
diff -u -r439894cb0508e69af3ece09ae57a62feac09e3f2 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/.launches/DG.launch (.../DG.launch) (revision 439894cb0508e69af3ece09ae57a62feac09e3f2)
+++ firmware/.launches/DG.launch (.../DG.launch) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -1,9 +1,13 @@
+
+
+
+
@@ -13,4 +17,5 @@
+
Index: firmware/App/Controllers/DrainPump.c
===================================================================
diff -u -r2851a8bc8f6180634f47b96feb00e4c0054252d3 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 2851a8bc8f6180634f47b96feb00e4c0054252d3)
+++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -54,9 +54,10 @@
/// Enumeration of drain pump states.
typedef enum DrainPump_States
{
- DRAIN_PUMP_OFF_STATE = 0, ///< Drain pump off state.
- DRAIN_PUMP_CONTROL_TO_TARGET_STATE, ///< Drain pump control to target state.
- NUM_OF_DRAIN_PUMP_STATES ///< Number of drain pump states.
+ DRAIN_PUMP_OFF_STATE = 0, ///< Drain pump off state
+ DRAIN_PUMP_OPEN_LOOP_STATE, ///< Drain pump open loop state
+ DRAIN_PUMP_CONTROL_TO_TARGET_STATE, ///< Drain pump control to target state
+ NUM_OF_DRAIN_PUMP_STATES ///< Number of drain pump states
} DRAIN_PUMP_STATE_T;
/// Enumeration of drain pump self test states.
@@ -85,16 +86,18 @@
static BOOL isDrainPumpOn = FALSE; ///< Drain pump is currently running
static U32 drainPumpDAC = 0; ///< initial drain pump DAC value
static U32 drainPumpDACSet = 0; ///< currently set drain pump DAC value
-static PUMP_CONTROL_MODE_T drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested drain pump control mode.
-static PUMP_CONTROL_MODE_T drainPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< currently set drain pump control mode.
+static PUMP_CONTROL_MODE_T drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; ///< requested drain pump control mode.
+static PUMP_CONTROL_MODE_T drainPumpControlModeSet = PUMP_CONTROL_MODE_OPEN_LOOP; ///< currently set drain pump control mode.
static OVERRIDE_U32_T drainPumpDataPublishInterval = { DRAIN_PUMP_DATA_PUB_INTERVAL, DRAIN_PUMP_DATA_PUB_INTERVAL, 0, 0 }; ///< interval (in ms) at which to publish RO flow data to CAN bus.
static OVERRIDE_U32_T targetDrainPumpSpeed = { 0, 0, 0, 0 }; ///< Target RO pressure (in PSI).
static U32 drainControlTimerCounter = 0; ///< determines when to perform control on drain pump
static DRAIN_PUMP_SELF_TEST_STATE_T drainPumpSelfTestState = DRAIN_PUMP_SELF_TEST_STATE_START; ///< current drain pump self test state
-static U32 drainPumpSelfTestTimerCount = 0; ///< timer counter for drain pump self test
+static U32 drainPumpSelfTestTimerCount = 0; ///< timer counter for drain pump self test
+
+static BOOL hasClosedLoopBeenRequested = FALSE;
// ********** private function prototypes **********
@@ -237,24 +240,43 @@
#endif
#endif
- // if we've been given a pressure, transition to control to target state
- if ( getTargetDrainPumpSpeed() > 0 )
+ // if we've been given a pressure, transition to open loop state
+ // as it will not be controlling and it will just run
+ if ( getTargetDrainPumpSpeed() > 0 && !hasClosedLoopBeenRequested )
{
// set drain pump enable pin
SET_DRAIN_PUMP_ENABLE();
// set drain pump control mode
drainPumpControlModeSet = drainPumpControlMode;
// Check if drain pump mode is closed loop
- if ( drainPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP )
- {
- resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP, MIN_DRAIN_PUMP_RPM_TARGET );
- }
+ //if ( drainPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP )
+ //{
+ // resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP, MIN_DRAIN_PUMP_RPM_TARGET );
+ //}
// set drain pump DAC
drainPumpDACSet = drainPumpDAC;
setFPGADrainPumpSpeed( drainPumpDACSet );
// set pump to on
isDrainPumpOn = TRUE;
- result = DRAIN_PUMP_CONTROL_TO_TARGET_STATE;
+ result = DRAIN_PUMP_OPEN_LOOP_STATE;
+ }
+
+ if ( hasClosedLoopBeenRequested )
+ {
+ // set drain pump enable pin
+ SET_DRAIN_PUMP_ENABLE();
+ // set drain pump control mode
+ drainPumpControlModeSet = drainPumpControlMode;
+
+
+ resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP, MIN_DRAIN_PUMP_RPM_TARGET );
+
+ // set drain pump DAC
+ drainPumpDACSet = drainPumpDAC;
+ setFPGADrainPumpSpeed( drainPumpDACSet );
+ // set pump to on
+ isDrainPumpOn = TRUE;
+ result = DRAIN_PUMP_CONTROL_TO_TARGET_STATE;
}
return result;
Index: firmware/App/Controllers/DrainPump.h
===================================================================
diff -u -rbe5079c95b05c303878763b458dc0854a600317e -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision be5079c95b05c303878763b458dc0854a600317e)
+++ firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -39,7 +39,10 @@
void execDrainPumpMonitor( void );
void execDrainPumpController( void );
-BOOL setDrainPumpTargetSpeed( U32 rpm, PUMP_CONTROL_MODE_T mode );
+BOOL setDrainPumpTargetSpeed( U32 rpm, PUMP_CONTROL_MODE_T mode );
+
+
+
void signalDrainPumpHardStop( void );
SELF_TEST_STATUS_T execDrainPumpTest( void );
Index: firmware/App/Controllers/ROPump.c
===================================================================
diff -u -r2851a8bc8f6180634f47b96feb00e4c0054252d3 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 2851a8bc8f6180634f47b96feb00e4c0054252d3)
+++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -65,17 +65,18 @@
#define RO_FLOW_ADC_TO_LPM_FACTOR 10909.0909 ///< conversion factor from ADC counts to LPM (liters/min) for RO flow rate (multiply this by inverse of FPGA reading).
#define ROP_FLOW_TO_PWM_DC(flow) ((F32)(flow / 1000)) //TODO dara ///< Initial conversion factor from target flow rate to PWM duty cycle estimate
-#define ROP_RAMP_UP_P_COEFFICIENT 0.009 //TODO dara
-#define ROP_RAMP_UP_I_COEFFICIENT 0.00 //TODO dara
-#define ROP_FLOW_TARGET_TOLERANCE 20U //TODO dara ///< Tolerance in between the target flow rate and the actual flow rate in mL
+#define ROP_RAMP_UP_P_COEFFICIENT 0.0 //TODO dara
+#define ROP_RAMP_UP_I_COEFFICIENT 0.09 //TODO dara
+#define ROP_FLOW_TARGET_TOLERANCE 0.1 //TODO dara ///< Tolerance in between the target flow rate and the actual flow rate in mL
/// Enumeration of RO pump states.
typedef enum ROPump_States
{
- RO_PUMP_OFF_STATE = 0, ///< RO pump off state.
- RO_PUMP_RAMP_UP_STATE, ///< RO pump ramp up to target flow rate state.
- RO_PUMP_CONTROL_TO_TARGET_STATE, ///< RO pump control to target pressure state.
- NUM_OF_RO_PUMP_STATES ///< Number of RO pump states.
+ RO_PUMP_OFF_STATE = 0, ///< RO pump off state
+ RO_PUMP_OPEN_LOOP_STATE, ///< RO pump open loop state
+ RO_PUMP_RAMP_UP_STATE, ///< RO pump ramp up to target flow rate state
+ RO_PUMP_CONTROL_TO_TARGET_STATE, ///< RO pump control to target pressure state
+ NUM_OF_RO_PUMP_STATES ///< Number of RO pump states
} RO_PUMP_STATE_T;
/// Enumeration of RO pump self test states.
@@ -91,7 +92,12 @@
// pin assignments for pump test DIP switch 0
#define RO_PUMP_TEST_SPI5_PORT_MASK 0x00000100 // (ENA - re-purposed as input GPIO)
// dialIn pump stop and direction macros
-#define GET_DIP_SW0_TEST() ( ( mibspiREG5->PC2 & RO_PUMP_TEST_SPI5_PORT_MASK ) != 0 )
+#define GET_DIP_SW0_TEST() ( ( mibspiREG5->PC2 & RO_PUMP_TEST_SPI5_PORT_MASK ) != 0 )
+
+// TODO: Remove the below code. FOR TESTING ONLY
+#define PRIMARY_HEATER_MIBSPI1_PORT_MASK 0x00000002 // (CS1 - re-purposed as input GPIO)
+#define TOGGLEPUMP() (( mibspiREG1->PC2 & PRIMARY_HEATER_MIBSPI1_PORT_MASK ) != 0)
+//TODO: Remove the above code. FOR TESTING ONLY
// ********** private data **********
@@ -105,7 +111,7 @@
//static OVERRIDE_U32_T roPumpDataPublishInterval = { 0, 0, 0, 0 }; //From branch Remove ///< interval (in ms) at which to publish RO flow data to CAN bus.
//static OVERRIDE_U32_T targetROPumpPressure = { 0, 0, 0, 0 }; //From branch ///< Target RO pressure (in PSI). //TODO remove
-static OVERRIDE_U32_T targetROPumpFlowRate = { 0, 0, 0, 0 }; //From Branch ///< Target RO flow rate (in LPM_) // TODO dara
+static OVERRIDE_F32_T targetROPumpFlowRate = { 0, 0, 0, 0 }; //From Branch ///< Target RO flow rate (in LPM_) // TODO dara
static OVERRIDE_U32_T roPumpDataPublishInterval = { RO_PUMP_DATA_PUB_INTERVAL, RO_PUMP_DATA_PUB_INTERVAL, 0, 0 }; ///< interval (in ms) at which to publish RO flow data to CAN bus.
static OVERRIDE_U32_T targetROPumpPressure = { 0, 0, 0, 0 }; ///< Target RO pressure (in PSI).
static OVERRIDE_F32_T measuredROFlowRateLPM = { 0.0, 0.0, 0.0, 0 }; ///< measured RO flow rate (in LPM).
@@ -148,7 +154,7 @@
MIN_RO_PUMP_PWM_DUTY_CYCLE, MAX_RO_PUMP_PWM_DUTY_CYCLE );
// Initialize the P controller during ramp up
- initializePIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE,
+ initializePIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE,
ROP_RAMP_UP_P_COEFFICIENT, ROP_RAMP_UP_I_COEFFICIENT,
MIN_RO_PUMP_PWM_DUTY_CYCLE, MAX_RO_PUMP_PWM_DUTY_CYCLE );
}
@@ -190,15 +196,15 @@
return result;
}
-BOOL setROPumpTargetFlowRate( U32 roFlowRate, PUMP_CONTROL_MODE_T mode )
+BOOL setROPumpTargetFlowRate( F32 roFlowRate )
{
BOOL result = FALSE;
- if ( roFlowRate < MAX_RO_FLOWRATE && roFlowRate >= MIN_RO_FLOWRATE )
+ if ( roFlowRate < MAX_RO_FLOWRATE_LPM && roFlowRate >= MIN_RO_FLOWRATE_LPM )
{
targetROPumpFlowRate.data = roFlowRate;
- roPumpControlMode = mode;
- roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( roFlowRate );
+ roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP;
+ roPumpPWMDutyCyclePct = roFlowRate;
}
else // requested pressure out of range
{
@@ -218,7 +224,7 @@
*************************************************************************/
void signalROPumpHardStop( void )
{
- targetROPumpPressure.data = 0;
+ targetROPumpFlowRate.data = 0;
stopROPump();
roPumpState = RO_PUMP_OFF_STATE;
roPumpPWMDutyCyclePct = 0.0;
@@ -283,6 +289,9 @@
{
case RO_PUMP_OFF_STATE:
roPumpState = handleROPumpOffState();
+ break;
+
+ case RO_PUMP_OPEN_LOOP_STATE:
break;
case RO_PUMP_RAMP_UP_STATE:
@@ -349,17 +358,18 @@
#endif
}
#endif
-#endif
+#endif
- // If there is a
+ // If there is a flow, transition to P controller to get
+ // the corresponding pressure of that flow
if ( getTargetROPumpFlowRate() > 0 )
{
roPumpControlModeSet = roPumpControlMode;
// set initial PWM duty cycle
- roPumpPWMDutyCyclePctSet = roPumpPWMDutyCyclePct;
+ roPumpPWMDutyCyclePctSet = ROP_FLOW_TO_PWM_DC( getTargetROPumpFlowRate() );
setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet );
// reset controller
- resetPIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, roPumpPWMDutyCyclePctSet );
+ resetPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, roPumpPWMDutyCyclePctSet );
// set pump to on
isROPumpOn = TRUE;
result = RO_PUMP_RAMP_UP_STATE;
@@ -378,7 +388,8 @@
// set pump to on
isROPumpOn = TRUE;
result = RO_PUMP_CONTROL_TO_TARGET_STATE;
- }*/
+ }*/
+
return result;
}
@@ -401,14 +412,14 @@
if ( fabs( actualFlowRate - targetFlowRate ) > ROP_FLOW_TARGET_TOLERANCE )
{
- F32 newPWM = runPIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, targetFlowRate, actualFlowRate );
+ F32 newPWM = runPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, targetFlowRate, actualFlowRate );
roPumpPWMDutyCyclePctSet = newPWM;
setROPumpControlSignalPWM( newPWM );
}
else
{
// Reset the P controller for the flow rate
- resetPIController( P_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE );
+ resetPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE );
tgtROPumpPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET );
roPumpControlModeSet = roPumpControlMode;
@@ -442,18 +453,22 @@
// control at set interval
if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL )
{
- if ( roPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP )
- {
- F32 tgtPres = tgtROPumpPressure;
- F32 actPres = measuredROPumpPressure;
- F32 newPWM;
+ F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET );
+
+ //if ( OVERRIDE_KEY == targetROPumpFlowRate.override )
+ //{
+ // targetFlowRate = targetROPumpFlowRate.ovData;
+ //}
+ F32 newPWM = runPIController( PI_CONTROLLER_ID_RO_PUMP, tgtROPumpPressure, actualPressure );
+ roPumpPWMDutyCyclePctSet = newPWM;
+ setROPumpControlSignalPWM( newPWM );
-#ifndef EMC_TEST_BUILD
+/*#ifndef EMC_TEST_BUILD
newPWM = runPIController( PI_CONTROLLER_ID_RO_PUMP, tgtPres, actPres );
roPumpPWMDutyCyclePctSet = newPWM;
setROPumpControlSignalPWM( newPWM );
-#endif
- }
+#endif*/
+
roControlTimerCounter = 0;
}
@@ -537,9 +552,9 @@
* @return the current target RO pressure (in PSI).
*************************************************************************/
//U32 getTargetROPumpPressure( void )
-U32 getTargetROPumpFlowRate( void )
+F32 getTargetROPumpFlowRate( void )
{
- U32 result = targetROPumpFlowRate.data;
+ F32 result = targetROPumpFlowRate.data;
if ( OVERRIDE_KEY == targetROPumpFlowRate.override )
{
@@ -692,7 +707,7 @@
return result;
}
-BOOL testSetTargetROPumpFlowRateOverride( U32 value )
+BOOL testSetTargetROPumpFlowRateOverride( F32 value )
{
BOOL result = FALSE;
@@ -701,7 +716,7 @@
targetROPumpFlowRate.ovInitData = targetROPumpFlowRate.data; // backup current target pressure
targetROPumpFlowRate.ovData = value;
targetROPumpFlowRate.override = OVERRIDE_KEY;
- result = setROPumpTargetFlowRate( value, roPumpControlMode );
+ result = setROPumpTargetFlowRate( value );
}
return result;
@@ -717,7 +732,7 @@
targetROPumpFlowRate.override = OVERRIDE_RESET;
targetROPumpFlowRate.ovInitData = 0;
targetROPumpFlowRate.ovData = 0;
- result = setROPumpTargetFlowRate( targetROPumpFlowRate.data, roPumpControlMode );
+ result = setROPumpTargetFlowRate( targetROPumpFlowRate.data );
}
return result;
Index: firmware/App/Controllers/ROPump.h
===================================================================
diff -u -rbe5079c95b05c303878763b458dc0854a600317e -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision be5079c95b05c303878763b458dc0854a600317e)
+++ firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -33,8 +33,8 @@
#define MAX_RO_PRESSURE 140 ///< Maximum target RO outlet pressure (in PSI). //TODO remove
#define MIN_RO_PRESSURE 100 ///< Minimum target RO outlet pressure (in PSI). //TODO remove
-#define MAX_RO_FLOWRATE 2000 //TODO dara
-#define MIN_RO_FLOWRATE 300 //TODO dara
+#define MAX_RO_FLOWRATE_LPM 1.2 //TODO dara
+#define MIN_RO_FLOWRATE_LPM 0.2 //TODO dara
// ********** public function prototypes **********
@@ -44,22 +44,22 @@
BOOL setROPumpTargetPressure( U32 roPressure, PUMP_CONTROL_MODE_T mode ); //TODO remove
-BOOL setROPumpTargetFlowRate( U32 roFlowRate, PUMP_CONTROL_MODE_T mode );
+BOOL setROPumpTargetFlowRate( F32 roFlowRate );
void signalROPumpHardStop( void );
BOOL isReverseOsmosisPumpOn( void );
SELF_TEST_STATUS_T execROPumpTest( void );
-DATA_GET_PROTOTYPE( U32, getTargetROPumpFlowRate ); //TODO change
+DATA_GET_PROTOTYPE( F32, getTargetROPumpFlowRate ); //TODO change
DATA_GET_PROTOTYPE( F32, getMeasuredROFlowRate );
BOOL testSetROPumpDataPublishIntervalOverride( U32 value );
BOOL testResetROPumpDataPublishIntervalOverride( void );
BOOL testSetTargetROPumpPressureOverride( U32 value ); //TODO remove
BOOL testResetTargetROPumpPressureOverride( void ); //TODO remove
-BOOL testSetTargetROPumpFlowRateOverride( U32 value );
+BOOL testSetTargetROPumpFlowRateOverride( F32 value );
BOOL testResetTargetROPumpFlowRateOverride( void );
BOOL testSetMeasuredROFlowRateOverride( F32 value );
Index: firmware/App/DGCommon.h
===================================================================
diff -u -r3f3729899d6811c763bc8e5ef9baf54a2d5c9cfe -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/DGCommon.h (.../DGCommon.h) (revision 3f3729899d6811c763bc8e5ef9baf54a2d5c9cfe)
+++ firmware/App/DGCommon.h (.../DGCommon.h) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -36,9 +36,9 @@
// #define TASK_TIMING_OUTPUT_ENABLED 1 // re-purposes drain pump enable pin for task timing
// #define BETA_V1_BUILD 1
// #define DISABLE_HEATERS_AND_TEMPS 1
- #define ENABLE_DIP_SWITCHES 1
- #define EMC_TEST_BUILD 1
- #define ALARMS_DEBUG 1
+// #define ENABLE_DIP_SWITCHES 1
+// #define EMC_TEST_BUILD 1
+// #define ALARMS_DEBUG 1
// #define HEATERS_DEBUG 1
// #define PRESSURES_DEBUG 1
#include
Index: firmware/App/Modes/ModeHeatDisinfect.c
===================================================================
diff -u -rbe5079c95b05c303878763b458dc0854a600317e -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision be5079c95b05c303878763b458dc0854a600317e)
+++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -37,11 +37,13 @@
#define HEAT_DISINFECTION_TARGET_TEMP 85U ///< Heat disinfection target temperature
#define HEAT_DISINFECTION_OVERALL_TIME 60U ///< Heat disinfection overall time in minutes
-#define HEAT_DISINFECTION_RECIRC_PATH_TIME 5U
-#define HEAT_DISINFECTION_FLUSH_TIME 3U
+#define HEAT_DISINFECTION_RECIRC_PATH_TIME_MINS 5U
+#define HEAT_DISINFECTION_FLUSH_TIME_MINS 3U
+#define HEAT_DISINFECTION_OVERALL_TIME_MINS 30U
-#define DRAIN_PUMP_TARGET_RPM 2800U
-#define RO_PUMP_TARGET_PRESSURE 110U
+#define DRAIN_PUMP_TARGET_DELTA_PRESSURE 0U
+#define DRAIN_PUMP_TARGET_RPM 2800U
+#define RO_PUMP_TARGET_FLOW_RATE_LPM 0.9
// ********** private data **********
@@ -54,7 +56,8 @@
static void setActuatorsToStop( void );
static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStart( void );
-static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacuateDialysate( void );
+static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacDialysateReservoir1( void );
+static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacDialysateReservoir2( void );
static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWater( void );
static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectHeatWater( void );
static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRecirculationPath( void );
@@ -102,17 +105,20 @@
*************************************************************************/
U32 execHeatDisinfectMode( void )
{
- // execute current heat disinfect state
switch ( heatDisinfectionState )
{
case DG_HEAT_DISINFECT_STATE_START:
heatDisinfectionState = handleHeatDisinfectStart();
break;
- case DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE:
- heatDisinfectionState = handleHeatDisinfectEvacuateDialysate();
+ case DG_HEAT_DISINFECT_STATE_EVAC_DIALYSATE_RESERVOIR_1:
+ heatDisinfectionState = handleHeatDisinfectEvacDialysateReservoir1();
break;
+ case DG_HEAT_DISINFECT_STATE_EVAC_DIALYSATE_RESERVOIR_2:
+ heatDisinfectionState = handleHeatDisinfectEvacDialysateReservoir2();
+ break;
+
case DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER:
heatDisinfectionState = handleHeatDisinfectFillWithWater();
break;
@@ -174,9 +180,10 @@
*************************************************************************/
void startDGHeatDisinfect( void )
{
- // make sure DG is not in the middle of something and it is in standby
+ // NOTE: make sure DG is not in the middle of something and it is in standby
//
- transitionToHeatDisinfectMode(); // Call request start heat disinfect
+ initHeatDisinfectMode();
+ requestNewOperationMode( DG_MODE_HEAT );
}
/*********************************************************************//**
@@ -189,16 +196,49 @@
*************************************************************************/
void stopDGHeatDisinfect( void )
{
- heatDisinfectionState = DG_HEAT_DISINFECT_STATE_START; // request standby mode
- setActuatorsToStop(); // Not needed
+ //heatDisinfectionState = DG_HEAT_DISINFECT_STATE_START; // request standby mode
+ setActuatorsToStop();
+ requestNewOperationMode( DG_MODE_STAN );
}
// ********** private function definitions **********
static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStart( void )
{
- DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_START;
+ DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_EVAC_DIALYSATE_RESERVOIR_1;
+ setActuatorsToStop();
+
+ /*setValveState ( VPI, VALVE_STATE_OPEN );
+ setValveState ( VBF, VALVE_STATE_OPEN );
+ setValveState ( VSP, VALVE_STATE_CLOSED );
+ setValveState ( VPD, VALVE_STATE_OPEN_C_TO_NO );
+ setValveState ( VPO, VALVE_STATE_NOFILL_C_TO_NO );
+ setValveState ( VDR, VALVE_STATE_DRAIN_C_TO_NO );
+ setValveState ( VRC, VALVE_STATE_RECIRC_C_TO_NC );
+ setValveState ( VRO, VALVE_STATE_R2_C_TO_NO );
+ setValveState ( VRD, VALVE_STATE_R1_C_TO_NC );
+ setValveState ( VRI, VALVE_STATE_R2_C_TO_NC );
+ setValveState ( VRF, VALVE_STATE_R1_C_TO_NC );
+
+ setROPumpTargetFlowRate( 0 );
+ //setDrainPumpTargetSpeed( DRAIN_PUMP_TARGET_RPM, PUMP_CONTROL_MODE_OPEN_LOOP );
+ stopInletUVReactor();
+ stopOutletUVReactor();
+ stopPrimaryHeater();
+ stopTrimmerHeater();*/
+
+ //TODO FOR TESTING ONLY, REMOVE
+ state = DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH;
+ //TODO FOR TESTING ONLY, REMOVE
+
+ return state;
+}
+
+static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacDialysateReservoir1( void )
+{
+ DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_EVAC_DIALYSATE_RESERVOIR_1;
+
setValveState ( VPI, VALVE_STATE_OPEN );
setValveState ( VBF, VALVE_STATE_OPEN );
setValveState ( VSP, VALVE_STATE_CLOSED );
@@ -211,22 +251,21 @@
setValveState ( VRI, VALVE_STATE_R1_C_TO_NO );
setValveState ( VRF, VALVE_STATE_R2_C_TO_NO );
- setROPumpTargetPressure( 0, PUMP_CONTROL_MODE_CLOSED_LOOP );
- setDrainPumpTargetSpeed( 0, PUMP_CONTROL_MODE_OPEN_LOOP );
+ setROPumpTargetFlowRate( 0 );
+ signalDrainPumpHardStop();
stopInletUVReactor();
stopOutletUVReactor();
stopPrimaryHeater();
stopTrimmerHeater();
return state;
}
-static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacuateDialysate( void )
+
+static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacDialysateReservoir2( void )
{
- DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE;
- return state;
-
}
+
static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWater( void )
{
DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER;
@@ -247,10 +286,33 @@
{
DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH;
- return state;
+ setValveState ( VPI, VALVE_STATE_OPEN );
+ setValveState ( VBF, VALVE_STATE_OPEN );
+ setValveState ( VSP, VALVE_STATE_CLOSED );
+ setValveState ( VPD, VALVE_STATE_OPEN_C_TO_NO );
+ setValveState ( VPO, VALVE_STATE_NOFILL_C_TO_NO );
+ //setValveState ( VDR, VALVE_STATE_RECIRC_C_TO_NC ); For the actual heat disinfection
+ setValveState ( VDR, VALVE_STATE_DRAIN_C_TO_NO ); // For sending the fluid to drain for pump testing
+ setValveState ( VRC, VALVE_STATE_RECIRC_C_TO_NC );
+ setValveState ( VRO, VALVE_STATE_R2_C_TO_NO );
+ setValveState ( VRD, VALVE_STATE_R1_C_TO_NO );
+ setValveState ( VRI, VALVE_STATE_R1_C_TO_NO );
+ setValveState ( VRF, VALVE_STATE_R2_C_TO_NO );
+ setROPumpTargetFlowRate( 0.7 );
+ //setDrainPumpTargetSpeed( 0, PUMP_CONTROL_MODE_CLOSED_LOOP );
+ //startInletUVReactor();
+ //startOutletUVReactor();
+ //startPrimaryHeater();
+ //stopTrimmerHeater();
+ // For debugging purposes only REMOVE
+ state = DG_HEAT_DISINFECT_STATE_DISINFECT_RESERVOIR_1_TO_2;
+ // For debugging purposes only REMOVE
+
+ return state;
}
+
static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectReservoir1To2( void )
{
DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_RESERVOIR_1_TO_2;
@@ -293,9 +355,8 @@
setValveState ( VPD, VALVE_STATE_DRAIN_C_TO_NC );
//TODO composition pumps
-
- setROPumpTargetPressure( 0, PUMP_CONTROL_MODE_CLOSED_LOOP );
- setDrainPumpTargetSpeed( 0, PUMP_CONTROL_MODE_OPEN_LOOP );
+ signalROPumpHardStop();
+ signalDrainPumpHardStop();
stopInletUVReactor();
stopOutletUVReactor();
stopPrimaryHeater();
Index: firmware/App/Modes/OperationModes.c
===================================================================
diff -u -r8f5feed92f41a476d5656038bcdfe884e17bd593 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 8f5feed92f41a476d5656038bcdfe884e17bd593)
+++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -55,7 +55,7 @@
/* FAUL */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG },
/* SERV */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG },
/* INIT */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_INIT, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG },
- /* STAN */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_CIRC, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_NLEG, DG_MODE_CHEM },
+ /* STAN */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_CIRC, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_CHEM },
/* SOLO */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_NLEG },
/* CIRC */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_CIRC, DG_MODE_FILL, DG_MODE_DRAI, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG },
/* FILL */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_CIRC, DG_MODE_FILL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG },
Index: firmware/App/Services/FPGA.c
===================================================================
diff -u -r8f5feed92f41a476d5656038bcdfe884e17bd593 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 8f5feed92f41a476d5656038bcdfe884e17bd593)
+++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -229,7 +229,7 @@
// TODO Remove the below line
// Initialize the valves
- fpgaActuatorSetPoints.fpgaValveStates = 0x015F;
+ //fpgaActuatorSetPoints.fpgaValveStates = 0x015F;
// TODO Remove the above line
// initialize fpga comm buffers
Index: firmware/App/Services/PIControllers.c
===================================================================
diff -u -r53af4ddc318cc5299f15e3cc1ce506b166e6e156 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 53af4ddc318cc5299f15e3cc1ce506b166e6e156)
+++ firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -57,7 +57,7 @@
{ // Kp Ki uMax uMin ref meas err esw esum ctrl
{ 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_RO_PUMP
- { 0.0, 0.0, 0.99, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // P_CONTROLLER_ID_RO_PUMP_RAMP_UP
+ { 0.0, 0.0, 0.99, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // I_CONTROLLER_ID_RO_PUMP_RAMP_UP
{ 0.0, 0.0, 3000, 300, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_DRAIN_PUMP
{ 0.0, 0.0, 0.89, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_PRIMARY_HEATER
{ 0.0, 0.0, 0.50, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } // PI_CONTROLLER_ID_TRIMMER_HEATER
Index: firmware/App/Services/PIControllers.h
===================================================================
diff -u -rbe5079c95b05c303878763b458dc0854a600317e -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Services/PIControllers.h (.../PIControllers.h) (revision be5079c95b05c303878763b458dc0854a600317e)
+++ firmware/App/Services/PIControllers.h (.../PIControllers.h) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -34,7 +34,7 @@
typedef enum ControllerList
{
PI_CONTROLLER_ID_RO_PUMP = 0, ///< RO Pump controller.
- P_CONTROLLER_ID_RO_PUMP_RAMP_UP, ///< RO Pump controller during ramp up time.
+ I_CONTROLLER_ID_RO_PUMP_RAMP_UP, ///< RO Pump controller during ramp up time.
PI_CONTROLLER_ID_DRAIN_PUMP, ///< Drain Pump controller.
PI_CONTROLLER_ID_PRIMARY_HEATER, ///< Primary Heater controller.
PI_CONTROLLER_ID_TRIMMER_HEATER, ///< Trimmer Heater controller.
Index: firmware/App/Services/SystemComm.c
===================================================================
diff -u -r53af4ddc318cc5299f15e3cc1ce506b166e6e156 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 53af4ddc318cc5299f15e3cc1ce506b166e6e156)
+++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -14,1143 +14,1103 @@
* @date (original) 05-Nov-2019
*
***************************************************************************/
-
-#include // for memcpy()
-
-#include "can.h"
-#include "sci.h"
-#include "sys_dma.h"
-
-#include "SystemComm.h"
-#include "Comm.h"
-#include "Interrupts.h"
-#include "Timers.h"
-#include "Utilities.h"
-#include "SystemCommMessages.h"
-
-/**
- * @addtogroup SystemComm
- * @{
- */
-// ********** private definitions **********
-
-#define NUM_OF_CAN_OUT_BUFFERS 5 ///< # of CAN buffers for transmit
-#define NUM_OF_CAN_IN_BUFFERS 6 ///< # of CAN buffers for receiving
-#ifndef DEBUG_ENABLED
- #define NUM_OF_MSG_IN_BUFFERS 6 ///< # of Msg buffers for receiving
-#else
- #define NUM_OF_MSG_IN_BUFFERS 7
- #define SCI1_RECEIVE_DMA_REQUEST 30
- #define SCI1_TRANSMIT_DMA_REQUEST 31
-#endif
-
-#define CAN_XMIT_PACKET_TIMEOUT_MS 200 ///< if transmitted CAN frame does not cause a transmit complete interrupt within this time, re-send or move on
-#define MAX_XMIT_RETRIES 5 ///< maximum number of retries on no transmit complete interrupt timeout
-
-#define HD_COMM_TIMEOUT_IN_MS 2000 ///< HD has not sent any broadcast messages for this much time
-
-#define MAX_COMM_CRC_FAILURES 5 ///< maximum number of CRC errors within window period before alarm
-#define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window
-
-#define MSG_NOT_ACKED_TIMEOUT_MS ( MS_PER_SECOND * 1 ) ///< maximum time for a Denali message that requires ACK to be ACK'd
-#define MSG_NOT_ACKED_MAX_RETRIES 3 ///< 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 Delanli messages that can be pending ACK at any given time
-
-#pragma pack(push, 1)
+#include // for memcpy()
-/// Record for transmitted message that is pending acknowledgement from receiver.
-typedef struct
-{
- BOOL used;
- U16 seqNo;
- U16 retries;
- U32 timeStamp;
- COMM_BUFFER_T channel;
- U32 msgSize;
- U08 msg[ MAX_ACK_MSG_SIZE ];
-} PENDING_ACK_RECORD_T;
-
-#pragma pack(pop)
-
-// ********** private data **********
+#include "can.h"
+#include "sci.h"
+#include "sys_dma.h"
-/// Array of out-going CAN buffers.
-const COMM_BUFFER_T CAN_OUT_BUFFERS[ NUM_OF_CAN_OUT_BUFFERS ] =
-{
- COMM_BUFFER_OUT_CAN_DG_ALARM,
- COMM_BUFFER_OUT_CAN_DG_2_HD,
+#include "SystemComm.h"
+#include "Comm.h"
+#include "Interrupts.h"
+#include "Timers.h"
+#include "Utilities.h"
+#include "SystemCommMessages.h"
+
+// ********** private definitions **********
+
+#define NUM_OF_CAN_OUT_BUFFERS 4 // # of CAN buffers for transmit
+#define NUM_OF_CAN_IN_BUFFERS 6 // # of CAN buffers for receiving
+#ifndef DEBUG_ENABLED
+ #define NUM_OF_MSG_IN_BUFFERS 6 // # of Msg buffers for receiving
+#else
+ #define NUM_OF_MSG_IN_BUFFERS 7 // # of Msg buffers for receiving - 1 is UART
+ #define SCI1_RECEIVE_DMA_REQUEST 30
+ #define SCI1_TRANSMIT_DMA_REQUEST 31
+#endif
+
+#define CAN_XMIT_PACKET_TIMEOUT_MS 200 ///< if transmitted CAN frame does not cause a transmit complete interrupt within this time, re-send or move on
+
+#define HD_COMM_TIMEOUT_IN_MS 2000
+
+#define MAX_COMM_CRC_FAILURES 5
+#define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND)
+
+#define MSG_NOT_ACKED_TIMEOUT_MS ( MS_PER_SECOND * 1 )
+#define MSG_NOT_ACKED_MAX_RETRIES 3
+#define PENDING_ACK_LIST_SIZE 25
+
+#pragma pack(push, 1)
+
+typedef struct
+{
+ BOOL used;
+ U16 seqNo;
+ U16 retries;
+ U32 timeStamp;
+ COMM_BUFFER_T channel;
+ U32 msgSize;
+ U08 msg[ MAX_ACK_MSG_SIZE ];
+} PENDING_ACK_RECORD_T;
+
+#pragma pack(pop)
+
+// ********** private data **********
+
+const COMM_BUFFER_T CAN_OUT_BUFFERS[ NUM_OF_CAN_OUT_BUFFERS ] =
+{
+ COMM_BUFFER_OUT_CAN_DG_ALARM,
+ COMM_BUFFER_OUT_CAN_DG_2_HD,
COMM_BUFFER_OUT_CAN_DG_BROADCAST,
- COMM_BUFFER_OUT_CAN_PC,
- COMM_BUFFER_OUT_CAN_DG_2_UI
-};
+ COMM_BUFFER_OUT_CAN_PC
+};
-/// Array of in-coming CAN buffers.
-const COMM_BUFFER_T MSG_IN_BUFFERS[ NUM_OF_MSG_IN_BUFFERS ] =
-{
- COMM_BUFFER_IN_CAN_HD_ALARM,
- COMM_BUFFER_IN_CAN_UI_ALARM,
- COMM_BUFFER_IN_CAN_HD_2_DG,
- COMM_BUFFER_IN_CAN_HD_BROADCAST,
- COMM_BUFFER_IN_CAN_UI_BROADCAST,
- COMM_BUFFER_IN_CAN_PC,
-#ifdef DEBUG_ENABLED
- COMM_BUFFER_IN_UART_PC
-#endif
-};
+const COMM_BUFFER_T MSG_IN_BUFFERS[ NUM_OF_MSG_IN_BUFFERS ] =
+{
+ COMM_BUFFER_IN_CAN_HD_ALARM,
+ COMM_BUFFER_IN_CAN_UI_ALARM,
+ COMM_BUFFER_IN_CAN_HD_2_DG,
+ COMM_BUFFER_IN_CAN_HD_BROADCAST,
+ COMM_BUFFER_IN_CAN_UI_BROADCAST,
+ COMM_BUFFER_IN_CAN_PC,
+#ifdef DEBUG_ENABLED
+ COMM_BUFFER_IN_UART_PC
+#endif
+};
-static U08 lastCANPacketSent[ CAN_MESSAGE_PAYLOAD_SIZE ]; ///< Keep last packet sent on CAN bus in case we need to re-send.
-static CAN_MESSAGE_BOX_T lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0; ///< Keep channel last packet was sent on CAN bus in case we need to re-send.
-static U32 lastCANPacketSentTimeStamp = 0; ///< Keep time last packet sent on CAN bus so we can timeout on transmission attempt.
-
-static PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; ///< list of outgoing messages that are awaiting an ACK
-
-static volatile BOOL dgIsOnlyCANNode = TRUE; ///< flag indicating whether DG is alone on CAN bus.
-static U32 canXmitRetryCtr = 0; ///< counter for CAN transmit retries.
-static volatile BOOL hdIsCommunicating = FALSE; ///< has HD sent a message since last check
-static volatile U32 timeOfLastHDCheckIn = 0; ///< last time we received an HD broadcast
-
+static U08 lastCANPacketSent[ CAN_MESSAGE_PAYLOAD_SIZE ];
+static CAN_MESSAGE_BOX_T lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0;
+static U32 lastCANPacketSentTimeStamp = 0;
+
#ifdef DEBUG_ENABLED
- // debug buffers
- static U08 pcXmitPacket[ 1024 ];
- static U08 pcRecvPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- // DMA control records
- static g_dmaCTRL pcDMAXmitControlRecord;
- static g_dmaCTRL pcDMARecvControlRecord;
+static U08 pcXmitPacket[ 1024 ];
+static U08 pcRecvPacket[ PC_MESSAGE_PACKET_SIZE ] = { 0, 0, 0, 0, 0, 0, 0, 0 };
#endif
-// ********** private function prototypes **********
-
-static void clearCANXmitBuffers( void );
-
-static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void );
-static U32 transmitNextCANPacket( void );
-
-static void processIncomingData( void );
-static S32 parseMessageFromBuffer( U08 *data, U32 len );
-static void consumeBufferPaddingBeforeSync( COMM_BUFFER_T buffer );
-static void processReceivedMessages( void );
-static void processReceivedMessage( MESSAGE_T *message );
-
-static void checkForCommTimeouts( void );
-static void checkTooManyBadMsgCRCs( void );
-
-static BOOL matchACKtoPendingACKList( S16 seqNo );
-static void checkPendingACKList( void );
-
+static PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; // list of outgoing messages that are awaiting an ACK
+
+// DMA control records
+static g_dmaCTRL pcDMAXmitControlRecord; // DMA transmit control record (UART-debug)
+static g_dmaCTRL pcDMARecvControlRecord; // DMA receive control record (UART-debug)
+
+static volatile BOOL hdIsCommunicating = FALSE; // has HD sent a message since last check
+static volatile U32 timeOfLastHDCheckIn = 0; // last time we received an HD broadcast
+
+static U32 badCRCTimeStamps[ MAX_COMM_CRC_FAILURES ]; // time of last five bad message CRCs (wrapping list)
+static U32 badCRCListIdx = 0; // where next bad message CRC time stamp will go in list
+static U32 badCRCListCount = 0; // # of bad CRCs in the list
+
+// ********** private function prototypes **********
+
#ifdef DEBUG_ENABLED
static void initUARTAndDMA( void );
static U32 transmitNextUARTPacket( void );
#endif
-/*********************************************************************//**
- * @brief
- * The initSystemComm function initializes the SystemComm module.
- * @details
- * Inputs : none
- * Outputs : SystemComm module initialized.
- * @return none
- *************************************************************************/
-void initSystemComm( void )
-{
- U32 i;
-
-#ifdef DEBUG_ENABLED
- // initialize UART and DMA for PC communication
- initUARTAndDMA();
-#endif
-
- // 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 pending ACK list
- for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
- {
- pendingAckList[ i ].used = FALSE;
- }
-}
-
-/*********************************************************************//**
- * @brief
- * The isHDCommunicating function determines whether the HD is communicating \n
- * with the DG.
- * @details
- * Inputs : hdIsCommunicating
- * Outputs : none
- * @return TRUE if HD has broadcast since last call, FALSE if not
- *************************************************************************/
-BOOL isHDCommunicating( void )
-{
- return hdIsCommunicating;
+
+static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void );
+static U32 transmitNextCANPacket( void );
+
+static void processIncomingData( void );
+static S32 parseMessageFromBuffer( U08 *data, U32 len );
+static void consumeBufferPaddingBeforeSync( COMM_BUFFER_T buffer );
+static void processReceivedMessages( void );
+static void processReceivedMessage( MESSAGE_T *message );
+
+static void checkForCommTimeouts( void );
+static void checkTooManyBadMsgCRCs( void );
+
+static BOOL matchACKtoPendingACKList( S16 seqNo );
+static void checkPendingACKList( void );
+
+/*************************************************************************
+ * @brief initSystemComm
+ * The initSystemComm function initializes the SystemComm module.
+ * @details
+ * Inputs : none
+ * Outputs : SystemComm module initialized.
+ * @param none
+ * @return none
+ *************************************************************************/
+void initSystemComm( void )
+{
+ U32 i;
+
+#ifdef DEBUG_ENABLED
+ // initialize UART and DMA for PC communication
+ initUARTAndDMA();
+#endif
+
+ // initialize bad message CRC list
+ for ( i = 0; i < MAX_COMM_CRC_FAILURES; i++ )
+ {
+ badCRCTimeStamps[ i ] = 0;
+ }
+
+ // initialize pending ACK list
+ for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
+ {
+ pendingAckList[ i ].used = FALSE;
+ }
}
-/*********************************************************************//**
+/*************************************************************************
* @brief
- * The isDGOnlyCANNode function determines whether the DG is the only node \n
- * currently on the CAN bus.
+ * The isHDCommunicating function determines whether the HD is communicating \n
+ * with the DG.
* @details
- * Inputs : dgIsOnlyCANNode
+ * Inputs : hdIsCommunicating
* Outputs : none
- * @return TRUE if DG is only node on CAN bus, FALSE if not
+ * @param none
+ * @return TRUE if HD has broadcast since last call, FALSE if not
*************************************************************************/
-BOOL isDGOnlyCANNode( void )
+BOOL isHDCommunicating( void )
{
- return dgIsOnlyCANNode;
-}
-
-/*********************************************************************//**
- * @brief
- * The execSystemCommRx function manages received data from other sub-systems.
- * @details
- * Inputs : none
- * Outputs : Incoming frames processed.
- * @return none
- *************************************************************************/
-void execSystemCommRx( void )
-{
- // parse messages from comm buffers and queue them
- processIncomingData();
-
- // process received messages in the queue
- processReceivedMessages();
-
- // check for sub-system comm timeouts
- checkForCommTimeouts();
-
- // check ACK list for messages that need to be re-sent because they haven't been ACK'd
- checkPendingACKList();
-}
-
-/*********************************************************************//**
- * @brief
- * The execSystemCommTx function manages data to be transmitted to other \n
- * sub-systems.
- * @details
- * Inputs : none
- * Outputs : Next outgoing frame transmitted.
- * @return none
- *************************************************************************/
-void execSystemCommTx( void )
-{
- // if CAN transmitter is idle, start transmitting any pending packets
- if ( ( FALSE == dgIsOnlyCANNode ) && ( FALSE == isCAN1TransmitInProgress() ) )
- {
- transmitNextCANPacket();
- }
- else
- { // generally, transmitter should not be busy at time of this function call - check timeout just in case so we don't get stuck waiting forever
- if ( TRUE == didTimeout( lastCANPacketSentTimeStamp, CAN_XMIT_PACKET_TIMEOUT_MS ) )
+ BOOL result = hdIsCommunicating;
+
+ hdIsCommunicating = FALSE;
+
+ return result;
+}
+
+/*************************************************************************
+ * @brief execSystemCommRx
+ * The execSystemCommRx function manages received data from other sub-systems.
+ * @details
+ * Inputs : none
+ * Outputs : none
+ * @param none
+ * @return none
+ *************************************************************************/
+void execSystemCommRx( void )
+{
+ // parse messages from comm buffers and queue them
+ processIncomingData();
+
+ // process received messages in the queue
+ processReceivedMessages();
+
+ // check for sub-system comm timeouts
+ checkForCommTimeouts();
+
+ // check ACK list for messages that need to be re-sent because they haven't been ACK'd
+ checkPendingACKList();
+}
+
+/*************************************************************************
+ * @brief execSystemCommTx
+ * The execSystemCommTx function manages data to be transmitted to other \n
+ * sub-systems.
+ * @details
+ * Inputs : none
+ * Outputs : none
+ * @param none
+ * @return none
+ *************************************************************************/
+void execSystemCommTx( void )
+{
+ // if CAN transmitter is idle, start transmitting any pending packets
+ if ( FALSE == isCAN1TransmitInProgress() )
+ {
+ transmitNextCANPacket();
+ }
+ else
+ { // generally, transmitter should not be busy at time of this function call - check timeout just in case so we don't get stuck waiting forever
+ if ( TRUE == didTimeout( lastCANPacketSentTimeStamp, CAN_XMIT_PACKET_TIMEOUT_MS ) )
{
- // assume last packet was not successfully transmitted. Re-send last packet.
- if ( ++canXmitRetryCtr <= MAX_XMIT_RETRIES )
+ // TODO - depending on why we timed out, we may need to reset CAN controller???
+ // assume last packet was not successfully transmitted. TODO - Re-send last packet? Or should we move on?
+ canTransmit( canREG1, lastCANPacketSentChannel, lastCANPacketSent );
+ }
+ }
+
+#ifdef DEBUG_ENABLED
+ // if UART transmitter is idle, start transmitting any pending packets
+ if ( FALSE == isSCI1DMATransmitInProgress() )
+ {
+ transmitNextUARTPacket();
+ }
+#endif
+}
+
+/*************************************************************************
+ * @brief handleCANMsgInterrupt
+ * The handleCANMsgInterrupt function handles a CAN message interrupt. \n
+ * This may have occurred because a CAN packet transmission has completed \n
+ * or because a CAN packet has been received. The appropriate handler is \n
+ * called.
+ * @details
+ * Inputs : none
+ * Outputs : message interrupt handled
+ * @param srcCANBox : which CAN message box triggered this interrupt
+ * @return none
+ *************************************************************************/
+void handleCANMsgInterrupt( CAN_MESSAGE_BOX_T srcCANBox )
+{
+ // message interrupt is for a transmit message box?
+ if ( TRUE == isCANBoxForXmit( srcCANBox ) )
+ {
+ U32 bytesXmitted = transmitNextCANPacket();
+
+ if ( 0 == bytesXmitted )
+ {
+ signalCANXmitsCompleted();
+ }
+ }
+ else if ( TRUE == isCANBoxForRecv( srcCANBox ) )
+ {
+ U08 data[ CAN_MESSAGE_PAYLOAD_SIZE ];
+
+ // get CAN packet received on given CAN message box
+ if ( FALSE != canIsRxMessageArrived( canREG1, srcCANBox ) )
+ {
+ U32 result = canGetData( canREG1, srcCANBox, data );
+
+ // if packet retrieved, add to buffer
+ if ( result != 0 )
{
- canTransmit( canREG1, lastCANPacketSentChannel, lastCANPacketSent );
+ // add CAN packet to appropriate comm buffer based on the message box it came in on (s/b same #)
+ addToCommBuffer( srcCANBox, data, CAN_MESSAGE_PAYLOAD_SIZE );
+ }
+ }
+ }
+ else
+ {
+ // shouldn't get here - not an active message box
+ // s/w fault?
+ }
+}
+
+/*************************************************************************
+ * @brief handleUARTMsgRecvPacketInterrupt
+ * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive \n
+ * packet completed interrupt.
+ * @details
+ * Inputs : none
+ * Outputs : none
+ * @param none
+ * @return none
+ *************************************************************************/
#ifdef DEBUG_ENABLED
- {
- char debugStr[100];
- sprintf( debugStr, "SystemComm-DG resend Last Frame.\n" );
- sendDebugDataToUI( (U08*)debugStr );
- }
+void handleUARTMsgRecvPacketInterrupt( void )
+{
+ // buffer received packet
+ addToCommBuffer( COMM_BUFFER_IN_UART_PC, pcRecvPacket, PC_MESSAGE_PACKET_SIZE );
+ // prepare to receive next packet
+ dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord );
+ dmaSetChEnable( DMA_CH1, DMA_HW );
+ setSCI1DMAReceiveInterrupt();
+}
#endif
+
+/*************************************************************************
+ * @brief handleUARTMsgXmitPacketInterrupt
+ * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit \n
+ * packet completed interrupt.
+ * @details
+ * Inputs : none
+ * Outputs : none
+ * @param none
+ * @return none
+ *************************************************************************/
+#ifdef DEBUG_ENABLED
+void handleUARTMsgXmitPacketInterrupt( void )
+{
+ U32 bytesXmitted = transmitNextUARTPacket();
+
+ if ( 0 == bytesXmitted )
+ {
+ signalSCI1XmitsCompleted();
+ }
+}
+#endif
+
+/*************************************************************************
+ * @brief initUARTAndDMA
+ * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA \n
+ * to go with it for PC communication.
+ * @details
+ * Inputs : none
+ * Outputs : SCI1 and DMA initialized
+ * @param none
+ * @return none
+ *************************************************************************/
+#ifdef DEBUG_ENABLED
+static void initUARTAndDMA( void )
+{
+ // Enable DMA block transfer complete interrupts
+ dmaEnableInterrupt( DMA_CH1, BTC );
+ dmaEnableInterrupt( DMA_CH3, BTC );
+ // assign DMA channels to h/w DMA requests
+ dmaReqAssign( DMA_CH1, SCI1_RECEIVE_DMA_REQUEST );
+ dmaReqAssign( DMA_CH3, SCI1_TRANSMIT_DMA_REQUEST );
+ // set DMA channel priorities
+ dmaSetPriority( DMA_CH1, HIGHPRIORITY );
+ dmaSetPriority( DMA_CH3, LOWPRIORITY );
+
+ // initialize PC DMA Transmit Control Record
+ pcDMAXmitControlRecord.PORTASGN = 4; // port B (only choice per datasheet)
+ pcDMAXmitControlRecord.DADD = (U32)(&(sciREG->TD)); // dest. is SCI2 xmit register
+ pcDMAXmitControlRecord.SADD = (U32)pcXmitPacket; // source
+ pcDMAXmitControlRecord.CHCTRL = 0; // no chaining
+ pcDMAXmitControlRecord.ELCNT = 1; // frame is 1 element
+ pcDMAXmitControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames
+ pcDMAXmitControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte
+ pcDMAXmitControlRecord.WRSIZE = ACCESS_8_BIT; //
+ pcDMAXmitControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer
+ pcDMAXmitControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed
+ pcDMAXmitControlRecord.ADDMODERD = ADDR_INC1; // source addressing mode is post-increment
+ pcDMAXmitControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off
+ pcDMAXmitControlRecord.ELSOFFSET = 0; // not used
+ pcDMAXmitControlRecord.ELDOFFSET = 0; // not used
+ pcDMAXmitControlRecord.FRSOFFSET = 0; // not used
+ pcDMAXmitControlRecord.FRDOFFSET = 0; // not used
+
+ // initialize PC DMA Receipt Control Record
+ pcDMARecvControlRecord.PORTASGN = 4; // port B (only choice per datasheet)
+ pcDMARecvControlRecord.SADD = (U32)(&(sciREG->RD)); // source is SCI2 recv register
+ pcDMARecvControlRecord.DADD = (U32)pcRecvPacket; // transfer destination address
+ pcDMARecvControlRecord.CHCTRL = 0; // no chaining
+ pcDMARecvControlRecord.ELCNT = 1; // frame is 1 element
+ pcDMARecvControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames
+ pcDMARecvControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte
+ pcDMARecvControlRecord.WRSIZE = ACCESS_8_BIT; //
+ pcDMARecvControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer
+ pcDMARecvControlRecord.ADDMODERD = ADDR_FIXED; // source addressing mode is fixed
+ pcDMARecvControlRecord.ADDMODEWR = ADDR_INC1; // dest. addressing mode is post-increment
+ pcDMARecvControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off
+ pcDMARecvControlRecord.ELDOFFSET = 0; // not used
+ pcDMARecvControlRecord.ELSOFFSET = 0; // not used
+ pcDMARecvControlRecord.FRDOFFSET = 0; // not used
+ pcDMARecvControlRecord.FRSOFFSET = 0; // not used
+
+ // initiate PC packet receiving readiness via DMA
+ dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord );
+ dmaSetChEnable( DMA_CH1, DMA_HW );
+ setSCI1DMAReceiveInterrupt();
+}
+#endif
+
+/*************************************************************************
+ * @brief isCANBoxForXmit
+ * The isCANBoxForXmit function determines whether a given CAN message box \n
+ * is configured for transmit.
+ * @details
+ * Inputs : CAN_OUT_BUFFERS[]
+ * Outputs : none
+ * @param srcCANBox : which CAN message box to check
+ * @return TRUE if the given CAN message box is configured for transmit, FALSE if not.
+ *************************************************************************/
+BOOL isCANBoxForXmit( CAN_MESSAGE_BOX_T srcCANBox )
+{
+ BOOL result = FALSE;
+ U32 i;
+
+ for ( i = 0; i < NUM_OF_CAN_OUT_BUFFERS; i++ )
+ {
+ if ( CAN_OUT_BUFFERS[ i ] == srcCANBox )
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*************************************************************************
+ * @brief isCANBoxForRecv
+ * The isCANBoxForRecv function determines whether a given CAN message box \n
+ * is configured for receiving.
+ * @details
+ * Inputs : MSG_IN_BUFFERS[]
+ * Outputs : none
+ * @param srcCANBox : which CAN message box to check
+ * @return TRUE if the given CAN message box is configured for receiving, FALSE if not.
+ *************************************************************************/
+BOOL isCANBoxForRecv( CAN_MESSAGE_BOX_T srcCANBox )
+{
+ BOOL result = FALSE;
+ U32 i;
+
+ for ( i = 0; i < NUM_OF_CAN_IN_BUFFERS; i++ )
+ {
+ if ( MSG_IN_BUFFERS[ i ] == srcCANBox )
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+BOOL isDGOnlyCANNode( void )
+{
+ return FALSE;
+}
+
+
+/*************************************************************************
+********************** TRANSMIT SUPPORT FUNCTIONS ************************
+*************************************************************************/
+
+
+/*************************************************************************
+ * @brief findNextHighestPriorityCANPacketToTransmit
+ * The findNextHighestPriorityCANPacketToTransmit function gets the next \n
+ * 8 byte packet and initiates a CAN transmit on the appropriate CAN channel. \n
+ * @details
+ * Inputs : Output CAN Comm Buffer(s)
+ * Outputs : none
+ * @param msg : none
+ * @return buffer with highest priority CAN packet to transmit, \n
+ * COMM_BUFFER_NOT_USED if not CAN packets pending transmit found
+ *************************************************************************/
+static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void )
+{
+ COMM_BUFFER_T result = COMM_BUFFER_NOT_USED;
+ U32 i;
+
+ // search for next priority CAN packet to transmit
+ for ( i = 0; i < NUM_OF_CAN_OUT_BUFFERS; i++ )
+ {
+ if ( numberOfBytesInCommBuffer( CAN_OUT_BUFFERS[ i ] ) >= CAN_MESSAGE_PAYLOAD_SIZE )
+ {
+ result = CAN_OUT_BUFFERS[ i ];
+ break; // found highest priority packet to transmit - we're done
+ }
+ }
+
+ return result;
+}
+
+/*************************************************************************
+ * @brief transmitNextCANPacket
+ * The transmitNextCANPacket function gets the next 8 byte packet and initiates \n
+ * a CAN transmit on the appropriate CAN channel.
+ * @details
+ * Inputs : Output CAN Comm Buffers
+ * Outputs : CAN packet transmit initiated.
+ * @param msg : none
+ * @return # of bytes transmitted
+ *************************************************************************/
+static U32 transmitNextCANPacket( void )
+{
+ U32 result = 0;
+ COMM_BUFFER_T buffer = findNextHighestPriorityCANPacketToTransmit();
+
+ // if a buffer is found with a packet to transmit, get packet from buffer and transmit it
+ if ( buffer != COMM_BUFFER_NOT_USED )
+ {
+ U08 data[ CAN_MESSAGE_PAYLOAD_SIZE ];
+ U32 dataSize = getFromCommBuffer( buffer, data, CAN_MESSAGE_PAYLOAD_SIZE );
+ CAN_MESSAGE_BOX_T mBox = buffer; // CAN message boxes and comm buffers are aligned
+
+ // if there's another CAN packet to send, send it
+ if ( dataSize == CAN_MESSAGE_PAYLOAD_SIZE )
+ {
+ // we're transmitting another packet - signal transmitter is busy
+ signalCANXmitsInitiated();
+ // remember packet data being transmitted here in case transmission fails and we need to re-send
+ memcpy( lastCANPacketSent, data, CAN_MESSAGE_PAYLOAD_SIZE );
+ lastCANPacketSentChannel = mBox;
+ lastCANPacketSentTimeStamp = getMSTimerCount();
+ if ( 0 != canTransmit( canREG1, mBox, data ) )
+ {
+ result = CAN_MESSAGE_PAYLOAD_SIZE;
}
- // we must be only node on CAN bus - nobody is ACKing our transmitted frames
else
{
- dgIsOnlyCANNode = TRUE; // set only CAN node flag
- canXmitRetryCtr = MAX_XMIT_RETRIES;
- signalCANXmitsCompleted(); // clear pending xmit flag
- clearCANXmitBuffers(); // clear xmit buffers - nothing is going out right now
+ signalCANXmitsCompleted();
+ // TODO - shouldn't get here, but let's see if we do
+ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, (U32)mBox )
+ }
+ }
+ else
+ { // TODO - shouldn't get here - just testing - set first data to new s/w fault enum later
+ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, (U32)buffer, (U32)dataSize )
+ }
+ }
+
+ return result;
+}
+
+/*************************************************************************
+ * @brief transmitNextUARTPacket
+ * The transmitNextUARTPacket function sets up and initiates a DMA transmit \n
+ * of the next packet pending transmit (if any) via UART.
+ * @details
+ * Inputs : Output UART Comm Buffer(s)
+ * Outputs : UART DMA transmit initiated.
+ * @param msg : none
+ * @return # of bytes transmitted
+ *************************************************************************/
#ifdef DEBUG_ENABLED
+static U32 transmitNextUARTPacket( void )
+{
+ U32 result = 0;
+ U32 dataPend = numberOfBytesInCommBuffer( COMM_BUFFER_OUT_UART_PC );
+
+ if ( dataPend > 0 )
+ {
+ result = getFromCommBuffer( COMM_BUFFER_OUT_UART_PC, pcXmitPacket, dataPend );
+
+ // if there's data to transmit, transmit it
+ if ( result > 0 )
+ {
+ signalSCI1XmitsInitiated();
+ pcDMAXmitControlRecord.FRCNT = result; // set DMA transfer size
+ dmaSetCtrlPacket( DMA_CH3, pcDMAXmitControlRecord );
+ dmaSetChEnable( DMA_CH3, DMA_HW );
+ setSCI1DMATransmitInterrupt();
+ }
+ }
+
+ return result;
+}
+#endif
+
+
+/*************************************************************************
+********************** RECEIVE SUPPORT FUNCTIONS *************************
+*************************************************************************/
+
+
+/*************************************************************************
+ * @brief processIncomingData
+ * The processIncomingData function parses out messages from the Input \n
+ * Comm Buffers and adds them to the Received Message Queue.
+ * @details
+ * Inputs : Input Comm Buffers
+ * Outputs : Parsed message(s) added to Received Message Queue
+ * @param msg : none
+ * @return none
+ *************************************************************************/
+static void processIncomingData( void )
+{
+ U08 data[ 512 ]; // message work space
+ U32 i;
+ BOOL badCRCDetected = FALSE;
+
+ // queue any received messages
+ for ( i = 0; i < NUM_OF_MSG_IN_BUFFERS; i++ )
+ {
+ BOOL messagesInBuffer = TRUE; // assume true at first to get into while loop
+
+ while ( TRUE == messagesInBuffer )
+ {
+ U32 numOfBytesInBuffer;
+
+ // assume false so we don't get stuck in loop - only set to true if we find another complete message in buffer
+ messagesInBuffer = FALSE;
+
+ // since messages can have 8-byte alignment padding left unconsumed by last get, get padding out of buffer
+ consumeBufferPaddingBeforeSync( MSG_IN_BUFFERS[ i ] );
+ // do we have enough bytes in buffer for smallest message?
+ numOfBytesInBuffer = numberOfBytesInCommBuffer( MSG_IN_BUFFERS[ i ] );
+ if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE )
+ { // peek at minimum of all bytes available or max message size (+1 for sync byte)
+ U32 bytesPeeked = peekFromCommBuffer( MSG_IN_BUFFERS[ i ], data, MIN( numOfBytesInBuffer, sizeof( MESSAGE_WRAPPER_T ) + 1 ) );
+ S32 msgSize = parseMessageFromBuffer( data, bytesPeeked );
+
+ if ( msgSize > 0 ) // valid, complete message found?
{
- char debugStr[100];
- sprintf( debugStr, "SystemComm-DG is only node.\n" );
- sendDebugDataToUI( (U08*)debugStr );
+ MESSAGE_WRAPPER_T rcvMsg;
+ U08 *dataPtr = data+1; // skip over sync byte
+
+ // consume message (+sync byte)
+ msgSize = getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, msgSize + 1 );
+ // convert received message data to a message and add to message queue
+ messagesInBuffer = TRUE; // keep processing this buffer
+ // blank the new message record
+ blankMessageInWrapper( &rcvMsg );
+ // copy message header portion of message data to the new message
+ memcpy( &(rcvMsg.msg.hdr), dataPtr, sizeof(MESSAGE_HEADER_T) );
+ dataPtr += sizeof(MESSAGE_HEADER_T);
+ // copy message payload portion of message data to the new message
+ memcpy( &(rcvMsg.msg.payload), dataPtr, rcvMsg.msg.hdr.payloadLen );
+ dataPtr += rcvMsg.msg.hdr.payloadLen;
+ // copy CRC portion of message data to the new message
+ rcvMsg.crc = *dataPtr;
+ // add new message to queue for later processing
+ addToMsgQueue( MSG_Q_IN, &rcvMsg );
+ // if message from HD broadcast channel, update HD comm status
+ if ( COMM_BUFFER_IN_CAN_HD_BROADCAST == MSG_IN_BUFFERS[ i ] )
+ {
+ hdIsCommunicating = TRUE;
+ timeOfLastHDCheckIn = getMSTimerCount();
+ }
}
+ else if ( -1 == msgSize ) // candidate message with bad CRC found?
+ {
+ badCRCDetected = TRUE;
+ getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, 1 ); // consume sync byte so we can re-sync
+ messagesInBuffer = TRUE; // keep processing this buffer
+ } // looks like there is a complete message in the comm buffer
+ } // enough data left in comm buffer to possibly be a complete message
+ } // while loop to get all complete messages for each comm buffer
+ } // for loop to check all comm buffers for messages
+
+ // if any bad CRCs detected, see if too many
+ if ( TRUE == badCRCDetected )
+ {
+ checkTooManyBadMsgCRCs();
+ }
+}
+
+/*************************************************************************
+ * @brief consumeBufferPaddingBeforeSync
+ * The consumeBufferPaddingBeforeSync function removes any bytes in a given \n
+ * buffer that lie before a sync byte.
+ * @details
+ * Inputs : none
+ * Outputs : none
+ * @param msg : buffer : the comm buffer to process
+ * @return none
+ *************************************************************************/
+static void consumeBufferPaddingBeforeSync( COMM_BUFFER_T buffer )
+{
+ U08 data;
+ U32 numOfBytesInBuffer = numberOfBytesInCommBuffer( buffer );
+
+ // consume bytes out of buffer 1 at a time until we find the sync byte or it's empty
+ while ( numOfBytesInBuffer > 0 )
+ {
+ peekFromCommBuffer( buffer, &data, 1 );
+ if ( MESSAGE_SYNC_BYTE == data )
+ {
+ break; // we found a sync - we're done
+ }
+ else // not a sync byte, so consume it
+ {
+ getFromCommBuffer( buffer, &data, 1 );
+ numOfBytesInBuffer = numberOfBytesInCommBuffer( buffer );
+ }
+ }
+}
+
+/*************************************************************************
+ * @brief parseMessageFromBuffer
+ * The parseMessageFromBuffer function looks for a complete message in a \n
+ * given buffer. If a message is found, its size is returned.
+ * @details
+ * Inputs : none
+ * Outputs : none
+ * @param data : pointer to byte array to search for a message
+ * @param len : # of bytes in the data to search
+ * @return size of message if found, zero if no complete message found, \n
+ * -1 if message found but CRC fails.
+ *************************************************************************/
+static S32 parseMessageFromBuffer( U08 *data, U32 len )
+{
+ U32 i;
+ U32 payloadSize;
+ U32 msgSize;
+ S32 result = 0;
+
+ for ( i = 0; i < len; i++ )
+ {
+ // find sync byte
+ if ( MESSAGE_SYNC_BYTE == data[ i ] )
+ {
+ U32 pos = i + 1; // skip past sync byte implemented
+ U32 remSize = len - pos;
+
+ // if a minimum sized msg would fit in remaining, continue
+ if ( remSize >= MESSAGE_OVERHEAD_SIZE )
+ {
+ payloadSize = data[ pos + sizeof(MESSAGE_HEADER_T) - sizeof(U08) ];
+ msgSize = MESSAGE_OVERHEAD_SIZE + payloadSize;
+ // we now know the size of the message - we can now know if full message is contained in buffer
+ if ( msgSize <= remSize )
+ { // check CRC to make sure it's a valid message
+ if ( data[i+msgSize] == crc8( &data[pos], msgSize - 1 ) )
+ {
+ result = msgSize; // we found a complete, valid message of this size
+ }
+ else // CRC failed
+ {
+ result = -1; // we found a complete, invalid message
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*************************************************************************
+ * @brief processReceivedMessages
+ * The processReceivedMessages function processes any messages in the \n
+ * received message queues.
+ * @details
+ * Inputs : Received Message Queues
+ * Outputs : Message(s) processed.
+ * @param msg : none
+ * @return none
+ *************************************************************************/
+static void processReceivedMessages( void )
+{
+ BOOL isThereMsgRcvd = TRUE; // assume TRUE at first to get into while loop
+ MESSAGE_WRAPPER_T message;
+
+ while ( TRUE == isThereMsgRcvd )
+ {
+ // see if any messages received
+ isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN, &message );
+ if ( TRUE == isThereMsgRcvd )
+ { // CRC should be good because we checked it during parsing before adding to queue - but check it again for good measure
+ if ( message.crc == crc8( (U08*)(&message), sizeof(MESSAGE_HEADER_T) + message.msg.hdr.payloadLen ) )
+ {
+ // if ACK, mark pending message ACK'd
+ if ( MSG_ID_ACK == message.msg.hdr.msgID )
+ {
+ matchACKtoPendingACKList( message.msg.hdr.seqNo );
+ }
+ else
+ {
+ // if received message requires ACK, queue one up
+ if ( message.msg.hdr.seqNo < 0 )
+ {
+ sendACKMsg( &message.msg );
+ }
+ // otherwise, process the received message
+ processReceivedMessage( &message.msg );
+ }
+ }
+ else // CRC failed
+ {
+ checkTooManyBadMsgCRCs();
+ }
+ }
+ }
+}
+
+/*************************************************************************
+ * @brief checkForCommTimeouts
+ * The checkForCommTimeouts function checks for sub-system communication \n
+ * timeout errors.
+ * @details
+ * Inputs : timeOfLastDGCheckIn, timeOfLastUICheckIn
+ * Outputs : possibly a comm t/o alarm
+ * @param none
+ * @return none
+ *************************************************************************/
+static void checkForCommTimeouts( void )
+{
+ if ( TRUE == didTimeout( timeOfLastHDCheckIn, HD_COMM_TIMEOUT_IN_MS ) )
+ {
+ hdIsCommunicating = FALSE;
+#ifndef DEBUG_ENABLED
+ activateAlarmNoData( ALARM_ID_HD_COMM_TIMEOUT ); // TODO - add this alarm if we're in middle of a treatment? or if in a mode that comm loss would impact badly?
#endif
- }
- }
- }
-
-#ifdef DEBUG_ENABLED
- // if UART transmitter is idle, start transmitting any pending packets
- if ( FALSE == isSCI1DMATransmitInProgress() )
- {
- transmitNextUARTPacket();
- }
-#endif
-}
-
-/*********************************************************************//**
- * @brief
- * The handleCANMsgInterrupt function handles a CAN message interrupt. \n
- * This may have occurred because a CAN packet transmission has completed \n
- * or because a CAN packet has been received. The appropriate handler is \n
- * called.
- * @details
- * Inputs : none
- * Outputs : message interrupt handled
- * @param srcCANBox : which CAN message box triggered this interrupt
- * @return none
- *************************************************************************/
-void handleCANMsgInterrupt( CAN_MESSAGE_BOX_T srcCANBox )
-{
- // message interrupt is for a transmit message box?
- if ( TRUE == isCANBoxForXmit( srcCANBox ) )
- {
- U32 bytesXmitted = transmitNextCANPacket();
-
- if ( 0 == bytesXmitted )
- {
- signalCANXmitsCompleted();
- }
- }
- else if ( TRUE == isCANBoxForRecv( srcCANBox ) )
- {
- U08 data[ CAN_MESSAGE_PAYLOAD_SIZE ];
-
- // get CAN packet received on given CAN message box
- if ( FALSE != canIsRxMessageArrived( canREG1, srcCANBox ) )
- {
- U32 result = canGetData( canREG1, srcCANBox, data );
-
- // if packet retrieved, add to buffer
- if ( result != 0 )
- {
- // add CAN packet to appropriate comm buffer based on the message box it came in on (s/b same #)
- addToCommBuffer( srcCANBox, data, CAN_MESSAGE_PAYLOAD_SIZE );
- }
- }
- }
- else
- {
- // shouldn't get here - not an active message box
- // s/w fault?
- }
-}
-
-/*********************************************************************//**
- * @brief
- * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive \n
- * packet completed interrupt.
- * @details
- * Inputs : none
- * Outputs : none
- * @return none
- *************************************************************************/
-#ifdef DEBUG_ENABLED
-void handleUARTMsgRecvPacketInterrupt( void )
-{
- // buffer received packet
- addToCommBuffer( COMM_BUFFER_IN_UART_PC, pcRecvPacket, PC_MESSAGE_PACKET_SIZE );
- // prepare to receive next packet
- dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord );
- dmaSetChEnable( DMA_CH1, DMA_HW );
- setSCI1DMAReceiveInterrupt();
-}
-#endif
-
-/*********************************************************************//**
- * @brief
- * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit \n
- * packet completed interrupt.
- * @details
- * Inputs : none
- * Outputs : none
- * @return none
- *************************************************************************/
-#ifdef DEBUG_ENABLED
-void handleUARTMsgXmitPacketInterrupt( void )
-{
- U32 bytesXmitted = transmitNextUARTPacket();
-
- if ( 0 == bytesXmitted )
- {
- signalSCI1XmitsCompleted();
- }
-}
-#endif
-
-/*********************************************************************//**
- * @brief
- * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA \n
- * to go with it for PC communication.
- * @details
- * Inputs : none
- * Outputs : SCI1 and DMA initialized
- * @return none
- *************************************************************************/
-#ifdef DEBUG_ENABLED
-static void initUARTAndDMA( void )
-{
- // Enable DMA block transfer complete interrupts
- dmaEnableInterrupt( DMA_CH1, BTC );
- dmaEnableInterrupt( DMA_CH3, BTC );
- // assign DMA channels to h/w DMA requests
- dmaReqAssign( DMA_CH1, SCI1_RECEIVE_DMA_REQUEST );
- dmaReqAssign( DMA_CH3, SCI1_TRANSMIT_DMA_REQUEST );
- // set DMA channel priorities
- dmaSetPriority( DMA_CH1, HIGHPRIORITY );
- dmaSetPriority( DMA_CH3, LOWPRIORITY );
-
- // initialize PC DMA Transmit Control Record
- pcDMAXmitControlRecord.PORTASGN = 4; // port B (only choice per datasheet)
- pcDMAXmitControlRecord.DADD = (U32)(&(sciREG->TD)); // dest. is SCI2 xmit register
- pcDMAXmitControlRecord.SADD = (U32)pcXmitPacket; // source
- pcDMAXmitControlRecord.CHCTRL = 0; // no chaining
- pcDMAXmitControlRecord.ELCNT = 1; // frame is 1 element
- pcDMAXmitControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames
- pcDMAXmitControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte
- pcDMAXmitControlRecord.WRSIZE = ACCESS_8_BIT; //
- pcDMAXmitControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer
- pcDMAXmitControlRecord.ADDMODEWR = ADDR_FIXED; // dest. addressing mode is fixed
- pcDMAXmitControlRecord.ADDMODERD = ADDR_INC1; // source addressing mode is post-increment
- pcDMAXmitControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off
- pcDMAXmitControlRecord.ELSOFFSET = 0; // not used
- pcDMAXmitControlRecord.ELDOFFSET = 0; // not used
- pcDMAXmitControlRecord.FRSOFFSET = 0; // not used
- pcDMAXmitControlRecord.FRDOFFSET = 0; // not used
-
- // initialize PC DMA Receipt Control Record
- pcDMARecvControlRecord.PORTASGN = 4; // port B (only choice per datasheet)
- pcDMARecvControlRecord.SADD = (U32)(&(sciREG->RD)); // source is SCI2 recv register
- pcDMARecvControlRecord.DADD = (U32)pcRecvPacket; // transfer destination address
- pcDMARecvControlRecord.CHCTRL = 0; // no chaining
- pcDMARecvControlRecord.ELCNT = 1; // frame is 1 element
- pcDMARecvControlRecord.FRCNT = PC_MESSAGE_PACKET_SIZE; // block is 8 frames
- pcDMARecvControlRecord.RDSIZE = ACCESS_8_BIT; // element size is 1 byte
- pcDMARecvControlRecord.WRSIZE = ACCESS_8_BIT; //
- pcDMARecvControlRecord.TTYPE = FRAME_TRANSFER; // transfer type is block transfer
- pcDMARecvControlRecord.ADDMODERD = ADDR_FIXED; // source addressing mode is fixed
- pcDMARecvControlRecord.ADDMODEWR = ADDR_INC1; // dest. addressing mode is post-increment
- pcDMARecvControlRecord.AUTOINIT = AUTOINIT_OFF; // auto-init off
- pcDMARecvControlRecord.ELDOFFSET = 0; // not used
- pcDMARecvControlRecord.ELSOFFSET = 0; // not used
- pcDMARecvControlRecord.FRDOFFSET = 0; // not used
- pcDMARecvControlRecord.FRSOFFSET = 0; // not used
-
- // initiate PC packet receiving readiness via DMA
- dmaSetCtrlPacket( DMA_CH1, pcDMARecvControlRecord );
- dmaSetChEnable( DMA_CH1, DMA_HW );
- setSCI1DMAReceiveInterrupt();
-}
-#endif
-
-/*********************************************************************//**
- * @brief
- * The isCANBoxForXmit function determines whether a given CAN message box \n
- * is configured for transmit.
- * @details
- * Inputs : CAN_OUT_BUFFERS[]
- * Outputs : none
- * @param srcCANBox : which CAN message box to check
- * @return TRUE if the given CAN message box is configured for transmit, FALSE if not.
- *************************************************************************/
-BOOL isCANBoxForXmit( CAN_MESSAGE_BOX_T srcCANBox )
-{
- BOOL result = FALSE;
- U32 i;
-
- for ( i = 0; i < NUM_OF_CAN_OUT_BUFFERS; i++ )
- {
- if ( CAN_OUT_BUFFERS[ i ] == srcCANBox )
- {
- result = TRUE;
- break;
- }
- }
-
- return result;
-}
-
-/*********************************************************************//**
- * @brief
- * The isCANBoxForRecv function determines whether a given CAN message box \n
- * is configured for receiving.
- * @details
- * Inputs : MSG_IN_BUFFERS[]
- * Outputs : none
- * @param srcCANBox : which CAN message box to check
- * @return TRUE if the given CAN message box is configured for receiving, FALSE if not.
- *************************************************************************/
-BOOL isCANBoxForRecv( CAN_MESSAGE_BOX_T srcCANBox )
-{
- BOOL result = FALSE;
- U32 i;
-
- for ( i = 0; i < NUM_OF_CAN_IN_BUFFERS; i++ )
- {
- if ( MSG_IN_BUFFERS[ i ] == srcCANBox )
- {
- result = TRUE;
- break;
- }
- }
-
- return result;
+ }
}
-/*********************************************************************//**
- * @brief
- * The clearCANXmitBuffers function clears all CAN transmit buffers.
+/*************************************************************************
+ * @brief checkTooManyBadMsgCRCs
+ * The checkTooManyBadMsgCRCs function checks for too many bad message CRCs \n
+ * within a set period of time. Assumed function is being called when a new \n
+ * bad CRC is detected so a new bad CRC will be added to the list.
* @details
- * Inputs : CAN_OUT_BUFFERS[]
- * Outputs : CAN transmit buffers cleared.
+ * Inputs : badCRCTimeStamps[], badCRCListIdx, badCRCListCount
+ * Outputs : possibly a "too many bad CRCs" alarm
* @return none
*************************************************************************/
-static void clearCANXmitBuffers( void )
+static void checkTooManyBadMsgCRCs( void )
{
+ U32 listTimeInMS;
+
+ // replace oldest bad CRC in list with this new one
+ badCRCTimeStamps[ badCRCListIdx ] = getMSTimerCount();
+ // move list index to next position (may wrap)
+ badCRCListIdx = INC_WRAP( badCRCListIdx, 0, MAX_COMM_CRC_FAILURES - 1 );
+ // update list count
+ badCRCListCount = INC_CAP( badCRCListCount, MAX_COMM_CRC_FAILURES );
+ // check if too many bad CRCs in window of time
+ listTimeInMS = calcTimeSince( badCRCTimeStamps[ badCRCListIdx ] );
+ if ( ( badCRCListCount >= MAX_COMM_CRC_FAILURES ) && ( listTimeInMS <= MAX_COMM_CRC_FAILURE_WINDOW_MS ) )
+ {
+ activateAlarmNoData( ALARM_ID_COMM_TOO_MANY_BAD_CRCS );
+ }
+}
+
+/*************************************************************************
+ * @brief addMsgToPendingACKList
+ * The addMsgToPendingACKList function adds a given message to the pending \n
+ * ACK list. Messages in this list will require receipt of an ACK message \n
+ * for this particular message within a limited time.
+ * @details
+ * Inputs : pendingAckList[]
+ * Outputs : pendingAckList[]
+ * @param msg : pointer to msg within the message data
+ * @param msgData : pointer to message data to add to pending ACK list
+ * @param len : # of bytes of message data
+ * @return TRUE if message added successfully, FALSE if not
+ *************************************************************************/
+BOOL addMsgToPendingACKList( MESSAGE_T *msg, COMM_BUFFER_T channel, U08 *msgData, U32 len )
+{
+ BOOL result = FALSE;
U32 i;
- for ( i = 0; i < NUM_OF_CAN_OUT_BUFFERS; i++ )
+ // find first open slot in pending ACK list and add given msg data to it
+ for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
{
- clearBuffer( CAN_OUT_BUFFERS[ i ] );
+ _disable_IRQ(); // slot selection needs interrupt protection
+ if ( FALSE == pendingAckList[ i ].used )
+ {
+ S16 seqNo = msg->hdr.seqNo * -1; // remove ACK bit from seq #
+
+ pendingAckList[ i ].used = TRUE;
+ _enable_IRQ();
+ pendingAckList[ i ].seqNo = seqNo;
+ pendingAckList[ i ].channel = channel;
+ pendingAckList[ i ].timeStamp = getMSTimerCount();
+ pendingAckList[ i ].retries = MSG_NOT_ACKED_MAX_RETRIES;
+ pendingAckList[ i ].msgSize = len;
+ memcpy( pendingAckList[ i ].msg, msgData, len );
+ result = TRUE;
+ break;
+ }
+ else
+ {
+ _enable_IRQ();
+ }
}
-}
-
-
-/*************************************************************************
-********************** TRANSMIT SUPPORT FUNCTIONS ************************
-*************************************************************************/
-
-
-/*********************************************************************//**
- * @brief
- * The findNextHighestPriorityCANPacketToTransmit function gets the next \n
- * 8 byte packet and initiates a CAN transmit on the appropriate CAN channel. \n
- * @details
- * Inputs : Output CAN Comm Buffer(s)
- * Outputs : none
- * @return buffer with highest priority CAN packet to transmit, \n
- * COMM_BUFFER_NOT_USED if not CAN packets pending transmit found
- *************************************************************************/
-static COMM_BUFFER_T findNextHighestPriorityCANPacketToTransmit( void )
-{
- COMM_BUFFER_T result = COMM_BUFFER_NOT_USED;
- U32 i;
-
- // search for next priority CAN packet to transmit
- for ( i = 0; i < NUM_OF_CAN_OUT_BUFFERS; i++ )
- {
- if ( numberOfBytesInCommBuffer( CAN_OUT_BUFFERS[ i ] ) >= CAN_MESSAGE_PAYLOAD_SIZE )
- {
- result = CAN_OUT_BUFFERS[ i ];
- break; // found highest priority packet to transmit - we're done
- }
- }
-
- return result;
-}
-
-/*********************************************************************//**
- * @brief
- * The transmitNextCANPacket function gets the next 8 byte packet and initiates \n
- * a CAN transmit on the appropriate CAN channel.
- * @details
- * Inputs : Output CAN Comm Buffers
- * Outputs : CAN packet transmit initiated.
- * @return # of bytes transmitted
- *************************************************************************/
-static U32 transmitNextCANPacket( void )
-{
- U32 result = 0;
- COMM_BUFFER_T buffer = findNextHighestPriorityCANPacketToTransmit();
-
- // if a buffer is found with a packet to transmit, get packet from buffer and transmit it
- if ( buffer != COMM_BUFFER_NOT_USED )
- {
- U08 data[ CAN_MESSAGE_PAYLOAD_SIZE ];
- U32 dataSize = getFromCommBuffer( buffer, data, CAN_MESSAGE_PAYLOAD_SIZE );
- CAN_MESSAGE_BOX_T mBox = buffer; // CAN message boxes and comm buffers are aligned
-
- // if there's another CAN packet to send, send it
- if ( dataSize == CAN_MESSAGE_PAYLOAD_SIZE )
- {
- // we're transmitting another packet - signal transmitter is busy
- signalCANXmitsInitiated();
- // remember packet data being transmitted here in case transmission fails and we need to re-send
- memcpy( lastCANPacketSent, data, CAN_MESSAGE_PAYLOAD_SIZE );
- lastCANPacketSentChannel = mBox;
- lastCANPacketSentTimeStamp = getMSTimerCount();
- if ( 0 != canTransmit( canREG1, mBox, data ) )
- {
- result = CAN_MESSAGE_PAYLOAD_SIZE;
- }
- else
- {
- signalCANXmitsCompleted();
- // TODO - shouldn't get here, but let's see if we do
- SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, (U32)mBox )
- }
- }
- else
- { // TODO - shouldn't get here - just testing - set first data to new s/w fault enum later
- SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, (U32)buffer, (U32)dataSize )
- }
- }
-
- return result;
-}
-
-/*********************************************************************//**
- * @brief
- * The transmitNextUARTPacket function sets up and initiates a DMA transmit \n
- * of the next packet pending transmit (if any) via UART.
- * @details
- * Inputs : Output UART Comm Buffer(s)
- * Outputs : UART DMA transmit initiated.
- * @return # of bytes transmitted
- *************************************************************************/
-#ifdef DEBUG_ENABLED
-static U32 transmitNextUARTPacket( void )
-{
- U32 result = 0;
- U32 dataPend = numberOfBytesInCommBuffer( COMM_BUFFER_OUT_UART_PC );
-
- if ( dataPend > 0 )
- {
- result = getFromCommBuffer( COMM_BUFFER_OUT_UART_PC, pcXmitPacket, dataPend );
-
- // if there's data to transmit, transmit it
- if ( result > 0 )
- {
- signalSCI1XmitsInitiated();
- pcDMAXmitControlRecord.FRCNT = result; // set DMA transfer size
- dmaSetCtrlPacket( DMA_CH3, pcDMAXmitControlRecord );
- dmaSetChEnable( DMA_CH3, DMA_HW );
- setSCI1DMATransmitInterrupt();
- }
- }
-
- return result;
-}
-#endif
-
-
-/*************************************************************************
-********************** RECEIVE SUPPORT FUNCTIONS *************************
-*************************************************************************/
-
-
-/*********************************************************************//**
- * @brief
- * The processIncomingData function parses out messages from the Input \n
- * Comm Buffers and adds them to the Received Message Queue.
- * @details
- * Inputs : Input Comm Buffers
- * Outputs : Parsed message(s) added to Received Message Queue
- * @return none
- *************************************************************************/
-static void processIncomingData( void )
-{
- U08 data[ 512 ]; // message work space
- U32 i;
- BOOL badCRCDetected = FALSE;
-
- // queue any received messages
- for ( i = 0; i < NUM_OF_MSG_IN_BUFFERS; i++ )
- {
- BOOL messagesInBuffer = TRUE; // assume true at first to get into while loop
-
- while ( TRUE == messagesInBuffer )
- {
- U32 numOfBytesInBuffer;
-
- // assume false so we don't get stuck in loop - only set to true if we find another complete message in buffer
- messagesInBuffer = FALSE;
-
- // since messages can have 8-byte alignment padding left unconsumed by last get, get padding out of buffer
- consumeBufferPaddingBeforeSync( MSG_IN_BUFFERS[ i ] );
- // do we have enough bytes in buffer for smallest message?
- numOfBytesInBuffer = numberOfBytesInCommBuffer( MSG_IN_BUFFERS[ i ] );
- if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE )
- { // peek at minimum of all bytes available or max message size (+1 for sync byte)
- U32 bytesPeeked = peekFromCommBuffer( MSG_IN_BUFFERS[ i ], data, MIN( numOfBytesInBuffer, sizeof( MESSAGE_WRAPPER_T ) + 1 ) );
- S32 msgSize = parseMessageFromBuffer( data, bytesPeeked );
-
- dgIsOnlyCANNode = FALSE; // if we're getting a message, we can't be alone
- canXmitRetryCtr = 0;
- if ( msgSize > 0 ) // valid, complete message found?
- {
- MESSAGE_WRAPPER_T rcvMsg;
- U08 *dataPtr = data+1; // skip over sync byte
-
- // consume message (+sync byte)
- msgSize = getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, msgSize + 1 );
- // convert received message data to a message and add to message queue
- messagesInBuffer = TRUE; // keep processing this buffer
- // blank the new message record
- blankMessageInWrapper( &rcvMsg );
- // copy message header portion of message data to the new message
- memcpy( &(rcvMsg.msg.hdr), dataPtr, sizeof(MESSAGE_HEADER_T) );
- dataPtr += sizeof(MESSAGE_HEADER_T);
- // copy message payload portion of message data to the new message
- memcpy( &(rcvMsg.msg.payload), dataPtr, rcvMsg.msg.hdr.payloadLen );
- dataPtr += rcvMsg.msg.hdr.payloadLen;
- // copy CRC portion of message data to the new message
- rcvMsg.crc = *dataPtr;
- // add new message to queue for later processing
- addToMsgQueue( MSG_Q_IN, &rcvMsg );
- // if message from HD broadcast channel, update HD comm status
- if ( COMM_BUFFER_IN_CAN_HD_BROADCAST == MSG_IN_BUFFERS[ i ] )
- {
- hdIsCommunicating = TRUE;
- timeOfLastHDCheckIn = getMSTimerCount();
- }
- }
- else if ( -1 == msgSize ) // candidate message with bad CRC found?
- {
- badCRCDetected = TRUE;
- getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, 1 ); // consume sync byte so we can re-sync
- messagesInBuffer = TRUE; // keep processing this buffer
- } // looks like there is a complete message in the comm buffer
- } // enough data left in comm buffer to possibly be a complete message
- } // while loop to get all complete messages for each comm buffer
- } // for loop to check all comm buffers for messages
-
- // if any bad CRCs detected, see if too many
- if ( TRUE == badCRCDetected )
- {
- checkTooManyBadMsgCRCs();
- }
-}
-
-/*********************************************************************//**
- * @brief
- * The consumeBufferPaddingBeforeSync function removes any bytes in a given \n
- * buffer that lie before a sync byte.
- * @details
- * Inputs : none
- * Outputs : Any padding at front of comm buffer is consumed.
- * @param msg : buffer : the comm buffer to process
- * @return none
- *************************************************************************/
-static void consumeBufferPaddingBeforeSync( COMM_BUFFER_T buffer )
-{
- U08 data;
- U32 numOfBytesInBuffer = numberOfBytesInCommBuffer( buffer );
-
- // consume bytes out of buffer 1 at a time until we find the sync byte or it's empty
- while ( numOfBytesInBuffer > 0 )
- {
- peekFromCommBuffer( buffer, &data, 1 );
- if ( MESSAGE_SYNC_BYTE == data )
- {
- break; // we found a sync - we're done
- }
- else // not a sync byte, so consume it
- {
- getFromCommBuffer( buffer, &data, 1 );
- numOfBytesInBuffer = numberOfBytesInCommBuffer( buffer );
- }
- }
-}
-
-/*********************************************************************//**
- * @brief
- * The parseMessageFromBuffer function looks for a complete message in a \n
- * given buffer. If a message is found, its size is returned.
- * @details
- * Inputs : none
- * Outputs : If a complete message can be found in buffer contents, it is parsed out.
- * @param data : pointer to byte array to search for a message
- * @param len : # of bytes in the data to search
- * @return size of message if found, zero if no complete message found, \n
- * -1 if message found but CRC fails.
- *************************************************************************/
-static S32 parseMessageFromBuffer( U08 *data, U32 len )
-{
- U32 i;
- U32 payloadSize;
- U32 msgSize;
- S32 result = 0;
-
- for ( i = 0; i < len; i++ )
- {
- // find sync byte
- if ( MESSAGE_SYNC_BYTE == data[ i ] )
- {
- U32 pos = i + 1; // skip past sync byte implemented
- U32 remSize = len - pos;
-
- // if a minimum sized msg would fit in remaining, continue
- if ( remSize >= MESSAGE_OVERHEAD_SIZE )
- {
- payloadSize = data[ pos + sizeof(MESSAGE_HEADER_T) - sizeof(U08) ];
- msgSize = MESSAGE_OVERHEAD_SIZE + payloadSize;
- // we now know the size of the message - we can now know if full message is contained in buffer
- if ( msgSize <= remSize )
- { // check CRC to make sure it's a valid message
- if ( data[i+msgSize] == crc8( &data[pos], msgSize - 1 ) )
- {
- result = msgSize; // we found a complete, valid message of this size
- }
- else // CRC failed
- {
- result = -1; // we found a complete, invalid message
- }
- }
- }
- break;
- }
- }
-
- return result;
-}
-
-/*********************************************************************//**
- * @brief
- * The processReceivedMessages function processes any messages in the \n
- * received message queues.
- * @details
- * Inputs : Received Message Queues
- * Outputs : Message(s) processed.
- * @return none
- *************************************************************************/
-static void processReceivedMessages( void )
-{
- BOOL isThereMsgRcvd = TRUE; // assume TRUE at first to get into while loop
- MESSAGE_WRAPPER_T message;
-
- while ( TRUE == isThereMsgRcvd )
- {
- // see if any messages received
- isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN, &message );
- if ( TRUE == isThereMsgRcvd )
- { // CRC should be good because we checked it during parsing before adding to queue - but check it again for good measure
- if ( message.crc == crc8( (U08*)(&message), sizeof(MESSAGE_HEADER_T) + message.msg.hdr.payloadLen ) )
- {
- // if ACK, mark pending message ACK'd
- if ( MSG_ID_ACK == message.msg.hdr.msgID )
- {
- matchACKtoPendingACKList( message.msg.hdr.seqNo );
- }
- else
- {
- // if received message requires ACK, queue one up
- if ( message.msg.hdr.seqNo < 0 )
- {
- sendACKMsg( &message.msg );
- }
- // otherwise, process the received message
- processReceivedMessage( &message.msg );
- }
- }
- else // CRC failed
- {
- checkTooManyBadMsgCRCs();
- }
- }
- }
-}
-
-/*********************************************************************//**
- * @brief
- * The checkForCommTimeouts function checks for sub-system communication \n
- * timeout errors.
- * @details
- * Inputs : timeOfLastDGCheckIn, timeOfLastUICheckIn
- * Outputs : possibly a comm t/o alarm
- * @return none
- *************************************************************************/
-static void checkForCommTimeouts( void )
-{
- if ( TRUE == didTimeout( timeOfLastHDCheckIn, HD_COMM_TIMEOUT_IN_MS ) )
- {
- hdIsCommunicating = FALSE;
-#ifndef DEBUG_ENABLED
- activateAlarmNoData( ALARM_ID_HD_COMM_TIMEOUT ); // TODO - add this alarm if we're in middle of a treatment? or if in a mode that comm loss would impact badly?
-#endif
- }
-}
-
-/*********************************************************************//**
- * @brief
- * The checkTooManyBadMsgCRCs function checks for too many bad message CRCs \n
- * within a set period of time. Assumed function is being called when a new \n
- * bad CRC is detected so a new bad CRC will be added to the list.
- * @details
- * Inputs : badCRCTimeStamps[], badCRCListIdx, badCRCListCount
- * Outputs : possibly a "too many bad CRCs" alarm
- * @return none
- *************************************************************************/
-static void checkTooManyBadMsgCRCs( void )
+ return result;
+}
+
+/*************************************************************************
+ * @brief matchACKtoPendingACKList
+ * The matchACKtoPendingACKList function searches the pending ACK list to \n
+ * see if the sequence # from a received ACK msg matches any. If found, \n
+ * the list entry is removed.
+ * @details
+ * Inputs : pendingAckList[]
+ * Outputs : pendingAckList[]
+ * @param seqNo : sequence # to match to an entry in the list
+ * @return TRUE if a match was found, FALSE if not
+ *************************************************************************/
+static BOOL matchACKtoPendingACKList( S16 seqNo )
{
- if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_BAD_MSG_CRC ) )
+ BOOL result = FALSE;
+ U32 i;
+
+ // find match
+ for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
{
- SET_ALARM_WITH_1_U32_DATA( ALARM_ID_COMM_TOO_MANY_BAD_CRCS, 2 ); // 2 for DG
- }
-#ifdef DEBUG_ENABLED
+ if ( ( TRUE == pendingAckList[ i ].used ) && ( pendingAckList[ i ].seqNo == seqNo ) )
+ { // remove message pending ACK from list
+ pendingAckList[ i ].used = FALSE;
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*************************************************************************
+ * @brief checkPendingACKList
+ * The checkPendingACKList function searches the pending ACK list to \n
+ * see if any have expired. Any such messages will be queued for retransmission \n
+ * and if max retries reached a fault is triggered.
+ * @details
+ * Inputs : pendingAckList[]
+ * Outputs : pendingAckList[]
+ * @param none
+ * @return none
+ *************************************************************************/
+static void checkPendingACKList( void )
+{
+ U32 i;
+
+ // find expired messages pending ACK
+ for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
{
- char debugStr[100];
- sprintf( debugStr, "SystemComm-DG-Bad Msg CRC.\n" );
- sendDebugDataToUI( (U08*)debugStr );
+ if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, MSG_NOT_ACKED_TIMEOUT_MS ) ) )
+ {
+ if ( pendingAckList[ i ].retries > 0 )
+ { // re-queue message for transmit
+ pendingAckList[ i ].retries--;
+ pendingAckList[ i ].timeStamp = getMSTimerCount();
+ addToCommBuffer( pendingAckList[ i ].channel, pendingAckList[ i ].msg, pendingAckList[ i ].msgSize );
+ }
+ else
+ {
+ U16 msgID;
+
+ memcpy( &msgID, &pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) );
+ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID );
+ }
+ }
}
-#endif
-}
-
-/*********************************************************************//**
- * @brief
- * The addMsgToPendingACKList function adds a given message to the pending \n
- * ACK list. Messages in this list will require receipt of an ACK message \n
- * for this particular message within a limited time.
- * @details
- * Inputs : pendingAckList[]
- * Outputs : pendingAckList[]
- * @param msg : pointer to msg within the message data
- * @param msgData : pointer to message data to add to pending ACK list
- * @param len : # of bytes of message data
- * @return TRUE if message added successfully, FALSE if not
- *************************************************************************/
-BOOL addMsgToPendingACKList( MESSAGE_T *msg, COMM_BUFFER_T channel, U08 *msgData, U32 len )
-{
- BOOL result = FALSE;
- U32 i;
-
- // find first open slot in pending ACK list and add given msg data to it
- for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
- {
- _disable_IRQ(); // slot selection needs interrupt protection
- if ( FALSE == pendingAckList[ i ].used )
- {
- S16 seqNo = msg->hdr.seqNo * -1; // remove ACK bit from seq #
-
- pendingAckList[ i ].used = TRUE;
- _enable_IRQ();
- pendingAckList[ i ].seqNo = seqNo;
- pendingAckList[ i ].channel = channel;
- pendingAckList[ i ].timeStamp = getMSTimerCount();
- pendingAckList[ i ].retries = MSG_NOT_ACKED_MAX_RETRIES;
- pendingAckList[ i ].msgSize = len;
- memcpy( pendingAckList[ i ].msg, msgData, len );
- result = TRUE;
- break;
- }
- else
- {
- _enable_IRQ();
- }
- }
-
- return result;
-}
-
-/*********************************************************************//**
- * @brief
- * The matchACKtoPendingACKList function searches the pending ACK list to \n
- * see if the sequence # from a received ACK msg matches any. If found, \n
- * the list entry is removed.
- * @details
- * Inputs : pendingAckList[]
- * Outputs : pendingAckList[]
- * @param seqNo : sequence # to match to an entry in the list
- * @return TRUE if a match was found, FALSE if not
- *************************************************************************/
-static BOOL matchACKtoPendingACKList( S16 seqNo )
-{
- BOOL result = FALSE;
- U32 i;
-
- // find match
- for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
- {
- if ( ( TRUE == pendingAckList[ i ].used ) && ( pendingAckList[ i ].seqNo == seqNo ) )
- { // remove message pending ACK from list
- pendingAckList[ i ].used = FALSE;
- result = TRUE;
- break;
- }
- }
-
- return result;
-}
-
-/*********************************************************************//**
- * @brief
- * The checkPendingACKList function searches the pending ACK list to \n
- * see if any have expired. Any such messages will be queued for retransmission \n
- * and if max retries reached a fault is triggered.
- * @details
- * Inputs : pendingAckList[]
- * Outputs : pendingAckList[]
- * @return none
- *************************************************************************/
-static void checkPendingACKList( void )
-{
- U32 i;
-
- // find expired messages pending ACK
- for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ )
- {
- if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, MSG_NOT_ACKED_TIMEOUT_MS ) ) )
- {
- if ( pendingAckList[ i ].retries > 0 )
- { // re-queue message for transmit
- pendingAckList[ i ].retries--;
- pendingAckList[ i ].timeStamp = getMSTimerCount();
- addToCommBuffer( pendingAckList[ i ].channel, pendingAckList[ i ].msg, pendingAckList[ i ].msgSize );
- }
- else
- {
- U16 msgID;
-
- memcpy( &msgID, &pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) );
- SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID );
- }
- }
- }
-}
-
-/*********************************************************************//**
- * @brief
- * The processReceivedMessage function processes a given message.
- * @details
- * Inputs : none
- * Outputs : message processed
- * @param message : pointer to message to process
- * @return none
- *************************************************************************/
-static void processReceivedMessage( MESSAGE_T *message )
-{
- U16 msgID = message->hdr.msgID;
-
- // handle any messages from other sub-systems
- switch ( msgID )
- {
- case MSG_ID_POWER_OFF_WARNING:
- handlePowerOffWarning( message );
- break;
-
- case MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS:
- handleSetDialysateTemperatureCmd( message );
- break;
-
- case MSG_ID_REQUEST_FW_VERSIONS:
- handleFWVersionCmd( message );
- break;
-
- case MSG_ID_DG_SWITCH_RESERVOIR_CMD:
- handleSwitchReservoirCmd( message );
- break;
-
- case MSG_ID_DG_FILL_CMD:
- handleFillCmd( message );
- break;
-
- case MSG_ID_DG_DRAIN_CMD:
- handleDrainCmd( message );
- break;
-
- case MSG_ID_STARTING_STOPPING_TREATMENT_CMD:
- handleStartStopTreatmentMsg( message );
- break;
-
- case MSG_ID_DG_SAMPLE_WATER_CMD:
- handleSampleWaterCmd( message );
- break;
-
- case MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD:
- handleStartStopTrimmerHeaterCmd( message );
- break;
-
- case MSG_ID_DG_START_STOP_HEAT_DISINFECT:
- handleStartStopDGHeatDisinfect( message );
- break;
-
- case MSG_ID_DG_TESTER_LOGIN_REQUEST:
- handleTesterLogInRequest( message );
- break;
-
- default:
- // unrecognized message ID received - ok, ignore - may be a test message handled below
- break;
- }
-
- // handle any test messages if tester has logged in successfully
- if ( ( msgID > MSG_ID_FIRST_DG_TESTER_MESSAGE ) && ( msgID <= END_OF_MSG_IDS ) && ( TRUE == isTestingActivated() ) )
- {
- switch ( msgID )
- {
- case MSG_ID_DG_ALARM_STATE_OVERRIDE:
- handleTestAlarmStateOverrideRequest( message );
- break;
-
- case MSG_ID_DG_WATCHDOG_TASK_CHECKIN_OVERRIDE:
- handleTestWatchdogCheckInStateOverrideRequest( message );
- break;
-
- case MSG_ID_DG_SET_RTC_DATE_TIME:
- handleSetRTCTimestamp( message );
- break;
-
- case MSG_ID_START_STOP_PRIMARY_HEATER:
- handleStartStopPrimaryHeater ( message );
- break;
-
- case MSG_ID_LOAD_CELL_OVERRIDE:
- handleTestLoadCellOverrideRequest( message );
- break;
-
- case MSG_ID_LOAD_CELLL_SEND_INTERVAL_OVERRIDE:
- handleTestLoadCellDataBroadcastIntervalOverrideRequest( message );
- break;
-
- case MSG_ID_PRESSURE_OVERRIDE:
- handleTestPressureSensorOverrideRequest( message );
- break;
-
- case MSG_ID_PRESSURE_SEND_INTERVAL_OVERRIDE:
- handleTestPressureDataBroadcastIntervalOverrideRequest( message );
- break;
-
- case MSG_ID_RO_PUMP_SET_PT_OVERRIDE:
- handleTestROPumpSetPointOverrideRequest( message );
- break;
-
- case MSG_ID_RO_MEASURED_FLOW_OVERRIDE:
- handleTestROMeasuredFlowOverrideRequest( message );
- break;
-
- case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE:
- handleTestROPumpDataBroadcastIntervalOverrideRequest( message );
- break;
-
- case MSG_ID_DRAIN_PUMP_SET_PT_OVERRIDE:
- handleTestDrainPumpSetPointOverrideRequest( message );
- break;
-
- case MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE:
- handleTestDrainPumpDataBroadcastIntervalOverrideRequest( message );
- break;
-
- case MSG_ID_VALVE_STATE_OVERRIDE:
- handleTestValveStateOverrideRequest( message );
- break;
-
- case MSG_ID_VALVES_STATES_PUBLISH_INTERVAL_OVERRIDE:
- handleTestValvesStatesPublishIntervalOverrideRequest( message );
- break;
-
- case MSG_ID_DG_SAFETY_SHUTDOWN_OVERRIDE:
- handleTestDGSafetyShutdownOverrideRequest( message );
-
- case MSG_ID_TEMPERATURE_SENSORS_VALUE_OVERRIDE:
- handleTestTemperatureSensorsOverrideRequest ( message );
- break;
-
- case MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE:
- handleTestTemperatureSensorsDataPublishOverrideRequest ( message );
- break;
-
- case MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE:
- handleTestHeatersDataPublishOverrideRequest ( message );
- break;
-
- default:
- // TODO - unrecognized message ID received - ignore
- break;
- }
- }
-}
+}
-/**@}*/
+/*************************************************************************
+ * @brief processReceivedMessage
+ * The processReceivedMessage function processes a given message.
+ * @details
+ * Inputs : none
+ * Outputs : message processed
+ * @param message : pointer to message to process
+ * @return none
+ *************************************************************************/
+static void processReceivedMessage( MESSAGE_T *message )
+{
+ U16 msgID = message->hdr.msgID;
+
+ // handle any messages from other sub-systems
+ switch ( msgID )
+ {
+ case MSG_ID_POWER_OFF_WARNING:
+ handlePowerOffWarning( message );
+ break;
+
+ case MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS:
+ handleSetDialysateTemperatureCmd( message );
+ break;
+
+ case MSG_ID_REQUEST_FW_VERSIONS:
+ handleFWVersionCmd( message );
+ break;
+
+ case MSG_ID_DG_SWITCH_RESERVOIR_CMD:
+ handleSwitchReservoirCmd( message );
+ break;
+
+ case MSG_ID_DG_FILL_CMD:
+ handleFillCmd( message );
+ break;
+
+ case MSG_ID_DG_DRAIN_CMD:
+ handleDrainCmd( message );
+ break;
+
+ case MSG_ID_STARTING_STOPPING_TREATMENT_CMD:
+ handleStartStopTreatmentMsg( message );
+ break;
+
+ case MSG_ID_DG_SAMPLE_WATER_CMD:
+ handleSampleWaterCmd( message );
+ break;
+
+ case MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD:
+ handleStartStopTrimmerHeaterCmd( message );
+ break;
+
+ case MSG_ID_DG_START_STOP_HEAT_DISINFECT:
+ handleStartStopDGHeatDisinfect( message );
+ break;
+
+ case MSG_ID_DG_TESTER_LOGIN_REQUEST:
+ handleTesterLogInRequest( message );
+ break;
+
+ default:
+ // unrecognized message ID received - ok, ignore - may be a test message handled below
+ break;
+ }
+
+ // handle any test messages if tester has logged in successfully
+ if ( ( msgID > MSG_ID_FIRST_DG_TESTER_MESSAGE ) && ( msgID <= END_OF_MSG_IDS ) && ( TRUE == isTestingActivated() ) )
+ {
+ switch ( msgID )
+ {
+ case MSG_ID_DG_ALARM_STATE_OVERRIDE:
+ handleTestAlarmStateOverrideRequest( message );
+ break;
+
+ case MSG_ID_DG_WATCHDOG_TASK_CHECKIN_OVERRIDE:
+ handleTestWatchdogCheckInStateOverrideRequest( message );
+ break;
+
+ case MSG_ID_DG_SET_RTC_DATE_TIME:
+ handleSetRTCTimestamp( message );
+ break;
+
+ case MSG_ID_START_STOP_PRIMARY_HEATER:
+ handleStartStopPrimaryHeater ( message );
+ break;
+
+ case MSG_ID_LOAD_CELL_OVERRIDE:
+ handleTestLoadCellOverrideRequest( message );
+ break;
+
+ case MSG_ID_LOAD_CELLL_SEND_INTERVAL_OVERRIDE:
+ handleTestLoadCellDataBroadcastIntervalOverrideRequest( message );
+ break;
+
+ case MSG_ID_PRESSURE_OVERRIDE:
+ handleTestPressureSensorOverrideRequest( message );
+ break;
+
+ case MSG_ID_PRESSURE_SEND_INTERVAL_OVERRIDE:
+ handleTestPressureDataBroadcastIntervalOverrideRequest( message );
+ break;
+
+ case MSG_ID_RO_PUMP_SET_PT_OVERRIDE:
+ handleTestROPumpSetPointOverrideRequest( message );
+ break;
+
+ case MSG_ID_RO_MEASURED_FLOW_OVERRIDE:
+ handleTestROMeasuredFlowOverrideRequest( message );
+ break;
+
+ case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE:
+ handleTestROPumpDataBroadcastIntervalOverrideRequest( message );
+ break;
+
+ case MSG_ID_DRAIN_PUMP_SET_PT_OVERRIDE:
+ handleTestDrainPumpSetPointOverrideRequest( message );
+ break;
+
+ case MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE:
+ handleTestDrainPumpDataBroadcastIntervalOverrideRequest( message );
+ break;
+
+ case MSG_ID_VALVE_STATE_OVERRIDE:
+ handleTestValveStateOverrideRequest( message );
+ break;
+
+ case MSG_ID_VALVES_STATES_PUBLISH_INTERVAL_OVERRIDE:
+ handleTestValvesStatesPublishIntervalOverrideRequest( message );
+ break;
+
+ case MSG_ID_DG_SAFETY_SHUTDOWN_OVERRIDE:
+ handleTestDGSafetyShutdownOverrideRequest( message );
+
+ case MSG_ID_TEMPERATURE_SENSORS_VALUE_OVERRIDE:
+ handleTestTemperatureSensorsOverrideRequest ( message );
+ break;
+
+ case MSG_ID_TEMPERATURE_SENSORS_PUBLISH_INTERVAL_OVERRIDE:
+ handleTestTemperatureSensorsDataPublishOverrideRequest ( message );
+ break;
+
+ case MSG_ID_HEATERS_PUBLISH_INTERVAL_ORVERRIDE:
+ handleTestHeatersDataPublishOverrideRequest ( message );
+ break;
+
+ default:
+ // TODO - unrecognized message ID received - ignore
+ break;
+ }
+ }
+}
Index: firmware/App/Services/SystemComm.h
===================================================================
diff -u -rdd70052b03eeb284223a4aade8567a4acec63efb -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Services/SystemComm.h (.../SystemComm.h) (revision dd70052b03eeb284223a4aade8567a4acec63efb)
+++ firmware/App/Services/SystemComm.h (.../SystemComm.h) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -14,55 +14,47 @@
* @date (original) 05-Nov-2019
*
***************************************************************************/
-
-#ifndef __SYSTEM_COMM_H__
-#define __SYSTEM_COMM_H__
-
-#include "DGCommon.h"
-#include "CommBuffers.h"
-#include "MsgQueues.h"
-
-/**
- * @defgroup SystemComm SystemComm
- * @brief System communication module. Manages incoming and outgoing CAN frames.
- *
- * @addtogroup SystemComm
- * @{
- */
-// ********** public definitions **********
-
-#define MESSAGE_SYNC_BYTE 0xA5 ///< Denali message syncronization byte.
-
-#define CAN_MESSAGE_PAYLOAD_SIZE 8 ///< CAN frame payload size (in bytes).
-#ifdef DEBUG_ENABLED
- #define PC_MESSAGE_PACKET_SIZE 8
-#endif
-
-#define MSG_ID_ACK 0xFFFF ///< Denali message ID for acknowledging received messages (when required).
-#define MSG_ACK_BIT 0x8000 ///< ACK bit in sequence number that indicates an ACK is required.
-#define MAX_MSG_SEQ_NO 0x7FFF ///< Maximum sequence number for Denali message (then wraps to 1).
-#define MIN_MSG_SEQ_NO 0x0001 ///< Minimum sequence number for Denali message.
-#define MAX_ACK_MSG_SIZE ( sizeof( MESSAGE_WRAPPER_T ) + 1 + CAN_MESSAGE_PAYLOAD_SIZE ) ///< Maximum size (in bytes) of Denali message including full (wrapped) message + sync + any CAN padding)
+#ifndef __SYSTEM_COMM_H__
+#define __SYSTEM_COMM_H__
-typedef COMM_BUFFER_T CAN_MESSAGE_BOX_T; ///< the CAN comm buffers align with the active CAN message boxes
-
-// ********** public function prototypes **********
-
-void initSystemComm( void );
-void execSystemCommRx( void );
-void execSystemCommTx( void );
-void handleCANMsgInterrupt( CAN_MESSAGE_BOX_T srcCANBox );
-#ifdef DEBUG_ENABLED
- void handleUARTMsgRecvPacketInterrupt( void );
- void handleUARTMsgXmitPacketInterrupt( void );
-#endif
+#include "DGCommon.h"
+#include "CommBuffers.h"
+#include "MsgQueues.h"
+
+// ********** public definitions **********
+
+#define MESSAGE_SYNC_BYTE 0xA5
+
+#define CAN_MESSAGE_PAYLOAD_SIZE 8
+#ifdef DEBUG_ENABLED
+ #define PC_MESSAGE_PACKET_SIZE 8
+#endif
+
+#define MSG_ID_ACK 0xFFFF
+#define MSG_ACK_BIT 0x8000
+#define MAX_MSG_SEQ_NO 0x7FFF
+#define MIN_MSG_SEQ_NO 0x0001
+#define MAX_ACK_MSG_SIZE ( sizeof( MESSAGE_WRAPPER_T ) + 1 + CAN_MESSAGE_PAYLOAD_SIZE ) // must hold full (wrapped) message + sync + any CAN padding
+
+typedef COMM_BUFFER_T CAN_MESSAGE_BOX_T; // the first 12 comm buffers align with the 12 active CAN message boxes
+
+// ********** public function prototypes **********
+
+void initSystemComm( void );
+void execSystemCommRx( void );
+void execSystemCommTx( void );
+void handleCANMsgInterrupt( CAN_MESSAGE_BOX_T srcCANBox );
+#ifdef DEBUG_ENABLED
+ void handleUARTMsgRecvPacketInterrupt( void );
+ void handleUARTMsgXmitPacketInterrupt( void );
+#endif
+BOOL isHDCommunicating( void );
+BOOL addMsgToPendingACKList( MESSAGE_T *msg, COMM_BUFFER_T channel, U08 *msgData, U32 len );
+
BOOL isCANBoxForXmit( CAN_MESSAGE_BOX_T srcCANBox );
BOOL isCANBoxForRecv( CAN_MESSAGE_BOX_T srcCANBox );
-BOOL isHDCommunicating( void );
-BOOL isDGOnlyCANNode( void );
-BOOL addMsgToPendingACKList( MESSAGE_T *msg, COMM_BUFFER_T channel, U08 *msgData, U32 len );
-/**@}*/
-
-#endif
+BOOL isDGOnlyCANNode( void );
+
+#endif
Index: firmware/App/Services/SystemCommMessages.c
===================================================================
diff -u -r53af4ddc318cc5299f15e3cc1ce506b166e6e156 -r359cf587f2f935ef9f40a16d17c4105efa653c1d
--- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 53af4ddc318cc5299f15e3cc1ce506b166e6e156)
+++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 359cf587f2f935ef9f40a16d17c4105efa653c1d)
@@ -1268,7 +1268,7 @@
*************************************************************************/
//DATA_OVERRIDE_HANDLER_FUNC_U32( U32, handleTestROPumpSetPointOverrideRequest, testSetTargetROPumpPressureOverride, testResetTargetROPumpPressureOverride ) //Todo remove
-DATA_OVERRIDE_HANDLER_FUNC_U32( U32, handleTestROPumpSetPointOverrideRequest, testSetTargetROPumpFlowRateOverride, testResetTargetROPumpFlowRateOverride )
+DATA_OVERRIDE_HANDLER_FUNC_U32( F32, handleTestROPumpSetPointOverrideRequest, testSetTargetROPumpFlowRateOverride, testResetTargetROPumpFlowRateOverride )
/*************************************************************************
* @brief