diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml
index b239181..09f6cc3 100644
--- a/nbproject/configurations.xml
+++ b/nbproject/configurations.xml
@@ -22,8 +22,8 @@
src/mcc_generated_files/device_config.h
- src/middleware/clickHandler.h
src/middleware/blinker.h
+ src/middleware/click_handler.h
src/xf/ireactive.h
@@ -58,7 +58,7 @@
src/middleware/blinker.c
- src/middleware/clickHandler.c
+ src/middleware/click_handler.c
src/xf/xf.c
@@ -200,6 +200,9 @@
+
+
+
diff --git a/src/middleware/click_handler.c b/src/middleware/click_handler.c
new file mode 100644
index 0000000..32a227e
--- /dev/null
+++ b/src/middleware/click_handler.c
@@ -0,0 +1,177 @@
+/**
+ * @author Rémi Heredero
+ * @version 1.0.0
+ * @date July 2023
+ * @file click_handler.c
+ */
+
+#include "click_handler.h"
+
+void CLICK_HANDLER_init(CLICK_HANDLER* me){
+ me->state = STCH_INIT;
+ me->clickTimer = 250;
+ me->wait.f = NULL;
+ me->long_click.f = NULL;
+ me->single_click.f = NULL;
+ me->double_click.f = NULL;
+}
+
+void CLICK_HANDLER_startBehaviour(CLICK_HANDLER* me){
+ POST(me, &CLICK_HANDLER_processEvent, evCHinit, 0, 0);
+}
+
+bool CLICK_HANDLER_processEvent(Event* ev) {
+ bool processed = false;
+ CLICK_HANDLER* me = (CLICK_HANDLER*)Event_getTarget(ev);
+ CLICK_HANDLER_STATES oldState = me->state;
+ evIDT evid = Event_getId(ev);
+
+ switch (me->state) { // onState
+ case STCH_INIT:
+ if (ev->id == evCHinit) {
+ me->state = STCH_WAIT;
+ }
+ break;
+
+ case STCH_WAIT:
+ if(evid == evCHpbpress) {
+ me->state = STCH_LONG_CLICK;
+ CLICK_HANDLER_emitTimer(me, me->clickTimer);
+ }
+ break;
+
+ case STCH_LONG_CLICK:
+ if(evid == evCHpbrelease) {
+ me->state = STCH_SINGLE_CLICK;
+ }
+ if(evid == evCHtimer) {
+ me->state = STCH_WAIT;
+ }
+ break;
+
+ case STCH_SINGLE_CLICK:
+ if(evid == evCHpbpress) {
+ me->state = STCH_DOUBLE_CLICK;
+ }
+ if(evid == evCHtimer) {
+ me->state = STCH_WAIT;
+ }
+ break;
+
+ case STCH_DOUBLE_CLICK:
+ if(evid == evCHpbrelease) {
+ me->state = STCH_WAIT;
+ }
+ if(evid == evCHtimer) {
+ me->state = STCH_WAIT;
+ }
+ break;
+ }
+
+ if(oldState != me->state){
+ switch (oldState) { // onExit
+ case STCH_INIT:
+ break;
+
+ case STCH_WAIT:
+ break;
+
+ case STCH_LONG_CLICK:
+ if(evid == evCHtimer) {
+ if (me->long_click.f != NULL) {
+ me->long_click.f(me->long_click.p);
+ }
+ }
+ break;
+
+ case STCH_SINGLE_CLICK:
+ if(evid == evCHtimer) {
+ if (me->single_click.f != NULL) {
+ me->single_click.f(me->single_click.p);
+ }
+ }
+ break;
+
+ case STCH_DOUBLE_CLICK:
+ if(evid == evCHtimer) {
+ if(me->double_click.f != NULL) {
+ me->double_click.f(me->double_click.p);
+ }
+ }
+ if(evid == evCHpbrelease) {
+ if(me->double_click.f != NULL) {
+ me->double_click.f(me->double_click.p);
+ }
+ }
+ break;
+ }
+
+ switch (me->state) { // onEntry
+ case STCH_INIT:
+ break;
+
+ case STCH_WAIT:
+ break;
+
+ case STCH_LONG_CLICK:
+ break;
+
+ case STCH_SINGLE_CLICK:
+ break;
+
+ case STCH_DOUBLE_CLICK:
+ break;
+ }
+
+ processed = true;
+ }
+ return processed;
+}
+
+/*************
+ * Callbacks *
+ *************/
+
+void CLICK_HANDLER_onWait(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) {
+ me->wait.f = f;
+ me->wait.p = p;
+}
+
+void CLICK_HANDLER_onLong_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) {
+ me->long_click.f = f;
+ me->long_click.p = p;
+}
+
+void CLICK_HANDLER_onSingle_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) {
+ me->single_click.f = f;
+ me->single_click.p = p;
+}
+
+void CLICK_HANDLER_onDouble_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) {
+ me->double_click.f = f;
+ me->double_click.p = p;
+}
+
+/************
+ * EMITTERS *
+ ************/
+
+void CLICK_HANDLER_emitTimer(CLICK_HANDLER* me, uint16_t t) {
+ POST(me, &CLICK_HANDLER_processEvent, evCHtimer, t, 0);
+}
+
+void CLICK_HANDLER_emitPbpress(CLICK_HANDLER* me, uint16_t t) {
+ POST(me, &CLICK_HANDLER_processEvent, evCHpbpress, t, 0);
+}
+
+void CLICK_HANDLER_emitPbrelease(CLICK_HANDLER* me, uint16_t t) {
+ POST(me, &CLICK_HANDLER_processEvent, evCHpbrelease, t, 0);
+}
+
+/***********
+ * SETTERS *
+ ***********/
+
+void CLICK_HANDLER_setClickTimer(CLICK_HANDLER* me, uint16_t v) {
+ me->clickTimer = v;
+}
diff --git a/src/middleware/click_handler.h b/src/middleware/click_handler.h
new file mode 100644
index 0000000..a79b8a0
--- /dev/null
+++ b/src/middleware/click_handler.h
@@ -0,0 +1,125 @@
+/**
+ * @author Rémi Heredero
+ * @version 1.0.0
+ * @date July 2023
+ * @file click_handler.h
+ */
+#ifndef CLICK_HANDLER_H
+#define CLICK_HANDLER_H
+
+#include "../xf/xf.h"
+
+typedef enum {
+ STCH_INIT,
+ STCH_WAIT,
+ STCH_LONG_CLICK,
+ STCH_SINGLE_CLICK,
+ STCH_DOUBLE_CLICK
+} CLICK_HANDLER_STATES;
+
+typedef enum {
+ evCHinit = 100,
+ evCHtimer,
+ evCHpbpress,
+ evCHpbrelease
+} CLICK_HANDLER_EVENTS;
+
+typedef void (*CLICK_HANDLER_CALLBACK_FUNCTION)(void*);
+typedef struct {
+ CLICK_HANDLER_CALLBACK_FUNCTION f; // function
+ void* p; // param(s)
+} CLICK_HANDLER_CALLBACK;
+
+typedef struct {
+ CLICK_HANDLER_STATES state;
+ uint16_t clickTimer;
+ CLICK_HANDLER_CALLBACK wait;
+ CLICK_HANDLER_CALLBACK long_click;
+ CLICK_HANDLER_CALLBACK single_click;
+ CLICK_HANDLER_CALLBACK double_click;
+} CLICK_HANDLER;
+
+/**
+ * Initialize the CLICK_HANDLER
+ * @param me the CLICK_HANDLER itself
+ */
+void CLICK_HANDLER_init(CLICK_HANDLER* me);
+
+/**
+ * Start the CLICK_HANDLER state machine
+ * @param me the CLICK_HANDLER itself
+ */
+void CLICK_HANDLER_startBehaviour(CLICK_HANDLER* me);
+
+/**
+ * Process the event
+ * @param ev the event to process
+ * @return true if the event is processed
+ */
+bool CLICK_HANDLER_processEvent(Event* ev);
+
+/*************
+ * Callbacks *
+ *************/
+
+/**
+ * Set the callback function to call when the CLICK_HANDLER is entering state wait
+ * @param me the CLICK_HANDLER itself
+ * @param f the function to call
+ * @param p the param(s) to pass to the function
+ */
+void CLICK_HANDLER_onWait(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p);
+
+/**
+ * Set the callback function to call when the CLICK_HANDLER is entering state long_click
+ * @param me the CLICK_HANDLER itself
+ * @param f the function to call
+ * @param p the param(s) to pass to the function
+ */
+void CLICK_HANDLER_onLong_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p);
+
+/**
+ * Set the callback function to call when the CLICK_HANDLER is entering state single_click
+ * @param me the CLICK_HANDLER itself
+ * @param f the function to call
+ * @param p the param(s) to pass to the function
+ */
+void CLICK_HANDLER_onSingle_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p);
+
+/**
+ * Set the callback function to call when the CLICK_HANDLER is entering state double_click
+ * @param me the CLICK_HANDLER itself
+ * @param f the function to call
+ * @param p the param(s) to pass to the function
+ */
+void CLICK_HANDLER_onDouble_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p);
+
+/************
+ * EMITTERS *
+ ************/
+
+/**
+ * Emit the timer event
+ * @param me the CLICK_HANDLER itself
+ * @param t time to wait in ms before triggering event
+ */void CLICK_HANDLER_emitTimer(CLICK_HANDLER* me, uint16_t t);
+
+/**
+ * Emit the pbpress event
+ * @param me the CLICK_HANDLER itself
+ * @param t time to wait in ms before triggering event
+ */void CLICK_HANDLER_emitPbpress(CLICK_HANDLER* me, uint16_t t);
+
+/**
+ * Emit the pbrelease event
+ * @param me the CLICK_HANDLER itself
+ * @param t time to wait in ms before triggering event
+ */void CLICK_HANDLER_emitPbrelease(CLICK_HANDLER* me, uint16_t t);
+
+/***********
+ * SETTERS *
+ ***********/
+
+void CLICK_HANDLER_setClickTimer(CLICK_HANDLER* me, uint16_t v);
+
+#endif