Index: AlarmMgmt.c =================================================================== diff -u -r15a8d5ff98b2d88bd0f32a37b41f4eec0f7a7088 -r91cff0134623a852aeb37b497b2263cf4a9ba6cb --- AlarmMgmt.c (.../AlarmMgmt.c) (revision 15a8d5ff98b2d88bd0f32a37b41f4eec0f7a7088) +++ AlarmMgmt.c (.../AlarmMgmt.c) (revision 91cff0134623a852aeb37b497b2263cf4a9ba6cb) @@ -14,53 +14,53 @@ * @date (original) 30-Jul-2024 * ***************************************************************************/ - -#include "mibspi.h" - + +#include "mibspi.h" + #define __ALARM_MGMT_C__ #include "Messaging.h" #include "OperationModes.h" -#include "TaskGeneral.h" -#include "Timers.h" +#include "TaskGeneral.h" +#include "Timers.h" -/** - * @addtogroup AlarmManagement - * @{ - */ - -// ********** private definitions ********** +/** + * @addtogroup AlarmManagement + * @{ + */ +// ********** private definitions ********** + // *** This declaration will cause a compiler error if ALARM_TABLE does not have same # of alarms as the Alarm_List enumeration. U08 alarmTableSizeAssertion[ ( ( sizeof( ALARM_TABLE ) / sizeof( ALARM_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; // *** This declaration will cause a compiler error if ALARM_RANK_TABLE does not have same # of alarms as the Alarm_List enumeration. U08 alarmRankTableSizeAssertion[ ( ( sizeof( ALARM_RANK_TABLE ) / sizeof( ALARM_RANK_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; -// ********** private data ********** - -static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm +// ********** private data ********** + +static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm static BOOL alarmIsDetected[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm condition (detected or cleared) - -// ********** private function prototypes ********** - -/*********************************************************************//** - * @brief - * The initAlarmMgmt function initializes the AlarmMgmt unit. - * @details \b Inputs: none - * @details \b Outputs: alarmIsActive[], alarmIsDetected[] - * @return none - *************************************************************************/ -void initAlarmMgmt( void ) -{ + +// ********** private function prototypes ********** + +/*********************************************************************//** + * @brief + * The initAlarmMgmt function initializes the AlarmMgmt unit. + * @details \b Inputs: none + * @details \b Outputs: alarmIsActive[], alarmIsDetected[] + * @return none + *************************************************************************/ +void initAlarmMgmt( void ) +{ ALARM_ID_T a; - - // Initialize alarm states and start time stamps - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) - { + + // Initialize alarm states and start time stamps + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { alarmIsActive[ a ] = FALSE; - alarmIsDetected[ a ] = FALSE; - } + alarmIsDetected[ a ] = FALSE; + } } /*********************************************************************//** @@ -128,7 +128,7 @@ return result; } - + /*********************************************************************//** * @brief * The activateAlarm function activates a given alarm. @@ -144,11 +144,11 @@ // Verify valid alarm index if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { - // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm + // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm if ( ( FALSE == alarmIsActive[ alarm ] ) || - ( ( FALSE == alarmIsDetected[ alarm ] ) && ( FALSE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) ) ) + ( ( FALSE == alarmIsDetected[ alarm ] ) && ( FALSE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) ) ) { - // Activate alarm + // Activate alarm alarmIsActive[ alarm ] = TRUE; alarmIsDetected[ alarm ] = TRUE; @@ -157,10 +157,10 @@ { clearAlarmCondition( alarm ); } - } - } - else - { + } + } + else + { #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE3, (U32)alarm ) #endif @@ -171,8 +171,8 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE3, (U32)alarm ) #endif } -} - +} + /*********************************************************************//** * @brief * The clearAlarmCondition function clears a given alarm's condition detected @@ -222,32 +222,32 @@ } } -/*********************************************************************//** - * @brief - * The clearAlarm function clears a given alarm if it is recoverable. Also - * an alarm message is broadcast to the rest of the system. +/*********************************************************************//** + * @brief + * The clearAlarm function clears a given alarm if it is recoverable. Also + * an alarm message is broadcast to the rest of the system. * @details \b Message \b Sent: MSG_ID_ALARM_CLEARED if alarm cleared. * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given alarm ID invalid. - * @details \b Inputs: ALARM_TABLE[], alarmIsActive[] + * @details \b Inputs: ALARM_TABLE[], alarmIsActive[] * @details \b Outputs: alarmIsActive[] - * @param alarm ID of alarm to clear - * @return none - *************************************************************************/ -void clearAlarm( ALARM_ID_T alarm ) -{ - // Verify given alarm - if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) - { - // Verify alarm can be cleared - if ( FALSE == ALARM_TABLE[ alarm ].alarmNoClear ) - { - // Clear alarm and broadcast alarm clear if not already cleared - if ( TRUE == alarmIsActive[ alarm ] ) + * @param alarm ID of alarm to clear + * @return none + *************************************************************************/ +void clearAlarm( ALARM_ID_T alarm ) +{ + // Verify given alarm + if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) + { + // Verify alarm can be cleared + if ( FALSE == ALARM_TABLE[ alarm ].alarmNoClear ) + { + // Clear alarm and broadcast alarm clear if not already cleared + if ( TRUE == alarmIsActive[ alarm ] ) { ALARM_ID_DATA_PUBLISH_T data; data.alarmID = (U32) alarm; - + alarmIsActive[ alarm ] = FALSE; clearAlarmCondition( alarm ); #ifdef _TD_ @@ -259,11 +259,11 @@ #ifdef _RO_ broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_RO_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); #endif - } - } - } - else - { + } + } + } + else + { #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR2, (U32)alarm ) #endif @@ -273,7 +273,7 @@ #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR2, (U32)alarm ) #endif - } + } } /*********************************************************************//** @@ -306,18 +306,18 @@ alarmIsDetected[ alarm ] = detected; } -/*********************************************************************//** - * @brief - * The isAlarmActive function determines whether a given alarm is currently +/*********************************************************************//** + * @brief + * The isAlarmActive function determines whether a given alarm is currently * active. - * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given alarm ID is invalid. - * @details \b Inputs: alarmIsActive[] - * @details \b Outputs: none - * @param alarm ID of alarm to check active status for - * @return TRUE if given alarm is active, FALSE if not - *************************************************************************/ -BOOL isAlarmActive( ALARM_ID_T alarm ) -{ + * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given alarm ID is invalid. + * @details \b Inputs: alarmIsActive[] + * @details \b Outputs: none + * @param alarm ID of alarm to check active status for + * @return TRUE if given alarm is active, FALSE if not + *************************************************************************/ +BOOL isAlarmActive( ALARM_ID_T alarm ) +{ BOOL result = FALSE; if ( alarm < NUM_OF_ALARM_IDS ) @@ -335,9 +335,9 @@ #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_ALARM_ID_REFERENCED1, (U32)alarm ) #endif - } - - return result; + } + + return result; } /*********************************************************************//** @@ -411,25 +411,25 @@ return result; } - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ - - -/*********************************************************************//** - * @brief - * The testAlarmStateOverride function overrides the state of the - * alarm active state for a given alarm with the alarm management with - * a given active state. - * @details \b Inputs: none - * @details \b Outputs: alarm activated or cleared + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testAlarmStateOverride function overrides the state of the + * alarm active state for a given alarm with the alarm management with + * a given active state. + * @details \b Inputs: none + * @details \b Outputs: alarm activated or cleared * @param message Override message from Dialin which includes an ID of * the alarm to override and the state to override the alarm to. - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testAlarmStateOverride( MESSAGE_T *message ) -{ + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testAlarmStateOverride( MESSAGE_T *message ) +{ BOOL result = FALSE; TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &payload ); @@ -439,30 +439,30 @@ { U32 alarmID = payload.index; BOOL state = (BOOL)payload.state.u32; - - if ( alarmID < NUM_OF_ALARM_IDS ) - { - if ( TRUE == state ) - { - activateAlarmNoData( (ALARM_ID_T)alarmID ); - } - else + + if ( alarmID < NUM_OF_ALARM_IDS ) + { + if ( TRUE == state ) { -#ifdef _TD_ + activateAlarmNoData( (ALARM_ID_T)alarmID ); + } + else + { +#ifdef _TD_ clearAlarmTD( (ALARM_ID_T)alarmID ); -#endif +#endif #ifdef _DD_ clearAlarmDD( (ALARM_ID_T)alarmID ); #endif #ifdef _RO_ clearAlarmRO( (ALARM_ID_T)alarmID ); #endif - } - result = TRUE; + } + result = TRUE; } - } - - return result; -} - + } + + return result; +} + /**@}*/ Index: CommBuffers.c =================================================================== diff -u -r423aa34698d30a44e3b12b74e4243c3a8b5821de -r91cff0134623a852aeb37b497b2263cf4a9ba6cb --- CommBuffers.c (.../CommBuffers.c) (revision 423aa34698d30a44e3b12b74e4243c3a8b5821de) +++ CommBuffers.c (.../CommBuffers.c) (revision 91cff0134623a852aeb37b497b2263cf4a9ba6cb) @@ -14,9 +14,9 @@ * @date (original) 30-Jul-2024 * ***************************************************************************/ - -#include // For memcpy() - + +#include // For memcpy() + #include "CommBuffers.h" #include "Messaging.h" #ifdef _TD_ @@ -28,66 +28,66 @@ #ifdef _RO_ #include "SystemCommRO.h" #endif -#include "Timers.h" - +#include "Timers.h" + /** * @addtogroup CommBuffers * @{ */ -// ********** private definitions ********** - -#define COMM_BUFFER_LENGTH 768 ///< Max bytes in each comm buffer (each side of double buffer is this size) -#define DOUBLE_BUFFERS 2 ///< Need 2 buffers for double buffering -#define BUFFER_OVERFLOW_PERSISTENCE_MS 5000 ///< How many ms buffer overflows must persist before fault - -// ********** private data ********** - -static volatile U32 commBufferByteCount[ NUM_OF_COMM_BUFFERS ][ DOUBLE_BUFFERS ]; ///< For each buffer, how many bytes does it contain? (also index to next available) -static volatile U32 activeDoubleBuffer[ NUM_OF_COMM_BUFFERS ]; ///< For each buffer, which double buffer is being fed right now? +// ********** private definitions ********** + +#define COMM_BUFFER_LENGTH 768 ///< Max bytes in each comm buffer (each side of double buffer is this size) +#define DOUBLE_BUFFERS 2 ///< Need 2 buffers for double buffering +#define BUFFER_OVERFLOW_PERSISTENCE_MS 5000 ///< How many ms buffer overflows must persist before fault + +// ********** private data ********** + +static volatile U32 commBufferByteCount[ NUM_OF_COMM_BUFFERS ][ DOUBLE_BUFFERS ]; ///< For each buffer, how many bytes does it contain? (also index to next available) +static volatile U32 activeDoubleBuffer[ NUM_OF_COMM_BUFFERS ]; ///< For each buffer, which double buffer is being fed right now? static U08 commBuffers[ NUM_OF_COMM_BUFFERS ][ DOUBLE_BUFFERS ][ COMM_BUFFER_LENGTH ]; ///< Each is double buffered to avoid thread contention - -static U32 firstBufferOverflowTimeStamp = 0; ///< Time stamp of a prior overflow event - allows for an overflow persistence check - -// ********** private function prototypes ********** - -static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ); -static void getDataFromInactiveBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ); - -/*********************************************************************//** - * @brief - * The initCommBuffers function initializes the CommBuffers unit. - * @details Inputs: none - * @details Outputs: CommBuffers unit initialized. - * @return none - *************************************************************************/ -void initCommBuffers( void ) -{ - S32 b; - - // Reset and zero out all buffers - for ( b = 0; b < NUM_OF_COMM_BUFFERS; b++ ) - { - clearBuffer( (COMM_BUFFER_T)b ); - } -} - -/*********************************************************************//** - * @brief - * The clearBuffer function clears (empties) a given buffer. + +static U32 firstBufferOverflowTimeStamp = 0; ///< Time stamp of a prior overflow event - allows for an overflow persistence check + +// ********** private function prototypes ********** + +static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ); +static void getDataFromInactiveBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ); + +/*********************************************************************//** + * @brief + * The initCommBuffers function initializes the CommBuffers unit. + * @details Inputs: none + * @details Outputs: CommBuffers unit initialized. + * @return none + *************************************************************************/ +void initCommBuffers( void ) +{ + S32 b; + + // Reset and zero out all buffers + for ( b = 0; b < NUM_OF_COMM_BUFFERS; b++ ) + { + clearBuffer( (COMM_BUFFER_T)b ); + } +} + +/*********************************************************************//** + * @brief + * The clearBuffer function clears (empties) a given buffer. * @note This function is thread safe. IRQ interrupts are disabled while - * buffers are being cleared. - * @details Inputs: none - * @details Outputs: given buffer is cleared. - * @param buffer ID of the buffer to clear - * @return none - *************************************************************************/ -void clearBuffer( COMM_BUFFER_T buffer ) -{ - if ( buffer < NUM_OF_COMM_BUFFERS ) - { - S32 d; - + * buffers are being cleared. + * @details Inputs: none + * @details Outputs: given buffer is cleared. + * @param buffer ID of the buffer to clear + * @return none + *************************************************************************/ +void clearBuffer( COMM_BUFFER_T buffer ) +{ + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + S32 d; + // Thread protection for queue operations _disable_IRQ(); @@ -101,345 +101,345 @@ // Release thread protection _enable_IRQ(); } -} - -/*********************************************************************//** - * @brief - * The addToCommBuffer function adds data of specified length to a given - * communication buffer. - * @note This function will add to the active side of the double buffer. +} + +/*********************************************************************//** + * @brief + * The addToCommBuffer function adds data of specified length to a given + * communication buffer. + * @note This function will add to the active side of the double buffer. * @note This function is thread safe. IRQ interrupts are disabled during - * buffer operations. + * buffer operations. * @details Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given buffer is invalid or - * it is full. - * @details Inputs: commBufferByteCount[], activeDoubleBuffer[] - * @details Outputs: commBuffers[], commBufferByteCount[] - * @param buffer ID of buffer to add data to - * @param data Pointer to byte array containing data to add to buffer - * @param len Length of data (in bytes) - * @return TRUE if data added to buffer successfully, FALSE if not - *************************************************************************/ -BOOL addToCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 len ) -{ - BOOL result = FALSE; - - // Verify given buffer - if ( buffer < NUM_OF_COMM_BUFFERS ) - { - BOOL bufferFull = FALSE; - U32 activeBuffer; + * it is full. + * @details Inputs: commBufferByteCount[], activeDoubleBuffer[] + * @details Outputs: commBuffers[], commBufferByteCount[] + * @param buffer ID of buffer to add data to + * @param data Pointer to byte array containing data to add to buffer + * @param len Length of data (in bytes) + * @return TRUE if data added to buffer successfully, FALSE if not + *************************************************************************/ +BOOL addToCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 len ) +{ + BOOL result = FALSE; + + // Verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + BOOL bufferFull = FALSE; + U32 activeBuffer; U32 currentActiveBufCount; // Where to start adding new data to buffer (after existing data) if ( ( FALSE == isOnlyCANNode() ) || ( FALSE == isCANBoxForXmit( (CAN_MESSAGE_BOX_T)buffer ) ) ) - { - // Thread protection for queue operations - _disable_IRQ(); - - activeBuffer = activeDoubleBuffer[ buffer ]; - currentActiveBufCount = commBufferByteCount[ buffer ][ activeBuffer ]; - - // Check to make sure buffer is not too full to service this add - if ( len <= ( COMM_BUFFER_LENGTH - currentActiveBufCount ) ) - { - U08 *buffPtr; // Buffer destination for added data - - // Set destination pointer to end of active buffer data - buffPtr = &commBuffers[ buffer ][ activeBuffer ][ currentActiveBufCount ]; - // Copy source data to destination buffer - memcpy( buffPtr, data, len ); - // Adjust buffer count per this data add (also reserves space to add data before releasing thread protection) - commBufferByteCount[ buffer ][ activeBuffer ] += len; - // Data successfully added to buffer - result = TRUE; - } - else // Buffer too full to add this much data - { - bufferFull = TRUE; - } - // Release thread protection + { + // Thread protection for queue operations + _disable_IRQ(); + + activeBuffer = activeDoubleBuffer[ buffer ]; + currentActiveBufCount = commBufferByteCount[ buffer ][ activeBuffer ]; + + // Check to make sure buffer is not too full to service this add + if ( len <= ( COMM_BUFFER_LENGTH - currentActiveBufCount ) ) + { + U08 *buffPtr; // Buffer destination for added data + + // Set destination pointer to end of active buffer data + buffPtr = &commBuffers[ buffer ][ activeBuffer ][ currentActiveBufCount ]; + // Copy source data to destination buffer + memcpy( buffPtr, data, len ); + // Adjust buffer count per this data add (also reserves space to add data before releasing thread protection) + commBufferByteCount[ buffer ][ activeBuffer ] += len; + // Data successfully added to buffer + result = TRUE; + } + else // Buffer too full to add this much data + { + bufferFull = TRUE; + } + // Release thread protection _enable_IRQ(); } - - // If buffer was full, check persistence - trigger s/w fault if persists - if ( TRUE == bufferFull ) - { + + // If buffer was full, check persistence - trigger s/w fault if persists + if ( TRUE == bufferFull ) + { clearBuffer( buffer ); - // Not first overflow? - if ( firstBufferOverflowTimeStamp != 0 ) - { - // If buffer overflows persists, fault - if ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, (U32)buffer ) - } - } - else // First overflow - set time stamp for persistence check - { - firstBufferOverflowTimeStamp = getMSTimerCount(); - } - } - else - { // If good for persistence time period, reset persistence check - if ( ( firstBufferOverflowTimeStamp != 0 ) && ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) ) - { - firstBufferOverflowTimeStamp = 0; - } - } - } - else // Invalid buffer given - { + // Not first overflow? + if ( firstBufferOverflowTimeStamp != 0 ) + { + // If buffer overflows persists, fault + if ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, (U32)buffer ) + } + } + else // First overflow - set time stamp for persistence check + { + firstBufferOverflowTimeStamp = getMSTimerCount(); + } + } + else + { // If good for persistence time period, reset persistence check + if ( ( firstBufferOverflowTimeStamp != 0 ) && ( calcTimeSince( firstBufferOverflowTimeStamp ) > BUFFER_OVERFLOW_PERSISTENCE_MS ) ) + { + firstBufferOverflowTimeStamp = 0; + } + } + } + else // Invalid buffer given + { #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_INVALID_BUFFER, buffer ) -#endif +#endif #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_INVALID_BUFFER, buffer ) #endif #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_ADD_INVALID_BUFFER, buffer ) #endif - } - - return result; -} - -/*********************************************************************//** - * @brief - * The getFromCommBuffer function fills a given byte array with a specified - * number of bytes from a given buffer and returns the number of bytes + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getFromCommBuffer function fills a given byte array with a specified + * number of bytes from a given buffer and returns the number of bytes * retrieved from the buffer. - * @note This function will draw from the inactive side of the double buffer - * and, if needed, switch double buffers to draw the rest of the requested data. + * @note This function will draw from the inactive side of the double buffer + * and, if needed, switch double buffers to draw the rest of the requested data. * @note This function is thread safe. IRQ interrupts are disabled during buffer * operations. - * @details Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given buffer is invalid. - * @details Inputs: commBuffers[], commBufferByteCount[], activeDoubleBuffer[] - * @details Outputs: commBuffers[], commBufferByteCount[], activeDoubleBuffer[], - * and the given data array is populated with data from the buffer. - * @param buffer ID of buffer to retrieve data from - * @param data Pointer to byte array to populate with buffer data - * @param len Number of bytes to retrieve from buffer into given byte array. - * @return the number of bytes retrieved. - *************************************************************************/ -U32 getFromCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 len ) -{ - U32 result = 0; - - // Verify given buffer - if ( buffer < NUM_OF_COMM_BUFFERS ) - { - // Thread protection for queue operations - _disable_IRQ(); - // Verify requested # of bytes to get are in the buffer - if ( ( len <= ( COMM_BUFFER_LENGTH * DOUBLE_BUFFERS ) ) && ( len <= numberOfBytesInCommBuffer( buffer ) ) ) - { - U32 activeBuffer = activeDoubleBuffer[ buffer ]; - U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); - U32 bytesInInactiveBuffer = commBufferByteCount[ buffer ][ inactiveBuffer ]; - U32 sizeOfFirstConsumption = MIN( len, bytesInInactiveBuffer ); - - // See what we can get from inactive buffer - getDataFromInactiveBuffer( buffer, data, sizeOfFirstConsumption ); // Will switch double buffers if we empty inactive buffer - // Will return # of bytes consumed - result = sizeOfFirstConsumption; - // Do we need more from active buffer? - if ( len > sizeOfFirstConsumption ) - { - U32 remNumOfBytes = len - sizeOfFirstConsumption; - U08 *remPtr = data + sizeOfFirstConsumption; - - getDataFromInactiveBuffer( buffer, remPtr, remNumOfBytes ); - // Will return # of bytes consumed - result += remNumOfBytes; - } - } - // Release thread protection - _enable_IRQ(); - } - else // Invalid buffer given - { + * @details Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given buffer is invalid. + * @details Inputs: commBuffers[], commBufferByteCount[], activeDoubleBuffer[] + * @details Outputs: commBuffers[], commBufferByteCount[], activeDoubleBuffer[], + * and the given data array is populated with data from the buffer. + * @param buffer ID of buffer to retrieve data from + * @param data Pointer to byte array to populate with buffer data + * @param len Number of bytes to retrieve from buffer into given byte array. + * @return the number of bytes retrieved. + *************************************************************************/ +U32 getFromCommBuffer( COMM_BUFFER_T buffer, U08* data, U32 len ) +{ + U32 result = 0; + + // Verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + // Thread protection for queue operations + _disable_IRQ(); + // Verify requested # of bytes to get are in the buffer + if ( ( len <= ( COMM_BUFFER_LENGTH * DOUBLE_BUFFERS ) ) && ( len <= numberOfBytesInCommBuffer( buffer ) ) ) + { + U32 activeBuffer = activeDoubleBuffer[ buffer ]; + U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); + U32 bytesInInactiveBuffer = commBufferByteCount[ buffer ][ inactiveBuffer ]; + U32 sizeOfFirstConsumption = MIN( len, bytesInInactiveBuffer ); + + // See what we can get from inactive buffer + getDataFromInactiveBuffer( buffer, data, sizeOfFirstConsumption ); // Will switch double buffers if we empty inactive buffer + // Will return # of bytes consumed + result = sizeOfFirstConsumption; + // Do we need more from active buffer? + if ( len > sizeOfFirstConsumption ) + { + U32 remNumOfBytes = len - sizeOfFirstConsumption; + U08 *remPtr = data + sizeOfFirstConsumption; + + getDataFromInactiveBuffer( buffer, remPtr, remNumOfBytes ); + // Will return # of bytes consumed + result += remNumOfBytes; + } + } + // Release thread protection + _enable_IRQ(); + } + else // Invalid buffer given + { #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_GET_INVALID_BUFFER, buffer ) -#endif +#endif #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_GET_INVALID_BUFFER, buffer ) #endif #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_GET_INVALID_BUFFER, buffer ) #endif - } - - return result; -} - -/*********************************************************************//** - * @brief - * The peekFromCommBuffer function fills a given byte array with a given + } + + return result; +} + +/*********************************************************************//** + * @brief + * The peekFromCommBuffer function fills a given byte array with a given * number of bytes from a given buffer. * @note This function does NOT consume the bytes - it only peeks at them. * A call to numberOfBytesInCommBuffer() should be made prior to calling * this function to determine how many bytes are currently in the buffer. * @warning Do not call this function with a "len" greater than the number - * of bytes currently in the buffer. + * of bytes currently in the buffer. * @details Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given buffer is invalid. - * @details Inputs: commBuffers[], commBufferByteCount[], activeDoubleBuffer[] - * @details Outputs: given array populated with requested number of bytes from the buffer. - * @param buffer ID of buffer to retrieve data from - * @param data Pointer to byte array to populate with buffer data - * @param len Number of bytes to retrieve from the given buffer. - * @return the number of bytes retrieved. - *************************************************************************/ -U32 peekFromCommBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ) -{ - U32 numOfBytesPeeked = 0; - - // Verify given buffer - if ( buffer < NUM_OF_COMM_BUFFERS ) - { - // Thread protection for queue operations - _disable_IRQ(); - // Verify requested # of bytes to peek are in the buffer - if ( ( len <= ( COMM_BUFFER_LENGTH * DOUBLE_BUFFERS ) ) && ( len <= numberOfBytesInCommBuffer( buffer ) ) ) - { - U32 activeBuffer = activeDoubleBuffer[ buffer ]; - U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); - U32 bytesInInactiveBuffer = commBufferByteCount[ buffer ][ inactiveBuffer ]; - - if ( len <= bytesInInactiveBuffer ) - { - memcpy( data, &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], len ); - numOfBytesPeeked = len; - } - else // Will need to get the rest from active buffer - { - U32 remNumOfBytes = len - bytesInInactiveBuffer; - U08 *remPtr = data + bytesInInactiveBuffer; - - memcpy( data, &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], bytesInInactiveBuffer ); - memcpy( remPtr, &commBuffers[ buffer ][ activeBuffer ][ 0 ], remNumOfBytes ); - numOfBytesPeeked = bytesInInactiveBuffer + remNumOfBytes; - } - } - // Release thread protection - _enable_IRQ(); - } - else // Invalid buffer given - { + * @details Inputs: commBuffers[], commBufferByteCount[], activeDoubleBuffer[] + * @details Outputs: given array populated with requested number of bytes from the buffer. + * @param buffer ID of buffer to retrieve data from + * @param data Pointer to byte array to populate with buffer data + * @param len Number of bytes to retrieve from the given buffer. + * @return the number of bytes retrieved. + *************************************************************************/ +U32 peekFromCommBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ) +{ + U32 numOfBytesPeeked = 0; + + // Verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) + { + // Thread protection for queue operations + _disable_IRQ(); + // Verify requested # of bytes to peek are in the buffer + if ( ( len <= ( COMM_BUFFER_LENGTH * DOUBLE_BUFFERS ) ) && ( len <= numberOfBytesInCommBuffer( buffer ) ) ) + { + U32 activeBuffer = activeDoubleBuffer[ buffer ]; + U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); + U32 bytesInInactiveBuffer = commBufferByteCount[ buffer ][ inactiveBuffer ]; + + if ( len <= bytesInInactiveBuffer ) + { + memcpy( data, &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], len ); + numOfBytesPeeked = len; + } + else // Will need to get the rest from active buffer + { + U32 remNumOfBytes = len - bytesInInactiveBuffer; + U08 *remPtr = data + bytesInInactiveBuffer; + + memcpy( data, &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], bytesInInactiveBuffer ); + memcpy( remPtr, &commBuffers[ buffer ][ activeBuffer ][ 0 ], remNumOfBytes ); + numOfBytesPeeked = bytesInInactiveBuffer + remNumOfBytes; + } + } + // Release thread protection + _enable_IRQ(); + } + else // Invalid buffer given + { #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_PEEK_INVALID_BUFFER, buffer ) -#endif +#endif #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_PEEK_INVALID_BUFFER, buffer ) #endif #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_PEEK_INVALID_BUFFER, buffer ) #endif - } - - return numOfBytesPeeked; -} - -/*********************************************************************//** - * @brief - * The numberOfBytesInCommBuffer function determines how many bytes + } + + return numOfBytesPeeked; +} + +/*********************************************************************//** + * @brief + * The numberOfBytesInCommBuffer function determines how many bytes * are currently contained in a given comm buffer. Both sides of the * double buffers are considered for this. - * @details Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given buffer is invalid. - * @details Inputs: activeDoubleBuffer[], commBufferByteCount[] - * @details Outputs: none - * @param buffer ID of buffer to get byte count for - * @return the number of bytes currently in the given comm buffer. - *************************************************************************/ -U32 numberOfBytesInCommBuffer( COMM_BUFFER_T buffer ) -{ - U32 result = 0; - - // Verify given buffer - if ( buffer < NUM_OF_COMM_BUFFERS ) - { - U32 activeBuffer = activeDoubleBuffer[ buffer ]; - U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); - - result = commBufferByteCount[ buffer ][ inactiveBuffer ] + commBufferByteCount[ buffer ][ activeBuffer ]; - } - else // Invalid buffer + * @details Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given buffer is invalid. + * @details Inputs: activeDoubleBuffer[], commBufferByteCount[] + * @details Outputs: none + * @param buffer ID of buffer to get byte count for + * @return the number of bytes currently in the given comm buffer. + *************************************************************************/ +U32 numberOfBytesInCommBuffer( COMM_BUFFER_T buffer ) +{ + U32 result = 0; + + // Verify given buffer + if ( buffer < NUM_OF_COMM_BUFFERS ) { -#ifdef _TD_ + U32 activeBuffer = activeDoubleBuffer[ buffer ]; + U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); + + result = commBufferByteCount[ buffer ][ inactiveBuffer ] + commBufferByteCount[ buffer ][ activeBuffer ]; + } + else // Invalid buffer + { +#ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_COUNT_INVALID_BUFFER, buffer ) -#endif +#endif #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_COUNT_INVALID_BUFFER, buffer ) #endif #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_COMM_BUFFERS_COUNT_INVALID_BUFFER, buffer ) #endif - } - - return result; -} - -/*********************************************************************//** - * @brief + } + + return result; +} + +/*********************************************************************//** + * @brief * The switchDoubleBuffer function switches the active and inactive sides - * of the given buffer. + * of the given buffer. * @warning This function should only be called when the current inactive * buffer has been emptied. Any unconsumed data in inactive buffer will be - * lost. - * @details Inputs: activeDoubleBuffer[] - * @details Outputs: activeDoubleBuffer[], commBufferByteCount[] - * @param buffer ID of buffer to switch double buffers - * @return the new active side of the given double buffer (0 or 1) - *************************************************************************/ -static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ) -{ - U32 activeBuffer = activeDoubleBuffer[ buffer ]; - U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); - - // Ensure inactive buffer is reset before making active - commBufferByteCount[ buffer ][ inactiveBuffer ] = 0; - // Switch buffers - activeDoubleBuffer[ buffer ] = inactiveBuffer; - - // Return the new active buffer (was just inactive) - return inactiveBuffer; -} - -/*********************************************************************//** - * @brief - * The getDataFromInactiveBuffer function retrieves a given number of bytes + * lost. + * @details Inputs: activeDoubleBuffer[] + * @details Outputs: activeDoubleBuffer[], commBufferByteCount[] + * @param buffer ID of buffer to switch double buffers + * @return the new active side of the given double buffer (0 or 1) + *************************************************************************/ +static U32 switchDoubleBuffer( COMM_BUFFER_T buffer ) +{ + U32 activeBuffer = activeDoubleBuffer[ buffer ]; + U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); + + // Ensure inactive buffer is reset before making active + commBufferByteCount[ buffer ][ inactiveBuffer ] = 0; + // Switch buffers + activeDoubleBuffer[ buffer ] = inactiveBuffer; + + // Return the new active buffer (was just inactive) + return inactiveBuffer; +} + +/*********************************************************************//** + * @brief + * The getDataFromInactiveBuffer function retrieves a given number of bytes * from the inactive side of a given buffer. * @warning This function should only be called by getFromCommBuffer(). - * Parameters will be pre-validated there. - * @details Inputs: commBuffers[], activeDoubleBuffer[], commBufferByteCount[] - * @details Outputs: commBuffers[], activeDoubleBuffer[], commBufferByteCount[] - * @param buffer ID of buffer to get data from inactive side of + * Parameters will be pre-validated there. + * @details Inputs: commBuffers[], activeDoubleBuffer[], commBufferByteCount[] + * @details Outputs: commBuffers[], activeDoubleBuffer[], commBufferByteCount[] + * @param buffer ID of buffer to get data from inactive side of * @param data Pointer to byte array to populate with data from inactive - * side of buffer - * @param len Number of bytes to get from the buffer - * @return none - *************************************************************************/ -static void getDataFromInactiveBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ) -{ - U32 activeBuffer = activeDoubleBuffer[ buffer ]; - U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); - U32 bytesInInactiveBuffer = commBufferByteCount[ buffer ][ inactiveBuffer ]; - - // Get the requested data from inactive buffer - memcpy( data, &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], len ); - - if ( len < bytesInInactiveBuffer ) - { - U08 *endPtr = (&commBuffers[ buffer ][ inactiveBuffer ][ 0 ] + len); - - // Move un-consumed data in inactive buffer to start of inactive buffer - memcpy( &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], endPtr, ( bytesInInactiveBuffer - len ) ); - // Reduce byte count for inactive buffer by # of bytes consumed - commBufferByteCount[ buffer ][ inactiveBuffer ] -= len; - } - else - { - // Inactive buffer has been emptied so switch double buffers - switchDoubleBuffer( buffer ); // Switch will zero count off inactive buffer - } -} + * side of buffer + * @param len Number of bytes to get from the buffer + * @return none + *************************************************************************/ +static void getDataFromInactiveBuffer( COMM_BUFFER_T buffer, U08 *data, U32 len ) +{ + U32 activeBuffer = activeDoubleBuffer[ buffer ]; + U32 inactiveBuffer = GET_TOGGLE( activeBuffer, 0, 1 ); + U32 bytesInInactiveBuffer = commBufferByteCount[ buffer ][ inactiveBuffer ]; + // Get the requested data from inactive buffer + memcpy( data, &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], len ); + + if ( len < bytesInInactiveBuffer ) + { + U08 *endPtr = (&commBuffers[ buffer ][ inactiveBuffer ][ 0 ] + len); + + // Move un-consumed data in inactive buffer to start of inactive buffer + memcpy( &commBuffers[ buffer ][ inactiveBuffer ][ 0 ], endPtr, ( bytesInInactiveBuffer - len ) ); + // Reduce byte count for inactive buffer by # of bytes consumed + commBufferByteCount[ buffer ][ inactiveBuffer ] -= len; + } + else + { + // Inactive buffer has been emptied so switch double buffers + switchDoubleBuffer( buffer ); // Switch will zero count off inactive buffer + } +} + /**@}*/ Index: MessagePayloads.h =================================================================== diff -u --- MessagePayloads.h (revision 0) +++ MessagePayloads.h (revision 91cff0134623a852aeb37b497b2263cf4a9ba6cb) @@ -0,0 +1,55 @@ +/************************************************************************** +* +* 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 MessagePayloads.h +* +* @author (last) Sean +* @date (last) 07-Nov-2024 +* +* @author (original) Sean +* @date (original) 07-Nov-2024 +* +***************************************************************************/ + +#ifndef __MESSAGE_PAYLOADS_H__ +#define __MESSAGE_PAYLOADS_H__ + +#include "TDCommon.h" + +/** + * @addtogroup Messaging + * @{ + */ + +// ********** public definitions ********** + +#pragma pack(push, 1) + +/// Payload record structure for requesting dialysate delivery. +typedef struct +{ + BOOL start; ///< Flag indicating whether to start/continue dialysate delivery (TRUE) or stop (FALSE). + F32 dialRate; ///< Set dialysate rate (mL/min). + F32 ufRate; ///< Set ultrafiltration rate (mL/min). + F32 dialTemp; ///< Set dialysate temperature (deg C). + BOOL bypassDialyzer; ///< Flag indicating whether bypass of dialyzer is requested. + U32 acidType; ///< Type of acid being used to make dialysate. + U32 bicarbType; ///< Type of bicarb being used to make dialysate. +} DIALYSATE_DELIVERY_REQ_PAYLOAD_T; + +/// Payload record structure for requesting RO water. +typedef struct +{ + BOOL start; ///< Flag indicating whether to start/continue RO water delivery (TRUE) or stop (FALSE). + F32 roRate; ///< Set RO water rate (mL/min). +} RO_WATER_REQ_PAYLOAD_T; + +#pragma pack(pop) + +/**@}*/ + +#endif Index: SystemComm.c =================================================================== diff -u -r3ca022103ce50b39e5d805b7577c7f360730412d -r91cff0134623a852aeb37b497b2263cf4a9ba6cb --- SystemComm.c (.../SystemComm.c) (revision 3ca022103ce50b39e5d805b7577c7f360730412d) +++ SystemComm.c (.../SystemComm.c) (revision 91cff0134623a852aeb37b497b2263cf4a9ba6cb) @@ -15,15 +15,15 @@ * ***************************************************************************/ -#include // For memcpy() - -#include "can.h" -#include "sci.h" -#include "sys_dma.h" - -#include "Comm.h" +#include // For memcpy() + +#include "can.h" +#include "sci.h" +#include "sys_dma.h" + +#include "Comm.h" #include "Interrupts.h" -#include "Messaging.h" +#include "Messaging.h" #include "OperationModes.h" #include "SystemComm.h" #ifdef _TD_ @@ -35,133 +35,133 @@ #ifdef _RO_ #include "SystemCommRO.h" #endif -#include "Timers.h" -#include "Utilities.h" - +#include "Timers.h" +#include "Utilities.h" + /** * @addtogroup SystemComm * @{ */ -// ********** private definitions ********** - -#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 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 MSG_NOT_ACKED_TIMEOUT_MS 250 ///< Maximum time for a Denali message that requires ACK to be ACK'd -#define MSG_NOT_ACKED_MAX_RETRIES 10 ///< Maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm -#define PENDING_ACK_LIST_SIZE 25 ///< Maximum number of Denali messages that can be pending ACK at any given time +#define MSG_NOT_ACKED_TIMEOUT_MS 250 ///< Maximum time for a Denali message that requires ACK to be ACK'd +#define MSG_NOT_ACKED_MAX_RETRIES 10 ///< Maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm +#define PENDING_ACK_LIST_SIZE 25 ///< Maximum number of Denali messages that can be pending ACK at any given time + #define PENDING_ACK_LIST_OVERRIDE_UI_CHANNEL 1 ///< Value for determining UI channel when Pending ACKs are overriden. #define PENDING_ACK_LIST_OVERRIDE_DD_CHANNEL 2 ///< Value for determining DD channel when Pending ACKs are overriden. #define PENDING_ACK_LIST_OVERRIDE_TD_CHANNEL 3 ///< Value for determining TD channel when Pending ACKs are overriden. #define PENDING_ACK_LIST_OVERRIDE_RO_CHANNEL 4 ///< Value for determining RO channel when Pending ACKs are overriden. -#pragma pack(push, 1) - +#pragma pack(push, 1) + /// Record for transmitted message that is pending acknowledgment from receiver. -typedef struct -{ - BOOL used; ///< Used. - U16 seqNo; ///< Message sequence number. - U16 retries; ///< Number of retries. - U32 timeStamp; ///< Time stamp. - COMM_BUFFER_T channel; ///< Channel ID. - U32 msgSize; ///< Message size. - U08 msg[ MAX_ACK_MSG_SIZE ]; ///< Message. -} PENDING_ACK_RECORD_T; - -#pragma pack(pop) - -// ********** private data ********** - -static U08 lastCANPacketSent[ CAN_FRAME_PAYLOAD_SIZE ]; ///< Keep last packet sent on CAN bus in case we need to re-send. -static CAN_MESSAGE_BOX_T lastCANPacketSentChannel; ///< Keep channel last packet was sent on CAN bus in case we need to re-send. -static U32 lastCANPacketSentTimeStamp; ///< Keep time last packet sent on CAN bus so we can timeout on transmission attempt. +typedef struct +{ + BOOL used; ///< Used. + U16 seqNo; ///< Message sequence number. + U16 retries; ///< Number of retries. + U32 timeStamp; ///< Time stamp. + COMM_BUFFER_T channel; ///< Channel ID. + U32 msgSize; ///< Message size. + U08 msg[ MAX_ACK_MSG_SIZE ]; ///< Message. +} PENDING_ACK_RECORD_T; + +#pragma pack(pop) + +// ********** private data ********** + +static U08 lastCANPacketSent[ CAN_FRAME_PAYLOAD_SIZE ]; ///< Keep last packet sent on CAN bus in case we need to re-send. +static CAN_MESSAGE_BOX_T lastCANPacketSentChannel; ///< Keep channel last packet was sent on CAN bus in case we need to re-send. +static U32 lastCANPacketSentTimeStamp; ///< Keep time last packet sent on CAN bus so we can timeout on transmission attempt. static U32 canXmitRetryCtr; ///< Counter for CAN transmit retries. - -static volatile PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; ///< List of outgoing messages that are awaiting an ACK -static OVERRIDE_U32_T pendingACKOverride = { 0, 0, 0, 0 }; ///< Pending ACK override data structure. - -// ********** private function prototypes ********** - -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 volatile PENDING_ACK_RECORD_T pendingAckList[ PENDING_ACK_LIST_SIZE ]; ///< List of outgoing messages that are awaiting an ACK +static OVERRIDE_U32_T pendingACKOverride = { 0, 0, 0, 0 }; ///< Pending ACK override data structure. + +// ********** private function prototypes ********** + +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 matchACKtoPendingACKList( S16 seqNo ); -static void checkPendingACKList( void ); - -/*********************************************************************//** - * @brief - * The initSystemComm function initializes the SystemComm unit. - * @details \b Inputs: none - * @details \b Outputs: SystemComm unit variables initialized. - * @return none - *************************************************************************/ -void initSystemComm( void ) -{ + +static void matchACKtoPendingACKList( S16 seqNo ); +static void checkPendingACKList( void ); + +/*********************************************************************//** + * @brief + * The initSystemComm function initializes the SystemComm unit. + * @details \b Inputs: none + * @details \b Outputs: SystemComm unit variables initialized. + * @return none + *************************************************************************/ +void initSystemComm( void ) +{ U32 i; lastCANPacketSentTimeStamp = 0; canXmitRetryCtr = 0; - lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0; - - // Initialize pending ACK list - for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) - { - pendingAckList[ i ].used = FALSE; - } -} - -/*********************************************************************//** - * @brief + lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0; + + // Initialize pending ACK list + for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) + { + pendingAckList[ i ].used = FALSE; + } +} + +/*********************************************************************//** + * @brief * The execSystemCommRx function manages received data from other sub-systems. * @note This function should be called periodically to keep up with incoming - * data on CAN bus. - * @details \b Inputs: none - * @details \b Outputs: Incoming messages parsed and processed. - * @return none - *************************************************************************/ -void execSystemCommRx( void ) + * data on CAN bus. + * @details \b Inputs: none + * @details \b Outputs: Incoming messages parsed and 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 have not been ACK'd + // 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 have not been ACK'd checkPendingACKList(); if ( TRUE == hasDialinCheckInExpired() ) { // It has been a while since the user logged in but not activity has been received from Dialin so set the tester's status to log out setTesterStatusToLoggedOut(); - } -} - -/*********************************************************************//** - * @brief - * The execSystemCommTx function manages data to be transmitted to other - * sub-systems. + } +} + +/*********************************************************************//** + * @brief + * The execSystemCommTx function manages data to be transmitted to other + * sub-systems. * @note This function should be called periodically to keep up with outgoing * data being queued for transmit on CAN bus. - * @details \b Inputs: lastCANPacketSentTimeStamp, canXmitRetryCtr, lastCANPacketSentChannel + * @details \b Inputs: lastCANPacketSentTimeStamp, canXmitRetryCtr, lastCANPacketSentChannel * @details \b Outputs: Outgoing message transmission from outgoing CAN buffers - * is initiated - * @return none - *************************************************************************/ -void execSystemCommTx( void ) -{ + * is initiated + * @return none + *************************************************************************/ +void execSystemCommTx( void ) +{ // Do not transmit if no other nodes on CAN bus if ( FALSE == isOnlyCANNode() ) { @@ -195,286 +195,286 @@ } // end - pending xmit timeout? } // end - transmit in progress or not } // end - DG not alone on CAN bus -} - -/*********************************************************************//** - * @brief +} + +/*********************************************************************//** + * @brief * The handleCANMsgInterrupt function handles a CAN frame interrupt from - * a given CAN mail box. - * This may have occurred because a CAN frame transmission has completed - * or because a CAN frame has been received. The appropriate handler is + * a given CAN mail box. + * This may have occurred because a CAN frame transmission has completed + * or because a CAN frame has been received. The appropriate handler is * called. - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid CAN mail box given. - * @details \b Inputs: none - * @details \b Outputs: message interrupt handled - * @param srcCANBox which CAN mail 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 ) ) - { + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid CAN mail box given. + * @details \b Inputs: none + * @details \b Outputs: message interrupt handled + * @param srcCANBox which CAN mail 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; - bytesXmitted = transmitNextCANPacket(); - - // If nothing more to send, signal that transmitter is available - if ( 0 == bytesXmitted ) - { - signalCANXmitsCompleted(); + bytesXmitted = transmitNextCANPacket(); + + // If nothing more to send, signal that transmitter is available + if ( 0 == bytesXmitted ) + { + signalCANXmitsCompleted(); } - } - else if ( TRUE == isCANBoxForRecv( srcCANBox ) ) - { - U08 data[ CAN_FRAME_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_FRAME_PAYLOAD_SIZE ); - } - } - } - else - { + } + else if ( TRUE == isCANBoxForRecv( srcCANBox ) ) + { + U08 data[ CAN_FRAME_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_FRAME_PAYLOAD_SIZE ); + } + } + } + else + { // Should not get here - not an active message box #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CAN_MESSAGE_BOX, srcCANBox ) -#endif +#endif #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CAN_MESSAGE_BOX, srcCANBox ) #endif #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CAN_MESSAGE_BOX, srcCANBox ) #endif - } -} - -/*********************************************************************//** - * @brief - * The isCANBoxForXmit function determines whether a given CAN mail box - * is configured for transmit. - * @details \b Inputs: CAN_OUT_BUFFERS[] - * @details \b Outputs: none - * @param srcCANBox which CAN mail box to determine configuration for - * @return TRUE if the given CAN mail 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 ( getOutBufferID( i ) == srcCANBox ) - { - result = TRUE; - break; - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The isCANBoxForRecv function determines whether a given CAN mail box - * is configured for receiving. - * @details \b Inputs: CAN_IN_BUFFERS[] - * @details \b Outputs: none - * @param srcCANBox which CAN mail box to determine configuration for - * @return TRUE if the given CAN mail 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 ( getInBufferID( i ) == srcCANBox ) - { - result = TRUE; - break; - } - } - - return result; + } } - -/************************************************************************* -********************** TRANSMIT SUPPORT FUNCTIONS ************************ -*************************************************************************/ - - -/*********************************************************************//** - * @brief +/*********************************************************************//** + * @brief + * The isCANBoxForXmit function determines whether a given CAN mail box + * is configured for transmit. + * @details \b Inputs: CAN_OUT_BUFFERS[] + * @details \b Outputs: none + * @param srcCANBox which CAN mail box to determine configuration for + * @return TRUE if the given CAN mail 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 ( getOutBufferID( i ) == srcCANBox ) + { + result = TRUE; + break; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The isCANBoxForRecv function determines whether a given CAN mail box + * is configured for receiving. + * @details \b Inputs: CAN_IN_BUFFERS[] + * @details \b Outputs: none + * @param srcCANBox which CAN mail box to determine configuration for + * @return TRUE if the given CAN mail 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 ( getInBufferID( i ) == srcCANBox ) + { + result = TRUE; + break; + } + } + + return result; +} + + +/************************************************************************* +********************** TRANSMIT SUPPORT FUNCTIONS ************************ +*************************************************************************/ + + +/*********************************************************************//** + * @brief * The findNextHighestPriorityCANPacketToTransmit function determines which - * outgoing buffer with data in it has the highest priority. - * @details \b Inputs: Outgoing CAN buffer - * @details \b Outputs: none - * @return Highest priority CAN buffer with data to transmit, - * COMM_BUFFER_NOT_USED if there is no data to be transmitted. - *************************************************************************/ -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( getOutBufferID( i ) ) >= CAN_FRAME_PAYLOAD_SIZE ) - { - result = getOutBufferID( i ); - break; // Found highest priority packet to transmit - we are done - } - } - - return result; -} - -/*********************************************************************//** - * @brief + * outgoing buffer with data in it has the highest priority. + * @details \b Inputs: Outgoing CAN buffer + * @details \b Outputs: none + * @return Highest priority CAN buffer with data to transmit, + * COMM_BUFFER_NOT_USED if there is no data to be transmitted. + *************************************************************************/ +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( getOutBufferID( i ) ) >= CAN_FRAME_PAYLOAD_SIZE ) + { + result = getOutBufferID( i ); + break; // Found highest priority packet to transmit - we are done + } + } + + return result; +} + +/*********************************************************************//** + * @brief * The transmitNextCANPacket function creates a frame from the next 8 bytes * to transmit (if there is data to transmit) and initiates a CAN transmit * on the appropriate CAN channel. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid byte count or - * if frame transmit fails. - * @details \b Inputs: Output CAN buffers - * @details \b Outputs: none - * @return number of bytes transmitted (8 or 0) - *************************************************************************/ -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_FRAME_PAYLOAD_SIZE ]; - U32 dataSize = getFromCommBuffer( buffer, data, CAN_FRAME_PAYLOAD_SIZE ); - CAN_MESSAGE_BOX_T mBox = buffer; // CAN message boxes and comm buffers are aligned - - // If there is another CAN packet to send, send it - if ( dataSize == CAN_FRAME_PAYLOAD_SIZE ) - { - // We are 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_FRAME_PAYLOAD_SIZE ); - lastCANPacketSentChannel = mBox; - lastCANPacketSentTimeStamp = getMSTimerCount(); - if ( 0 != canTransmit( canREG1, mBox, data ) ) - { - result = CAN_FRAME_PAYLOAD_SIZE; - } - else - { - signalCANXmitsCompleted(); + * if frame transmit fails. + * @details \b Inputs: Output CAN buffers + * @details \b Outputs: none + * @return number of bytes transmitted (8 or 0) + *************************************************************************/ +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_FRAME_PAYLOAD_SIZE ]; + U32 dataSize = getFromCommBuffer( buffer, data, CAN_FRAME_PAYLOAD_SIZE ); + CAN_MESSAGE_BOX_T mBox = buffer; // CAN message boxes and comm buffers are aligned + + // If there is another CAN packet to send, send it + if ( dataSize == CAN_FRAME_PAYLOAD_SIZE ) + { + // We are 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_FRAME_PAYLOAD_SIZE ); + lastCANPacketSentChannel = mBox; + lastCANPacketSentTimeStamp = getMSTimerCount(); + if ( 0 != canTransmit( canREG1, mBox, data ) ) + { + result = CAN_FRAME_PAYLOAD_SIZE; + } + else + { + signalCANXmitsCompleted(); #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_SYSTEM_CMMM_CAN_TRANSMIT_REJECTED, (U32)mBox ) -#endif +#endif #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_SYSTEM_CMMM_CAN_TRANSMIT_REJECTED, (U32)mBox ) #endif #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_SYSTEM_CMMM_CAN_TRANSMIT_REJECTED, (U32)mBox ) #endif - } - } - else - { + } + } + else + { #ifdef _TD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_SYSTEM_COMM_INVALID_FRAME_SIZE, ((U32)buffer << 16) | dataSize ) -#endif +#endif #ifdef _DD_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_SYSTEM_COMM_INVALID_FRAME_SIZE, ((U32)buffer << 16) | dataSize ) #endif #ifdef _RO_ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_SYSTEM_COMM_INVALID_FRAME_SIZE, ((U32)buffer << 16) | dataSize ) #endif - } - } - - return result; -} - - -/************************************************************************* -********************** RECEIVE SUPPORT FUNCTIONS ************************* -*************************************************************************/ - - -/*********************************************************************//** - * @brief - * The processIncomingData function parses out messages from the incoming - * CAN buffers and adds them to the Received Message Queue. - * @details \b Inputs: none - * @details \b Outputs: canXmitRetryCtr - * @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_CAN_IN_BUFFERS; i++ ) - { - BOOL messagesInBuffer = TRUE; // Assume true at first to get into while loop - - while ( TRUE == messagesInBuffer ) - { - U32 numOfBytesInBuffer; - - // Assume false so we do not get stuck in loop. Set to true only 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( getInBufferID( i ) ); - // Do we have enough bytes in buffer for smallest message? - numOfBytesInBuffer = numberOfBytesInCommBuffer( getInBufferID( i ) ); - if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE ) - { // Peek at minimum of all bytes available or max message size (+1 for sync byte) - U32 bytesPeeked = peekFromCommBuffer( getInBufferID( i ), data, MIN( numOfBytesInBuffer, sizeof( MESSAGE_WRAPPER_T ) + 1 ) ); + } + } + + return result; +} + + +/************************************************************************* +********************** RECEIVE SUPPORT FUNCTIONS ************************* +*************************************************************************/ + + +/*********************************************************************//** + * @brief + * The processIncomingData function parses out messages from the incoming + * CAN buffers and adds them to the Received Message Queue. + * @details \b Inputs: none + * @details \b Outputs: canXmitRetryCtr + * @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_CAN_IN_BUFFERS; i++ ) + { + BOOL messagesInBuffer = TRUE; // Assume true at first to get into while loop + + while ( TRUE == messagesInBuffer ) + { + U32 numOfBytesInBuffer; + + // Assume false so we do not get stuck in loop. Set to true only 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( getInBufferID( i ) ); + // Do we have enough bytes in buffer for smallest message? + numOfBytesInBuffer = numberOfBytesInCommBuffer( getInBufferID( i ) ); + if ( numOfBytesInBuffer >= MESSAGE_OVERHEAD_SIZE ) + { // Peek at minimum of all bytes available or max message size (+1 for sync byte) + U32 bytesPeeked = peekFromCommBuffer( getInBufferID( i ), data, MIN( numOfBytesInBuffer, sizeof( MESSAGE_WRAPPER_T ) + 1 ) ); S32 msgSize = parseMessageFromBuffer( data, bytesPeeked ); setOnlyCANNode( FALSE ); // Since we are getting a message, this indicates we are not the only node on the CAN bus - 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( getInBufferID( 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 + 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( getInBufferID( 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; // Set incoming buffer that message came into - rcvMsg.msg.in_buffer = (COMM_BUFFER_T)i; - // Add new message to queue for later processing + rcvMsg.msg.in_buffer = (COMM_BUFFER_T)i; + // Add new message to queue for later processing addToMsgQueue( MSG_Q_IN, &rcvMsg ); #ifdef _TD_ // If message from DG broadcast channel, update DG comm status @@ -487,222 +487,222 @@ { checkInFromUI(); } -#endif - } - else if ( -1 == msgSize ) // Candidate message with bad CRC found? - { - badCRCDetected = TRUE; - getFromCommBuffer( getInBufferID( 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 to re-sync with the data. - * @details \b Inputs: none +#endif + } + else if ( -1 == msgSize ) // Candidate message with bad CRC found? + { + badCRCDetected = TRUE; + getFromCommBuffer( getInBufferID( 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 to re-sync with the data. + * @details \b Inputs: none * @details \b Outputs: Any bytes in buffers preceding a sync byte at front - * of buffer is consumed. - * @param buffer the CAN buffer to re-sync - * @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 is empty - while ( numOfBytesInBuffer > 0 ) - { - peekFromCommBuffer( buffer, &data, 1 ); - if ( MESSAGE_SYNC_BYTE == data ) - { - break; // We found a sync - we are 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 + * of buffer is consumed. + * @param buffer the CAN buffer to re-sync + * @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 is empty + while ( numOfBytesInBuffer > 0 ) + { + peekFromCommBuffer( buffer, &data, 1 ); + if ( MESSAGE_SYNC_BYTE == data ) + { + break; // We found a sync - we are 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 * buffer (pointed to by given data pointer). If a message is found, its * size is returned. * @note The message is not consumed (removed) from the buffer. Calling * function is expected to retrieve the message by consuming the returned - * message size from the given buffer. - * @details \b Inputs: none - * @details \b Outputs: none - * @param data pointer to start of a CAN buffer to search for a message in - * @param len number of bytes in the data to search + * message size from the given buffer. + * @details \b Inputs: none + * @details \b Outputs: none + * @param data pointer to start of a CAN buffer to search for a message in + * @param len number of bytes in the data to search * @return The size of the message, if found, zero if no complete message - * is 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 is 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 all messages in the - * received message queue. - * @details \b Inputs: none - * @details \b Outputs: none - * @return none - *************************************************************************/ -static void processReceivedMessages( void ) -{ - BOOL isThereMsgRcvd = TRUE; // Assume TRUE at first to get into while loop - MESSAGE_WRAPPER_T message; + * is found, -1 if message found but CRC fails. + *************************************************************************/ +static S32 parseMessageFromBuffer( U08 *data, U32 len ) +{ + U32 i; + U32 payloadSize; + U32 msgSize; + S32 result = 0; - 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_THAT_REQUIRES_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 ); - } - // Process the received message - processReceivedMessage( &message.msg ); - } - } - else // CRC failed - { - checkTooManyBadMsgCRCs(); - } - } - } -} - -/*********************************************************************//** - * @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 ( 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 is 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 all messages in the + * received message queue. + * @details \b Inputs: none + * @details \b Outputs: none + * @return none + *************************************************************************/ +static void processReceivedMessages( void ) +{ + BOOL isThereMsgRcvd = TRUE; // Assume TRUE at first to get into while loop + MESSAGE_WRAPPER_T message; + + while ( TRUE == isThereMsgRcvd ) + { + // See if any messages received + isThereMsgRcvd = getFromMsgQueue( MSG_Q_IN, &message ); + if ( TRUE == isThereMsgRcvd ) + { // CRC should be good because we checked it during parsing before adding to queue - but check it again for good measure + if ( message.crc == crc8( (U08*)(&message), sizeof(MESSAGE_HEADER_T) + message.msg.hdr.payloadLen ) ) + { + // If ACK, mark pending message ACK'd + if ( MSG_ID_ACK_MESSAGE_THAT_REQUIRES_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 ); + } + // Process the received message + processReceivedMessage( &message.msg ); + } + } + else // CRC failed + { + checkTooManyBadMsgCRCs(); + } + } + } +} + +/*********************************************************************//** + * @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. - * @note List operations are thread protected by disabling IRQ interrupts. - * @details \b Inputs: pendingAckList[] - * @details \b Outputs: pendingAckList[] + * @note List operations are thread protected by disabling IRQ interrupts. + * @details \b Inputs: pendingAckList[] + * @details \b Outputs: pendingAckList[] * @param msg Pointer to the message record (needed for header info) - * @param channel CAN channel that the message was transmitted on (needed for re-send attempts) - * @param msgData Pointer to serialized message data to add to pending ACK list (needed for re-send attempts) - * @param len Number of bytes of message data (needed for re-send attempts) - * @return TRUE if the message was added to the list 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( (U08*)pendingAckList[ i ].msg, msgData, len ); - result = TRUE; - break; - } - else - { - _enable_IRQ(); - } + * @param channel CAN channel that the message was transmitted on (needed for re-send attempts) + * @param msgData Pointer to serialized message data to add to pending ACK list (needed for re-send attempts) + * @param len Number of bytes of message data (needed for re-send attempts) + * @return TRUE if the message was added to the list 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( (U08*)pendingAckList[ i ].msg, msgData, len ); + result = TRUE; + break; + } + else + { + _enable_IRQ(); + } } - return result; -} - -/*********************************************************************//** - * @brief - * The matchACKtoPendingACKList function searches the pending ACK list to + return result; +} + +/*********************************************************************//** + * @brief + * The matchACKtoPendingACKList function searches the pending ACK list to * see if the sequence # from a received ACK msg matches any transmitted * messages pending an ACK. If found, the list entry is removed (no longer - * pending). - * @details \b Inputs: pendingAckList[] - * @details \b Outputs: pendingAckList[] - * @param seqNo sequence number to match to an entry in the list - * @return none - *************************************************************************/ -static void matchACKtoPendingACKList( S16 seqNo ) -{ + * pending). + * @details \b Inputs: pendingAckList[] + * @details \b Outputs: pendingAckList[] + * @param seqNo sequence number to match to an entry in the list + * @return none + *************************************************************************/ +static void matchACKtoPendingACKList( S16 seqNo ) +{ U32 i; - - // Find match - for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) - { - if ( ( TRUE == pendingAckList[ i ].used ) && ( pendingAckList[ i ].seqNo == seqNo ) ) + + // Find match + for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) + { + if ( ( TRUE == pendingAckList[ i ].used ) && ( pendingAckList[ i ].seqNo == seqNo ) ) { #ifdef _TD_ // Remove message pending ACK from list @@ -724,41 +724,41 @@ { pendingAckList[ i ].used = FALSE; } - break; - } - } -} - -/*********************************************************************//** - * @brief - * The checkPendingACKList function searches the pending ACK list to - * see if any have expired. Any such messages will be queued for retransmission + break; + } + } +} + +/*********************************************************************//** + * @brief + * The checkPendingACKList function searches the pending ACK list to + * see if any have expired. Any such messages will be queued for retransmission * if max retries not yet reached - * @details \b Alarm: ALARM_ID_XX_CAN_MESSAGE_NOT_ACKED_BY_XX if expired and max retries reached. - * @details \b Inputs: pendingAckList[] - * @details \b 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, (U08*)pendingAckList[ i ].msg, pendingAckList[ i ].msgSize ); + * @details \b Alarm: ALARM_ID_XX_CAN_MESSAGE_NOT_ACKED_BY_XX if expired and max retries reached. + * @details \b Inputs: pendingAckList[] + * @details \b 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, (U08*)pendingAckList[ i ].msg, pendingAckList[ i ].msgSize ); } - // If no retries left, alarm - else - { - U16 msgID; - + // If no retries left, alarm + else + { + U16 msgID; + memcpy( &msgID, (U08*)&pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); #ifdef _TD_ if ( pendingAckList[ i ].channel != COMM_BUFFER_OUT_CAN_TD_2_DD ) @@ -787,10 +787,10 @@ } #endif pendingAckList[ i ].used = FALSE; // Take pending message off of list - } - } - } -} + } + } + } +} /************************************************************************* Index: WatchdogMgmt.c =================================================================== diff -u -r15a8d5ff98b2d88bd0f32a37b41f4eec0f7a7088 -r91cff0134623a852aeb37b497b2263cf4a9ba6cb --- WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 15a8d5ff98b2d88bd0f32a37b41f4eec0f7a7088) +++ WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 91cff0134623a852aeb37b497b2263cf4a9ba6cb) @@ -15,7 +15,7 @@ * ***************************************************************************/ -#ifdef _TD_ +#ifdef _TD_ #include "CpldInterface.h" #include "FpgaTD.h" #endif @@ -28,94 +28,94 @@ #endif //#include "InternalADC.h" #include "Messaging.h" -#include "OperationModes.h" -#include "Timers.h" -#include "WatchdogMgmt.h" - +#include "OperationModes.h" +#include "Timers.h" +#include "WatchdogMgmt.h" + /** * @addtogroup WatchdogMgmt * @{ */ -// ********** private definitions ********** - -#define MIN_WATCHDOG_PET_INTERVAL_MS 45 ///< Minimum watchdog pet interval (in ms). -#define WATCHDOG_POST_TIMEOUT_MS 500 ///< Watchdog POST test timeout (in ms). +// ********** private definitions ********** + +#define MIN_WATCHDOG_PET_INTERVAL_MS 45 ///< Minimum watchdog pet interval (in ms). +#define WATCHDOG_POST_TIMEOUT_MS 500 ///< Watchdog POST test timeout (in ms). #define WATCHDOG_RECOVERY_TIME_MS 500 ///< After watchdog POST test, wait this long (in ms) before moving on. #define MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED 5.0F ///< Maximum voltage on 24V line when watchdog is expired. // TODO - check w/ Systems. Takes time for V to bleed off. Had to raise to 5V. #define MIN_24V_LEVEL_ON_WATCHDOG_RECOVER 22.6F ///< Minimum voltage on 24V line when watchdog is recovered. -#define MIN_BACKUP_ALARM_CURRENT_MA 200.0F ///< Minimum backup alarm audio current (in mA) detected when watchdog is expired. +#define MIN_BACKUP_ALARM_CURRENT_MA 200.0F ///< Minimum backup alarm audio current (in mA) detected when watchdog is expired. #define MAX_BACKUP_ALARM_CURRENT_MA 10.0F ///< Maximum backup alarm audio current (in mA) detected when watchdog is recovered. #define MAX_SAFETY_SHUTDOWN_MISMATCH_MS 100 ///< Maximum time (in ms) that safety shutdown cmd vs. feedback can be mismatched. -/// Enumeration of watchdog self-test states. -typedef enum Watchdog_Self_Test_States -{ - WATCHDOG_SELF_TEST_STATE_START = 0, ///< Watchdog self-test start state - WATCHDOG_SELF_TEST_STATE_IN_PROGRESS, ///< Watchdog self-test in progress state - WATCHDOG_SELF_TEST_STATE_RECOVER, ///< Watchdog self-test recovery state - WATCHDOG_SELF_TEST_STATE_COMPLETE, ///< Watchdog self-test completed state - NUM_OF_WATCHDOG_SELF_TEST_STATES ///< Number of watchdog self-test states -} WATCHDOG_SELF_TEST_STATE_T; - -// ********** private data ********** - -static U32 lastWatchdogPetTime; ///< Timestamp (ms counter) since last watchdog pet. -static OVERRIDE_U32_T watchdogTaskCheckedIn[ NUM_OF_TASKS ]; ///< Array of flags indicating whether individual tasks have checked in with watchdog manager. -static WATCHDOG_SELF_TEST_STATE_T watchdogSelfTestState; ///< Current watchdog self-test state. -static SELF_TEST_STATUS_T watchdogSelfTestStatus; ///< Watchdog self-test state status. +/// Enumeration of watchdog self-test states. +typedef enum Watchdog_Self_Test_States +{ + WATCHDOG_SELF_TEST_STATE_START = 0, ///< Watchdog self-test start state + WATCHDOG_SELF_TEST_STATE_IN_PROGRESS, ///< Watchdog self-test in progress state + WATCHDOG_SELF_TEST_STATE_RECOVER, ///< Watchdog self-test recovery state + WATCHDOG_SELF_TEST_STATE_COMPLETE, ///< Watchdog self-test completed state + NUM_OF_WATCHDOG_SELF_TEST_STATES ///< Number of watchdog self-test states +} WATCHDOG_SELF_TEST_STATE_T; + +// ********** private data ********** + +static U32 lastWatchdogPetTime; ///< Timestamp (ms counter) since last watchdog pet. +static OVERRIDE_U32_T watchdogTaskCheckedIn[ NUM_OF_TASKS ]; ///< Array of flags indicating whether individual tasks have checked in with watchdog manager. +static WATCHDOG_SELF_TEST_STATE_T watchdogSelfTestState; ///< Current watchdog self-test state. +static SELF_TEST_STATUS_T watchdogSelfTestStatus; ///< Watchdog self-test state status. static U32 watchdogSelfTestTimerCount; ///< Watchdog self-test state timer counter. -static U32 safetyShutdownFeedbackMismatchTS; ///< Persistence timestamp for safety shutdown cmd vs. feedback mismatch. - -// ********** private function prototypes ********** - -static void resetWDTaskCheckIns( void ); -static BOOL haveAllTasksCheckedIn( void ); -static void petWatchdog( void ); -static BOOL hasTaskGeneralCheckedIn( U32 task ); - -/*********************************************************************//** - * @brief - * The initWatchdogMgmt function initializes the watchdog management unit. - * @details \b Inputs: none - * @details \b Outputs: Watchdog management unit initialized. - * @return none - *************************************************************************/ -void initWatchdogMgmt( void ) -{ - U32 i; - - lastWatchdogPetTime = 0; - watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; - watchdogSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; +static U32 safetyShutdownFeedbackMismatchTS; ///< Persistence timestamp for safety shutdown cmd vs. feedback mismatch. + +// ********** private function prototypes ********** + +static void resetWDTaskCheckIns( void ); +static BOOL haveAllTasksCheckedIn( void ); +static void petWatchdog( void ); +static BOOL hasTaskGeneralCheckedIn( U32 task ); + +/*********************************************************************//** + * @brief + * The initWatchdogMgmt function initializes the watchdog management unit. + * @details \b Inputs: none + * @details \b Outputs: Watchdog management unit initialized. + * @return none + *************************************************************************/ +void initWatchdogMgmt( void ) +{ + U32 i; + + lastWatchdogPetTime = 0; + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; + watchdogSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; watchdogSelfTestTimerCount = 0; safetyShutdownFeedbackMismatchTS = getMSTimerCount(); - - // Initialize task check-ins to false - for ( i = 0; i < NUM_OF_TASKS; i++ ) - { - watchdogTaskCheckedIn[ i ].data = FALSE; - watchdogTaskCheckedIn[ i ].ovData = FALSE; - watchdogTaskCheckedIn[ i ].ovInitData = FALSE; - watchdogTaskCheckedIn[ i ].override = OVERRIDE_RESET; - } -} - -/*********************************************************************//** - * @brief + + // Initialize task check-ins to false + for ( i = 0; i < NUM_OF_TASKS; i++ ) + { + watchdogTaskCheckedIn[ i ].data = FALSE; + watchdogTaskCheckedIn[ i ].ovData = FALSE; + watchdogTaskCheckedIn[ i ].ovInitData = FALSE; + watchdogTaskCheckedIn[ i ].override = OVERRIDE_RESET; + } +} + +/*********************************************************************//** + * @brief * The execWatchdogMgmt function executes the watchdog management service. * If all tasks have checked in, the watchdog is pet. - * @details \b Inputs: watchdogTaskCheckedIn[] - * @details \b Outputs: watchdogTaskCheckedIn[] + * @details \b Inputs: watchdogTaskCheckedIn[] + * @details \b Outputs: watchdogTaskCheckedIn[] * @details \b Alarm: ALARM_ID_XX_WATCHDOG_EXPIRED if safety activated * @warning: It may be necessary to comment out the alarm activation lines to * prevent the alarm occurring while debugging. - * @return none - *************************************************************************/ -void execWatchdogMgmt( void ) -{ + * @return none + *************************************************************************/ +void execWatchdogMgmt( void ) +{ BOOL allTasksCheckedIn; #ifdef _TD_ PIN_SIGNAL_STATE_T safetyShutdownFeedbackSignal = getCPLDSafety(); @@ -124,21 +124,21 @@ // TODO : clean up once we get the clarity PIN_SIGNAL_STATE_T safetyShutdownFeedbackSignal = PIN_SIGNAL_HIGH; #endif - PIN_SIGNAL_STATE_T safetyShutdownSoftwareCmd = ( TRUE == isSafetyShutdownActivated() ? PIN_SIGNAL_LOW : PIN_SIGNAL_HIGH ); - - // Called by background task, so give bg task credit for checking in - checkInWithWatchdogMgmt( TASK_BG ); - - // Check to see if all monitored tasks have checked in - allTasksCheckedIn = haveAllTasksCheckedIn(); - - // If all monitored tasks checked in, pet watchdog and clear the slate - if ( ( TRUE == allTasksCheckedIn ) && ( TRUE == didTimeout( lastWatchdogPetTime, MIN_WATCHDOG_PET_INTERVAL_MS ) ) ) - { - petWatchdog(); - resetWDTaskCheckIns(); + PIN_SIGNAL_STATE_T safetyShutdownSoftwareCmd = ( TRUE == isSafetyShutdownActivated() ? PIN_SIGNAL_LOW : PIN_SIGNAL_HIGH ); + + // Called by background task, so give bg task credit for checking in + checkInWithWatchdogMgmt( TASK_BG ); + + // Check to see if all monitored tasks have checked in + allTasksCheckedIn = haveAllTasksCheckedIn(); + + // If all monitored tasks checked in, pet watchdog and clear the slate + if ( ( TRUE == allTasksCheckedIn ) && ( TRUE == didTimeout( lastWatchdogPetTime, MIN_WATCHDOG_PET_INTERVAL_MS ) ) ) + { + petWatchdog(); + resetWDTaskCheckIns(); } -#ifdef _TD_ +#ifdef _TD_ // Check to see if watchdog has expired or safety shutdown feedback does not match s/w command (only after POST completed) if ( ( safetyShutdownSoftwareCmd != safetyShutdownFeedbackSignal ) && ( getCurrentOperationMode() != MODE_INIT ) ) #endif @@ -149,86 +149,86 @@ #ifdef _RO_ // Check to see if watchdog has expired or safety shutdown feedback does not match s/w command (only after POST completed) if ( ( safetyShutdownSoftwareCmd != safetyShutdownFeedbackSignal ) && ( getCurrentOperationMode() != RO_MODE_INIT ) ) -#endif - { +#endif + { if ( ( PIN_SIGNAL_LOW == safetyShutdownFeedbackSignal ) || ( TRUE == didTimeout( safetyShutdownFeedbackMismatchTS, MAX_SAFETY_SHUTDOWN_MISMATCH_MS ) ) ) { #ifdef _TD_ activateAlarmNoData( ALARM_ID_TD_WATCHDOG_EXPIRED ); -#endif +#endif #ifdef _DD_ activateAlarmNoData( ALARM_ID_DD_WATCHDOG_EXPIRED ); #endif #ifdef _RO_ //activateAlarmNoData( ALARM_ID_RO_WATCHDOG_EXPIRED ); #endif } - } + } else { safetyShutdownFeedbackMismatchTS = getMSTimerCount(); } -} - -/*********************************************************************//** - * @brief - * The checkInWithWatchdogMgmt function checks a given task in with the - * watchdog management service. - * @details \b Inputs: none - * @details \b Outputs: task is checked in +} + +/*********************************************************************//** + * @brief + * The checkInWithWatchdogMgmt function checks a given task in with the + * watchdog management service. + * @details \b Inputs: none + * @details \b Outputs: task is checked in * @details \b Alarms: ALARM_ID_TD_SOFTWARE_FAULT if invalid task given - * @param task the task that is checking in - * @return none - *************************************************************************/ -void checkInWithWatchdogMgmt( TASK_T task ) -{ - if ( task < NUM_OF_TASKS ) - { - watchdogTaskCheckedIn[ task ].data = TRUE; + * @param task the task that is checking in + * @return none + *************************************************************************/ +void checkInWithWatchdogMgmt( TASK_T task ) +{ + if ( task < NUM_OF_TASKS ) + { + watchdogTaskCheckedIn[ task ].data = TRUE; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_WATCHDOG_INVALID_TASK, task ) - } -} - -/*********************************************************************//** - * @brief - * The execWatchdogTest function executes the watchdog self-test. + } +} + +/*********************************************************************//** + * @brief + * The execWatchdogTest function executes the watchdog self-test. * @warning This function should be called periodically until a pass or fail * result is returned. - * @details \b Inputs: watchdogSelfTestState, watchdogSelfTestTimerCount + * @details \b Inputs: watchdogSelfTestState, watchdogSelfTestTimerCount * @details \b Outputs: watchdogSelfTestState, watchdogSelfTestTimerCount, * watchdogSelfTestStatus * @details \b Alarm: ALARM_ID_XX_WATCHDOG_POST_TEST_FAILED if self-test fails. * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT if self-test state is invalid. - * @return in progress, passed, or failed - *************************************************************************/ -SELF_TEST_STATUS_T execWatchdogTest( void ) -{ - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - - switch ( watchdogSelfTestState ) - { - case WATCHDOG_SELF_TEST_STATE_START: - watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_IN_PROGRESS; - watchdogSelfTestTimerCount = getMSTimerCount(); - // No break here so we pass through directly to in progress processing - - case WATCHDOG_SELF_TEST_STATE_IN_PROGRESS: - while ( FALSE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_POST_TIMEOUT_MS ) ) - { - // Waiting here for w.d. test period to prevent this task from checking in - watchdog should expire + * @return in progress, passed, or failed + *************************************************************************/ +SELF_TEST_STATUS_T execWatchdogTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + + switch ( watchdogSelfTestState ) + { + case WATCHDOG_SELF_TEST_STATE_START: + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_IN_PROGRESS; + watchdogSelfTestTimerCount = getMSTimerCount(); + // No break here so we pass through directly to in progress processing + + case WATCHDOG_SELF_TEST_STATE_IN_PROGRESS: + while ( FALSE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_POST_TIMEOUT_MS ) ) + { + // Waiting here for w.d. test period to prevent this task from checking in - watchdog should expire } -#ifdef _TD_ +#ifdef _TD_ // if ( PIN_SIGNAL_LOW == getCPLDSafety() ) #else // if ( TBD ) -#endif +#endif // { // F32 v24 = getIntADCVoltageConverted( INT_ADC_24V_ACTUATORS ); // F32 audioCurrent = getFPGABackupAlarmAudioCurrent(); -// +// // // Verify 24V is down when w.d. expired // if ( v24 > MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED ) // { @@ -246,19 +246,19 @@ // watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; // } // } -// } -// else -// { +// } +// else +// { // SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 1 ); -// watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; -// } +// watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; +// } // watchdogSelfTestTimerCount = getMSTimerCount(); // watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_RECOVER; - break; - - case WATCHDOG_SELF_TEST_STATE_RECOVER: - if ( TRUE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_RECOVERY_TIME_MS ) ) - { // Verify watchdog expired signal no longer active + break; + + case WATCHDOG_SELF_TEST_STATE_RECOVER: + if ( TRUE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_RECOVERY_TIME_MS ) ) + { // Verify watchdog expired signal no longer active #ifdef _TD_ // if ( PIN_SIGNAL_HIGH == getCPLDSafety() ) #else @@ -295,24 +295,24 @@ // SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 6 ); // watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; // } -// result = watchdogSelfTestStatus; -// watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_COMPLETE; - } - break; - - case WATCHDOG_SELF_TEST_STATE_COMPLETE: - // If we get called in this state, assume we are doing self-test again - watchdogSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; - watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; - break; - - default: - result = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_WATCHDOG_INVALID_SELF_TEST_STATE, watchdogSelfTestState ) - break; +// result = watchdogSelfTestStatus; +// watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_COMPLETE; + } + break; + + case WATCHDOG_SELF_TEST_STATE_COMPLETE: + // If we get called in this state, assume we are doing self-test again + watchdogSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; + break; + + default: + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_WATCHDOG_INVALID_SELF_TEST_STATE, watchdogSelfTestState ) + break; } - - return result; + + return result; } /*********************************************************************//** @@ -326,62 +326,62 @@ void resetWatchdogPOSTState( void ) { watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; -} - -/*********************************************************************//** - * @brief - * The resetWDTaskCheckIns function resets the task check-ins with the watchdog. - * @details \b Inputs: none - * @details \b Outputs: watchdogTaskCheckedIn[] array reset to all false. - * @return none - *************************************************************************/ -static void resetWDTaskCheckIns( void ) -{ - U32 i; - - // Initialize task check-ins to false - for ( i = 0; i < NUM_OF_TASKS; i++ ) - { - watchdogTaskCheckedIn[ i ].data = FALSE; - } -} - -/*********************************************************************//** - * @brief - * The haveAllTasksCheckedIn function determines whether all tasks have - * checked in. - * @details \b Inputs: watchdogTaskCheckedIn[] - * @details \b Outputs: none - * @return TRUE if all tasks have checked in since last watchdog pet, FALSE if not. - *************************************************************************/ -static BOOL haveAllTasksCheckedIn( void ) -{ - BOOL result = TRUE; - U32 i; - - // Check that each task has checked in - for ( i = 0; i < NUM_OF_TASKS; i++ ) - { - if ( FALSE == hasTaskGeneralCheckedIn( i ) ) - { - result = FALSE; - break; - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The hasTaskGeneralCheckedIn function gets the checked in status of a given - * task. - * @details \b Inputs: watchdogTaskCheckedIn[] +} + +/*********************************************************************//** + * @brief + * The resetWDTaskCheckIns function resets the task check-ins with the watchdog. + * @details \b Inputs: none + * @details \b Outputs: watchdogTaskCheckedIn[] array reset to all false. + * @return none + *************************************************************************/ +static void resetWDTaskCheckIns( void ) +{ + U32 i; + + // Initialize task check-ins to false + for ( i = 0; i < NUM_OF_TASKS; i++ ) + { + watchdogTaskCheckedIn[ i ].data = FALSE; + } +} + +/*********************************************************************//** + * @brief + * The haveAllTasksCheckedIn function determines whether all tasks have + * checked in. + * @details \b Inputs: watchdogTaskCheckedIn[] * @details \b Outputs: none - * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given task is invalid. - * @param task ID of task to determine checked in status of - * @return TRUE if given task has checked in, FALSE if not - *************************************************************************/ + * @return TRUE if all tasks have checked in since last watchdog pet, FALSE if not. + *************************************************************************/ +static BOOL haveAllTasksCheckedIn( void ) +{ + BOOL result = TRUE; + U32 i; + + // Check that each task has checked in + for ( i = 0; i < NUM_OF_TASKS; i++ ) + { + if ( FALSE == hasTaskGeneralCheckedIn( i ) ) + { + result = FALSE; + break; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The hasTaskGeneralCheckedIn function gets the checked in status of a given + * task. + * @details \b Inputs: watchdogTaskCheckedIn[] + * @details \b Outputs: none + * @details \b Alarm: ALARM_ID_XX_SOFTWARE_FAULT if given task is invalid. + * @param task ID of task to determine checked in status of + * @return TRUE if given task has checked in, FALSE if not + *************************************************************************/ BOOL hasTaskGeneralCheckedIn( U32 task ) { BOOL result = FALSE; @@ -412,46 +412,46 @@ return result; } - -/*********************************************************************//** - * @brief - * The petWatchdog function pets the watchdog by pulsing the watchdog pet - * signal. - * @details \b Inputs: none - * @details \b Outputs: Watchdog pet signal is pulsed - * @return none - *************************************************************************/ -static void petWatchdog( void ) -{ + +/*********************************************************************//** + * @brief + * The petWatchdog function pets the watchdog by pulsing the watchdog pet + * signal. + * @details \b Inputs: none + * @details \b Outputs: Watchdog pet signal is pulsed + * @return none + *************************************************************************/ +static void petWatchdog( void ) +{ // Pulse the watchdog signal -#ifdef _TD_ +#ifdef _TD_ toggleCPLDWatchdog(); #else // TBD -#endif - - // Remember when we last pet the watchdog - lastWatchdogPetTime = getMSTimerCount(); -} - - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ - - -/*********************************************************************//** - * @brief - * The testWatchdogTaskCheckInOverride function overrides the state of the - * check-in for a given task with a given check-in state. +#endif + + // Remember when we last pet the watchdog + lastWatchdogPetTime = getMSTimerCount(); +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testWatchdogTaskCheckInOverride function overrides the state of the + * check-in for a given task with a given check-in state. * @warning Dialin must be logged into related firmware stack to perform * an override successfully. - * @details \b Inputs: none - * @details \b Outputs: watchdogTaskCheckedIn[] + * @details \b Inputs: none + * @details \b Outputs: watchdogTaskCheckedIn[] * @param message Override message from Dialin which includes an ID of * the task to override and the check-in status to override the task to. * @return TRUE if override successful, FALSE if not - *************************************************************************/ + *************************************************************************/ BOOL testWatchdogTaskCheckInOverride( MESSAGE_T *message ) { BOOL result = u32ArrayOverride( message, &watchdogTaskCheckedIn[0], NUM_OF_TASKS - 1, FALSE, TRUE );