/************************************************************************** * * Copyright (c) 2019-2020 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 Interrupts.c * * @date 22-Oct-2019 * @author S. Nash * * @brief Interrupts service module. Provides interrupt handling \n * functions. * **************************************************************************/ #include #include "can.h" #include "sci.h" #include "sys_dma.h" #include "AlarmMgmt.h" #include "Comm.h" #include "Interrupts.h" #include "FPGA.h" #include "SystemComm.h" #ifdef DEBUG_ENABLED #include "SystemCommMessages.h" #endif // ********** private definitions ********** // ********** private data ********** #ifdef DEBUG_ENABLED static U32 sci1FrameErrorCnt = 0; static U32 sci1OverrunErrorCnt = 0; #endif static U32 sci2FrameErrorCnt = 0; static U32 sci2OverrunErrorCnt = 0; static U32 can1PassiveCnt = 0; static U32 can1WarningCnt = 0; static U32 can1BusOffCnt = 0; static U32 can1ParityCnt = 0; // ********** private function prototypes ********** /************************************************************************* * @brief phantomInterrupt * The phantomInterrupt function handles phantom interrupts. * @details * Inputs : none * Outputs : phantom interrupt handled. * @param none * @return none *************************************************************************/ void phantomInterrupt(void) { // TODO - what to do with phantom interrupts? } /************************************************************************* * @brief canMessageNotification * The canMessageNotification function handles CAN message notifications. * @details * Inputs : none * Outputs : CAN message notification handled. * @param node : which CAN controller * @param messageBox : which message box triggered the message notification * @return none *************************************************************************/ void canMessageNotification(canBASE_t *node, uint32 messageBox) { if ( node == canREG1 ) { handleCANMsgInterrupt( (CAN_MESSAGE_BOX_T)messageBox ); } } /************************************************************************* * @brief canErrorNotification * The canErrorNotification function handles CAN error notifications. * @details * Inputs : none * 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 \n * canLEVEL_WARNING (0x40) : When RX- or TX error counter are between 64 and 127 \n * canLEVEL_BUS_OFF (0x80) : When RX- or TX error counter are between 128 and 255 \n * canLEVEL_PARITY_ERR (0x100): When parity error detected on CAN RAM read access * @return none *************************************************************************/ void canErrorNotification(canBASE_t *node, uint32 notification) { #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later char debugStr[ 256 ]; #endif if ( node == canREG1 ) { if ( notification & canLEVEL_PARITY_ERR ) { can1ParityCnt++; #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later sprintf( debugStr, "CAN parity error:%5d \n", can1ParityCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); #endif } else if ( notification & canLEVEL_BUS_OFF ) { can1BusOffCnt++; #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later sprintf( debugStr, "CAN bus off error:%5d \n", can1BusOffCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); #endif } else if ( notification & canLEVEL_WARNING ) { can1WarningCnt++; #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later sprintf( debugStr, "CAN bus warning:%5d \n", can1WarningCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); #endif } else if ( notification & canLEVEL_PASSIVE ) { can1PassiveCnt++; #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later sprintf( debugStr, "CAN passive warning:%5d \n", can1PassiveCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); #endif } else { // ignore - other bits undefined } } } /************************************************************************* * @brief sciNotification * The sciNotification function handles UART communication error interrupts. \n * Frame and Over-run errors are handled. * @details * Inputs : none * Outputs : UART error interrupts handled. * @param sci : Pointer to the SCI peripheral that detected the error * @param flags : error flag(s) * @return none *************************************************************************/ void sciNotification(sciBASE_t *sci, uint32 flags) { #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later char debugStr[ 256 ]; #endif if ( sci == scilinREG ) { if ( ( flags & SCI_FE_INT ) != 0 ) { sci2FrameErrorCnt++; clearSCI2CommErrors(); // TODO - try to do something to recover (+ max retries = comm fault) #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later sprintf( debugStr, "FPGA UART frame error:%5d \n", sci2FrameErrorCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); #endif } if ( ( flags & SCI_OE_INT ) != 0 ) { sci2OverrunErrorCnt++; clearSCI2CommErrors(); // TODO - try to do something to recover (+ max retries = comm fault) #ifdef DEBUG_ENABLED // TODO - temporary debug code - remove later sprintf( debugStr, "FPGA UART overrun error:%5d \n", sci2OverrunErrorCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); #endif } } #ifdef DEBUG_ENABLED if ( sci == sciREG ) { if ( ( flags & SCI_FE_INT ) != 0 ) { sci1FrameErrorCnt++; clearSCI1CommErrors(); // TODO - try to do something to recover (+ max retries = comm fault) // TODO - temporary debug code - remove later sprintf( debugStr, "Debug UART frame error:%5d \n", sci1FrameErrorCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); } if ( ( flags & SCI_OE_INT ) != 0 ) { sci1OverrunErrorCnt++; clearSCI1CommErrors(); // TODO - try to do something to recover (+ max retries = comm fault) // TODO - temporary debug code - remove later sprintf( debugStr, "Debug UART overrun error:%5d \n", sci1OverrunErrorCnt ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); } } #endif } /************************************************************************* * @brief dmaGroupANotification * The dmaGroupANotification function handles communication DMA interrupts. * @details * Inputs : none * 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; #ifdef DEBUG_ENABLED case DMA_CH1: // PC receive channel clearSCI1DMAReceiveInterrupt(); // handle received packet from PC handleUARTMsgRecvPacketInterrupt(); break; #endif case DMA_CH2: // FPGA transmit channel clearSCI2DMATransmitInterrupt(); signalFPGATransmitCompleted(); break; #ifdef DEBUG_ENABLED case DMA_CH3: // PC transmit channel clearSCI1DMATransmitInterrupt(); // send next pending packet to PC (if any) handleUARTMsgXmitPacketInterrupt(); break; #endif default: // TODO - ignore? break; } } }