This commit is contained in:
cfif 2024-12-04 13:10:49 +03:00
commit 57162fd4e9
3 changed files with 180 additions and 0 deletions

View File

@ -0,0 +1,54 @@
//
// Created by xemon on 16.11.22.
//
#ifndef UVEOS_ON_NATION_USERINPUTWATCHBUTTON_H
#define UVEOS_ON_NATION_USERINPUTWATCHBUTTON_H
#include <cmsis_os.h>
#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

View File

@ -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;
}

17
modular.json Normal file
View File

@ -0,0 +1,17 @@
{
"dep": [
{
"type": "git",
"provider": "NAVIGATOR_UVEOS_NATION_TELIT",
"repo": "UserInputEvent"
}
],
"cmake": {
"inc_dirs": [
"Inc"
],
"srcs": [
"Src/**.c"
]
}
}