Index: firmware/App/Controllers/UVReactors.c =================================================================== diff -u --- firmware/App/Controllers/UVReactors.c (revision 0) +++ firmware/App/Controllers/UVReactors.c (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -0,0 +1,570 @@ + +#include "reg_het.h" +#include "gio.h" +#include "TaskGeneral.h" +#include "UVReactors.h" +#include "Common.h" +#include "SystemCommMessages.h" +#include "Timers.h" + +/** + * @addtogroup UV Reactors + * @{ + */ + +// ********** private definitions ********** + +#define INLET_UV_REACTOR_ENABLE_PIN 0 ///< Inlet UV reactor GPIO pin number (enable pin). +#define OUTLET_UV_REACTOR_ENABLE_PIN 1 ///< Outlet UV reactor GPIO pin number (enable Pin). +#define INLET_UV_REACTOR_INDICATION_PIN 26 ///< Inlet UV reactor N2HET1 pin number (health check). +#define OUTLET_UV_REACTOR_INDICATION_PIN 11 ///< Outlet UV reactor N2HET1 pin number (health check). +#define UV_REACTORS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors data publication time interval. +/// Self test wait time after enabling the reactors and before checking for their health in ms. +#define SELF_TEST_DELAY_TIME 1000 +#define MAX_ALLOWED_UNHEALTHY_REACTOR_COUNTER ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors max counter to be unhealthy. + +/// UV reactors self test states +typedef enum self_tests +{ + UV_REACTORS_SELF_TEST_OFF = 0, ///< UV reactors self test state off + UV_REACTORS_SELF_TEST_CHECK_HEALTH, ///< UV reactors self test check health + UV_REACTORS_SELF_TEST_COMPLETE, ///< UV reactors self test complete + NUM_OF_UV_REACTORS_SELF_TEST_STATES, ///< Number of UV reactors self test states +} UV_REACTORS_SELF_TEST_STATE_T; + +/// UV reactors exec states +typedef enum exec_states +{ + UV_REACTOR_STATE_OFF = 0, ///< UV reactor state off + UV_REACTOR_STATE_ON, ///< UV reactor state on + NUM_OF_UV_REACTOR_STATES, ///< Number of UV reactor states +} UV_REACTOR_STATE_T; + +/// UV reactor status +typedef struct +{ + UV_REACTOR_STATE_T execState; ///< UV reactor executive state + PIN_SIGNAL_STATE_T pinSignalState; ///< UV reactor pin signal state + BOOL hasTurnOnBeenRequested; ///< UV reactor turn on request + U32 reactorEnablePin; ///< UV reactor enable pin of GIO port A + U32 reactorHealthStatusPin; ///< UV reactor status pin of N2HET1 + U32 reactorUnhealthyCounter; ///< UV reactor counter of the number of times it is unhealthy in a row + OVERRIDE_U32_T healthStatus; ///< UV reactor current health status +} UV_REACTOR_STATUS_T; + +// ********** private data ********** + +static UV_REACTOR_STATUS_T reactorsStatus[ NUM_OF_UV_REACTORS ]; ///< UV reactors status array +static UV_REACTORS_SELF_TEST_STATE_T uvReactorsSelfTestStates = UV_REACTORS_SELF_TEST_OFF; ///< UV reactors self test state +static SELF_TEST_STATUS_T uvReactosSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; ///< Valves self test result + +static OVERRIDE_U32_T uvReactorsDataPublishInterval = { UV_REACTORS_DATA_PUB_INTERVAL, + UV_REACTORS_DATA_PUB_INTERVAL, 0, 0 }; ///< UV reactors data publish interval + +static U32 dataPublishCounter = 0; ///< UV reactors data publish counter +static U32 selfTestElapsedTime = 0; ///< UV reactors self test elapsed time + +// Self test functions +static UV_REACTORS_SELF_TEST_STATE_T handleUVReactorsSelfTestOff( void ); +static UV_REACTORS_SELF_TEST_STATE_T handleUVReactorsSelfTestCheckHealth( void ); + +// Exec functions +static UV_REACTOR_STATE_T handleUVReactorStateOff( UV_REACTORS_T reactor ); +static UV_REACTOR_STATE_T handleUVReactorStateOn( UV_REACTORS_T reactor ); + +// Support functions +static U32 isReactorHealthy( UV_REACTORS_T reactor ); +static void setReactorEnableStatus( UV_REACTORS_T reactor, PIN_SIGNAL_STATE_T state ); +static void publishUVReactorsData( void ); +static U32 getPublishUVReactorsDataInterval( void ); + +/*********************************************************************//** + * @brief + * The initUVReactors function initializes the UV reactors module. + * @details Inputs: uvReactosSelfTestResult, dataPublishCounter, + * reactorsStatus, selfTestStates + * @details Outputs: uvReactosSelfTestResult, dataPublishCounter, + * reactorsStatus, selfTestStates + * @return none + *************************************************************************/ +void initUVReactors( void ) +{ + UV_REACTORS_T reactor; + uvReactosSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; + uvReactorsSelfTestStates = UV_REACTORS_SELF_TEST_OFF; + dataPublishCounter = 0; + + // Initialize the UV reactors. These values are specific to the inlet and outlet reactor + // so they cannot be in a for loop + reactorsStatus[ INLET_UV_REACTOR ].reactorEnablePin = INLET_UV_REACTOR_ENABLE_PIN; + reactorsStatus[ INLET_UV_REACTOR ].reactorHealthStatusPin = INLET_UV_REACTOR_INDICATION_PIN; + + reactorsStatus[ OUTLET_UV_REACTOR ].reactorEnablePin = OUTLET_UV_REACTOR_ENABLE_PIN; + reactorsStatus[ OUTLET_UV_REACTOR ].reactorHealthStatusPin = OUTLET_UV_REACTOR_INDICATION_PIN; + + // Initialize the common values in the UV reactors + for( reactor = INLET_UV_REACTOR; reactor < NUM_OF_UV_REACTORS; reactor++ ) + { + reactorsStatus[ reactor ].pinSignalState = PIN_SIGNAL_LOW; + reactorsStatus[ reactor ].execState = UV_REACTOR_STATE_OFF; + reactorsStatus[ reactor ].hasTurnOnBeenRequested = FALSE; + } +} + +/*********************************************************************//** + * @brief + * The execUVReactorsSelfTest function executes the UV reactors self test. + * @details Inputs: FuvReactorsSelfTestStates + * @details Outputs: uvReactorsSelfTestStates + * @return Status of self test + *************************************************************************/ +SELF_TEST_STATUS_T execUVReactorsSelfTest( void ) +{ + switch ( uvReactorsSelfTestStates ) + { + case UV_REACTORS_SELF_TEST_OFF: + uvReactorsSelfTestStates = handleUVReactorsSelfTestOff(); + break; + + case UV_REACTORS_SELF_TEST_CHECK_HEALTH: + uvReactorsSelfTestStates = handleUVReactorsSelfTestCheckHealth(); + break; + + case UV_REACTORS_SELF_TEST_COMPLETE: + // Done with self test, do nothing. + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_SELF_TEST_STATE, + uvReactorsSelfTestStates ); + uvReactorsSelfTestStates = UV_REACTORS_SELF_TEST_COMPLETE; + break; + } + + return uvReactosSelfTestResult; +} + +/*********************************************************************//** + * @brief + * The execUVReactos function executes the UV reactors exec states. + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @return none + *************************************************************************/ +void execUVReactos( void ) +{ + UV_REACTORS_T reactor; + + for ( reactor = INLET_UV_REACTOR; reactor < NUM_OF_UV_REACTORS; reactor++ ) + { + switch ( reactorsStatus[ reactor ].execState ) + { + case UV_REACTOR_STATE_OFF: + reactorsStatus[ reactor ].execState = handleUVReactorStateOff( reactor ); + break; + + case UV_REACTOR_STATE_ON: + reactorsStatus[ reactor ].execState = handleUVReactorStateOn( reactor ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_EXEC_STATE, + reactorsStatus[ reactor ].execState ); + reactorsStatus[ reactor].execState = UV_REACTOR_STATE_OFF; + break; + } + + publishUVReactorsData(); + } +} + +/*********************************************************************//** + * @brief + * The getUVReactorHealth function returns the health status of a UV reactor. + * @details Inputs: reactorsStatus + * @details Outputs: none + * @param reactor to return its health + * @return returns the health of the requested UV reactor + *************************************************************************/ +BOOL getUVReactorHealth( UV_REACTORS_T reactor ) +{ + BOOL health; + + // Check if the reactor selected is in range + if ( reactor < NUM_OF_UV_REACTORS ) + { + // Check if the health is in override or not + if ( reactorsStatus[ reactor ].healthStatus.override == OVERRIDE_KEY ) + { + health = reactorsStatus[ reactor ].healthStatus.ovData; + } + else + { + health = reactorsStatus[ reactor ].healthStatus.data; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, reactor ) + } + + return health; +} + +/*********************************************************************//** + * @brief + * The turnOnUVReactor function turns on the selected UV reactor per request. + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @param reactor to turn on + * @return returns TRUE if the reactor was not already on + *************************************************************************/ +BOOL turnOnUVReactor( UV_REACTORS_T reactor ) +{ + BOOL result = FALSE; + + // Check if the called reactor is in range. Otherwise, raise an alarm + if ( reactor < NUM_OF_UV_REACTORS ) + { + if ( FALSE == reactorsStatus[ reactor ].hasTurnOnBeenRequested ) + { + reactorsStatus[ reactor ].hasTurnOnBeenRequested = TRUE; + result = TRUE; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, reactor ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The turnOffUVReactor function turns off the selected UV reactor per request. + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @param reactor to turn off + * @return returns TRUE if the reactor was not already off + *************************************************************************/ +BOOL turnOffUVReactor( UV_REACTORS_T reactor ) +{ + BOOL result = FALSE; + // Check if the called reactor is in range + if ( reactor < NUM_OF_UV_REACTORS ) + { + reactorsStatus[ reactor ].hasTurnOnBeenRequested = FALSE; + result = TRUE; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, reactor ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleUVReactorsSelfTestOff function handles the self test off state. + * @details Inputs: selfTestElapsedTime + * @details Outputs: selfTestElapsedTime + * @return returns the next state of the self test state machine + *************************************************************************/ +static UV_REACTORS_SELF_TEST_STATE_T handleUVReactorsSelfTestOff( void ) +{ + UV_REACTORS_SELF_TEST_STATE_T state = UV_REACTORS_SELF_TEST_CHECK_HEALTH; + + // Enable both the reactors and set the timer to check the health of the reactors after time elapsed + setReactorEnableStatus( INLET_UV_REACTOR, PIN_SIGNAL_HIGH ); + setReactorEnableStatus( OUTLET_UV_REACTOR, PIN_SIGNAL_HIGH ); + selfTestElapsedTime = getMSTimerCount(); + + return state; +} + +/*********************************************************************//** + * @brief + * The handleUVReactorsSelfTestCheckHealth function handles the self test + * check health state. + * @details Inputs: selfTestElapsedTime, uvReactosSelfTestResult + * @details Outputs: uvReactosSelfTestResult + * @return returns the next state of the self test state machine + *************************************************************************/ +static UV_REACTORS_SELF_TEST_STATE_T handleUVReactorsSelfTestCheckHealth( void ) +{ + UV_REACTORS_SELF_TEST_STATE_T state = UV_REACTORS_SELF_TEST_CHECK_HEALTH; + + if ( didTimeout( selfTestElapsedTime, SELF_TEST_DELAY_TIME ) ) + { + // Get the health status of the reactors + BOOL isInletHealthy = (BOOL)isReactorHealthy( INLET_UV_REACTOR ); + BOOL isOutletHealty = (BOOL)isReactorHealthy( OUTLET_UV_REACTOR ); + + // Check if both of them are healthy and if not, raise an alarm + if ( TRUE == isInletHealthy && TRUE == isOutletHealty ) + { + uvReactosSelfTestResult = SELF_TEST_STATUS_PASSED; + } + else + { + uvReactosSelfTestResult = SELF_TEST_STATUS_FAILED; + // Check which reactor has not been healthy and raise an alarm + if ( !isInletHealthy ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_UV_REACTOR_NOT_HEALTHY , INLET_UV_REACTOR ); + } + else + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_UV_REACTOR_NOT_HEALTHY , OUTLET_UV_REACTOR ); + } + } + + // Turn off the UV reactors once the test is finished + setReactorEnableStatus( INLET_UV_REACTOR, PIN_SIGNAL_LOW ); + setReactorEnableStatus( OUTLET_UV_REACTOR, PIN_SIGNAL_LOW ); + + state = UV_REACTORS_SELF_TEST_COMPLETE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleUVReactorStateOff function handles the off state. + * @details Inputs: reactorsStatus + * @details Outputs: none + * @param reactor to check its state + * @return returns the next state of the exec state machine + *************************************************************************/ +static UV_REACTOR_STATE_T handleUVReactorStateOff( UV_REACTORS_T reactor ) +{ + UV_REACTOR_STATE_T state = UV_REACTOR_STATE_OFF; + + // If the a reactor is requested to be on and it is off, turn it on + // and change the state + if( TRUE == reactorsStatus[ reactor ].hasTurnOnBeenRequested ) + { + setReactorEnableStatus( reactor, PIN_SIGNAL_HIGH ); + + state = UV_REACTOR_STATE_ON; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleUVReactorStateOn function handles the on state. + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @param reactor to checks it status + * @return returns the next state of the exec state machine + *************************************************************************/ +static UV_REACTOR_STATE_T handleUVReactorStateOn( UV_REACTORS_T reactor ) +{ + UV_REACTOR_STATE_T state = UV_REACTOR_STATE_ON; + + reactorsStatus[ reactor ].healthStatus.data = isReactorHealthy( reactor ); + + // Check if the reactor is healthy + if ( FALSE == getUVReactorHealth( reactor ) && ++reactorsStatus[ reactor ].reactorUnhealthyCounter > MAX_ALLOWED_UNHEALTHY_REACTOR_COUNTER ) + { + // The reactor has been unhealthy for a certain amount of time + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_UV_REACTOR_NOT_HEALTHY, reactor ); + } + else + { + // If the reactor is healthy, zero out the counter + reactorsStatus[ reactor ].reactorUnhealthyCounter = 0; + } + + // Check if it has been requested to turn off a reactor + if( FALSE == reactorsStatus[ reactor ].hasTurnOnBeenRequested ) + { + setReactorEnableStatus( reactor, PIN_SIGNAL_LOW ); + + state = UV_REACTOR_STATE_OFF; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The setReactorEnableStatus function sets a reactor to enable or + * disable state. + * @details Inputs: reactorsStatus + * @details Outputs: none + * @param reactor to set it enable status + * @param state to set the reactor (high or low) + * @return none + *************************************************************************/ +static void setReactorEnableStatus( UV_REACTORS_T reactor, PIN_SIGNAL_STATE_T state ) +{ + // Set the GIO pin to enable or disable + gioSetBit( gioPORTA, reactorsStatus[ reactor ].reactorEnablePin, state ); + + // Update the pin signal state + reactorsStatus[ reactor ].pinSignalState = state; +} + +/*********************************************************************//** + * @brief + * The isReactorHealthy function checks the health status of a reactor. + * @details Inputs: reactorsStatus + * @details Outputs: none + * @param reactor to check its health + * @return returns TRUE if the reactor is healthy otherwise a FALSE + *************************************************************************/ +static U32 isReactorHealthy( UV_REACTORS_T reactor ) +{ + return gioGetBit( hetPORT1, reactorsStatus[ reactor ].reactorHealthStatusPin ); +} + +/*********************************************************************//** + * @brief + * The getPublishValvesDataInterval function gets the data publish interval + * @details Inputs: uvReactorsDataPublishInterval + * @details Outputs: none + * @return returns data publish interval + *************************************************************************/ +static U32 getPublishUVReactorsDataInterval( void ) +{ + U32 result = uvReactorsDataPublishInterval.data; + + if ( OVERRIDE_KEY == uvReactorsDataPublishInterval.override ) + { + result = uvReactorsDataPublishInterval.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The publishUVReactorsData function publishes the UV reactors data. + * @details Inputs: dataPublishCounter, reactorsStatus + * @details Outputs: dataPublishCounter + * @return none + *************************************************************************/ +static void publishUVReactorsData( void ) +{ + if ( ++dataPublishCounter > getPublishUVReactorsDataInterval() ) + { + UV_REACTORS_DATA_T uvReactorsData; + // Publish the reactors health status + uvReactorsData.inletUVReactorHealthStatus = reactorsStatus[ INLET_UV_REACTOR ].reactorHealthStatusPin; + uvReactorsData.outletUVReactorHealthStatus = reactorsStatus[ OUTLET_UV_REACTOR ].reactorHealthStatusPin; + uvReactorsData.inletUVReactorState = reactorsStatus[ INLET_UV_REACTOR ].execState; + uvReactorsData.outletUVReactorHealthStatus = reactorsStatus[ OUTLET_UV_REACTOR ].execState; + + broadcastUVReactorsData( &uvReactorsData ); + + dataPublishCounter = 0; + } +} + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + +/*********************************************************************//** + * @brief + * The testSetReactorsDataPublishInterval function overrides the UV + * reactors data publish interval. + * @details Inputs: uvReactorsDataPublishInterval + * @details Outputs: uvReactorsDataPublishInterval + * @param value which is override value for the UV reactors data publish + * interval + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetReactorsDataPublishInterval( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_GENERAL_INTERVAL; + + result = TRUE; + uvReactorsDataPublishInterval.ovData = intvl; + uvReactorsDataPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetReactorsDataPublishInterval function resets the override + * of the UV reactors publish interval. + * @details Inputs: uvReactorsDataPublishInterval + * @details Outputs: uvReactorsDataPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetReactorsDataPublishInterval( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + uvReactorsDataPublishInterval.override = OVERRIDE_RESET; + uvReactorsDataPublishInterval.ovData = uvReactorsDataPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetUVReactorHealthOverride function overrides the UV reactors + * health + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @param reactor that its health will be overridden + * @param health which is high for healthy on and low for not healthy + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetUVReactorHealthOverride( U32 reactor, BOOL health ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() && (UV_REACTORS_T)reactor < NUM_OF_UV_REACTORS ) + { + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovInitData = reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.data; + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.override = OVERRIDE_KEY; + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovData = (U32)health; + + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetUVReactorHealthOverride function resets the override + * of the UV reactors health + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @param reactor that its health will be reset + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetUVReactorHealthOverride( U32 reactor ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() && (UV_REACTORS_T)reactor < NUM_OF_UV_REACTORS ) + { + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.override = OVERRIDE_RESET; + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovData = reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovInitData; + } + + return result; +} + +/**@}*/ Index: firmware/App/Controllers/UVReactors.h =================================================================== diff -u --- firmware/App/Controllers/UVReactors.h (revision 0) +++ firmware/App/Controllers/UVReactors.h (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -0,0 +1,54 @@ + +#ifndef APP_CONTROLLERS_UVREACTORS_H_ +#define APP_CONTROLLERS_UVREACTORS_H_ + +#include "Common.h" + +/** + * @defgroup UV Reactors UV Reactors + * @brief UV reactors driver module. + * Controls the inlet and outlet of Acuva Strike II-B21 V10K L60 M UV-LED reactors. + * EN: 50581:2012. The reactors have and On/Off switch and a health pin. + * + * @addtogroup UV Reactors + * @{ + */ + +/// UV reactors names +typedef enum uv_reactors_names +{ + INLET_UV_REACTOR = 0, ///< Inlet UV reactor + OUTLET_UV_REACTOR, ///< Outlet UV reactor + NUM_OF_UV_REACTORS, ///< Number of UV reactors +} UV_REACTORS_T; + +/// UV reactors data publish +typedef struct +{ + U32 inletUVReactorHealthStatus; ///< Inlet UV reactor health status + U32 outletUVReactorHealthStatus; ///< Outlet UV reactor health status + U32 inletUVReactorState; ///< Inlet UV reactor state + U32 outletUVReactorState; ///< Outlet UV reactor state +} UV_REACTORS_DATA_T; + +void initUVReactors( void ); + +SELF_TEST_STATUS_T execUVReactorsSelfTest( void ); + +void execUVReactos( void ); + +BOOL getUVReactorHealth( UV_REACTORS_T reactor ); + +BOOL turnOnUVReactor( UV_REACTORS_T reactor ); + +BOOL turnOffUVReactor( UV_REACTORS_T reactor ); + +BOOL testSetReactorsDataPublishInterval( U32 value ); +BOOL testResetReactorsDataPublishInterval( void ); + +BOOL testSetUVReactorHealthOverride( U32 reactor, BOOL health ); +BOOL testResetUVReactorHealthOverride( U32 reactor ); + +/**@}*/ + +#endif Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r4d7d40a27130dc813d653f044cbb856b1b7d8481 -r00b0fcefb9f74e7c050b5c83ad5c285e6769ef78 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 4d7d40a27130dc813d653f044cbb856b1b7d8481) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -24,6 +24,7 @@ #include "Pressures.h" #include "RTC.h" #include "TemperatureSensors.h" +#include "UVReactors.h" #include "WatchdogMgmt.h" /** @@ -126,6 +127,11 @@ postState = handlePOSTStatus( testStatus ); break; + case DG_POST_STATE_UV_REACTORS: + testStatus = execUVReactorsSelfTest(); + postState = handlePOSTStatus( testStatus ); + break; + case DG_POST_STATE_WATCHDOG: testStatus = execWatchdogTest(); handlePOSTStatus( testStatus ); // ignoring return value because last test Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -ra726311564521affd46cbbaf129bdffb22e1d58f -r00b0fcefb9f74e7c050b5c83ad5c285e6769ef78 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision a726311564521affd46cbbaf129bdffb22e1d58f) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -147,6 +147,21 @@ SW_FAULT_ID_CONCENTRATE_PUMP_EXEC_INVALID_STATE, // 55 SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, SW_FAULT_ID_CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE, + SW_FAULT_ID_UV_REACTORS_INVALID_EXEC_STATE, + SW_FAULT_ID_UV_REACTORS_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_THERMISTORS_INVALID_EXEC_STATE, // 60 + SW_FAULT_ID_THERMISTORS_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_INVALID_THERMISTOR_SELECTED, + SW_FAULT_ID_FAN_INVALID_EXEC_STATE, + SW_FAULT_ID_FAN_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_INVALID_FAN_SELECTED, // 65 + SW_FAULT_ID_RO_PUMP_INVALID_EXEC_STATE, + SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, + SW_FAULT_ID_DRAIN_PUMP_INVALID_EXEC_STATE, + SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, + SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, // 70 + SW_FAULT_ID_DRAIN_PUMP_INVALID_DELTA_PRESSURE_SELECTED, + SW_FAULT_ID_INVALID_TEMPERATURE_SENSOR_SELECTED, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r498aa2804b2babde370f74f0cf9a333655fc0410 -r00b0fcefb9f74e7c050b5c83ad5c285e6769ef78 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 498aa2804b2babde370f74f0cf9a333655fc0410) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -14,102 +14,102 @@ * @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" - + +#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 ///< Number of CAN buffers for transmit -#define NUM_OF_CAN_IN_BUFFERS 6 ///< Number of CAN buffers for receiving -#ifndef DEBUG_ENABLED - #define NUM_OF_MSG_IN_BUFFERS 6 ///< Number 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 +// ********** private definitions ********** + +#define NUM_OF_CAN_OUT_BUFFERS 5 ///< Number of CAN buffers for transmit +#define NUM_OF_CAN_IN_BUFFERS 6 ///< Number of CAN buffers for receiving +#ifndef DEBUG_ENABLED + #define NUM_OF_MSG_IN_BUFFERS 6 ///< Number 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) -/// Record for transmitted message that is pending acknowledgement from receiver. -typedef struct -{ - BOOL used; ///< Flag indicates whether the pending ACK slot is used or not - U16 seqNo; ///< Sequence number - U16 retries; ///< Retry count - U32 timeStamp; ///< Message time stamp - COMM_BUFFER_T channel; ///< Comm buffer channel - U32 msgSize; ///< Message size - U08 msg[ MAX_ACK_MSG_SIZE ]; ///< Bytes representation of the message -} PENDING_ACK_RECORD_T; - -#pragma pack(pop) - -// ********** private data ********** +#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 -/// 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, +#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) + +/// Record for transmitted message that is pending acknowledgement from receiver. +typedef struct +{ + BOOL used; ///< Flag indicates whether the pending ACK slot is used or not + U16 seqNo; ///< Sequence number + U16 retries; ///< Retry count + U32 timeStamp; ///< Message time stamp + COMM_BUFFER_T channel; ///< Comm buffer channel + U32 msgSize; ///< Message size + U08 msg[ MAX_ACK_MSG_SIZE ]; ///< Bytes representation of the message +} PENDING_ACK_RECORD_T; + +#pragma pack(pop) + +// ********** private data ********** + +/// 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, COMM_BUFFER_OUT_CAN_DG_BROADCAST, - COMM_BUFFER_OUT_CAN_PC, + COMM_BUFFER_OUT_CAN_PC, COMM_BUFFER_OUT_CAN_DG_2_UI -}; +}; -/// 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 -}; +/// 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 +}; -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 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 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 + #ifdef DEBUG_ENABLED // debug buffers static U08 pcXmitPacket[ 1024 ]; @@ -119,71 +119,71 @@ static g_dmaCTRL pcDMARecvControlRecord; #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 ); - +// ********** 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 ); + #ifdef DEBUG_ENABLED static void initUARTAndDMA( void ); static U32 transmitNextUARTPacket( void ); #endif -/*********************************************************************//** - * @brief - * The initSystemComm function initializes the SystemComm module. - * @details Inputs: none - * @details Outputs: SystemComm module initialized. - * @return none - *************************************************************************/ -void initSystemComm( void ) -{ - U32 i; - -#ifdef DEBUG_ENABLED - // initialize UART and DMA for PC communication - initUARTAndDMA(); -#endif - +/*********************************************************************//** + * @brief + * The initSystemComm function initializes the SystemComm module. + * @details Inputs: none + * @details 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 - * with the DG. - * @details Inputs: hdIsCommunicating - * @details Outputs: none - * @return TRUE if HD has broadcast since last call, FALSE if not - *************************************************************************/ -BOOL isHDCommunicating( void ) -{ - return hdIsCommunicating; + // 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 + * with the DG. + * @details Inputs: hdIsCommunicating + * @details Outputs: none + * @return TRUE if HD has broadcast since last call, FALSE if not + *************************************************************************/ +BOOL isHDCommunicating( void ) +{ + return hdIsCommunicating; +} + +/*********************************************************************//** + * @brief * The isDGOnlyCANNode function determines whether the DG is the only node * currently on the CAN bus. * @details Inputs: dgIsOnlyCANNode @@ -193,39 +193,39 @@ BOOL isDGOnlyCANNode( void ) { return dgIsOnlyCANNode; -} - -/*********************************************************************//** - * @brief - * The execSystemCommRx function manages received data from other sub-systems. - * @details Inputs: none - * @details 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 sub-systems. - * @details Inputs: none - * @details Outputs: Next outgoing frame transmitted. - * @return none - *************************************************************************/ -void execSystemCommTx( void ) +} + +/*********************************************************************//** + * @brief + * The execSystemCommRx function manages received data from other sub-systems. + * @details Inputs: none + * @details 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 sub-systems. + * @details Inputs: none + * @details Outputs: Next outgoing frame transmitted. + * @return none + *************************************************************************/ +void execSystemCommTx( void ) +{ // don't bother with transmitting if no other nodes on CAN bus if ( FALSE == dgIsOnlyCANNode ) { @@ -271,217 +271,217 @@ } // end - are we retrying xmit or are we alone on CAN bus } // end - pending xmit timeout? } // end - transmit in progress or not - } // end - DG not alone on CAN bus - -#ifdef DEBUG_ENABLED - // if UART transmitter is idle, start transmitting any pending packets - if ( FALSE == isSCI1DMATransmitInProgress() ) - { - transmitNextUARTPacket(); - } -#endif -} - -/*********************************************************************//** - * @brief + } // end - DG not alone on CAN bus + +#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. This * may have occurred because a CAN packet transmission has completed or - * because a CAN packet has been received. The appropriate handler is called. - * @details Inputs: none - * @details 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? - } -} - -#ifdef DEBUG_ENABLED -/*********************************************************************//** - * @brief - * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive - * packet completed interrupt. - * @details Inputs: none - * @details Outputs: none - * @return none - *************************************************************************/ -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(); -} - -/*********************************************************************//** - * @brief - * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit - * packet completed interrupt. - * @details Inputs: none - * @details Outputs: none - * @return none - *************************************************************************/ -void handleUARTMsgXmitPacketInterrupt( void ) -{ - U32 bytesXmitted = transmitNextUARTPacket(); - - if ( 0 == bytesXmitted ) - { - signalSCI1XmitsCompleted(); - } -} - -/*********************************************************************//** - * @brief - * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA - * to go with it for PC communication. - * @details Inputs: none - * @details Outputs: SCI1 and DMA initialized - * @return none - *************************************************************************/ -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 - * is configured for transmit. - * @details Inputs: CAN_OUT_BUFFERS[] - * @details 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 - * is configured for receiving. - * @details Inputs: MSG_IN_BUFFERS[] - * @details 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; + * because a CAN packet has been received. The appropriate handler is called. + * @details Inputs: none + * @details 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? + } } +#ifdef DEBUG_ENABLED /*********************************************************************//** * @brief + * The handleUARTMsgRecvPacketInterrupt function handles a DMA UART receive + * packet completed interrupt. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +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(); +} + +/*********************************************************************//** + * @brief + * The handleUARTMsgXmitPacketInterrupt function handles a DMA UART transmit + * packet completed interrupt. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +void handleUARTMsgXmitPacketInterrupt( void ) +{ + U32 bytesXmitted = transmitNextUARTPacket(); + + if ( 0 == bytesXmitted ) + { + signalSCI1XmitsCompleted(); + } +} + +/*********************************************************************//** + * @brief + * The initUARTAndDMA function initializes the SCI1 peripheral and the DMA + * to go with it for PC communication. + * @details Inputs: none + * @details Outputs: SCI1 and DMA initialized + * @return none + *************************************************************************/ +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 + * is configured for transmit. + * @details Inputs: CAN_OUT_BUFFERS[] + * @details 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 + * is configured for receiving. + * @details Inputs: MSG_IN_BUFFERS[] + * @details 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. * @details Inputs: CAN_OUT_BUFFERS[] * @details Outputs: CAN transmit buffers cleared. @@ -495,369 +495,369 @@ { clearBuffer( CAN_OUT_BUFFERS[ i ] ); } -} - - -/************************************************************************* -********************** TRANSMIT SUPPORT FUNCTIONS ************************ -*************************************************************************/ - -/*********************************************************************//** - * @brief - * The findNextHighestPriorityCANPacketToTransmit function gets the next - * 8 byte packet and initiates a CAN transmit on the appropriate CAN channel. - * @details Inputs: Output CAN Comm Buffer(s) - * @details Outputs: none - * @return buffer with highest priority CAN packet to transmit, - * 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 - * a CAN transmit on the appropriate CAN channel. - * @details Inputs: Output CAN Comm Buffers - * @details Outputs: CAN packet transmit initiated. - * @return number 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; -} - -#ifdef DEBUG_ENABLED -/*********************************************************************//** - * @brief - * The transmitNextUARTPacket function sets up and initiates a DMA transmit - * of the next packet pending transmit (if any) via UART. - * @details Inputs: Output UART Comm Buffer(s) - * @details Outputs: UART DMA transmit initiated. - * @return number of bytes transmitted - *************************************************************************/ -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 - * comm buffers and adds them to the received message queue. - * @details Inputs: Input Comm Buffers - * @details 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 ); - +} + + +/************************************************************************* +********************** TRANSMIT SUPPORT FUNCTIONS ************************ +*************************************************************************/ + +/*********************************************************************//** + * @brief + * The findNextHighestPriorityCANPacketToTransmit function gets the next + * 8 byte packet and initiates a CAN transmit on the appropriate CAN channel. + * @details Inputs: Output CAN Comm Buffer(s) + * @details Outputs: none + * @return buffer with highest priority CAN packet to transmit, + * 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 + * a CAN transmit on the appropriate CAN channel. + * @details Inputs: Output CAN Comm Buffers + * @details Outputs: CAN packet transmit initiated. + * @return number 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; +} + +#ifdef DEBUG_ENABLED +/*********************************************************************//** + * @brief + * The transmitNextUARTPacket function sets up and initiates a DMA transmit + * of the next packet pending transmit (if any) via UART. + * @details Inputs: Output UART Comm Buffer(s) + * @details Outputs: UART DMA transmit initiated. + * @return number of bytes transmitted + *************************************************************************/ +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 + * comm buffers and adds them to the received message queue. + * @details Inputs: Input Comm Buffers + * @details 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 ] ) - { + 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 - * buffer that lie before a sync byte. - * @details Inputs: none - * @details Outputs: Any padding at front of comm buffer is consumed. - * @param 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 - * given buffer. If a message is found, its size is returned. - * @details Inputs: none - * @details 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 number of bytes in the data to search - * @return size of message if found, zero if no complete message found, - * -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 - * received message queues. - * @details Inputs: Received Message Queues - * @details 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 timeout errors. - * @details Inputs: timeOfLastDGCheckIn, timeOfLastUICheckIn - * @details 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 - * within a set period of time. Assumed function is being called when a new - * bad CRC is detected so a new bad CRC will be added to the list. - * @details Inputs: badCRCTimeStamps[], badCRCListIdx, badCRCListCount - * @details Outputs: possibly a "too many bad CRCs" alarm - * @return none - *************************************************************************/ -static void checkTooManyBadMsgCRCs( void ) + 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 + * buffer that lie before a sync byte. + * @details Inputs: none + * @details Outputs: Any padding at front of comm buffer is consumed. + * @param 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 + * given buffer. If a message is found, its size is returned. + * @details Inputs: none + * @details 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 number of bytes in the data to search + * @return size of message if found, zero if no complete message found, + * -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 + * received message queues. + * @details Inputs: Received Message Queues + * @details 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 timeout errors. + * @details Inputs: timeOfLastDGCheckIn, timeOfLastUICheckIn + * @details 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 + * within a set period of time. Assumed function is being called when a new + * bad CRC is detected so a new bad CRC will be added to the list. + * @details Inputs: badCRCTimeStamps[], badCRCListIdx, badCRCListCount + * @details Outputs: possibly a "too many bad CRCs" alarm + * @return none + *************************************************************************/ +static void checkTooManyBadMsgCRCs( void ) +{ if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_BAD_MSG_CRC ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_COMM_TOO_MANY_BAD_CRCS, 2 ); // 2 for DG - } + } #ifdef DEBUG_ENABLED { char debugStr[100]; @@ -866,260 +866,252 @@ sendDebugDataToUI( (U08*)debugStr ); } #endif -} - -/*********************************************************************//** - * @brief - * The addMsgToPendingACKList function adds a given message to the pending - * ACK list. Messages in this list will require receipt of an ACK message - * for this particular message within a limited time. - * @details Inputs: pendingAckList[] - * @details 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 number 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 - * see if the sequence number from a received ACK msg matches any. If found, - * the list entry is removed. - * @details Inputs: pendingAckList[] - * @details Outputs: pendingAckList[] - * @param seqNo sequence number 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 +} + +/*********************************************************************//** + * @brief + * The addMsgToPendingACKList function adds a given message to the pending + * ACK list. Messages in this list will require receipt of an ACK message + * for this particular message within a limited time. + * @details Inputs: pendingAckList[] + * @details 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 number 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 + * see if the sequence number from a received ACK msg matches any. If found, + * the list entry is removed. + * @details Inputs: pendingAckList[] + * @details Outputs: pendingAckList[] + * @param seqNo sequence number 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 see if - * any have expired. Any such messages will be queued for retransmission - * and if max retries reached a fault is triggered. - * @details Inputs: pendingAckList[] - * @details Outputs: pendingAckList[] - * @return none - *************************************************************************/ -static void checkPendingACKList( void ) -{ - U32 i; - - // find expired messages pending ACK - for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) - { // pending ACK expired? - if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, MSG_NOT_ACKED_TIMEOUT_MS ) ) ) - { // if retries left, reset and resend pending message - 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 ); + * any have expired. Any such messages will be queued for retransmission + * and if max retries reached a fault is triggered. + * @details Inputs: pendingAckList[] + * @details Outputs: pendingAckList[] + * @return none + *************************************************************************/ +static void checkPendingACKList( void ) +{ + U32 i; + + // find expired messages pending ACK + for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) + { // pending ACK expired? + if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, MSG_NOT_ACKED_TIMEOUT_MS ) ) ) + { // if retries left, reset and resend pending message + 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 ); } - // if no retries left, alarm - else - { - U16 msgID; - - memcpy( &msgID, &pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); + // if no retries left, alarm + 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 ); - pendingAckList[ i ].used = FALSE; // take pending message off of list - } - } - } -} - -/*********************************************************************//** - * @brief - * The processReceivedMessage function processes a given message. - * @details Inputs: none - * @details 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_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_RPM_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 ); + pendingAckList[ i ].used = FALSE; // take pending message off of list + } + } + } +} + +/*********************************************************************//** + * @brief + * The processReceivedMessage function processes a given message. + * @details Inputs: none + * @details 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_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_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 ); + + 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_MEASURED_FLOW_OVERRIDE: + handleTestROMeasuredFlowOverrideRequest( message ); + break; + + case MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: + handleTestROPumpDataBroadcastIntervalOverrideRequest( 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 ); + break; + + 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; + case MSG_ID_CONDUCTIVITY_OVERRIDE: handleTestSetConductivityOverrideRequest ( message ); break; @@ -1164,11 +1156,27 @@ handleConcentratePumpPublishIntervalOverride( message ); break; - default: - // TODO - unrecognized message ID received - ignore - break; - } - } -} + case MSG_ID_DG_START_STOP_INLET_UV_REACTOR: + handleStartStopInletUVReactor( message ); + break; + case MSG_ID_UV_REACTORS_DATA_PUBLISH_INTERVAL_OVERRIDE: + handleUVReactorsDataPublishIntervalOverride( message ); + break; + + case MSG_ID_DG_START_STOP_OUTLET_UV_REACTOR: + handleStartStopOutletUVReactor( message ); + break; + + case MSG_ID_DG_UV_REACTORS_HEALTH_OVERRIDE: + handleUVReactorsHealthOverride( message ); + break; + + default: + // TODO - unrecognized message ID received - ignore + break; + } + } +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -ra6bf8a0785fba2986292aeff04e1aa944ff07195 -r00b0fcefb9f74e7c050b5c83ad5c285e6769ef78 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a6bf8a0785fba2986292aeff04e1aa944ff07195) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -14,269 +14,270 @@ * @date (original) 05-Nov-2019 * ***************************************************************************/ - + #include // for memcpy() -#include "reg_system.h" +#include "reg_system.h" #include "Accel.h" -#include "ConcentratePumps.h" +#include "ConcentratePumps.h" #include "ConductivitySensors.h" #include "DrainPump.h" -#include "FPGA.h" -#include "Heaters.h" -#include "LoadCell.h" +#include "FPGA.h" +#include "Heaters.h" +#include "LoadCell.h" #include "MessagePayloads.h" -#include "ModeStandby.h" -#include "ModeRecirculate.h" +#include "ModeStandby.h" +#include "ModeRecirculate.h" #include "MsgQueues.h" #include "NVDataMgmt.h" -#include "OperationModes.h" -#include "Pressures.h" -#include "Reservoirs.h" -#include "ROPump.h" -#include "RTC.h" -#include "SystemComm.h" -#include "SafetyShutdown.h" -#include "SystemCommMessages.h" -#include "TemperatureSensors.h" -#include "Utilities.h" -#include "Valves.h" -#include "WatchdogMgmt.h" +#include "OperationModes.h" +#include "Pressures.h" +#include "Reservoirs.h" +#include "ROPump.h" +#include "RTC.h" +#include "SystemComm.h" +#include "SafetyShutdown.h" +#include "SystemCommMessages.h" +#include "TemperatureSensors.h" +#include "Utilities.h" +#include "Valves.h" +#include "WatchdogMgmt.h" +#include "UVReactors.h" /** * @addtogroup SystemCommMessages * @{ */ - -// ********** private definitions ********** - -#define ACK_REQUIRED TRUE ///< Require an ACK. -#define ACK_NOT_REQUIRED FALSE ///< Not require an ACK. - + +// ********** private definitions ********** + +#define ACK_REQUIRED TRUE ///< Require an ACK. +#define ACK_NOT_REQUIRED FALSE ///< Not require an ACK. + #ifdef DEBUG_ENABLED #define DEBUG_EVENT_MAX_TEXT_LEN 40 #endif - -// ********** private data ********** - -static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. -static volatile U16 nextSeqNo = 1; ///< Next sequence number. - -// ********** private function prototypes ********** - -static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ); -static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); - -/*********************************************************************//** - * @brief - * The serializeMessage function serializes a given message into a given - * array of bytes. A sequence # is added to the message here and the ACK - * bit of the sequence # is set if ACK is required per parameter. A sync byte - * is inserted at the beginning of the message and an 8-bit CRC is appended to - * the end of the message. The message is queued for transmission in the given buffer. - * @details Inputs: none - * @details Outputs: given data array populated with serialized message data and queued for transmit. - * @param msg message to serialize - * @param buffer outgoing buffer that message should be queued in - * @param ackReq is an acknowledgement from receiver required? - * @return size (in bytes) of serialized message populated in given data array. - *************************************************************************/ -static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) -{ - BOOL result = FALSE; - BOOL error = FALSE; - U32 msgSize = 0; - U32 sizeMod, sizePad; - U32 i; - U08 crc; - U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data - - // prefix data with message sync byte - data[ msgSize++ ] = MESSAGE_SYNC_BYTE; - - // set sequence # and ACK bit (unless this is an ACK to a received message) - if ( msg.hdr.msgID != MSG_ID_ACK ) - { - // thread protect next sequence # access & increment - _disable_IRQ(); - msg.hdr.seqNo = nextSeqNo; - nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); - _enable_IRQ(); - if ( TRUE == ackReq ) - { - msg.hdr.seqNo *= -1; - } - } - - // calculate message CRC - crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); - - // serialize message header data - memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); - msgSize += sizeof( MESSAGE_HEADER_T ); - - // serialize message payload (only used bytes per payloadLen field) - memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); - msgSize += msg.hdr.payloadLen; - - // add 8-bit CRC - data[ msgSize++ ] = crc; - - // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) - sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; - sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); - for ( i = 0; i < sizePad; i++ ) - { - data[ msgSize++ ] = 0; - } - - // if ACK required, add to pending ACK list - if ( TRUE == ackReq ) - { - if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) - { - error = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) - } - } - - if ( FALSE == error ) - { - // add serialized message data to appropriate out-going comm buffer - result = addToCommBuffer( buffer, data, msgSize ); - } - - return result; -} -/*********************************************************************//** - * @brief - * The sendACKMsg function constructs and queues for transmit an ACK message - * for a given received message. - * @details Inputs: none - * @details Outputs: ACK message queued for transmit on broadcast CAN channel. - * @param message message to send an ACK for - * @return TRUE if ACK message queued successfully, FALSE if not - *************************************************************************/ -BOOL sendACKMsg( MESSAGE_T *message ) -{ - BOOL result; - MESSAGE_T msg; - - // create a message record - blankMessage( &msg ); - // send ACK back with same seq. #, but w/o ACK bit - msg.hdr.seqNo = message->hdr.seqNo * -1; - // ACK messages always have this ID - msg.hdr.msgID = MSG_ID_ACK; - // ACK messages always have no payload - msg.hdr.payloadLen = 0; - - // serialize and queue the message for transmit on broadcast channel - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} +// ********** private data ********** -/*********************************************************************//** - * @brief +static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. +static volatile U16 nextSeqNo = 1; ///< Next sequence number. + +// ********** private function prototypes ********** + +static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ); +static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); +static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); + +/*********************************************************************//** + * @brief + * The serializeMessage function serializes a given message into a given + * array of bytes. A sequence # is added to the message here and the ACK + * bit of the sequence # is set if ACK is required per parameter. A sync byte + * is inserted at the beginning of the message and an 8-bit CRC is appended to + * the end of the message. The message is queued for transmission in the given buffer. + * @details Inputs: none + * @details Outputs: given data array populated with serialized message data and queued for transmit. + * @param msg message to serialize + * @param buffer outgoing buffer that message should be queued in + * @param ackReq is an acknowledgement from receiver required? + * @return size (in bytes) of serialized message populated in given data array. + *************************************************************************/ +static U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) +{ + BOOL result = FALSE; + BOOL error = FALSE; + U32 msgSize = 0; + U32 sizeMod, sizePad; + U32 i; + U08 crc; + U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data + + // prefix data with message sync byte + data[ msgSize++ ] = MESSAGE_SYNC_BYTE; + + // set sequence # and ACK bit (unless this is an ACK to a received message) + if ( msg.hdr.msgID != MSG_ID_ACK ) + { + // thread protect next sequence # access & increment + _disable_IRQ(); + msg.hdr.seqNo = nextSeqNo; + nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); + _enable_IRQ(); + if ( TRUE == ackReq ) + { + msg.hdr.seqNo *= -1; + } + } + + // calculate message CRC + crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); + + // serialize message header data + memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); + msgSize += sizeof( MESSAGE_HEADER_T ); + + // serialize message payload (only used bytes per payloadLen field) + memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); + msgSize += msg.hdr.payloadLen; + + // add 8-bit CRC + data[ msgSize++ ] = crc; + + // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) + sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; + sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); + for ( i = 0; i < sizePad; i++ ) + { + data[ msgSize++ ] = 0; + } + + // if ACK required, add to pending ACK list + if ( TRUE == ackReq ) + { + if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) + { + error = TRUE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + } + } + + if ( FALSE == error ) + { + // add serialized message data to appropriate out-going comm buffer + result = addToCommBuffer( buffer, data, msgSize ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The sendACKMsg function constructs and queues for transmit an ACK message + * for a given received message. + * @details Inputs: none + * @details Outputs: ACK message queued for transmit on broadcast CAN channel. + * @param message message to send an ACK for + * @return TRUE if ACK message queued successfully, FALSE if not + *************************************************************************/ +BOOL sendACKMsg( MESSAGE_T *message ) +{ + BOOL result; + MESSAGE_T msg; + + // create a message record + blankMessage( &msg ); + // send ACK back with same seq. #, but w/o ACK bit + msg.hdr.seqNo = message->hdr.seqNo * -1; + // ACK messages always have this ID + msg.hdr.msgID = MSG_ID_ACK; + // ACK messages always have no payload + msg.hdr.payloadLen = 0; + + // serialize and queue the message for transmit on broadcast channel + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The sendTestAckResponseMsg function constructs a simple response message for - * a handled test message and queues it for transmit on the appropriate UART channel. - * @details Inputs: none - * @details Outputs: response message constructed and queued for transmit. - * @param msgID ID of handled message that we are responding to - * @param buffer outgoing buffer that message should be queued in - * @param ack TRUE if test message was handled successfully, FALSE if not - * @return TRUE if response message successfully queued for transmit, FALSE if not - *************************************************************************/ -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ) -{ - BOOL result; - MESSAGE_T msg; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = msgID; - msg.hdr.payloadLen = sizeof( U08 ); - msg.payload[ 0 ] = (U08)ack; - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, buffer, ACK_NOT_REQUIRED ); - - return result; -} + * a handled test message and queues it for transmit on the appropriate UART channel. + * @details Inputs: none + * @details Outputs: response message constructed and queued for transmit. + * @param msgID ID of handled message that we are responding to + * @param buffer outgoing buffer that message should be queued in + * @param ack TRUE if test message was handled successfully, FALSE if not + * @return TRUE if response message successfully queued for transmit, FALSE if not + *************************************************************************/ +static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ) +{ + BOOL result; + MESSAGE_T msg; - -// *********************************************************************** -// ***************** Message Sending Helper Functions ******************** -// *********************************************************************** + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = msgID; + msg.hdr.payloadLen = sizeof( U08 ); + msg.payload[ 0 ] = (U08)ack; -/*********************************************************************//** - * @brief - * The broadcastAlarmTriggered function constructs an alarm triggered msg to - * be broadcast and queues the msg for transmit on the appropriate CAN channel. - * @details Inputs: none - * @details Outputs: alarm triggered msg constructed and queued. - * @param alarm ID of alarm triggered - * @param almData1 1st data associated with alarm - * @param almData2 2nd data associated with alarm - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastAlarmTriggered( U16 alarm, ALARM_DATA_T almData1, ALARM_DATA_T almData2 ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_ALARM_TRIGGERED; - msg.hdr.payloadLen = sizeof( U16 ) + sizeof( ALARM_DATA_T ) + sizeof( ALARM_DATA_T ); - - memcpy( payloadPtr, &alarm, sizeof( U16 ) ); - payloadPtr += sizeof( U16 ); - memcpy( payloadPtr, &almData1, sizeof( ALARM_DATA_T ) ); - payloadPtr += sizeof( ALARM_DATA_T ); - memcpy( payloadPtr, &almData2, sizeof( ALARM_DATA_T ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_ALARM, ACK_REQUIRED ); - - return result; -} + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, buffer, ACK_NOT_REQUIRED ); -/*********************************************************************//** - * @brief - * The broadcastAlarmCleared function constructs an alarm cleared msg to be - * broadcast and queues the msg for transmit on the appropriate CAN channel. - * @details Inputs: none - * @details Outputs: alarm cleared msg constructed and queued. - * @param alarm ID of alarm cleared - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastAlarmCleared( U16 alarm ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_ALARM_CLEARED; - msg.hdr.payloadLen = sizeof( U16 ); - - memcpy( payloadPtr, &alarm, sizeof( U16 ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_ALARM, ACK_REQUIRED ); - - return result; -} + return result; +} + +// *********************************************************************** +// ***************** Message Sending Helper Functions ******************** +// *********************************************************************** + /*********************************************************************//** * @brief + * The broadcastAlarmTriggered function constructs an alarm triggered msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: alarm triggered msg constructed and queued. + * @param alarm ID of alarm triggered + * @param almData1 1st data associated with alarm + * @param almData2 2nd data associated with alarm + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastAlarmTriggered( U16 alarm, ALARM_DATA_T almData1, ALARM_DATA_T almData2 ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_ALARM_TRIGGERED; + msg.hdr.payloadLen = sizeof( U16 ) + sizeof( ALARM_DATA_T ) + sizeof( ALARM_DATA_T ); + + memcpy( payloadPtr, &alarm, sizeof( U16 ) ); + payloadPtr += sizeof( U16 ); + memcpy( payloadPtr, &almData1, sizeof( ALARM_DATA_T ) ); + payloadPtr += sizeof( ALARM_DATA_T ); + memcpy( payloadPtr, &almData2, sizeof( ALARM_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_ALARM, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The broadcastAlarmCleared function constructs an alarm cleared msg to be + * broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: alarm cleared msg constructed and queued. + * @param alarm ID of alarm cleared + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastAlarmCleared( U16 alarm ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_ALARM_CLEARED; + msg.hdr.payloadLen = sizeof( U16 ); + + memcpy( payloadPtr, &alarm, sizeof( U16 ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_ALARM, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The broadcastAccelData function constructs an accelerometer data msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none @@ -321,231 +322,231 @@ return result; } -/*********************************************************************//** - * @brief +/*********************************************************************//** + * @brief * The broadcastRTCEpoch function constructs an epoch msg to be broadcast - * and queues the msg for transmit on the appropriate CAN channel. - * @details Inputs: none - * @details Outputs: RTC time and date in epoch - * @param epoch Current time and date in epoch - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastRTCEpoch( U32 epoch ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_RTC_EPOCH; - msg.hdr.payloadLen = sizeof( U32 ); - - memcpy( payloadPtr, &epoch, sizeof( U32 ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} + * and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: RTC time and date in epoch + * @param epoch Current time and date in epoch + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastRTCEpoch( U32 epoch ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; -/*********************************************************************//** - * @brief - * The broadcastDGHDOperationMode function constructs a DG operation mode - * broadcast message and queues the msg for transmit on the appropriate CAN channel. - * @details Inputs: none - * @details Outputs: DG operation mode msg constructed and queued - * @param mode current operation mode of the DG. - * @param subMode current sub-mode of the current operation mode of the DG. - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastDGOperationMode( U32 mode, U32 subMode ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_OP_MODE; - msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); - - memcpy( payloadPtr, &mode, sizeof( U32 ) ); - payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, &subMode, sizeof( U32 ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_RTC_EPOCH; + msg.hdr.payloadLen = sizeof( U32 ); -/*********************************************************************//** - * @brief - * The broadcastLoadCellData function sends out load cell data. - * @details Inputs: none - * @details Outputs: load cell data msg constructed and queued - * @param loadCellA1 load cell A 1 data in grams - * @param loadCellA2 load cell A 2 data in grams - * @param loadCellB1 load cell B 1 data in grams - * @param loadCellB2 load cell B 2 data in grams - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastLoadCellData( F32 loadCellA1, F32 loadCellA2, F32 loadCellB1, F32 loadCellB2 ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - LOAD_CELL_DATA_T payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_LOAD_CELL_READINGS; - msg.hdr.payloadLen = sizeof( LOAD_CELL_DATA_T ); - - payload.loadCellA1inGram = loadCellA1; - payload.loadCellA2inGram = loadCellA2; - payload.loadCellB1inGram = loadCellB1; - payload.loadCellB2inGram = loadCellB2; - - memcpy( payloadPtr, &payload, sizeof( LOAD_CELL_DATA_T ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} + memcpy( payloadPtr, &epoch, sizeof( U32 ) ); -/*********************************************************************//** - * @brief - * The broadcastValvesStates function sends out DG valves states. - * @details Inputs: none - * @details Outputs: Valves states msg constructed and queued - * @param valvesStates valves states - * refer to setFPGAValveStates function in FPGA.c for details - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastValvesStates( U16 valvesStates ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_VALVES_STATES; - msg.hdr.payloadLen = sizeof( U16 ); - - memcpy( payloadPtr, &valvesStates, sizeof( U16 ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); -/*********************************************************************//** - * @brief - * The broadcastHeatersData function sends out DG heaters data - * @details Inputs: heaters data - * @details Outputs: heatears data msg constructed and queued - * @param mainPrimaryDC main primary heater duty cycle - * @param smallPrimaryDC small primary heater duty cycle - * @param trimmerDC trimmer heater duty cycle - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastHeatersData ( U32 mainPrimaryDC, U32 smallPrimaryDC, U32 trimmerDC ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - HEATERS_DATA_T payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_HEATERS_DATA; - msg.hdr.payloadLen = sizeof( HEATERS_DATA_T ); - - payload.mainPrimayHeaterDC = mainPrimaryDC; - payload.smallPrimaryHeaterDC = smallPrimaryDC; - payload.trimmerHeaterDC = trimmerDC; - - memcpy( payloadPtr, &payload, sizeof( HEATERS_DATA_T ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} + return result; +} -/*********************************************************************//** - * @brief - * The broadcastROPumpData function sends out RO pump data. - * @details Inputs: none - * @details Outputs: RO pump data msg constructed and queued - * @param tgtPressure target pressure for RO pump in PSI - * @param measFlow measure RO flow rate in LPM - * @param setPWM set PWM duty cycle in % - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastROPumpData( U32 tgtPressure, F32 measFlow, F32 setPWM ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - RO_PUMP_DATA_T payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_RO_PUMP_DATA; - msg.hdr.payloadLen = sizeof( RO_PUMP_DATA_T ); - - payload.setROPumpPressure = tgtPressure; - payload.measROFlowRate = measFlow; - payload.roPumpPWM = setPWM; - - memcpy( payloadPtr, &payload, sizeof( RO_PUMP_DATA_T ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} +/*********************************************************************//** + * @brief + * The broadcastDGHDOperationMode function constructs a DG operation mode + * broadcast message and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG operation mode msg constructed and queued + * @param mode current operation mode of the DG. + * @param subMode current sub-mode of the current operation mode of the DG. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastDGOperationMode( U32 mode, U32 subMode ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; -/*********************************************************************//** - * @brief - * The broadcastDrainPumpData function sends out drain pump data. - * @details Inputs: none - * @details Outputs: Drain pump data msg constructed and queued - * @param tgtSpeed target speed for drain pump in RPM - * @param dac set DAC value - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastDrainPumpData( U32 tgtSpeed, U32 dac ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - DRAIN_PUMP_DATA_T payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DRAIN_PUMP_DATA; - msg.hdr.payloadLen = sizeof( DRAIN_PUMP_DATA_T ); - - payload.setDrainPumpSpeed = tgtSpeed; - payload.dacValue = dac; - - memcpy( payloadPtr, &payload, sizeof( DRAIN_PUMP_DATA_T ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_OP_MODE; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); + + memcpy( payloadPtr, &mode, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &subMode, sizeof( U32 ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; } /*********************************************************************//** * @brief + * The broadcastLoadCellData function sends out load cell data. + * @details Inputs: none + * @details Outputs: load cell data msg constructed and queued + * @param loadCellA1 load cell A 1 data in grams + * @param loadCellA2 load cell A 2 data in grams + * @param loadCellB1 load cell B 1 data in grams + * @param loadCellB2 load cell B 2 data in grams + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastLoadCellData( F32 loadCellA1, F32 loadCellA2, F32 loadCellB1, F32 loadCellB2 ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + LOAD_CELL_DATA_T payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_LOAD_CELL_READINGS; + msg.hdr.payloadLen = sizeof( LOAD_CELL_DATA_T ); + + payload.loadCellA1inGram = loadCellA1; + payload.loadCellA2inGram = loadCellA2; + payload.loadCellB1inGram = loadCellB1; + payload.loadCellB2inGram = loadCellB2; + + memcpy( payloadPtr, &payload, sizeof( LOAD_CELL_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The broadcastValvesStates function sends out DG valves states. + * @details Inputs: none + * @details Outputs: Valves states msg constructed and queued + * @param valvesStates valves states + * refer to setFPGAValveStates function in FPGA.c for details + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastValvesStates( U16 valvesStates ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_VALVES_STATES; + msg.hdr.payloadLen = sizeof( U16 ); + + memcpy( payloadPtr, &valvesStates, sizeof( U16 ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The broadcastHeatersData function sends out DG heaters data + * @details Inputs: heaters data + * @details Outputs: heatears data msg constructed and queued + * @param mainPrimaryDC main primary heater duty cycle + * @param smallPrimaryDC small primary heater duty cycle + * @param trimmerDC trimmer heater duty cycle + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastHeatersData ( U32 mainPrimaryDC, U32 smallPrimaryDC, U32 trimmerDC ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + HEATERS_DATA_T payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_HEATERS_DATA; + msg.hdr.payloadLen = sizeof( HEATERS_DATA_T ); + + payload.mainPrimayHeaterDC = mainPrimaryDC; + payload.smallPrimaryHeaterDC = smallPrimaryDC; + payload.trimmerHeaterDC = trimmerDC; + + memcpy( payloadPtr, &payload, sizeof( HEATERS_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The broadcastROPumpData function sends out RO pump data. + * @details Inputs: none + * @details Outputs: RO pump data msg constructed and queued + * @param tgtPressure target pressure for RO pump in PSI + * @param measFlow measure RO flow rate in LPM + * @param setPWM set PWM duty cycle in % + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastROPumpData( U32 tgtPressure, F32 measFlow, F32 setPWM ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + RO_PUMP_DATA_T payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_RO_PUMP_DATA; + msg.hdr.payloadLen = sizeof( RO_PUMP_DATA_T ); + + payload.setROPumpPressure = tgtPressure; + payload.measROFlowRate = measFlow; + payload.roPumpPWM = setPWM; + + memcpy( payloadPtr, &payload, sizeof( RO_PUMP_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The broadcastDrainPumpData function sends out drain pump data. + * @details Inputs: none + * @details Outputs: Drain pump data msg constructed and queued + * @param tgtSpeed target speed for drain pump in RPM + * @param dac set DAC value + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastDrainPumpData( U32 tgtSpeed, U32 dac ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + DRAIN_PUMP_DATA_T payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DRAIN_PUMP_DATA; + msg.hdr.payloadLen = sizeof( DRAIN_PUMP_DATA_T ); + + payload.setDrainPumpSpeed = tgtSpeed; + payload.dacValue = dac; + + memcpy( payloadPtr, &payload, sizeof( DRAIN_PUMP_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The broadcastConcentratePumpData function sends out concentrate pumps' data. * @details Inputs: none * @details Outputs: concentrate pump data msg constructed and queued @@ -573,105 +574,105 @@ return result; } -/*********************************************************************//** - * @brief - * The broadcastPressureSensorsData function sends out DG pressure data. - * @details Inputs: none - * @details Outputs: Pressure data msg constructed and queued - * @param measROIn measured RO pump inlet pressure in PSI - * @param measROOut measured RO pump outlet pressure in PSI - * @param measDrainIn measured Drain pump inlet pressure in PSI - * @param measDrainOut measured Drain pump outlet pressure in PSI - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastPressureSensorsData( F32 measROIn, F32 measROOut, F32 measDrainIn, F32 measDrainOut ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - PRESSURES_DATA_T payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_PRESSURES_DATA; - msg.hdr.payloadLen = sizeof( PRESSURES_DATA_T ); - - payload.roPumpInletPressure = measROIn; - payload.roPumpOutletPressure = measROOut; - payload.drainPumpInletPressure = measDrainIn; - payload.drainPumpOutletPressure = measDrainOut; - - memcpy( payloadPtr, &payload, sizeof( PRESSURES_DATA_T ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; +/*********************************************************************//** + * @brief + * The broadcastPressureSensorsData function sends out DG pressure data. + * @details Inputs: none + * @details Outputs: Pressure data msg constructed and queued + * @param measROIn measured RO pump inlet pressure in PSI + * @param measROOut measured RO pump outlet pressure in PSI + * @param measDrainIn measured Drain pump inlet pressure in PSI + * @param measDrainOut measured Drain pump outlet pressure in PSI + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastPressureSensorsData( F32 measROIn, F32 measROOut, F32 measDrainIn, F32 measDrainOut ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + PRESSURES_DATA_T payload; + + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_PRESSURES_DATA; + msg.hdr.payloadLen = sizeof( PRESSURES_DATA_T ); + + payload.roPumpInletPressure = measROIn; + payload.roPumpOutletPressure = measROOut; + payload.drainPumpInletPressure = measDrainIn; + payload.drainPumpOutletPressure = measDrainOut; + + memcpy( payloadPtr, &payload, sizeof( PRESSURES_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; } -/*********************************************************************//** - * @brief - * The broadcastReservoirData function broadcasts the DG reservoir data. - * @details Inputs: none - * @details Outputs: Reservoir data msg constructed and queued - * @param resID ID of currently active reservoir - * @param fillToVol Current target fill to volume for inactive reservoir - * @param drainToVol Current target drain to volume for inactive reservoir - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastReservoirData( U32 resID, U32 fillToVol, U32 drainToVol ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - RESERVOIR_DATA_T payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_RESERVOIR_DATA; - msg.hdr.payloadLen = sizeof( RESERVOIR_DATA_T ); - - payload.activeReservoir = resID; - payload.fillToVolumeMl = fillToVol; - payload.drainToVolumeMl = drainToVol; - - memcpy( payloadPtr, &payload, sizeof( RESERVOIR_DATA_T ) ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} +/*********************************************************************//** + * @brief + * The broadcastReservoirData function broadcasts the DG reservoir data. + * @details Inputs: none + * @details Outputs: Reservoir data msg constructed and queued + * @param resID ID of currently active reservoir + * @param fillToVol Current target fill to volume for inactive reservoir + * @param drainToVol Current target drain to volume for inactive reservoir + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastReservoirData( U32 resID, U32 fillToVol, U32 drainToVol ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + RESERVOIR_DATA_T payload; -/*********************************************************************//** - * @brief - * The broadcastTemperatureSensorsData function sends out DG temperature - * sensors data. - * @details Inputs: none - * @details Outputs: temperature sensors data message constructed and queued + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_RESERVOIR_DATA; + msg.hdr.payloadLen = sizeof( RESERVOIR_DATA_T ); + + payload.activeReservoir = resID; + payload.fillToVolumeMl = fillToVol; + payload.drainToVolumeMl = drainToVol; + + memcpy( payloadPtr, &payload, sizeof( RESERVOIR_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The broadcastTemperatureSensorsData function sends out DG temperature + * sensors data. + * @details Inputs: none + * @details Outputs: temperature sensors data message constructed and queued * @param sensorsValue sensors value array - * @param byteLength payload length in bytes - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -BOOL broadcastTemperatureSensorsData ( U08 *sensorsValue, U32 byteLength ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_DG_TEMPERATURE_DATA; - msg.hdr.payloadLen = byteLength; - - memcpy( payloadPtr, sensorsValue, byteLength ); - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); - - return result; -} + * @param byteLength payload length in bytes + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastTemperatureSensorsData ( U08 *sensorsValue, U32 byteLength ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_TEMPERATURE_DATA; + msg.hdr.payloadLen = byteLength; + + memcpy( payloadPtr, sensorsValue, byteLength ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + /*********************************************************************//** * @brief * The broadcastConductivityData function sends out conductivity data. @@ -700,65 +701,91 @@ return result; } - -// *********************************************************************** -// **************** Message Handling Helper Functions ******************** -// *********************************************************************** +/*********************************************************************//** + * @brief + * The broadcastUVReactorsData function sends out the UV reactors data. + * @details Inputs: none + * @details Outputs: UV reactors data msg constructed and queued + * @param UV reactors msg constructed and queued + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastUVReactorsData( UV_REACTORS_DATA_T *uvReactorsData ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_UV_REACTORS_DATA; + msg.hdr.payloadLen = sizeof( UV_REACTORS_DATA_T ); -/*********************************************************************//** - * @brief - * The handlePowerOffWarning function handles a power off warning message - * from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handlePowerOffWarning( MESSAGE_T *message ) + memcpy( payloadPtr, uvReactorsData, sizeof( UV_REACTORS_DATA_T ) ); + + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +// *********************************************************************** +// **************** Message Handling Helper Functions ******************** +// *********************************************************************** + + +/*********************************************************************//** + * @brief + * The handlePowerOffWarning function handles a power off warning message + * from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handlePowerOffWarning( MESSAGE_T *message ) { if ( message->hdr.payloadLen == 0 ) { signalPowerOffWarning(); - } -} + } +} -/*********************************************************************//** - * @brief - * The handleSetDialysateTemperatureCmd function handles a dialysate temperature - * set points message from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSetDialysateTemperatureCmd( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( TARGET_TEMPS_PAYLOAD_T ) ) - { - TARGET_TEMPS_PAYLOAD_T payload; - - result = TRUE; - memcpy( &payload, message->payload, sizeof( TARGET_TEMPS_PAYLOAD_T ) ); - setPrimaryHeaterTargetTemperature( payload.targetPrimaryHeaterTemp ); - setTrimmerHeaterTargetTemperature( payload.targetTrimmerHeaterTemp ); - } - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); -} +/*********************************************************************//** + * @brief + * The handleSetDialysateTemperatureCmd function handles a dialysate temperature + * set points message from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetDialysateTemperatureCmd( MESSAGE_T *message ) +{ + BOOL result = FALSE; -/*********************************************************************//** - * @brief - * The handleFWVersionCmd function handles a FW version request message. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleFWVersionCmd( MESSAGE_T *message ) -{ - MESSAGE_T msg; + if ( message->hdr.payloadLen == sizeof( TARGET_TEMPS_PAYLOAD_T ) ) + { + TARGET_TEMPS_PAYLOAD_T payload; + + result = TRUE; + memcpy( &payload, message->payload, sizeof( TARGET_TEMPS_PAYLOAD_T ) ); + setPrimaryHeaterTargetTemperature( payload.targetPrimaryHeaterTemp ); + setTrimmerHeaterTargetTemperature( payload.targetTrimmerHeaterTemp ); + } + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} + +/*********************************************************************//** + * @brief + * The handleFWVersionCmd function handles a FW version request message. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleFWVersionCmd( MESSAGE_T *message ) +{ + MESSAGE_T msg; DG_VERSIONS_T payload; U08 *payloadPtr = msg.payload; @@ -777,259 +804,259 @@ // fill message payload memcpy( payloadPtr, &payload, sizeof( DG_VERSIONS_T ) ); - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); -} + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); +} -/*********************************************************************//** - * @brief - * The handleSwitchReservoirCmd function handles a switch reservoirs command - * from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSwitchReservoirCmd( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( U32 ) ) - { - RESERVOIR_ID_T reservoirID; - U32 resID; - - result = TRUE; - memcpy( &resID, message->payload, sizeof( U32 ) ); - reservoirID = (RESERVOIR_ID_T)resID; - setActiveReservoirCmd( reservoirID ); +/*********************************************************************//** + * @brief + * The handleSwitchReservoirCmd function handles a switch reservoirs command + * from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSwitchReservoirCmd( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + RESERVOIR_ID_T reservoirID; + U32 resID; + + result = TRUE; + memcpy( &resID, message->payload, sizeof( U32 ) ); + reservoirID = (RESERVOIR_ID_T)resID; + setActiveReservoirCmd( reservoirID ); } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); -} -/*********************************************************************//** - * @brief - * The handleFillCmd function handles a fill command from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleFillCmd( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( U32 ) ) - { - U32 fillToVolumeMl; - - result = TRUE; - memcpy( &fillToVolumeMl, message->payload, sizeof( U32 ) ); - startFillCmd( fillToVolumeMl ); + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} + +/*********************************************************************//** + * @brief + * The handleFillCmd function handles a fill command from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleFillCmd( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + U32 fillToVolumeMl; + + result = TRUE; + memcpy( &fillToVolumeMl, message->payload, sizeof( U32 ) ); + startFillCmd( fillToVolumeMl ); } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); -} -/*********************************************************************//** - * @brief - * The handleDrainCmd function handles a drain command from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleDrainCmd( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( DRAIN_CMD_T ) ) - { - DRAIN_CMD_T drainCmd; - - result = TRUE; - memcpy( &drainCmd, message->payload, sizeof( DRAIN_CMD_T ) ); - - startDrainCmd( drainCmd ); + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} + +/*********************************************************************//** + * @brief + * The handleDrainCmd function handles a drain command from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDrainCmd( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof( DRAIN_CMD_T ) ) + { + DRAIN_CMD_T drainCmd; + + result = TRUE; + memcpy( &drainCmd, message->payload, sizeof( DRAIN_CMD_T ) ); + + startDrainCmd( drainCmd ); } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); -} -/*********************************************************************//** - * @brief - * The handleStartStopTreatmentMsg function handles a treatment start/stop - * message from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleStartStopTreatmentMsg( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( U32 ) ) - { - BOOL startingTreatment; - - memcpy( &startingTreatment, message->payload, sizeof( U32 ) ); - - if ( DG_MODE_STAN == getCurrentOperationMode() && TRUE == startingTreatment ) - { - result = requestDGStart(); - } - else if ( DG_MODE_CIRC == getCurrentOperationMode() && FALSE == startingTreatment ) - { - result = requestDGStop(); - } + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} + +/*********************************************************************//** + * @brief + * The handleStartStopTreatmentMsg function handles a treatment start/stop + * message from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleStartStopTreatmentMsg( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + BOOL startingTreatment; + + memcpy( &startingTreatment, message->payload, sizeof( U32 ) ); + + if ( DG_MODE_STAN == getCurrentOperationMode() && TRUE == startingTreatment ) + { + result = requestDGStart(); + } + else if ( DG_MODE_CIRC == getCurrentOperationMode() && FALSE == startingTreatment ) + { + result = requestDGStop(); + } } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); -} -/*********************************************************************//** - * @brief - * The handleStartStopTrimmerHeaterCmd function handles a trimmer heater start/stop - * command message from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleStartStopTrimmerHeaterCmd( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( U32 ) ) - { - BOOL startingHeater; - - memcpy( &startingHeater, message->payload, sizeof( U32 ) ); - - if ( TRUE == startingHeater ) - { - result = startTrimmerHeaterCmd(); - } - else - { - result = stopTrimmerHeaterCmd(); - } + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} + +/*********************************************************************//** + * @brief + * The handleStartStopTrimmerHeaterCmd function handles a trimmer heater start/stop + * command message from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleStartStopTrimmerHeaterCmd( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + BOOL startingHeater; + + memcpy( &startingHeater, message->payload, sizeof( U32 ) ); + + if ( TRUE == startingHeater ) + { + result = startTrimmerHeaterCmd(); + } + else + { + result = stopTrimmerHeaterCmd(); + } } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); -} -/*********************************************************************//** - * @brief - * The handleSampleWaterCmd function handles a sample water command from the HD. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSampleWaterCmd( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == 0 ) - { - if ( DG_MODE_STAN == getCurrentOperationMode() ) - { - result = requestWaterSample(); - } + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} + +/*********************************************************************//** + * @brief + * The handleSampleWaterCmd function handles a sample water command from the HD. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSampleWaterCmd( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == 0 ) + { + if ( DG_MODE_STAN == getCurrentOperationMode() ) + { + result = requestWaterSample(); + } } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); -} -/*********************************************************************//** - * @brief - * The handleSetRTCTimestamp function handles a request to write time and - * date to RTC - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSetRTCTimestamp( MESSAGE_T *message ) -{ - BOOL result; - U08 seconds = message->payload[0]; - U08 minutes = message->payload[1]; - U08 hours = message->payload[2]; - U08 days = message->payload[3]; - U08 months = message->payload[4]; - U32 years; - memcpy(&years, &message->payload[5], sizeof( U32 )); - - result = setRTCTimestamp( seconds, minutes, hours, days, months, years ); - - // respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); +} -/*********************************************************************//** - * @brief - * The handleStartStopPrimaryHeater function handles a request start or - * stop the primary heater - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return result - *************************************************************************/ -BOOL handleStartStopPrimaryHeater( MESSAGE_T * message ) -{ - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( U32 ) ) - { - BOOL startingHeater; - - memcpy( &startingHeater, message->payload, sizeof( U32 ) ); - - if ( TRUE == startingHeater ) - { - result = startPrimaryHeater(); - } - else - { - stopPrimaryHeater(); - result = TRUE; - } +/*********************************************************************//** + * @brief + * The handleSetRTCTimestamp function handles a request to write time and + * date to RTC + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetRTCTimestamp( MESSAGE_T *message ) +{ + BOOL result; + U08 seconds = message->payload[0]; + U08 minutes = message->payload[1]; + U08 hours = message->payload[2]; + U08 days = message->payload[3]; + U08 months = message->payload[4]; + U32 years; + memcpy(&years, &message->payload[5], sizeof( U32 )); + + result = setRTCTimestamp( seconds, minutes, hours, days, months, years ); + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleStartStopPrimaryHeater function handles a request start or + * stop the primary heater + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return result + *************************************************************************/ +BOOL handleStartStopPrimaryHeater( MESSAGE_T * message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + BOOL startingHeater; + + memcpy( &startingHeater, message->payload, sizeof( U32 ) ); + + if ( TRUE == startingHeater ) + { + result = startPrimaryHeater(); + } + else + { + stopPrimaryHeater(); + result = TRUE; + } } - - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); - - return result; -} - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); - + return result; +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + #ifdef DEBUG_ENABLED - /*********************************************************************//** - * @brief - * The sendDebugData function sends debug data out to the PC port. - * @details - * @details Inputs: none - * @details Outputs: PC serial port - * @param dbgData Pointer to debug data - * @param len number of bytes of debug data - * @return TRUE if debug data was successfully queued for transmit, FALSE if not - *************************************************************************/ - BOOL sendDebugData( U08 *dbgData, U32 len ) - { - BOOL result; - - // add serialized message data to appropriate comm buffer - result = addToCommBuffer( COMM_BUFFER_OUT_UART_PC, dbgData, len ); - - return result; + /*********************************************************************//** + * @brief + * The sendDebugData function sends debug data out to the PC port. + * @details + * @details Inputs: none + * @details Outputs: PC serial port + * @param dbgData Pointer to debug data + * @param len number of bytes of debug data + * @return TRUE if debug data was successfully queued for transmit, FALSE if not + *************************************************************************/ + BOOL sendDebugData( U08 *dbgData, U32 len ) + { + BOOL result; + + // add serialized message data to appropriate comm buffer + result = addToCommBuffer( COMM_BUFFER_OUT_UART_PC, dbgData, len ); + + return result; } /*********************************************************************//** @@ -1059,81 +1086,81 @@ serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_2_UI, ACK_NOT_REQUIRED ); } } -#endif +#endif -/*********************************************************************//** - * @brief - * The isTestingActivated function determines whether a tester has successfully - * logged in to activate testing functionality. - * @details Inputs: testerLoggedIn - * @details Outputs: none - * @return TRUE if a tester has logged in to activate testing, FALSE if not - *************************************************************************/ -BOOL isTestingActivated( void ) -{ - return testerLoggedIn; -} +/*********************************************************************//** + * @brief + * The isTestingActivated function determines whether a tester has successfully + * logged in to activate testing functionality. + * @details Inputs: testerLoggedIn + * @details Outputs: none + * @return TRUE if a tester has logged in to activate testing, FALSE if not + *************************************************************************/ +BOOL isTestingActivated( void ) +{ + return testerLoggedIn; +} -/*********************************************************************//** - * @brief +/*********************************************************************//** + * @brief * The sendTestAckResponseMsg function constructs a simple response message for - * a handled test message and queues it for transmit on the appropriate UART channel. - * @details Inputs: none - * @details Outputs: response message constructed and queued for transmit. - * @param msgID ID of handled message that we are responding to - * @param ack TRUE if test message was handled successfully, FALSE if not - * @return TRUE if response message successfully queued for transmit, FALSE if not - *************************************************************************/ -static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ) -{ - BOOL result; - MESSAGE_T msg; - - // create a message record - blankMessage( &msg ); - msg.hdr.msgID = msgID; - msg.hdr.payloadLen = sizeof( U08 ); - msg.payload[ 0 ] = (U08)ack; - - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); - - return result; -} + * a handled test message and queues it for transmit on the appropriate UART channel. + * @details Inputs: none + * @details Outputs: response message constructed and queued for transmit. + * @param msgID ID of handled message that we are responding to + * @param ack TRUE if test message was handled successfully, FALSE if not + * @return TRUE if response message successfully queued for transmit, FALSE if not + *************************************************************************/ +static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ) +{ + BOOL result; + MESSAGE_T msg; -/*********************************************************************//** - * @brief - * The handleTesterLogInRequest function handles a request to login as a tester. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleTesterLogInRequest( MESSAGE_T *message ) -{ - // verify pass code - // TODO - placeholder - how do we want to authenticate tester? - if ( ( 3 == message->hdr.payloadLen ) && ( 0x31 == message->payload[ 0 ] ) && ( 0x32 == message->payload[ 1 ] ) && ( 0x33 == message->payload[ 2 ] ) ) - { - testerLoggedIn = TRUE; - } - else - { - testerLoggedIn = FALSE; - } - // respond to would be tester - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, testerLoggedIn ); -} + // create a message record + blankMessage( &msg ); + msg.hdr.msgID = msgID; + msg.hdr.payloadLen = sizeof( U08 ); + msg.payload[ 0 ] = (U08)ack; -/*********************************************************************//** - * @brief - * The handleTestWatchdogCheckInStateOverrideRequest function handles a - * request to override the check-in status of a given task. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ + // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTesterLogInRequest function handles a request to login as a tester. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTesterLogInRequest( MESSAGE_T *message ) +{ + // verify pass code + // TODO - placeholder - how do we want to authenticate tester? + if ( ( 3 == message->hdr.payloadLen ) && ( 0x31 == message->payload[ 0 ] ) && ( 0x32 == message->payload[ 1 ] ) && ( 0x33 == message->payload[ 2 ] ) ) + { + testerLoggedIn = TRUE; + } + else + { + testerLoggedIn = FALSE; + } + // respond to would be tester + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, testerLoggedIn ); +} + +/*********************************************************************//** + * @brief + * The handleTestWatchdogCheckInStateOverrideRequest function handles a + * request to override the check-in status of a given task. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestWatchdogCheckInStateOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; @@ -1157,15 +1184,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestAlarmStateOverrideRequest function handles a request to - * override the active status of a given alarm. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestAlarmStateOverrideRequest function handles a request to + * override the active status of a given alarm. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestAlarmStateOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; @@ -1189,15 +1216,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestLoadCellOverrideRequest function handles a request to - * override the value read from the given load cell. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestLoadCellOverrideRequest function handles a request to + * override the value read from the given load cell. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestLoadCellOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; @@ -1221,15 +1248,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestTemperatureSensorsOverrideRequest function handles a - * request to override a temperatures sensor's value. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestTemperatureSensorsOverrideRequest function handles a + * request to override a temperatures sensor's value. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestTemperatureSensorsOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; @@ -1253,16 +1280,16 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** -* @brief -* The handleTestTemperatureSensorsDataPublishOverrideRequest function handles -* a request to override the publish interval of temperature sensors data. -* @details -* @details Inputs: none -* @details Outputs: message handled -* @param message a pointer to the message to handle -* @return none -*************************************************************************/ +/*********************************************************************//** +* @brief +* The handleTestTemperatureSensorsDataPublishOverrideRequest function handles +* a request to override the publish interval of temperature sensors data. +* @details +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ void handleTestTemperatureSensorsDataPublishOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1285,16 +1312,16 @@ // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } - -/*********************************************************************//** - * @brief - * The handleTestHeatersDataPublishOverrideRequest function handles - * a request to override the publish interval of heaters data. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ + +/*********************************************************************//** + * @brief + * The handleTestHeatersDataPublishOverrideRequest function handles + * a request to override the publish interval of heaters data. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestHeatersDataPublishOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1318,15 +1345,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestLoadCellDataBroadcastIntervalOverrideRequest function handles - * a request to override the broadcast interval for load cell data. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestLoadCellDataBroadcastIntervalOverrideRequest function handles + * a request to override the broadcast interval for load cell data. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestLoadCellDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1350,15 +1377,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestPressureSensorOverrideRequest function handles a request to - * override the value read from the given pressure sensor. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestPressureSensorOverrideRequest function handles a request to + * override the value read from the given pressure sensor. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestPressureSensorOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; @@ -1382,15 +1409,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestPressureDataBroadcastIntervalOverrideRequest function handles - * a request to override the broadcast interval for load cell data. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestPressureDataBroadcastIntervalOverrideRequest function handles + * a request to override the broadcast interval for load cell data. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestPressureDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1414,15 +1441,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestROPumpSetPointOverrideRequest function handles a request to - * override the RO pump pressure set point (in PSI). - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestROPumpSetPointOverrideRequest function handles a request to + * override the RO pump pressure set point (in PSI). + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestROPumpSetPointOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1446,15 +1473,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestROMeasuredFlowOverrideRequest function handles a request to - * override the RO flow rate. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestROMeasuredFlowOverrideRequest function handles a request to + * override the RO flow rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1476,17 +1503,17 @@ // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} +} -/*********************************************************************//** - * @brief - * The handleTestROPumpDataBroadcastIntervalOverrideRequest function handles - * a request to override the broadcast interval for RO pump data. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestROPumpDataBroadcastIntervalOverrideRequest function handles + * a request to override the broadcast interval for RO pump data. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestROPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1510,15 +1537,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestDrainPumpSetPointOverrideRequest function handles a request to - * override the drain pump speed set point (in RPM). - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestDrainPumpSetPointOverrideRequest function handles a request to + * override the drain pump speed set point (in RPM). + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestDrainPumpSetPointOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1542,15 +1569,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestDrainPumpDataBroadcastIntervalOverrideRequest function handles - * a request to override the broadcast interval for drain pump data. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestDrainPumpDataBroadcastIntervalOverrideRequest function handles + * a request to override the broadcast interval for drain pump data. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestDrainPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1574,15 +1601,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestValveStateOverrideRequest function handles a request to - * override the state value read from the given valve. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestValveStateOverrideRequest function handles a request to + * override the state value read from the given valve. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestValveStateOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; @@ -1606,15 +1633,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestValvesStatesPublishIntervalOverrideRequest function handles - * a request to override the publish interval of valves states from the given valve. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestValvesStatesPublishIntervalOverrideRequest function handles + * a request to override the publish interval of valves states from the given valve. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestValvesStatesPublishIntervalOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1638,15 +1665,15 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestDGSafetyShutdownOverrideRequest function handles a - * request to override the safety shutdown signal. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ +/*********************************************************************//** + * @brief + * The handleTestDGSafetyShutdownOverrideRequest function handles a + * request to override the safety shutdown signal. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestDGSafetyShutdownOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -1857,6 +1884,138 @@ } /*********************************************************************//** +* @brief +* The handleStartStopInletUVReactor function handles a request to turn on/off +* the inlet UV reactor. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +BOOL handleStartStopInletUVReactor( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(U32) ) + { + BOOL startingReactor; + + memcpy( &startingReactor, message->payload, sizeof(U32) ); + + if ( TRUE == startingReactor ) + { + result = turnOnUVReactor( INLET_UV_REACTOR ); + } + else + { + result = turnOffUVReactor( INLET_UV_REACTOR ); + } + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); + + return result; +} + +/*********************************************************************//** +* @brief +* The handleUVReactorsDataPunlishIntervalOverride function handles a request +* to override the publish interval of the UV reactors data +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleUVReactorsDataPublishIntervalOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetReactorsDataPublishInterval( payload.state.u32 ); + } + else + { + result = testResetReactorsDataPublishInterval(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleStartStopOutletUVReactor function handles a request to turn +* on/off the outlet UV reactor. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +BOOL handleStartStopOutletUVReactor( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(U32) ) + { + BOOL startingReactor; + + memcpy( &startingReactor, message->payload, sizeof(U32) ); + + if ( TRUE == startingReactor ) + { + result = turnOnUVReactor( OUTLET_UV_REACTOR ); + } + else + { + result = turnOffUVReactor( OUTLET_UV_REACTOR ); + } + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result ); + + return result; +} + +/*********************************************************************//** +* @brief +* The handleUVReactorsHealthOverride function handles UV reactors health +* status override. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleUVReactorsHealthOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetUVReactorHealthOverride( payload.index, (BOOL)payload.state.u32 ); + } + else + { + result = testResetUVReactorHealthOverride( payload.index ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleDGSoftwareResetRequest function handles a request to * perform a software reset on DG. Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r498aa2804b2babde370f74f0cf9a333655fc0410 -r00b0fcefb9f74e7c050b5c83ad5c285e6769ef78 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 498aa2804b2babde370f74f0cf9a333655fc0410) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -14,64 +14,65 @@ * @date (original) 05-Nov-2019 * ***************************************************************************/ - -#ifndef __SYSTEM_COMM_MESSAGES_H__ -#define __SYSTEM_COMM_MESSAGES_H__ - -#include "DGCommon.h" -#include "MsgQueues.h" +#ifndef __SYSTEM_COMM_MESSAGES_H__ +#define __SYSTEM_COMM_MESSAGES_H__ + +#include "DGCommon.h" +#include "MsgQueues.h" +#include "UVReactors.h" + /** * @defgroup SystemCommMessages SystemCommMessages * @brief System communication messages service module. Handles and broadcasts system messages. * * @addtogroup SystemCommMessages * @{ */ - -// ********** public definitions ********** - -// ********** public function prototypes ********** - -// ACK MSG -BOOL sendACKMsg( MESSAGE_T *message ); - -// MSG_ID_ALARM_TRIGGERED -BOOL broadcastAlarmTriggered( U16 alarm, ALARM_DATA_T almData1, ALARM_DATA_T almData2 ); - -// MSG_ID_ALARM_CLEARED -BOOL broadcastAlarmCleared( U16 alarm ); - + +// ********** public definitions ********** + +// ********** public function prototypes ********** + +// ACK MSG +BOOL sendACKMsg( MESSAGE_T *message ); + +// MSG_ID_ALARM_TRIGGERED +BOOL broadcastAlarmTriggered( U16 alarm, ALARM_DATA_T almData1, ALARM_DATA_T almData2 ); + +// MSG_ID_ALARM_CLEARED +BOOL broadcastAlarmCleared( U16 alarm ); + // MSG_ID_DG_ACCELEROMETER_DATA BOOL broadcastAccelData( F32 x, F32 y, F32 z, F32 xm, F32 ym, F32 zm, F32 xt, F32 yt, F32 zt ); -// MSG_ID_RTC_EPOCH -BOOL broadcastRTCEpoch( U32 epoch ); // TODO - probably don't want DG to broadcast these - -// MSG_ID_DG_OP_MODE -BOOL broadcastDGOperationMode( U32 mode, U32 subMode ); - -// MSG_ID_LOAD_CELL_READINGS -BOOL broadcastLoadCellData( F32 loadCellA1, F32 loadCellA2, F32 loadCellB1, F32 loadCellB2 ); - -// MSG_ID_DG_VALVES_STATES -BOOL broadcastValvesStates( U16 valvesStates ); - -// MSG_ID_RO_PUMP_DATA -BOOL broadcastROPumpData( U32 tgtPressure, F32 measFlow, F32 setPWM ); - -// MSG_ID_DRAIN_PUMP_DATA -BOOL broadcastDrainPumpData( U32 tgtSpeed, U32 dac ); +// MSG_ID_RTC_EPOCH +BOOL broadcastRTCEpoch( U32 epoch ); // TODO - probably don't want DG to broadcast these +// MSG_ID_DG_OP_MODE +BOOL broadcastDGOperationMode( U32 mode, U32 subMode ); + +// MSG_ID_LOAD_CELL_READINGS +BOOL broadcastLoadCellData( F32 loadCellA1, F32 loadCellA2, F32 loadCellB1, F32 loadCellB2 ); + +// MSG_ID_DG_VALVES_STATES +BOOL broadcastValvesStates( U16 valvesStates ); + +// MSG_ID_RO_PUMP_DATA +BOOL broadcastROPumpData( U32 tgtPressure, F32 measFlow, F32 setPWM ); + +// MSG_ID_DRAIN_PUMP_DATA +BOOL broadcastDrainPumpData( U32 tgtSpeed, U32 dac ); + // MSG_ID_DG_CONCENTRATE_PUMP_DATA BOOL broadcastConcentratePumpData( void * concentratePumpDataPtr ); - -// MSG_ID_DG_PRESSURES_DATA -BOOL broadcastPressureSensorsData( F32 measROIn, F32 measROOut, F32 measDrainIn, F32 measDrainOut ); - -// MSG_ID_DG_RESERVOIR_DATA -BOOL broadcastReservoirData( U32 resID, U32 fillToVol, U32 drainToVol ); - + +// MSG_ID_DG_PRESSURES_DATA +BOOL broadcastPressureSensorsData( F32 measROIn, F32 measROOut, F32 measDrainIn, F32 measDrainOut ); + +// MSG_ID_DG_RESERVOIR_DATA +BOOL broadcastReservoirData( U32 resID, U32 fillToVol, U32 drainToVol ); + // MSG_ID_HEATERS_READINGS BOOL broadcastHeatersData ( U32 mainPrimaryDC, U32 smallPrimaryDC, U32 trimmerDC ); @@ -81,110 +82,112 @@ // MSG_ID_DG_CONDUCTIVITY_DATA BOOL broadcastConductivityData( void * conductivityDataPtr ); -// MSG_ID_POWER_OFF_WARNING -void handlePowerOffWarning( MESSAGE_T *message ); - -// MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS -void handleSetDialysateTemperatureCmd( MESSAGE_T *message ); - -// MSG_ID_REQUEST_FW_VERSIONS -void handleFWVersionCmd( MESSAGE_T *message ); - -// MSG_ID_DG_SWITCH_RESERVOIR -void handleSwitchReservoirCmd( MESSAGE_T *message ); - -// MSG_ID_DG_FILL -void handleFillCmd( MESSAGE_T *message ); - -// MSG_ID_DG_DRAIN -void handleDrainCmd( MESSAGE_T *message ); - -// MSG_ID_STARTING_STOPPING_TREATMENT -void handleStartStopTreatmentMsg( MESSAGE_T *message ); - -// MSG_ID_DG_SAMPLE_WATER_CMD -void handleSampleWaterCmd( MESSAGE_T *message ); - +// MSG_ID_POWER_OFF_WARNING +void handlePowerOffWarning( MESSAGE_T *message ); + +// MSG_ID_SET_DG_DIALYSATE_TEMP_TARGETS +void handleSetDialysateTemperatureCmd( MESSAGE_T *message ); + +// MSG_ID_REQUEST_FW_VERSIONS +void handleFWVersionCmd( MESSAGE_T *message ); + +// MSG_ID_DG_SWITCH_RESERVOIR +void handleSwitchReservoirCmd( MESSAGE_T *message ); + +// MSG_ID_DG_FILL +void handleFillCmd( MESSAGE_T *message ); + +// MSG_ID_DG_DRAIN +void handleDrainCmd( MESSAGE_T *message ); + +// MSG_ID_STARTING_STOPPING_TREATMENT +void handleStartStopTreatmentMsg( MESSAGE_T *message ); + +// MSG_ID_DG_SAMPLE_WATER_CMD +void handleSampleWaterCmd( MESSAGE_T *message ); + // MSG_ID_START_STOP_PRIMARY_HEATER BOOL handleStartStopPrimaryHeater( MESSAGE_T * message ); -// MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD -void handleStartStopTrimmerHeaterCmd( MESSAGE_T *message ); - -// *********** public test support message functions ********** - -#ifdef DEBUG_ENABLED -// DEBUG OUTPUT -BOOL sendDebugData( U08 *dbgData, U32 len ); +// MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD +void handleStartStopTrimmerHeaterCmd( MESSAGE_T *message ); +// MSG_ID_DG_UV_REACTORS_DATA +BOOL broadcastUVReactorsData( UV_REACTORS_DATA_T *uvReactorsData ); +// *********** public test support message functions ********** + +#ifdef DEBUG_ENABLED +// DEBUG OUTPUT +BOOL sendDebugData( U08 *dbgData, U32 len ); + // Debug message to UI for logging void sendDebugDataToUI( U08 *str ); -#endif - -// MSG_TESTER_LOG_IN -void handleTesterLogInRequest( MESSAGE_T *message ); -BOOL isTestingActivated( void ); - -// MSG_ID_DG_ALARM_STATE_OVERRIDE -void handleTestAlarmStateOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_WATCHDOG_TASK_CHECKIN_OVERRIDE: -void handleTestWatchdogCheckInStateOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_LOAD_CELL_OVERRIDE -void handleTestLoadCellOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_LOAD_CELLL_SEND_INTERVAL_OVERRIDE: -void handleTestLoadCellDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_TEMPERATURE_SENSORS_OVERRIDE -void handleTestTemperatureSensorsOverrideRequest ( MESSAGE_T *message ); - -// MSG_ID_TEMPERATURE_SENSORS_DATA_PUBLISH_OVERRIDE -void handleTestTemperatureSensorsDataPublishOverrideRequest ( MESSAGE_T *message ); - -// MSG_ID_PUBLSIH_HEATERS_DATA_OVERRIDE -void handleTestHeatersDataPublishOverrideRequest ( MESSAGE_T *message ); - -// MSG_ID_SET_RTC_TIMESTAMP -void handleSetRTCTimestamp( MESSAGE_T *message ); - -// MSG_ID_PRESSURE_OVERRIDE: -void handleTestPressureSensorOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_PRESSURE_SEND_INTERVAL_OVERRIDE: -void handleTestPressureDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_RO_PUMP_SET_PT_OVERRIDE: -void handleTestROPumpSetPointOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_RO_MEASURED_FLOW_OVERRIDE: -void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: -void handleTestROPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_DRAIN_PUMP_SET_PT_OVERRIDE: -void handleTestDrainPumpSetPointOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE: -void handleTestDrainPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_VALVE_STATE_OVERRIDE -void handleTestValveStateOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_VALVES_STATES_PUBLISH_INTERVAL_OVERRIDE -void handleTestValvesStatesPublishIntervalOverrideRequest( MESSAGE_T *message ); - -// MSG_ID_DG_SAFETY_SHUTDOWN_OVERRIDE: +#endif + +// MSG_TESTER_LOG_IN +void handleTesterLogInRequest( MESSAGE_T *message ); +BOOL isTestingActivated( void ); + +// MSG_ID_DG_ALARM_STATE_OVERRIDE +void handleTestAlarmStateOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_WATCHDOG_TASK_CHECKIN_OVERRIDE: +void handleTestWatchdogCheckInStateOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_LOAD_CELL_OVERRIDE +void handleTestLoadCellOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_LOAD_CELLL_SEND_INTERVAL_OVERRIDE: +void handleTestLoadCellDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_TEMPERATURE_SENSORS_OVERRIDE +void handleTestTemperatureSensorsOverrideRequest ( MESSAGE_T *message ); + +// MSG_ID_TEMPERATURE_SENSORS_DATA_PUBLISH_OVERRIDE +void handleTestTemperatureSensorsDataPublishOverrideRequest ( MESSAGE_T *message ); + +// MSG_ID_PUBLSIH_HEATERS_DATA_OVERRIDE +void handleTestHeatersDataPublishOverrideRequest ( MESSAGE_T *message ); + +// MSG_ID_SET_RTC_TIMESTAMP +void handleSetRTCTimestamp( MESSAGE_T *message ); + +// MSG_ID_PRESSURE_OVERRIDE: +void handleTestPressureSensorOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_PRESSURE_SEND_INTERVAL_OVERRIDE: +void handleTestPressureDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_RO_PUMP_SET_PT_OVERRIDE: +void handleTestROPumpSetPointOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_RO_MEASURED_FLOW_OVERRIDE: +void handleTestROMeasuredFlowOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: +void handleTestROPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_DRAIN_PUMP_SET_PT_OVERRIDE: +void handleTestDrainPumpSetPointOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE: +void handleTestDrainPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_VALVE_STATE_OVERRIDE +void handleTestValveStateOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_VALVES_STATES_PUBLISH_INTERVAL_OVERRIDE +void handleTestValvesStatesPublishIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_DG_SAFETY_SHUTDOWN_OVERRIDE: void handleTestDGSafetyShutdownOverrideRequest( MESSAGE_T *message ); // MSG_ID_CONDUCTIVITY_OVERRIDE void handleTestSetConductivityOverrideRequest( MESSAGE_T *message ); // MSG_ID_CONDUCTIVITY_PUBLISH_INTERVAL_OVERRIDE -void handleTestSetConductivityDataPublishIntervalOverrideRequest( MESSAGE_T *message ); - +void handleTestSetConductivityDataPublishIntervalOverrideRequest( MESSAGE_T *message ); + // MSG_ID_DG_ACCEL_OVERRIDE: void handleTestDGAccelOverrideRequest( MESSAGE_T *message ); @@ -197,9 +200,21 @@ // MSG_ID_DG_ACCEL_SET_CALIBRATION: void handleSetAccelCalibration( MESSAGE_T *message ); +// MSG_ID_DG_START_STOP_INLET_UV_REACTOR +BOOL handleStartStopInletUVReactor( MESSAGE_T *message ); + +//MSG_ID_UV_REACTORS_DATA_PUBLISH_INTERVAL_OVERRIDE +void handleUVReactorsDataPublishIntervalOverride( MESSAGE_T *message ); + // MSG_ID_DG_SOFTWARE_RESET_REQUEST void handleDGSoftwareResetRequest( MESSAGE_T *message); +// MSG_ID_DG_START_STOP_OUTLET_UV_REACTOR +BOOL handleStartStopOutletUVReactor( MESSAGE_T *message ); + +// MSG_ID_DG_UV_REACTORS_HEALTH_OVERRIDE +void handleUVReactorsHealthOverride( MESSAGE_T *message ); + // MSG_ID_DG_CONCENTRATE_PUMP_MEASURED_SPEED_OVERRIDE void handleConcentratePumpMeasuredSpeedOverride( MESSAGE_T *message ); @@ -214,4 +229,4 @@ /**@}*/ -#endif +#endif Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -r3f22d883958a14b6193d6cd59c9acdbbd359b69e -r00b0fcefb9f74e7c050b5c83ad5c285e6769ef78 --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 3f22d883958a14b6193d6cd59c9acdbbd359b69e) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 00b0fcefb9f74e7c050b5c83ad5c285e6769ef78) @@ -26,7 +26,8 @@ #include "ROPump.h" #include "SystemComm.h" #include "SystemCommMessages.h" -#include "TaskGeneral.h" +#include "TaskGeneral.h" +#include "UVReactors.h" #include "WatchdogMgmt.h" /** @@ -51,7 +52,15 @@ * @return none *************************************************************************/ void taskGeneral( void ) -{ +{ + /* Order of exec functions + * 1. Comm Rx + * 2. Monitors + * 3. Op modes + * 4. Controllers + * 5. Comm Tx + * */ + #ifdef TASK_TIMING_OUTPUT_ENABLED // SET_TASK_ON(); // TODO - uncomment and define TASK_TIMING_OUTPUT_ENABLED to monitor this tasks timing #endif @@ -75,7 +84,10 @@ execConcentratePumpController(); // manage time-based reservoir tasks - execReservoirs(); + execReservoirs(); + + // Manage UV reactors controller + execUVReactos(); #ifndef DISABLE_HEATERS_AND_TEMPS // Primary heaters state machine