/** * \file * \brief Event driver implementation. * \author Erich Styger, erich.styger@hslu.ch * \license SPDX-License-Identifier: BSD-3-Clause * This module implements a generic event driver. We are using numbered events starting with zero. * EVNT_HandleEvent() can be used to process the pending events. Note that the event with the number zero * has the highest priority and will be handled first. */ #include "platform.h" #if PL_CONFIG_USE_EVENTS #include "Event.h" /* our own interface */ #include "McuCriticalSection.h" typedef uint32_t EVNT_MemUnit; /*!< memory unit used to store events flags */ #define EVNT_MEM_UNIT_NOF_BITS (sizeof(EVNT_MemUnit)*8u) /*!< number of bits in memory unit */ static EVNT_MemUnit EVNT_Events[((EVNT_NOF_EVENTS-1)/EVNT_MEM_UNIT_NOF_BITS)+1]; /*!< Bit set of events */ #define SET_EVENT(event) \ EVNT_Events[(event)/EVNT_MEM_UNIT_NOF_BITS] |= (1u<<(EVNT_MEM_UNIT_NOF_BITS-1))>>(((event)%EVNT_MEM_UNIT_NOF_BITS)) /*!< Set the event */ #define CLR_EVENT(event) \ EVNT_Events[(event)/EVNT_MEM_UNIT_NOF_BITS] &= ~((1u<<(EVNT_MEM_UNIT_NOF_BITS-1))>>(((event)%EVNT_MEM_UNIT_NOF_BITS))) /*!< Clear the event */ #define GET_EVENT(event) \ (EVNT_Events[(event)/EVNT_MEM_UNIT_NOF_BITS]&((1u<<(EVNT_MEM_UNIT_NOF_BITS-1))>>(((event)%EVNT_MEM_UNIT_NOF_BITS)))) /*!< Return TRUE if event is set */ void EVNT_SetEvent(EVNT_Handle event) { McuCriticalSection_CriticalVariable() McuCriticalSection_EnterCritical(); SET_EVENT(event); McuCriticalSection_ExitCritical(); } void EVNT_ClearEvent(EVNT_Handle event) { McuCriticalSection_CriticalVariable() McuCriticalSection_EnterCritical(); CLR_EVENT(event); McuCriticalSection_ExitCritical(); } bool EVNT_EventIsSet(EVNT_Handle event) { bool res; McuCriticalSection_CriticalVariable() McuCriticalSection_EnterCritical(); res = (GET_EVENT(event)!=0); McuCriticalSection_ExitCritical(); return res; } bool EVNT_EventIsSetAutoClear(EVNT_Handle event) { bool res; McuCriticalSection_CriticalVariable() McuCriticalSection_EnterCritical(); res = GET_EVENT(event); if (res) { CLR_EVENT(event); /* automatically clear event */ } McuCriticalSection_ExitCritical(); return res; } void EVNT_HandleEvent(void (*callback)(EVNT_Handle), bool clearEvent) { /* Handle the one with the highest priority. Zero is the event with the highest priority. */ EVNT_Handle event; McuCriticalSection_CriticalVariable() McuCriticalSection_EnterCritical(); for (event=(EVNT_Handle)0; event