diff --git a/src/board/button.c b/src/board/button.c new file mode 100644 index 0000000..7156c98 --- /dev/null +++ b/src/board/button.c @@ -0,0 +1,161 @@ +/** + * @author Rémi Heredero + * @version 1.0.0 + * @date July 2023 + * @file button.c + */ + +#include "button.h" +#include "../mcc_generated_files/pin_manager.h" +#include "../app/factory.h" +#include "led.h" + +void BUTTON_init(BUTTON* me, uint8_t id) { + me->id = id; + me->state = STPB_INIT; + me->poll_time = 20; + me->press.f = NULL; + me->release.f = NULL; +} + +void BUTTON_initHW(BUTTON* me) { + switch (me->id) { + case 1: + INPUT1_SetDigitalInput(); + break; + case 2: + INPUT2_SetDigitalInput(); + break; + case 3: + INPUT3_SetDigitalInput(); + break; + default: + break; + } +} + +bool BUTTON_isPressed(BUTTON* me) { + switch (me->id) { + case 1: + return INPUT1_GetValue(); + break; + case 2: + return INPUT2_GetValue(); + break; + case 3: + return INPUT3_GetValue(); + break; + default: + return false; + break; + } +} + +void BUTTON_startBehaviour(BUTTON* me){ + POST(me, &BUTTON_processEvent, evPBinit, 0, 0); +} + +bool BUTTON_processEvent(Event* ev) { + bool processed = false; + BUTTON* me = (BUTTON*)Event_getTarget(ev); + BUTTON_STATES oldState = me->state; + evIDT evid = Event_getId(ev); + + switch (me->state) { // onState + case STPB_INIT: + if (ev->id == evPBinit) { + POST(me, &BUTTON_processEvent, evPBpoll, me->poll_time, 0); + if(BUTTON_isPressed(me)){ + me->state = STPB_PRESSED; + } else { + me->state = STPB_RELEASED; + } + } + break; + + case STPB_RELEASED: + if (ev->id == evPBpoll) { + POST(me, &BUTTON_processEvent, evPBpoll, me->poll_time, 0); + if(BUTTON_isPressed(me)){ + me->state = STPB_PRESSED; + } + } + break; + + case STPB_PRESSED: + if (ev->id == evPBpoll) { + POST(me, &BUTTON_processEvent, evPBpoll, me->poll_time, 0); + if(!BUTTON_isPressed(me)){ + me->state = STPB_RELEASED; + } + } + break; + } + + if(oldState != me->state){ + switch (oldState) { // onExit + case STPB_INIT: + break; + + case STPB_RELEASED: + break; + + case STPB_PRESSED: + break; + } + + switch (me->state) { // onEntry + case STPB_INIT: + break; + + case STPB_RELEASED: + if (me->release.f != NULL) { + me->release.f(me->release.p); + } + break; + + case STPB_PRESSED: + if (me->press.f != NULL) { + me->press.f(me->press.p); + } + break; + } + + processed = true; + } + return processed; +} + +/************* + * Callbacks * + *************/ + +void BUTTON_onPress(BUTTON* me, BUTTON_CALLBACK_FUNCTION f, void* p){ + me->press.f = f; + me->press.p = p; +} + +void BUTTON_onRelease(BUTTON* me, BUTTON_CALLBACK_FUNCTION f, void* p){ + me->release.f = f; + me->release.p = p; +} + +/************ + * EMITTERS * + ************/ + +void BUTTON_emitPoll(BUTTON* me, uint16_t t) { + POST(me, &BUTTON_processEvent, evPBpoll, t, 0); +} + +/*********** + * SETTERS * + ***********/ + +void BUTTON_setId(BUTTON* me, uint8_t v) { + me->id = v; +} + +void BUTTON_setPoll_time(BUTTON* me, uint16_t v) { + me->poll_time = v; +} \ No newline at end of file diff --git a/src/board/button.h b/src/board/button.h new file mode 100644 index 0000000..0a01a54 --- /dev/null +++ b/src/board/button.h @@ -0,0 +1,120 @@ +/** + * @author Rémi Heredero + * @version 1.0.0 + * @date July 2023 + * @file button.h + */ +#ifndef BUTTON_H +#define BUTTON_H + +#include "../xf/xf.h" + +typedef enum { + STPB_INIT, + STPB_RELEASED, + STPB_PRESSED +} BUTTON_STATES; + +typedef enum { + evPBinit = 50, + evPBpoll +} BUTTON_EVENTS; + +typedef void (*BUTTON_CALLBACK_FUNCTION)(void*); +typedef struct { + BUTTON_CALLBACK_FUNCTION f; // function + void* p; // param(s) +} BUTTON_CALLBACK; + +typedef struct { + BUTTON_STATES state; + uint8_t id; + uint16_t poll_time; + BUTTON_CALLBACK press; + BUTTON_CALLBACK release; +} BUTTON; + +/** + * Initialize the BUTTON + * @param me the BUTTON itself + */ +void BUTTON_init(BUTTON* me, uint8_t id); + +/** + * Initialize the hardware of the BUTTON + * @param me the BUTTON itself + */ +void BUTTON_initHW(BUTTON* me); + +/** + * @brief Check if the button is pressed + * The function returns true if the button is pressed, false otherwise + * + * @param me button itself + * @return true if the button is pressed + * @return false if the button is not pressed + */ +bool BUTTON_isPressed(BUTTON* me); + +/** + * Start the BUTTON state machine + * @param me the BUTTON itself + */ +void BUTTON_startBehaviour(BUTTON* me); + +/** + * Process the event + * @param ev the event to process + * @return true if the event is processed + */ +bool BUTTON_processEvent(Event* ev); + +/************* + * Callbacks * + *************/ + +/** + * Set the callback function to call when the BUTTON is pressed + * @param me the BUTTON itself + * @param f the function to call + * @param p the param(s) to pass to the function + */ +void BUTTON_onPress(BUTTON* me, BUTTON_CALLBACK_FUNCTION f, void* p); + +/** + * Set the callback function to call when the BUTTON is released + * @param me the BUTTON itself + * @param f the function to call + * @param p the param(s) to pass to the function + */ +void BUTTON_onRelease(BUTTON* me, BUTTON_CALLBACK_FUNCTION f, void* p); + +/************ + * EMITTERS * + ************/ + +/** + * Emit the poll event + * @param me the BUTTON itself + * @param t time to wait in ms before triggering event + */void BUTTON_emitPoll(BUTTON* me, uint16_t t); + +/*********** + * SETTERS * + ***********/ + +/** + * Set the id of the BUTTON + * @param me the BUTTON itself + * @param v the id to set + */ +void BUTTON_setId(BUTTON* me, uint8_t v); + +/** + * Set the poll time of the BUTTON + * @param me the BUTTON itself + * @param v the poll time to set + */ +void BUTTON_setPoll_time(BUTTON* me, uint16_t v); + +#endif