109 lines
3.3 KiB
C
109 lines
3.3 KiB
C
#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;
|
|
} |