commit 57162fd4e912b4c4a3c7c64b7ff2cf8ee640a63f Author: cfif Date: Wed Dec 4 13:10:49 2024 +0300 Init diff --git a/Inc/UserInputButtonWatcher.h b/Inc/UserInputButtonWatcher.h new file mode 100644 index 0000000..0c0ea9f --- /dev/null +++ b/Inc/UserInputButtonWatcher.h @@ -0,0 +1,54 @@ +// +// Created by xemon on 16.11.22. +// + +#ifndef UVEOS_ON_NATION_USERINPUTWATCHBUTTON_H +#define UVEOS_ON_NATION_USERINPUTWATCHBUTTON_H + +#include +#include "stdbool.h" +#include "stdint.h" + +#include "GpioPinInterface.h" +#include "UserInputButtonEvent.h" +#include "UserButtonsInterface.h" + +typedef struct { + tGpioPin pin; + bool state; + uint32_t begin; + uint32_t previousBegin; + bool fired; + uint16_t buttonId; +} tUserInputButtonWatch; + +typedef struct { + tUserInputButtonWatch *watches; + uint16_t watchesLimit; + uint16_t watchesCount; + uint32_t minimalDuration; + osMessageQueueId_t eventsOutQueue; +} tUserInputButtonWatcher; + +void UserInputButtonWatcher_Init( + tUserInputButtonWatcher *env, + tUserInputButtonWatch *watchesMem, + uint16_t watchesLimit, + size_t eventsQueueLength +); + +#define UserInputButtonWatcher_InitStatic(ENV, MEM, LEN) UserInputButtonWatcher_Init(ENV, MEM , sizeof(MEM)/sizeof(tUserInputButtonWatch),LEN) + +bool UserInputButtonWatcher_Add(tUserInputButtonWatcher *env, tGpioPin pin, uint16_t id); + +void UserInputButtonWatcher_Check(tUserInputButtonWatcher *env); + +void UserInputButtonWatcher_Clear(tUserInputButtonWatcher *env); + +void UserInputButtonWatcher_SimulateButton(tUserInputButtonWatcher *env, uint16_t butId); + +bool UserInputButtonWatcher_GetNext(tUserInputButtonWatcher *env, tUserInputButtonEvent *next, uint32_t timeout); + +tUserButtonsInterface UserInputButtonWatcher_GetInterface(tUserInputButtonWatcher *env); + +#endif //UVEOS_ON_NATION_USERINPUTWATCHBUTTON_H diff --git a/Src/UserInputButtonWatcher.c b/Src/UserInputButtonWatcher.c new file mode 100644 index 0000000..a372ebf --- /dev/null +++ b/Src/UserInputButtonWatcher.c @@ -0,0 +1,109 @@ +#include "UserInputButtonWatcher.h" + +void UserInputButtonWatcher_Init( + tUserInputButtonWatcher *env, + tUserInputButtonWatch *watchesMem, + uint16_t watchesLimit, + size_t eventsQueueLength +) { + env->minimalDuration = 50; + env->eventsOutQueue = osMessageQueueNew(eventsQueueLength, sizeof(tUserInputButtonEvent), NULL); + env->watchesCount = 0; + env->watches = watchesMem; + env->watchesLimit = watchesLimit; +} + +bool UserInputButtonWatcher_Add( + tUserInputButtonWatcher *env, + tGpioPin pin, + uint16_t id +) { + if (env->watchesCount >= env->watchesLimit) { + return false; + } + + tUserInputButtonWatch *next = env->watches + env->watchesCount; + + *next = (tUserInputButtonWatch) { + .begin=osKernelGetTickCount(), + .state= GpioPinGet(&pin), + .pin = pin, + .fired = true, + .buttonId = id, + }; + + ++env->watchesCount; + + return true; +} + + +void UserInputButtonWatcher_CheckButton(tUserInputButtonWatcher *env, tUserInputButtonWatch *watch, uint32_t NOW) { + bool current = GpioPinGet(&watch->pin); + + if (watch->state != current) { + if (watch->fired) { + watch->previousBegin = watch->begin; + watch->state = current; + watch->begin = NOW; + watch->fired = false; + } else { + watch->begin = watch->previousBegin; + watch->state = current; + watch->fired = true; + } + } + + if (!watch->fired) { + uint32_t currentDuration = NOW - watch->begin; + if (currentDuration > env->minimalDuration) { + + tUserInputButtonEvent event = { + .buttonId =watch->buttonId, + .duration = watch->begin - watch->previousBegin, + .action = watch->state == false ? USER_INPUT_BUTTON_ACTION_RAISE + : USER_INPUT_BUTTON_ACTION_FALL + }; + + watch->fired = true; + osMessageQueuePut(env->eventsOutQueue, &event, 0U, 100U); + } + } +} + +void UserInputButtonWatcher_SimulateButton(tUserInputButtonWatcher *env, uint16_t butId) { + tUserInputButtonEvent event = { + .buttonId = butId, + .duration = 1000, + .action = USER_INPUT_BUTTON_ACTION_RAISE + }; + + osMessageQueuePut(env->eventsOutQueue, &event, 0U, 100U); +} + +void UserInputButtonWatcher_Check(tUserInputButtonWatcher *env) { + + uint32_t NOW = osKernelGetTickCount(); + + for (uint16_t watchIdx = 0; watchIdx < env->watchesCount; ++watchIdx) { + UserInputButtonWatcher_CheckButton(env, env->watches + watchIdx, NOW); + } +} + + +void UserInputButtonWatcher_Clear(tUserInputButtonWatcher *env) { + osMessageQueueReset(env->eventsOutQueue); +} + +bool UserInputButtonWatcher_GetNext(tUserInputButtonWatcher *env, tUserInputButtonEvent *next, uint32_t timeout) { + return osMessageQueueGet(env->eventsOutQueue, next, 0, timeout) == osOK; +} + +tUserButtonsInterface UserInputButtonWatcher_GetInterface(tUserInputButtonWatcher *env) { + tUserButtonsInterface result = { + .env = env, + .clear = (userButtonsCall) UserInputButtonWatcher_Clear, + .getNextEvent = (userButtonsNextEventCall) UserInputButtonWatcher_GetNext + }; + return result; +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..665eaf7 --- /dev/null +++ b/modular.json @@ -0,0 +1,17 @@ +{ + "dep": [ + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "UserInputEvent" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file