/** * @author Rémi Heredero (remi@heredero.ch) * @version. 1.0.0 * @date 2023-06-15 */ #include "blinker.h" void BLINKER_init(BLINKER* me) { me->state = STBL_INIT; me->tON = 500; me->tOFF = 500; me->nBlink = 3; me->nBlinkIsOn = false; me->remainBlinks = 3; me->turnOn.fCallBack = NULL; me->turnOff.fCallBack = NULL; } blinkerCallBack BLINKER_defineCallBack(fBlinkerCallBack f, void* param) { blinkerCallBack c; c.fCallBack = f; c.param = param; return c; } void BLINKER_starBehaviour(BLINKER* me) { POST(me, &BLINKER_processEvent, evBLinit, 0, 0); } void BLINKER_setTurnOn(BLINKER* me, blinkerCallBack callBack) { me->turnOn = callBack; } void BLINKER_setTurnOff(BLINKER* me, blinkerCallBack callBack) { me->turnOff = callBack; } void BLINKER_setFinished(BLINKER* me, blinkerCallBack callBack){ me->finished = callBack; } void BLINKER_defineNblink(BLINKER* me, uint8_t n){ me->nBlink = n; } void BLINKER_setTimeOn(BLINKER*me, uint16_t t) { me->tON = t; } void BLINKER_setTimeOff(BLINKER*me, uint16_t t) { me->tOFF = t; } void BLINKER_blinkN(BLINKER* me){ POST(me, &BLINKER_processEvent, evBLblinkN, 0, 0); } void BLINKER_blink(BLINKER* me){ POST(me, &BLINKER_processEvent, evBLblink, 0, 0); } bool BLINKER_processEvent(Event* ev) { bool processed = false; BLINKER* me = (BLINKER*) Event_getTarget(ev); BLINKER_STATES oldState = me->state; evIDT evid = Event_getId(ev); switch(me->state) { case STBL_INIT: if(evid == evBLinit) { me->state = STBL_WAIT; } break; case STBL_WAIT: me->remainBlinks = me->nBlink; if(evid == evBLblinkN) { me->state = STBL_ON; me->nBlinkIsOn = true; POST(me, &BLINKER_processEvent, evBLtimer, me->tON, 0); } if(evid==evBLblink) { me->state = STBL_ON; me->nBlinkIsOn = false; POST(me, &BLINKER_processEvent, evBLtimer, me->tON, 0); } break; case STBL_ON: if(me->nBlinkIsOn) me->remainBlinks--; if(evid == evBLtimer) { me->state = STBL_OFF; POST(me, &BLINKER_processEvent, evBLtimer, me->tOFF, 0); } break; case STBL_OFF: if(evid == evBLtimer) { if(me->remainBlinks == 0) { me->state = STBL_WAIT; if(me->finished.fCallBack != NULL) me->finished.fCallBack(me->finished.param); } else { me->state = STBL_ON; POST(me, &BLINKER_processEvent, evBLtimer, me->tON, 0); } } break; } if(oldState != me->state) { switch(me->state) { // on entry case STBL_INIT: break; case STBL_WAIT: break; case STBL_ON: if(me->turnOn.fCallBack != NULL) me->turnOn.fCallBack(me->turnOn.param); break; case STBL_OFF: if(me->turnOff.fCallBack != NULL) me->turnOff.fCallBack(me->turnOff.param); break; } processed = true; } return processed; } void BLINKER_endBlink(BLINKER* me) { me->remainBlinks = 0; } void BLINKER_toggle(BLINKER* me){ switch(me->state) { case STBL_WAIT: BLINKER_blink(me); break; case STBL_OFF: BLINKER_endBlink(me); break; case STBL_ON: BLINKER_endBlink(me); break; } }