Advanced Distributed Systems module at HSLU
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

186 lines
5.4 KiB

/*
* Copyright (c) 2022, Erich Styger
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include "debounce.h"
#include "McuDebounce.h"
#include "McuRTOS.h"
#include "buttons.h"
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
#include "McuSystemView.h"
#endif
#include "application.h"
static void OnDebounceEvent(McuDbnc_EventKinds event, uint32_t buttons);
#define TIMER_PERIOD_MS 20 /* frequency of debouncing timer */
#define EVENT_QUEUE_LENGTH (5) /* number of elements in queue */
#define EVENT_QUEUE_ELEM_SIZE (sizeof(Debounce_event_e)) /* size of a queue item */
static QueueHandle_t eventQueue; /* queue handle */
static McuDbnc_Desc_t data =
{
.state = MCUDBMC_STATE_IDLE, /* state of state machine */
.timerPeriodMs = TIMER_PERIOD_MS, /* timer period for debouncing */
.timer = NULL, /* FreeRTOS timer handle */
.debounceTimeMs = 100, /* debouncing time */
.repeatTimeMs = 200, /* time for repeated button events */
.longKeyTimeMs = 1000, /* time for a long key press */
.getButtons = BTN_GetButtons, /* callback to get bitset of buttons */
.onDebounceEvent = OnDebounceEvent, /* debounce event handler */
};
static void vQueueButtonEvent(Debounce_event_e btn){
if(xQueueSendToBack(eventQueue, &btn, pdMS_TO_TICKS(100)) != pdPASS){
printf("Failed adding Button event to eventQueue. Maybe queue is full?");
}
}
static void OnDebounceEvent(McuDbnc_EventKinds event, uint32_t buttons) {
switch(event) {
case MCUDBNC_EVENT_PRESSED:
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
SEGGER_SYSVIEW_PrintfTarget("pressed, buttons %d:\n", buttons);
#endif
if (buttons&BTN_BIT_NAV_LEFT) {
vQueueButtonEvent(Button_Left_Pressed);
}
if (buttons&BTN_BIT_NAV_RIGHT) {
vQueueButtonEvent(Button_Right_Pressed);
}
if (buttons&BTN_BIT_NAV_UP) {
vQueueButtonEvent(Button_Up_Pressed);
}
if (buttons&BTN_BIT_NAV_DOWN) {
vQueueButtonEvent(Button_Down_Pressed);
}
if (buttons&BTN_BIT_NAV_CENTER) {
vQueueButtonEvent(Button_Center_Pressed);
}
break;
case MCUDBNC_EVENT_PRESSED_REPEAT:
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
SEGGER_SYSVIEW_PrintfTarget("pressed repeat, buttons %d:\n", buttons);
#endif
if (buttons&BTN_BIT_NAV_LEFT) {
vQueueButtonEvent(Button_LeftRepeat_Pressed);
}
if (buttons&BTN_BIT_NAV_RIGHT) {
vQueueButtonEvent(Button_RightRepeat_Pressed);
}
if (buttons&BTN_BIT_NAV_UP) {
vQueueButtonEvent(Button_UpRepeat_Pressed);
}
if (buttons&BTN_BIT_NAV_DOWN) {
vQueueButtonEvent(Button_DownRepeat_Pressed);
}
if (buttons&BTN_BIT_NAV_CENTER) {
vQueueButtonEvent(Button_CenterRepeat_Pressed);
}
break;
case MCUDBNC_EVENT_LONG_PRESSED:
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
SEGGER_SYSVIEW_PrintfTarget("pressed long, buttons %d:\n", buttons);
#endif
break;
case MCUDBNC_EVENT_LONG_PRESSED_REPEAT:
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
SEGGER_SYSVIEW_PrintfTarget("pressed long repeat, buttons %d:\n", buttons);
#endif
break;
case MCUDBNC_EVENT_RELEASED:
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
SEGGER_SYSVIEW_PrintfTarget("released, buttons %d:\n", buttons);
if (buttons&BTN_BIT_NAV_LEFT) {
vQueueButtonEvent(Button_Left_Released);
}
if (buttons&BTN_BIT_NAV_RIGHT) {
vQueueButtonEvent(Button_Right_Released);
}
if (buttons&BTN_BIT_NAV_UP) {
vQueueButtonEvent(Button_Up_Released);
}
if (buttons&BTN_BIT_NAV_DOWN) {
vQueueButtonEvent(Button_Down_Released);
}
if (buttons&BTN_BIT_NAV_CENTER) {
vQueueButtonEvent(Button_Center_Released);
}
#endif
break;
case MCUDBNC_EVENT_LONG_RELEASED:
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
SEGGER_SYSVIEW_PrintfTarget("long released, buttons %d:\n", buttons);
#endif
break;
case MCUDBNC_EVENT_END:
#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS
SEGGER_SYSVIEW_PrintfTarget("stopped debouncing\n");
#endif
(void)xTimerStop(data.timer, pdMS_TO_TICKS(100)); /* stop timer */
break;
default:
break;
}
}
static void vTimerCallbackDebounce(TimerHandle_t pxTimer) {
/* called with TIMER_PERIOD_MS during debouncing */
McuDbnc_Process(&data);
}
void Debounce_StartDebounce(uint32_t buttons) {
if (data.state==MCUDBMC_STATE_IDLE) {
data.scanValue = buttons;
data.state = MCUDBMC_STATE_START;
McuDbnc_Process(&data);
(void)xTimerStart(data.timer, pdMS_TO_TICKS(100));
}
}
void Debounce_StartDebounceFromISR(uint32_t buttons, BaseType_t *pxHigherPriorityTaskWoken) {
if (data.state==MCUDBMC_STATE_IDLE) {
data.scanValue = buttons;
data.state = MCUDBMC_STATE_START;
McuDbnc_Process(&data);
(void)xTimerStartFromISR(data.timer, pxHigherPriorityTaskWoken);
}
}
QueueHandle_t Debounce_GetEventQueueHandle() {
return eventQueue;
}
void Debounce_Deinit(void) {
/* nothing needed */
}
void Debounce_Init(void) {
// initialize debounce and timer
McuDbnc_Init();
data.timer = xTimerCreate(
"tmrDbnc", /* name */
pdMS_TO_TICKS(TIMER_PERIOD_MS), /* period/time */
pdTRUE, /* auto reload */
(void*)0, /* timer ID */
vTimerCallbackDebounce); /* callback */
if (data.timer==NULL) {
for(;;); /* failure! */
}
// initialize queue
eventQueue = xQueueCreate(EVENT_QUEUE_LENGTH, EVENT_QUEUE_ELEM_SIZE);
if(eventQueue == NULL){
for(;;); /* out of memory? */
}
vQueueAddToRegistry(eventQueue, "eventQueue");
}