/************************************************************************** * * Copyright (c) 2019-2019 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 "can.h" #include "sci.h" #include "sys_dma.h" #include "Interrupts.h" #include "FPGA.h" #include "SystemComm.h" // ********** private definitions ********** #define DMA_CH_STATUS_BIT(ch) ((U32)1U << (ch)) // ********** private data ********** static U32 frameErrorCnt = 0; static U32 overrunErrorCnt = 0; // ********** private function prototypes ********** /************************************************************************* * @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) { handleCANMsgInterrupt( (CAN_MESSAGE_BOX_T)messageBox ); } /************************************************************************* * @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) { if ( ( flags & SCI_FE_INT ) != 0 ) { frameErrorCnt++; } if ( ( flags & SCI_OE_INT ) != 0 ) { overrunErrorCnt++; } } /************************************************************************* * @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; case DMA_CH1: // PC receive channel clearSCI1DMAReceiveInterrupt(); // handle received packet from PC handleUARTMsgRecvPacketInterrupt(); break; case DMA_CH2: // FPGA transmit channel clearSCI2DMATransmitInterrupt(); signalFPGATransmitCompleted(); break; case DMA_CH3: // PC transmit channel clearSCI1DMATransmitInterrupt(); // send next pending packet to PC (if any) handleUARTMsgXmitPacketInterrupt(); break; default: // TODO - ignore? break; } } } /************************************************************************* * @brief setSCI1DMAReceiveInterrupt * The setSCI1DMAReceiveInterrupt function enables DMA receive interrupts \n * for the SCI1 peripheral. * @details * Inputs : none * Outputs : DMA receive interrupt is enabled. * @param none * @return none *************************************************************************/ void setSCI1DMAReceiveInterrupt( void ) { sciREG->SETINT = SCI_DMA_RECEIVE_INT; } /************************************************************************* * @brief setSCI1DMATransmitInterrupt * The setSCI1DMATransmitInterrupt function enables DMA transmit interrupts \n * for the SCI1 peripheral. * @details * Inputs : none * Outputs : DMA transmit interrupt is enabled. * @param none * @return none *************************************************************************/ void setSCI1DMATransmitInterrupt( void ) { sciREG->SETINT = SCI_DMA_TRANSMIT_INT; } /************************************************************************* * @brief clearSCI1DMAReceiveInterrupt * The clearSCI1DMAReceiveInterrupt function disables DMA receive interrupts \n * for the SCI1 peripheral. * @details * Inputs : none * Outputs : DMA receive interrupt is disabled. * @param none * @return none *************************************************************************/ void clearSCI1DMAReceiveInterrupt( void ) { sciREG->CLEARINT = SCI_DMA_RECEIVE_INT; } /************************************************************************* * @brief clearSCI1DMATransmitInterrupt * The clearSCI1DMATransmitInterrupt function disables DMA transmit interrupts \n * for the SCI1 peripheral. * @details * Inputs : none * Outputs : DMA transmit interrupt is disabled. * @param none * @return none *************************************************************************/ void clearSCI1DMATransmitInterrupt( void ) { sciREG->CLEARINT = SCI_DMA_TRANSMIT_INT; } /************************************************************************* * @brief setSCI2DMAReceiveInterrupt * The setSCI2DMAReceiveInterrupt function enables DMA receive interrupts \n * for the SCI2 peripheral. * @details * Inputs : none * Outputs : DMA receive interrupt is enabled. * @param none * @return none *************************************************************************/ void setSCI2DMAReceiveInterrupt( void ) { scilinREG->SETINT = SCI_DMA_RECEIVE_INT; } /************************************************************************* * @brief setSCI2DMATransmitInterrupt * The setSCI2DMATransmitInterrupt function enables DMA transmit interrupts \n * for the SCI2 peripheral. * @details * Inputs : none * Outputs : DMA transmit interrupt is enabled. * @param none * @return none *************************************************************************/ void setSCI2DMATransmitInterrupt( void ) { scilinREG->SETINT = SCI_DMA_TRANSMIT_INT; } /************************************************************************* * @brief clearSCI2DMAReceiveInterrupt * The clearSCI2DMAReceiveInterrupt function disables DMA receive interrupts \n * for the SCI2 peripheral. * @details * Inputs : none * Outputs : DMA receive interrupt is disabled. * @param none * @return none *************************************************************************/ void clearSCI2DMAReceiveInterrupt( void ) { scilinREG->CLEARINT = SCI_DMA_RECEIVE_INT; } /************************************************************************* * @brief clearSCI2DMATransmitInterrupt * The clearSCI2DMATransmitInterrupt function disables DMA transmit interrupts \n * for the SCI2 peripheral. * @details * Inputs : none * Outputs : DMA transmit interrupt is disabled. * @param none * @return none *************************************************************************/ void clearSCI2DMATransmitInterrupt( void ) { scilinREG->CLEARINT = SCI_DMA_TRANSMIT_INT; } /************************************************************************* * @brief isSCI1DMATransmitInProgress * The isSCI2DMATransmitInProgress function determines whether a DMA transmit \n * is in progress on the SCI1 peripheral. * @details * Inputs : status registers * Outputs : none * @param none * @return TRUE if a transmit is in progress, FALSE if not *************************************************************************/ BOOL isSCI1DMATransmitInProgress( void ) { BOOL transmitterBusy = ( ( sciREG->FLR & (U32)SCI_TX_INT ) == 0U ? TRUE : FALSE ); BOOL dmaTransmitterBusy = ( ( dmaREG->PEND & DMA_CH_STATUS_BIT(DMA_CH3) ) != 0U ? TRUE : FALSE ); return ( ( transmitterBusy == TRUE ) || ( dmaTransmitterBusy == TRUE ) ? TRUE : FALSE ); } /************************************************************************* * @brief isSCI2DMATransmitInProgress * The isSCI2DMATransmitInProgress function determines whether a DMA transmit \n * is in progress on the SCI2 peripheral. * @details * Inputs : status registers * Outputs : none * @param none * @return TRUE if a transmit is in progress, FALSE if not *************************************************************************/ BOOL isSCI2DMATransmitInProgress( void ) { BOOL transmitterBusy = ( ( scilinREG->FLR & (U32)SCI_TX_INT ) == 0U ? TRUE : FALSE ); BOOL dmaTransmitterBusy = ( ( dmaREG->PEND & DMA_CH_STATUS_BIT(DMA_CH2) ) != 0U ? TRUE : FALSE ); return ( ( transmitterBusy == TRUE ) || ( dmaTransmitterBusy == TRUE ) ? TRUE : FALSE ); } /************************************************************************* * @brief isCAN1TransmitInProgress * The isCAN1TransmitInProgress function determines whether a transmit \n * is in progress on the CAN1 peripheral. * @details * Inputs : status registers * Outputs : none * @param none * @return TRUE if a transmit is in progress, FALSE if not *************************************************************************/ BOOL isCAN1TransmitInProgress( void ) { BOOL result = ( ( canREG1->TXRQx[0] != 0 ) || ( canREG1->TXRQx[1] != 0 ) ? TRUE : FALSE ); return result; }