/* * error state handler * * Copyright (c) 2012-2023 emotas embedded communication GmbH *------------------------------------------------------------------- * $Id: codrv_error.c 47801 2023-07-06 14:39:17Z ro $ * * *------------------------------------------------------------------- * * */ /********************************************************************/ /** * \file * \brief error state handling * */ /* header of standard C - libraries ---------------------------------------------------------------------------*/ #include /* header of project specific types ---------------------------------------------------------------------------*/ #include #include #include #include #include "codrv_error.h" /* constant definitions ---------------------------------------------------------------------------*/ /* local defined data types ---------------------------------------------------------------------------*/ /* list of external used functions, if not in headers ---------------------------------------------------------------------------*/ /* list of global defined functions ---------------------------------------------------------------------------*/ /* list of local defined functions ---------------------------------------------------------------------------*/ /* external variables ---------------------------------------------------------------------------*/ /* global variables ---------------------------------------------------------------------------*/ static CAN_ERROR_FLAGS_T canErrorFlags; /* local defined variables ---------------------------------------------------------------------------*/ /***************************************************************************/ /** * \brief codrvCanErrorgetFlags - Reference to the error flags * * \retval * pointer to error flags * */ CAN_ERROR_FLAGS_T * codrvCanErrorGetFlags( void /* no parameter */ ) { return(&canErrorFlags); } /***************************************************************************/ /** * \brief codrvCanErrorInit - init Error variables * */ void codrvCanErrorInit( void /* no parameter */ ) { CAN_ERROR_FLAGS_T * pError; pError = codrvCanErrorGetFlags(); pError->canErrorRxOverrun = CO_FALSE; pError->canErrorPassive = CO_FALSE; pError->canErrorActive = CO_FALSE; pError->canErrorBusoff = CO_FALSE; pError->drvErrorGeneric = CO_FALSE; pError->canOldState = Error_Offline; /* last signaled state */ } /***********************************************************************/ /** * codrvCanErrorInformStack - inform the stack about changes * * Call outside of interrupts! * Typical call in codrvCanDriverHandler(). * */ RET_T codrvCanErrorInformStack( void /* no parameter */ ) { CAN_ERROR_FLAGS_T * pError; pError = codrvCanErrorGetFlags(); if (pError->canErrorRxOverrun == CO_TRUE) { /* CAN Overrun */ pError->canErrorRxOverrun = CO_FALSE; coCommStateEvent(CO_COMM_STATE_EVENT_CAN_OVERRUN); } if (pError->drvErrorGeneric == CO_TRUE) { /* general driver error */ pError->drvErrorGeneric = CO_FALSE; coCommStateEvent(CO_COMM_STATE_EVENT_DRV_ERROR); } /* signal CAN Error changed events * (Active <-> Passive -> Busoff -> Active) */ if ((pError->canNewState == Error_Busoff) || (pError->canErrorBusoff == CO_TRUE)) { if (pError->canOldState == Error_Active) { /* Passive event */ coCommStateEvent(CO_COMM_STATE_EVENT_PASSIVE); } if (pError->canOldState != Error_Busoff) { /* Busoff event */ coCommStateEvent(CO_COMM_STATE_EVENT_BUS_OFF); } } if ((pError->canOldState == Error_Busoff) || (pError->canOldState == Error_Offline) || (pError->canErrorBusoff == CO_TRUE)) { if (pError->canNewState == Error_Passive) { /* Active event */ coCommStateEvent(CO_COMM_STATE_EVENT_ACTIVE); /* Passive event*/ coCommStateEvent(CO_COMM_STATE_EVENT_PASSIVE); } } if ((pError->canOldState == Error_Active) && (pError->canNewState == Error_Passive) && (pError->canErrorBusoff == CO_FALSE)) { /* Passive event */ coCommStateEvent(CO_COMM_STATE_EVENT_PASSIVE); } if ((pError->canOldState == Error_Active) && (pError->canNewState == Error_Active)) { if (pError->canErrorBusoff == CO_TRUE) { /* Active event */ coCommStateEvent(CO_COMM_STATE_EVENT_ACTIVE); } else if (pError->canErrorPassive == CO_TRUE) { /* Passive event */ coCommStateEvent(CO_COMM_STATE_EVENT_PASSIVE); /* Active event */ coCommStateEvent(CO_COMM_STATE_EVENT_ACTIVE); } else { /* nothing */ } } /* if ((pError->canOldState == Error_Passive) || (pError->canOldState == Error_Busoff) || (pError->canOldState == Error_Offline)) */ if (pError->canOldState != Error_Active) { if (pError->canNewState == Error_Active) { /* Active event */ coCommStateEvent(CO_COMM_STATE_EVENT_ACTIVE); } } pError->canErrorPassive = CO_FALSE; pError->canErrorActive = CO_FALSE; pError->canErrorBusoff = CO_FALSE; pError->canOldState = pError->canNewState; return(RET_OK); }