Initial commit
This commit is contained in:
61
306-controller_interface.X/xf/event.c
Normal file
61
306-controller_interface.X/xf/event.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "event.h"
|
||||
#define NULL ((void*)(0))
|
||||
|
||||
void Event_init(struct Event_* me)
|
||||
{
|
||||
me->id = NULLEVENT;
|
||||
me->delay = 0;
|
||||
me->target = NULL;
|
||||
me->data = 0x0;
|
||||
me->processEvent = NULL;
|
||||
}
|
||||
|
||||
void Event_setData(Event* me, int64_t data)
|
||||
{
|
||||
me->data = data;
|
||||
}
|
||||
|
||||
int64_t Event_getData(Event* me)
|
||||
{
|
||||
return me->data;
|
||||
}
|
||||
|
||||
void Event_setPE(Event* me, processEventT processEvent)
|
||||
{
|
||||
me->processEvent = processEvent;
|
||||
}
|
||||
|
||||
void Event_setTarget(Event* me, void* target)
|
||||
{
|
||||
me->target = target;
|
||||
}
|
||||
|
||||
processEventT Event_getPE(Event* me)
|
||||
{
|
||||
return me->processEvent;
|
||||
}
|
||||
|
||||
void* Event_getTarget(Event* me)
|
||||
{
|
||||
return me->target;
|
||||
}
|
||||
|
||||
void Event_setId(Event* me, evIDT eventID)
|
||||
{
|
||||
me->id = eventID;
|
||||
}
|
||||
|
||||
evIDT Event_getId(Event* me)
|
||||
{
|
||||
return me->id;
|
||||
}
|
||||
|
||||
void Event_setDelay(Event* me, uint16_t delay)
|
||||
{
|
||||
me->delay = delay;
|
||||
}
|
||||
|
||||
uint16_t Event_getDelay(Event* me)
|
||||
{
|
||||
return me->delay;
|
||||
}
|
||||
35
306-controller_interface.X/xf/event.h
Normal file
35
306-controller_interface.X/xf/event.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "ireactive.h"
|
||||
|
||||
#ifndef EVENT_ONCE
|
||||
#define EVENT_ONCE
|
||||
|
||||
typedef uint8_t evIDT;
|
||||
#define NULLEVENT 0 // no event
|
||||
|
||||
struct Event_
|
||||
{
|
||||
evIDT id;
|
||||
processEventT processEvent;
|
||||
void* target;
|
||||
uint16_t delay;
|
||||
int64_t data;
|
||||
};
|
||||
|
||||
typedef struct Event_ Event;
|
||||
|
||||
//public methods
|
||||
void Event_init(Event* me);
|
||||
void Event_setTarget(Event* me, void* target);
|
||||
void Event_setPE(Event* me, processEventT processEvent);
|
||||
void* Event_getTarget(Event* me);
|
||||
processEventT Event_getPE(Event* me);
|
||||
void Event_setId(Event* me, evIDT eventID);
|
||||
evIDT Event_getId(Event* me);
|
||||
void Event_setDelay(Event* me, uint16_t delay);
|
||||
uint16_t Event_getDelay(Event* me);
|
||||
void Event_setData(Event* me, int64_t data);
|
||||
int64_t Event_getData(Event* me);
|
||||
|
||||
#endif
|
||||
8
306-controller_interface.X/xf/ireactive.h
Normal file
8
306-controller_interface.X/xf/ireactive.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef IREACTIVE_ONCE
|
||||
#define IREACTIVE_ONCE
|
||||
|
||||
struct Event_;
|
||||
|
||||
typedef bool (*processEventT)(struct Event_* ev);
|
||||
|
||||
#endif
|
||||
292
306-controller_interface.X/xf/xf.c
Normal file
292
306-controller_interface.X/xf/xf.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/******************************************************************************/
|
||||
/* FILENAME : xf.h */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* GOAL : Offers the femto XF functions (for PIC CPU) */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* AUTHOR : Medard Rieder / Pascal Sartoretti */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* DATE: : original (Medard Rieder 08.2011) */
|
||||
/* corrections & simplified (Pascal Sartoretti 06.2016) */
|
||||
/******************************************************************************/
|
||||
#include <stdbool.h> // boolean types
|
||||
#include "xf.h"
|
||||
#include "../mcc_generated_files/mcc.h"
|
||||
|
||||
/*
|
||||
* private methods of the XF
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Push an event on the events queue */
|
||||
/* INPUT : ev - the event number (not 0) */
|
||||
/* inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : return false if the queue was full, else true */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
bool XF_pushEvent(Event ev, bool inISR, TimerID* tmid);
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Pop an event on the events queue */
|
||||
/* INPUT : inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : return the next waiting event if any, else 0 */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
Event XF_popEvent(bool inISR);
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Post a timer in timers queue */
|
||||
/* INPUT : tm - time before event arrives */
|
||||
/* ev - event to post */
|
||||
/* inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : return the timer Id used */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
TimerID XF_scheduleTimer(Time tm, Event ev, bool inISR);
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Switch of the interrupts */
|
||||
/* INPUT : inISR - (true if called in an ISR, else f */
|
||||
/* OUTPUT : none */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
static void ENTERCRITICAL(bool inISR);
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Switch on the interrupts */
|
||||
/* INPUT : inISR - (true if called in an ISR, else f */
|
||||
/* OUTPUT : none */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
static void LEAVECRITICAL(bool inISR);
|
||||
|
||||
|
||||
/*
|
||||
* the XF instance
|
||||
*/
|
||||
XF theXF; // really the XF
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Init the XF structure */
|
||||
/* INPUT : - */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : Have to be called once */
|
||||
/******************************************************************************/
|
||||
void XF_init()
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<MAXEVENT; i++)
|
||||
{
|
||||
Event_init(&(theXF.eventQueue[i]));
|
||||
}
|
||||
|
||||
for (i=0; i<MAXTIMER; i++)
|
||||
{
|
||||
theXF.timerList[i].tm = NULLTIMER;
|
||||
Event_init(&(theXF.timerList[i].ev));
|
||||
}
|
||||
theXF.in = 0;
|
||||
theXF.out = 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Push an event on the events queue */
|
||||
/* INPUT : ev - the event number (not 0) */
|
||||
/* inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : return false if the queue was full, else true */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
bool XF_pushEvent(Event ev, bool inISR, TimerID* tmid)
|
||||
{
|
||||
uint8_t temp;
|
||||
Time tm;
|
||||
tm = Event_getDelay(&ev);
|
||||
if ( tm > 0)
|
||||
{
|
||||
Event_setDelay(&ev,0);
|
||||
*tmid = XF_scheduleTimer(tm, ev, inISR);
|
||||
}
|
||||
else
|
||||
{
|
||||
ENTERCRITICAL(inISR);
|
||||
|
||||
temp = (theXF.in+1) % (uint8_t)(sizeof(theXF.eventQueue) / sizeof(Event));
|
||||
if(temp == theXF.out)
|
||||
{
|
||||
LEAVECRITICAL(inISR);
|
||||
return false;
|
||||
}
|
||||
theXF.eventQueue[theXF.in] = ev;
|
||||
theXF.in = temp;
|
||||
LEAVECRITICAL(inISR);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Pop an event on the events queue */
|
||||
/* INPUT : inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : return the next waiting event if any, else 0 */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
Event XF_popEvent(bool inISR)
|
||||
{
|
||||
Event ev;
|
||||
ev.id = NULLEVENT;
|
||||
ev.target = NULL;
|
||||
ev.processEvent = NULL;
|
||||
|
||||
ENTERCRITICAL(inISR);
|
||||
if(theXF.in == theXF.out)
|
||||
{
|
||||
LEAVECRITICAL(inISR);
|
||||
return ev;
|
||||
}
|
||||
ev = theXF.eventQueue[theXF.out];
|
||||
theXF.out = (theXF.out + 1)%(uint8_t)(sizeof(theXF.eventQueue) / sizeof(Event));
|
||||
LEAVECRITICAL(inISR);
|
||||
return ev;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Post a timer in timers queue */
|
||||
/* INPUT : tm - time before event arrives */
|
||||
/* ev - event to post */
|
||||
/* inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : return the timer Id used */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
TimerID XF_scheduleTimer(Time tm, Event ev, bool inISR)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
ENTERCRITICAL(inISR);
|
||||
for (i=0; i<MAXTIMER; i++)
|
||||
{
|
||||
if (theXF.timerList[i].ev.id == NULLEVENT)
|
||||
{
|
||||
theXF.timerList[i].tm = tm;
|
||||
theXF.timerList[i].ev = ev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//here you could react
|
||||
//if timerlist is full
|
||||
|
||||
LEAVECRITICAL(inISR);
|
||||
return i;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Remove a timer in timers queue */
|
||||
/* INPUT : id - the timer id to remove */
|
||||
/* inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
void XF_unscheduleTimer(TimerID id, bool inISR)
|
||||
{
|
||||
ENTERCRITICAL(inISR);
|
||||
theXF.timerList[id].tm = NULLTIMER;
|
||||
Event_init(&(theXF.timerList[id].ev));
|
||||
LEAVECRITICAL(inISR);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Decrement timers to post events if time elapsed */
|
||||
/* INPUT : - */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : This function has to be called from the timer ISR */
|
||||
/******************************************************************************/
|
||||
void XF_decrementAndQueueTimers()
|
||||
{
|
||||
uint8_t i;
|
||||
for (i=0; i<MAXTIMER; i++)
|
||||
{
|
||||
if (theXF.timerList[i].ev.id != NULLEVENT)
|
||||
{
|
||||
theXF.timerList[i].tm-=TICKINTERVAL;
|
||||
if (theXF.timerList[i].tm ==0)
|
||||
{
|
||||
TimerID dummy;
|
||||
if (XF_pushEvent(theXF.timerList[i].ev, true, &dummy) == true)
|
||||
{
|
||||
XF_unscheduleTimer(i, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
theXF.timerList[i].tm=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//here you could use done to react
|
||||
//if timerID was not found (done == 0)
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Lock interrupts if not in ISR */
|
||||
/* INPUT : - */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
static void ENTERCRITICAL(bool inISR)
|
||||
{
|
||||
if (inISR == false)
|
||||
{
|
||||
//GIE = 0;
|
||||
INTERRUPT_GlobalInterruptDisable();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Unlock interrupts if not in ISR */
|
||||
/* INPUT : - */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
static void LEAVECRITICAL(bool inISR)
|
||||
{
|
||||
if (inISR == false)
|
||||
{
|
||||
//GIE = 1;
|
||||
INTERRUPT_GlobalInterruptEnable();
|
||||
}
|
||||
}
|
||||
|
||||
TimerID POST(void* target, processEventT processEvent, uint8_t id, Time delay , int64_t data)
|
||||
{
|
||||
TimerID tmid = MAXTIMER; //this is to say that no timer has been scheduled
|
||||
//is a timer has been scheduled, the ID will be
|
||||
//from 0 to MAXTIMER-1
|
||||
Event ev;
|
||||
Event_init(&ev);
|
||||
Event_setTarget(&ev,target);
|
||||
Event_setPE(&ev,processEvent);
|
||||
Event_setId(&ev,id);
|
||||
Event_setDelay(&ev,delay);
|
||||
Event_setData(&ev,data);
|
||||
XF_pushEvent(ev,false,&tmid);
|
||||
return tmid;
|
||||
}
|
||||
|
||||
void XF_executeOnce()
|
||||
{
|
||||
Event ev = XF_popEvent(false);
|
||||
//if this event is valid
|
||||
if (ev.id != NULLEVENT)
|
||||
{
|
||||
//if this event has a valid target
|
||||
if (ev.target != NULL)
|
||||
{
|
||||
//if this event has a valid state machine
|
||||
//function pointer
|
||||
if (ev.processEvent != NULL)
|
||||
{
|
||||
//call the state machine method function
|
||||
//and pass the event as parameter
|
||||
ev.processEvent(&ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
84
306-controller_interface.X/xf/xf.h
Normal file
84
306-controller_interface.X/xf/xf.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/******************************************************************************/
|
||||
/* FILENAME : xf.h */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* GOAL : Offers the femto XF functions */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* AUTHOR : Medard Rieder / Pascal Sartoretti */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* DATE: : original (Medard Rieder 08.2011) */
|
||||
/* corrections & simplified (Pascal Sartoretti 06.2016) */
|
||||
/******************************************************************************/
|
||||
#ifndef XF_DEF
|
||||
#define XF_DEF
|
||||
|
||||
#include <stdint.h> // usage of standard types
|
||||
#include <stdbool.h> // usage of boolean types
|
||||
#include "../mcc_generated_files/mcc.h"
|
||||
#include "event.h"
|
||||
|
||||
#define Time uint16_t // time type
|
||||
#define TimerID uint8_t // identifier of timer (position in buffer)
|
||||
|
||||
typedef struct Timer_ // timer structure
|
||||
{
|
||||
Time tm; // time
|
||||
Event ev; // event to post
|
||||
} Timer;
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* depending on usage, change MAXTIMER and MAXEVENT */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define MAXTIMER 8 // number of timers in our system
|
||||
#define MAXEVENT 12 // number of events in our system
|
||||
|
||||
#define NULLTIMER 0 // no value for time
|
||||
#define TICKINTERVAL 10 // this is the ticktimers duration
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef struct XF // the XF structure
|
||||
{
|
||||
Timer timerList[MAXTIMER]; // the timers
|
||||
Event eventQueue[MAXEVENT]; // the events
|
||||
uint8_t in; // the events in pointer
|
||||
uint8_t out; // the events out pointer
|
||||
} XF;
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Init the XF structure */
|
||||
/* INPUT : - */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : Have to be called once */
|
||||
/******************************************************************************/
|
||||
void XF_init();
|
||||
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Remove a timer in timers queue */
|
||||
/* INPUT : id - the timer id to remove */
|
||||
/* inISR - (true if called in an ISR, else false) */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : - */
|
||||
/******************************************************************************/
|
||||
void XF_unscheduleTimer(TimerID id, bool inISR);
|
||||
/******************************************************************************/
|
||||
/* FUNCTION : Decrement timers to post events if time elapsed */
|
||||
/* INPUT : - */
|
||||
/* OUTPUT : - */
|
||||
/* COMMENTS : This function has to be called from the timer ISR */
|
||||
/******************************************************************************/
|
||||
void XF_decrementAndQueueTimers();
|
||||
|
||||
/********************************************************************************/
|
||||
/* FUNCTION : POST an Event */
|
||||
/* INPUT : target - the address of the object with the state machine */
|
||||
/* processEvent - function pointer of the state machine function */
|
||||
/* id - the id of the event */
|
||||
/* delay - the delay if the event is a timeout event */
|
||||
/* data - user data */
|
||||
/* OUTPUT : TimerId - the id of the timeout if the event is a timeout */
|
||||
/* COMMENTS : */
|
||||
/********************************************************************************/
|
||||
TimerID POST(void* target, processEventT processEvent, uint8_t id, Time delay, int64_t data);
|
||||
|
||||
void XF_executeOnce();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user