2024A-SW/components/Switches/Switches.c
2025-11-23 16:01:02 -06:00

110 lines
4.2 KiB
C

/*
* This program source code file is part of the KTag project, a DIY laser tag
* game with customizable features and wide interoperability.
*
* 🛡️ <https://ktag.clubk.club> 🃞
*
* Copyright © 2024-2025 Joseph P. Kearney and the KTag developers.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* There should be a copy of the GNU Affero General Public License in the LICENSE
* file in the root of this repository. If not, see <http://www.gnu.org/licenses/>.
*/
#include <SystemK.h>
#include <driver/gpio.h>
#include <iot_button.h>
#include <freertos/FreeRTOS.h>
#include <freertos/portmacro.h>
static const char *TAG = "Switches";
// GPIO assignments
#define TRIGGER_GPIO GPIO_NUM_1
#define ACCESSORY_GPIO GPIO_NUM_4
static button_handle_t Trigger_Button;
static button_config_t Trigger_Button_Config = {
.type = BUTTON_TYPE_GPIO,
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
.gpio_button_config = {
.gpio_num = TRIGGER_GPIO,
.active_level = 0,
},
};
static button_handle_t Accessory_Button;
static button_config_t Accessory_Button_Config = {
.type = BUTTON_TYPE_GPIO,
.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
.gpio_button_config = {
.gpio_num = ACCESSORY_GPIO,
.active_level = 0,
},
};
static TickType_t TicksAtTriggerPress = 0;
static TickType_t TicksAtAccessoryPress = 0;
static TickType_t TicksAtAccessoryRelease = 0;
static void trigger_press_cb(void *arg, void *usr_data)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
TicksAtTriggerPress = xTaskGetTickCountFromISR();
KEvent_T switch_event = {.ID = KEVENT_TRIGGER_SWITCH_PRESSED, .Data = NULL};
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
}
static void trigger_release_cb(void *arg, void *usr_data)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
uint32_t triggerPressDurationInms = pdTICKS_TO_MS(xTaskGetTickCountFromISR() - TicksAtTriggerPress);
KEvent_T switch_event = {.ID = KEVENT_TRIGGER_SWITCH_RELEASED, .Data = (void *) triggerPressDurationInms};
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
}
static void accessory_press_cb(void *arg, void *usr_data)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
TicksAtAccessoryPress = xTaskGetTickCountFromISR();
uint32_t accessoryTimeReleasedInms = pdTICKS_TO_MS(xTaskGetTickCountFromISR() - TicksAtAccessoryRelease);
KEvent_T switch_event = {.ID = KEVENT_ACCESSORY_SWITCH_PRESSED, .Data = (void *) accessoryTimeReleasedInms};
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
}
static void accessory_release_cb(void *arg, void *usr_data)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
TicksAtAccessoryRelease = xTaskGetTickCountFromISR();
uint32_t accessoryPressDurationInms = pdTICKS_TO_MS(xTaskGetTickCountFromISR() - TicksAtAccessoryPress);
KEvent_T switch_event = {.ID = KEVENT_ACCESSORY_SWITCH_RELEASED, .Data = (void *) accessoryPressDurationInms};
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
}
void Initialize_Switches(void)
{
KLOG_INFO(TAG, "Initializing Switches...");
Trigger_Button = iot_button_create(&Trigger_Button_Config);
assert(Trigger_Button);
Accessory_Button = iot_button_create(&Accessory_Button_Config);
assert(Accessory_Button);
iot_button_register_cb(Trigger_Button, BUTTON_PRESS_DOWN, trigger_press_cb, NULL);
iot_button_register_cb(Trigger_Button, BUTTON_PRESS_UP, trigger_release_cb, NULL);
iot_button_register_cb(Accessory_Button, BUTTON_PRESS_DOWN, accessory_press_cb, NULL);
iot_button_register_cb(Accessory_Button, BUTTON_PRESS_UP, accessory_release_cb, NULL);
}