You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.2 KiB
103 lines
3.2 KiB
/**
|
|
* \file
|
|
* \brief Implementation of generic triggers.
|
|
* \author Erich Styger, erich.styger@hslu.ch
|
|
* \license SPDX-License-Identifier: BSD-3-Clause
|
|
* This module implements a trigger module.
|
|
* Triggers are special events which are triggered in a given time in the future
|
|
*/
|
|
#include "platform.h"
|
|
#include "Trigger.h"
|
|
#include "McuCriticalSection.h"
|
|
#include <stddef.h> /* for NULL */
|
|
|
|
/*! \brief Descriptor for a trigger. */
|
|
typedef struct TRG_TriggerDesc {
|
|
TRG_TriggerTime ticks; /*!< tick count until trigger */
|
|
TRG_Callback callback; /*!< callback function */
|
|
TRG_CallBackDataPtr data; /*!< additional data pointer for callback */
|
|
} TRG_TriggerDesc;
|
|
|
|
static TRG_TriggerDesc TRG_Triggers[TRG_NOF_TRIGGERS]; /*!< Array of triggers */
|
|
|
|
uint8_t TRG_SetTrigger(TRG_TriggerKind trigger, TRG_TriggerTime ticks, TRG_Callback callback, TRG_CallBackDataPtr data) {
|
|
McuCriticalSection_CriticalVariable()
|
|
|
|
McuCriticalSection_EnterCritical();
|
|
TRG_Triggers[trigger].ticks = ticks;
|
|
TRG_Triggers[trigger].callback = callback;
|
|
TRG_Triggers[trigger].data = data;
|
|
McuCriticalSection_ExitCritical();
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint8_t TRG_StopTrigger(TRG_TriggerKind trigger) {
|
|
McuCriticalSection_CriticalVariable()
|
|
|
|
McuCriticalSection_EnterCritical();
|
|
TRG_Triggers[trigger].ticks = 0;
|
|
TRG_Triggers[trigger].callback = NULL;
|
|
TRG_Triggers[trigger].data = NULL;
|
|
McuCriticalSection_ExitCritical();
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*!
|
|
* \brief Goes through the list of triggers and returns TRUE in case we have to call a callback.
|
|
* \return Returns TRUE if we have called a callback.
|
|
*/
|
|
static bool CheckCallbacks(void) {
|
|
TRG_TriggerKind i;
|
|
TRG_Callback callback;
|
|
TRG_CallBackDataPtr data;
|
|
bool calledCallBack = FALSE;
|
|
McuCriticalSection_CriticalVariable()
|
|
|
|
for(i=(TRG_TriggerKind)0;i<TRG_NOF_TRIGGERS;i++) {
|
|
McuCriticalSection_EnterCritical();
|
|
if (TRG_Triggers[i].ticks==0 && TRG_Triggers[i].callback != NULL) { /* trigger! */
|
|
callback = TRG_Triggers[i].callback; /* get a copy */
|
|
data = TRG_Triggers[i].data; /* get backup of data, as we overwrite it below */
|
|
/* reset trigger structure, as callback might setup this trigger again */
|
|
TRG_Triggers[i].callback = NULL; /* NULL callback prevents that we are called again */
|
|
McuCriticalSection_ExitCritical();
|
|
callback(data);
|
|
calledCallBack = TRUE; /* callback may have set a trigger at the current time: rescan trigger list */
|
|
} else {
|
|
McuCriticalSection_ExitCritical();
|
|
}
|
|
} /* for */
|
|
return calledCallBack;
|
|
}
|
|
|
|
void TRG_AddTick(void) {
|
|
TRG_TriggerKind i;
|
|
uint8_t res;
|
|
McuCriticalSection_CriticalVariable()
|
|
|
|
McuCriticalSection_EnterCritical();
|
|
for(i=(TRG_TriggerKind)0;i<TRG_NOF_TRIGGERS;i++) {
|
|
if (TRG_Triggers[i].ticks!=0) { /* prevent underflow */
|
|
TRG_Triggers[i].ticks--;
|
|
}
|
|
} /* for */
|
|
McuCriticalSection_ExitCritical();
|
|
do {
|
|
res = CheckCallbacks(); /* while there are callbacks, re-iterate */
|
|
} while(res);
|
|
}
|
|
|
|
void TRG_Deinit(void) {
|
|
/* nothing to do */
|
|
}
|
|
|
|
void TRG_Init(void) {
|
|
TRG_TriggerKind i;
|
|
|
|
for(i=(TRG_TriggerKind)0;i<TRG_NOF_TRIGGERS;i++) {
|
|
TRG_Triggers[i].ticks = 0;
|
|
TRG_Triggers[i].callback = NULL;
|
|
TRG_Triggers[i].data = NULL;
|
|
}
|
|
}
|
|
|
|
|