Index: firmware/App/Services/Interrupts.c =================================================================== diff -u -reb877ae36c28eb83553ee11ccccf42e2c4a5b4d2 -r84376e65112b149961efe193128cbbd495fafa6c --- firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision eb877ae36c28eb83553ee11ccccf42e2c4a5b4d2) +++ firmware/App/Services/Interrupts.c (.../Interrupts.c) (revision 84376e65112b149961efe193128cbbd495fafa6c) @@ -1,43 +1,150 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ +/************************************************************************** +* +* 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 +* +* @author (last) Sean +* @date (last) 12-May-2020 +* +* @author (original) Dara Navaei +* @date (original) 05-Nov-2019 +* +***************************************************************************/ +#include #include "can.h" +#include "het.h" +#include "rti.h" #include "sci.h" #include "sys_dma.h" -#include "Comm.h" +#include "AlarmMgmt.h" +#include "BloodFlow.h" +#include "Comm.h" +#include "DialInFlow.h" +#include "DialOutFlow.h" #include "Interrupts.h" #include "FPGA.h" #include "SystemComm.h" +#include "TaskGeneral.h" +#include "TaskPriority.h" +#include "TaskTimer.h" +#include "Utilities.h" +#ifdef DEBUG_ENABLED + #include "SystemCommMessages.h" +#endif -// ********** private definitions ********** +/** + * @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. + +#define HET1_EDGE_BP_ROTOR_HALL_SENSOR 0 +#define HET1_EDGE_DPI_ROTOR_HALL_SENSOR 1 +#define HET1_EDGE_DPO_ROTOR_HALL_SENSOR 2 - // ********** private data ********** -static U32 frameErrorCnt = 0; -static U32 overrunErrorCnt = 0; +#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 + * The initInterrupts function initializes the Interrupts module. + * @details + * Inputs : none + * Outputs : Interrupts module initialized. + * @return none + *************************************************************************/ +void initInterrupts( void ) +{ + // initialize various time windowed counts for monitoring CAN & UART errors and warnings + initTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_PASSIVE, MAX_COMM_ERRORS, COMM_ERROR_TIME_WINDOW_MS ); + 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 ); + initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_FRAME_ERROR, MAX_COMM_ERRORS, COMM_ERROR_TIME_WINDOW_MS ); + initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_OVERRUN, MAX_COMM_ERRORS, COMM_ERROR_TIME_WINDOW_MS ); +} -/************************************************************************* - * @brief canMessageNotification +/*********************************************************************//** + * @brief + * The phantomInterrupt function handles phantom interrupts. + * @details + * Inputs : none + * Outputs : phantom interrupt handled. + * @return none + *************************************************************************/ +void phantomInterrupt(void) +{ + // TODO - what to do with phantom interrupts? +#ifdef DEBUG_ENABLED + { + char debugStr[ 256 ]; + + sprintf( debugStr, "HD-phantom interrupt\n" ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); + } +#endif +} + +/*********************************************************************//** + * @brief + * The rtiNotification function handles real-time interrupt notifications. + * @details + * Inputs : none + * Outputs : RTI notification handled. + * @param notification : Which RTI timer 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: + // TODO - s/w fault? + break; + } +} + +/*********************************************************************//** + * @brief * The canMessageNotification function handles CAN message notifications. * @details * Inputs : none @@ -48,11 +155,90 @@ *************************************************************************/ void canMessageNotification(canBASE_t *node, uint32 messageBox) { - handleCANMsgInterrupt( (CAN_MESSAGE_BOX_T)messageBox ); + if ( node == canREG1 ) + { + handleCANMsgInterrupt( (CAN_MESSAGE_BOX_T)messageBox ); + } } -/************************************************************************* - * @brief sciNotification +/*********************************************************************//** + * @brief + * 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 + char debugStr[ 256 ]; +#endif + + if ( node == canREG1 ) + { + if ( notification & canLEVEL_PARITY_ERR ) + { + can1ParityCnt++; + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_PARITY ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_CAN_PARITY_ERROR ) + } +#ifdef DEBUG_ENABLED + sprintf( debugStr, "CAN parity error:%5d \n", can1ParityCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); +#endif + } + else if ( notification & canLEVEL_BUS_OFF ) + { + can1BusOffCnt++; + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_OFF ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_CAN_OFF_ERROR ) + } +#ifdef DEBUG_ENABLED + sprintf( debugStr, "CAN bus off error:%5d \n", can1BusOffCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); +#endif + } + else if ( notification & canLEVEL_WARNING ) + { + can1WarningCnt++; +#ifdef DEBUG_ENABLED + sprintf( debugStr, "CAN bus warning:%5d \n", can1WarningCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); +#endif + } + else if ( notification & canLEVEL_PASSIVE ) + { + can1PassiveCnt++; + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_CAN_PASSIVE ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_CAN_PASSIVE_WARNING ) + } +#ifdef DEBUG_ENABLED + sprintf( debugStr, "CAN passive warning:%5d \n", can1PassiveCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); +#endif + } + else + { + // ignore - other notifications undefined + } + } +} + +/*********************************************************************//** + * @brief * The sciNotification function handles UART communication error interrupts. \n * Frame and Over-run errors are handled. * @details @@ -64,18 +250,67 @@ *************************************************************************/ void sciNotification(sciBASE_t *sci, uint32 flags) { - if ( ( flags & SCI_FE_INT ) != 0 ) +#ifdef DEBUG_ENABLED + // TODO - temporary debug code - remove later + char debugStr[ 256 ]; +#endif + + if ( sci == scilinREG ) { - frameErrorCnt++; + if ( ( flags & SCI_FE_INT ) != 0 ) + { + sci2FrameErrorCnt++; + clearSCI2CommErrors(); + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_FRAME_ERROR ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_UART_FRAME_ERROR ) + } +#ifdef DEBUG_ENABLED + sprintf( debugStr, "FPGA UART FR err:%5d \n", sci2FrameErrorCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); +#endif + } + if ( ( flags & SCI_OE_INT ) != 0 ) + { + sci2OverrunErrorCnt++; + clearSCI2CommErrors(); + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_UART_OVERRUN ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_UART_OVERRUN_ERROR ) + } +#ifdef DEBUG_ENABLED + sprintf( debugStr, "FPGA UART OR err:%5d \n", sci2OverrunErrorCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); +#endif + } } - if ( ( flags & SCI_OE_INT ) != 0 ) +#ifdef DEBUG_ENABLED + if ( sci == sciREG ) { - overrunErrorCnt++; + if ( ( flags & SCI_FE_INT ) != 0 ) + { + sci1FrameErrorCnt++; + clearSCI1CommErrors(); + sprintf( debugStr, "Debug UART FR err:%5d\n", sci1FrameErrorCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); + } + if ( ( flags & SCI_OE_INT ) != 0 ) + { + sci1OverrunErrorCnt++; + clearSCI1CommErrors(); + sprintf( debugStr, "Debug UART OR err:%5d\n", sci1OverrunErrorCnt ); + sendDebugData( (U08*)debugStr, strlen(debugStr) ); + sendDebugDataToUI( (U08*)debugStr ); + } } +#endif } -/************************************************************************* - * @brief dmaGroupANotification +/*********************************************************************//** + * @brief * The dmaGroupANotification function handles communication DMA interrupts. * @details * Inputs : none @@ -95,27 +330,67 @@ 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; } } } +/*********************************************************************//** + * @brief + * The edgeNotification function handles rotor hall sensor interrupts. + * @details + * Inputs : none + * Outputs : Rotor hall sensor interrupt is handled according to pin associated with given edge. + * @param hetREG : HET controller associated with the edge. + * @param edge : Which edge was detected. + * @return none + *************************************************************************/ +void edgeNotification(hetBASE_t * hetREG, uint32 edge) +{ + if ( hetREG == hetREG1 ) + { + switch ( edge ) + { + case HET1_EDGE_BP_ROTOR_HALL_SENSOR: + signalBloodPumpRotorHallSensor(); + break; + + case HET1_EDGE_DPI_ROTOR_HALL_SENSOR: + //signalDialInPumpRotorHallSensor(); + signalDialOutPumpRotorHallSensor(); + break; + + case HET1_EDGE_DPO_ROTOR_HALL_SENSOR: + //signalDialOutPumpRotorHallSensor(); + signalDialInPumpRotorHallSensor(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INTERRUPTS_INVALID_EDGE_DETECTED, edge ) + break; + } + } +} + +/**@}*/