#include "can.h" #include "het.h" #include "rti.h" #include "sci.h" #include "sys_dma.h" #include "AlarmMgmtRO.h" #include "Comm.h" #include "Interrupts.h" #include "FPGA.h" #include "SystemComm.h" #include "TaskGeneral.h" #include "TaskPriority.h" #include "TaskTimer.h" #include "Utilities.h" /** * @addtogroup Interrupts * @{ */ // ********** private definitions ********** #define MAX_COMM_ERRORS 5 ///< Maximum number of a given comm error for a given time window. #define COMM_ERROR_TIME_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< Time window for comm error counts. // ********** private data ********** static BOOL sci2FEOEError = FALSE; ///< FPGA serial frame or overrun flag; static U32 can1WarningCnt = 0; ///< CAN warning mode counter. static U32 can1BusOffCnt = 0; ///< CAN buss off mode counter. static U32 can1ParityCnt = 0; ///< CAN parity error counter. // ********** private function prototypes ********** /*********************************************************************//** * @brief * The initInterrupts function initializes the Interrupts unit. * @details \b Inputs: none * @details \b Outputs: Interrupts unit initialized. * @return none *************************************************************************/ void initInterrupts( void ) { // Initialize various time windowed counts for monitoring CAN & UART errors and warnings initTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_OFF, MAX_COMM_ERRORS, COMM_ERROR_TIME_WINDOW_MS ); initTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_PARITY, MAX_COMM_ERRORS, COMM_ERROR_TIME_WINDOW_MS ); } /*********************************************************************//** * @brief * The phantomInterrupt function handles phantom interrupts. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT * @details \b Inputs: none * @details \b Outputs: phantom interrupt handled. * @return none *************************************************************************/ void phantomInterrupt(void) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_PHANTOM_INTERRUPT ) } /*********************************************************************//** * @brief * The rtiNotification function handles real-time interrupt notifications. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given notification is invalid/unexpected. * @details \b Inputs: none * @details \b Outputs: Task associated with given notification is executed. * @param notification ID of RTI timer that caused this interrupt * @return none *************************************************************************/ void rtiNotification(uint32 notification) { switch ( notification ) { case rtiNOTIFICATION_COMPARE0: taskTimer(); break; case rtiNOTIFICATION_COMPARE1: taskPriority(); break; case rtiNOTIFICATION_COMPARE2: // Do nothing - unused at this time break; case rtiNOTIFICATION_COMPARE3: taskGeneral(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_RTI_NOTIFICATION, notification ) break; } } /*********************************************************************//** * @brief * The canMessageNotification function handles CAN message notifications. * @details \b Inputs: none * @details \b Outputs: CAN message notification handled. * @param node ID of CAN controller that given notification came from. * @param messageBox ID of CAN mailbox that triggered the message notification * @return none *************************************************************************/ void canMessageNotification(canBASE_t *node, uint32 messageBox) { if ( node == canREG1 ) { handleCANMsgInterrupt( (CAN_MESSAGE_BOX_T)messageBox ); } } /*********************************************************************//** * @brief * The canErrorNotification function handles CAN error notifications. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if CAN parity or off error detected. * @details \b Inputs: none * @details \b Outputs: CAN error notification handled. * @param node which CAN controller * @param notification canLEVEL_PASSIVE (0x20) : When RX- or TX error counter are between 32 and 63 * canLEVEL_WARNING (0x40) : When RX- or TX error counter are between 64 and 127 * canLEVEL_BUS_OFF (0x80) : When RX- or TX error counter are between 128 and 255 * canLEVEL_PARITY_ERR (0x100): When parity error detected on CAN RAM read access * @return none *************************************************************************/ void canErrorNotification(canBASE_t *node, uint32 notification) { if ( node == canREG1 ) { // Parity error - message RAM is corrupted if ( notification & canLEVEL_PARITY_ERR ) { can1ParityCnt++; if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_PARITY ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_CAN_PARITY_ERROR ) } } // Bus off - our transmitter has counted 255+ errors else if ( notification & canLEVEL_BUS_OFF ) { can1BusOffCnt++; if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_OFF ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_CAN_OFF_ERROR ) } } // Warning - our transmitter has counted 96+ errors else if ( notification & canLEVEL_WARNING ) { can1WarningCnt++; } else { // Ignore other notifications - unhandled } } } /*********************************************************************//** * @brief * The sciNotification function handles UART communication error interrupts. * Frame and Over-run errors are recorded and cleared. * @details \b Inputs: none * @details \b Outputs: sci2FEOEError, sci2FEOEError * @param sci Pointer to the SCI peripheral that detected the error * @param flags 32 bits of error flags * @return none *************************************************************************/ void sciNotification(sciBASE_t *sci, uint32 flags) { #ifndef _VECTORCAST_ // Cannot set the pointers to be equal in VectorCAST. Can define pointers but the user does not have any control on the address of it if ( sci == scilinREG ) #endif { if ( ( flags & SCI_FE_INT ) != 0 ) { sci2FEOEError = TRUE; scilinREG->FLR |= SCI_FE_INT; } if ( ( flags & SCI_OE_INT ) != 0 ) { sci2FEOEError = TRUE; scilinREG->FLR |= SCI_OE_INT; } } } /*********************************************************************//** * @brief * The dmaGroupANotification function handles communication DMA interrupts. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given DMA channel is invalid/unexpected. * @details \b Inputs: none * @details \b Outputs: DMA interrupt is handled. * @param inttype type of DMA interrupt * @param channel DMA channel that caused the interrupt * @return none *************************************************************************/ void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel) { if ( inttype == BTC ) // Block transfer completed interrupt { switch ( channel ) { case DMA_CH0: // FPGA receive channel clearSCI2DMAReceiveInterrupt(); signalFPGAReceiptCompleted(); break; case DMA_CH2: // FPGA transmit channel clearSCI2DMATransmitInterrupt(); signalFPGATransmitCompleted(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_RO_SOFTWARE_FAULT, SW_FAULT_ID_UNEXPECTED_DMA_INTERRUPT, channel ) break; } } } /*********************************************************************//** * @brief * The getSci2FEOEError function returns the sci2FEOEError (OE - Overrun, * FE - Framing Error) status and resets the status if TRUE * @details \b Inputs: sci2FEOEError * @details \b Outputs: none * @return sci2 FE / OE error *************************************************************************/ BOOL getSci2FEOEError( void ) { BOOL returnValue = sci2FEOEError; if ( TRUE == returnValue ) { sci2FEOEError = FALSE; } return returnValue; } /**@}*/