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