/************************************************************************** * * Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file Level.c * * @author (last) Sean Nash * @date (last) 09-Nov-2024 * * @author (original) Sean Nash * @date (original) 09-Nov-2024 * ***************************************************************************/ #include "FpgaRO.h" #include "Level.h" #include "MessageSupport.h" #include "Messaging.h" #include "TaskPriority.h" #include "Timers.h" /** * @addtogroup Level * @{ */ // ********** private definitions ********** #define LEVEL_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the level data is published on the CAN bus. #define LEVEL_DEBOUNCE_TIME_MS ( MS_PER_SECOND / 10 ) ///< Level debounce time in milliseconds. #define DATA_PUBLISH_COUNTER_START_COUNT 7 ///< Data publish counter start count. /// Level status structure typedef struct { OVERRIDE_U32_T status; ///< Level status. U32 debounceStartTime; ///< Debounce start time. U32 debounceTime; ///< Debounce time } LEVEL_STATUS_T; // ********** private data ********** static U32 levelsDataPublicationCounter; ///< Level data publication counter. static OVERRIDE_U32_T levelsDataPublishInterval; ///< Interval (in ms) at which to publish Level data to CAN bus. static LEVEL_STATUS_T levelsStatus[ NUM_OF_LEVELS ]; ///< Level status array. // ********** private function prototypes ********** static void publishLevelsData( void ); /*********************************************************************//** * @brief * The initLevels function initializes the levels unit. * @details \b Inputs: none * @details \b Outputs: Level unit variables initialized. * @return none *************************************************************************/ void initLevels( void ) { U32 level; levelsDataPublicationCounter = DATA_PUBLISH_COUNTER_START_COUNT; // Initialize all the Level for ( level = 0; level < NUM_OF_LEVELS; level++ ) { levelsStatus[ level ].status.data = (U32)STATE_HIGH; levelsStatus[ level ].status.ovData = (U32)STATE_HIGH; levelsStatus[ level ].status.ovInitData = (U32)STATE_HIGH; levelsStatus[ level ].status.override = OVERRIDE_RESET; levelsStatus[ level ].debounceStartTime = 0; levelsStatus[ level ].debounceTime = LEVEL_DEBOUNCE_TIME_MS; } levelsDataPublishInterval.data = LEVEL_DATA_PUB_INTERVAL; levelsDataPublishInterval.ovData = LEVEL_DATA_PUB_INTERVAL; levelsDataPublishInterval.ovInitData = 0; levelsDataPublishInterval.override = OVERRIDE_RESET; } /*********************************************************************//** * @brief * The execLevels function executes the floater and level sensor states. * @details \b Inputs: level sensor and floater reading from FPGA * @details \b Outputs: levelStatus * @details \b Alarms: ALARM_ID_RO_SOFTWARE_FAULT when invalid level sensor is set. * @return none *************************************************************************/ void execLevels( void ) { U32 level; U32 currentLevelStatus = 0; for ( level = 0; level < NUM_OF_LEVELS; level++ ) { // Get the current level status // switch ( level ) // { // // Process the status of the Level // case FLOATER: // currentLevelStatus = ( getFPGAFloater1Status() != 0 ? STATE_LOW : STATE_MEDIUM ); // break; // //#ifndef _VECTORCAST_ // default: // SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_LEVEL_SELECTED, level ); // break; //#endif // } // // // Check if the current level status is not the same as the recorded data // if ( currentLevelStatus != levelsStatus[ level ].status.data ) // { // // If the debounce time is 0, start the timer // if ( 0 == levelsStatus[ level ].debounceStartTime ) // { // levelsStatus[ level ].debounceStartTime = getMSTimerCount(); // } // // If the debounce time has been elapsed, update the level sensor status to the new status // else if ( TRUE == didTimeout( levelsStatus[ level ].debounceStartTime, levelsStatus[ level ].debounceTime ) ) // { // switch ( level ) // { // case FLOATER: // SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_FLOATER_1_LEVEL_CHANGE, (U32)levelsStatus[ level ].status.data, (U32)currentLevelStatus ); // break; // //#ifndef _VECTORCAST_ // default: // SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_LEVEL_SELECTED, level ); // break; //#endif // } // // levelsStatus[ level ].debounceStartTime = 0; // levelsStatus[ level ].status.data = currentLevelStatus; // } // } // else // { // levelsStatus[ level ].debounceStartTime = 0; // } } // publishLevelsData(); } /*********************************************************************//** * @brief * The getLevelStatus function returns the status of the called level sensor. * @details \b Inputs: levelStatus * @details \b Outputs: levelStatus * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid level sensor * passed. * @param levelId which is the sensor that its status is requested * @return level status *************************************************************************/ //LEVEL_STATE_T getLevelStatus( LELVEL_T levelId ) //{ // U32 status = 0; // // if ( levelId < NUM_OF_LEVELS ) // { // // Assume there is no override // status = levelsStatus[ levelId ].status.data; // // if ( OVERRIDE_KEY == levelsStatus[ levelId ].status.override ) // { // status = levelsStatus[ levelId ].status.ovData; // } // } // else // { // SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DD_INVALID_LEVEL_ID, (U32)levelId ) // } // // return (LEVEL_STATE_T)status; //} /*********************************************************************//** * @brief * The publishLevelsData function broadcasts the level data at the * publication interval. * @details \b Inputs: levelsDataPublicationCounter * @details \b Outputs: levelsDataPublicationCounter * @details \b Message \b Sent: MSG_ID_DD_LEVEL_DATA to publish level * sensors data. * @return none *************************************************************************/ //static void publishLevelsData( void ) //{ // if ( ++levelsDataPublicationCounter >= getU32OverrideValue( &levelsDataPublishInterval ) ) // { // LEVEL_DATA_T data; // // data.floater1Level = (U32)getLevelStatus( FLOATER_1 ); // data.floater2Level = (U32)getLevelStatus( FLOATER_2 ); // data.bicarbLevel = (U32)getLevelStatus( BICARB_LEVEL ); // data.spentDialysateLevel = (U32)getLevelStatus( SPENT_DIALYSATE_LEVEL ); // // levelsDataPublicationCounter = 0; // // broadcastData( MSG_ID_DD_LEVEL_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( LEVEL_DATA_T ) ); // } //} /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testLevelsDataPublishIntervalOverride function overrides * the Level publish data interval. * @details \b Inputs: levelsDataPublishInterval * @details \b Outputs: levelsDataPublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the level data broadcast interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ //BOOL testLevelsDataPublishIntervalOverride( MESSAGE_T *message ) //{ // BOOL result = u32BroadcastIntervalOverride( message, &levelsDataPublishInterval, TASK_PRIORITY_INTERVAL ); // // return result; //} /*********************************************************************//** * @brief * The testLevelStatusOverride function sets the override status * for a specific level sensor. * @details \b Inputs: none * @details \b Outputs: levelStatus * @param message Override message from Dialin which includes an ID of * the level sensor to override and the state to override the level sensor to. * @return TRUE if override successful, FALSE if not *************************************************************************/ //BOOL testLevelStatusOverride( MESSAGE_T *message ) //{ // BOOL result = u32ArrayOverride( message, &levelsStatus[0].status, NUM_OF_LEVELS - 1, 0, NUM_OF_LEVELS_STATES -1 ); // // return result; //} /**@}*/