Compare commits

...

2 commits

Author SHA1 Message Date
Joe Kearney
138cf30b23 Resolved a problem double-receiving IR packets. 2025-03-22 14:30:25 -05:00
Joe Kearney
0ac0b4e330 Bumped versions. 2025-03-22 12:29:09 -05:00
5 changed files with 128 additions and 15 deletions

View file

@ -1,3 +1,25 @@
/*
* 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 <SystemK.h>
#include <driver/gpio.h> #include <driver/gpio.h>
#include <driver/rmt_tx.h> #include <driver/rmt_tx.h>
@ -53,6 +75,11 @@ static TimedPulseTrain_T Left_Rxd_RMT_Data;
static TimedPulseTrain_T Forward_Rxd_RMT_Data; static TimedPulseTrain_T Forward_Rxd_RMT_Data;
static TimedPulseTrain_T Right_Rxd_RMT_Data; static TimedPulseTrain_T Right_Rxd_RMT_Data;
volatile TickType_t Last_Time_Checked_In_Ticks = 0;
TagSensorLocation_T Active_Tag_Sensor = TAG_SENSOR_NONE;
SemaphoreHandle_t Tag_Sensor_Mutex;
static const TickType_t LOCKOUT_TIME_IN_TICKS = pdMS_TO_TICKS(100);
#define IR_RX_STACK_SIZE 4096 #define IR_RX_STACK_SIZE 4096
static StaticTask_t xTaskBuffer; static StaticTask_t xTaskBuffer;
static StackType_t xStack[IR_RX_STACK_SIZE]; static StackType_t xStack[IR_RX_STACK_SIZE];
@ -66,14 +93,45 @@ typedef struct
TagSensorLocation_T location; TagSensorLocation_T location;
} RxNotification_T; } RxNotification_T;
// Prevent double-receiving (or triple-receiving!) IR packets by locking out the other sensors for a short time once one sensor becomes active.
// A sensor is allowed if it is the already-active sensor or the lockout period has expired.
static BaseType_t Is_Sensor_Allowed(TagSensorLocation_T sensor_location, BaseType_t *xHigherPriorityTaskWoken)
{
BaseType_t is_allowed = pdFALSE;
TickType_t current_time_in_ticks = xTaskGetTickCountFromISR();
if (xSemaphoreTakeFromISR(Tag_Sensor_Mutex, xHigherPriorityTaskWoken) == pdTRUE)
{
if ((Active_Tag_Sensor != TAG_SENSOR_NONE) && (Active_Tag_Sensor != sensor_location) &&
((current_time_in_ticks - Last_Time_Checked_In_Ticks) < LOCKOUT_TIME_IN_TICKS))
{
// We're in lockout period and this is not the active sensor--ignore this sensor.
is_allowed = pdFALSE;
}
else
{
// It's OK to allow this sensor.
Active_Tag_Sensor = sensor_location;
Last_Time_Checked_In_Ticks = current_time_in_ticks;
is_allowed = pdTRUE;
}
xSemaphoreGiveFromISR(Tag_Sensor_Mutex, xHigherPriorityTaskWoken);
}
return is_allowed;
}
static bool RMT_Rx_Left_Done_Callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data) static bool RMT_Rx_Left_Done_Callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data)
{ {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
RxNotification_T notice;
notice.count = edata->num_symbols * 2; if (Is_Sensor_Allowed(TAG_SENSOR_LEFT, &xHigherPriorityTaskWoken) == pdTRUE)
notice.location = TAG_SENSOR_LEFT; {
RxNotification_T notice = {.count = edata->num_symbols * 2,
.location = TAG_SENSOR_LEFT};
xQueueSendFromISR(Receive_Queue, &notice, &xHigherPriorityTaskWoken); xQueueSendFromISR(Receive_Queue, &notice, &xHigherPriorityTaskWoken);
}
return xHigherPriorityTaskWoken; return xHigherPriorityTaskWoken;
} }
@ -81,11 +139,13 @@ static bool RMT_Rx_Left_Done_Callback(rmt_channel_handle_t channel, const rmt_rx
static bool RMT_Rx_Forward_Done_Callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data) static bool RMT_Rx_Forward_Done_Callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data)
{ {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
RxNotification_T notice;
notice.count = edata->num_symbols * 2; if (Is_Sensor_Allowed(TAG_SENSOR_FORWARD, &xHigherPriorityTaskWoken) == pdTRUE)
notice.location = TAG_SENSOR_FORWARD; {
RxNotification_T notice = {.count = edata->num_symbols * 2,
.location = TAG_SENSOR_FORWARD};
xQueueSendFromISR(Receive_Queue, &notice, &xHigherPriorityTaskWoken); xQueueSendFromISR(Receive_Queue, &notice, &xHigherPriorityTaskWoken);
}
return xHigherPriorityTaskWoken; return xHigherPriorityTaskWoken;
} }
@ -93,11 +153,13 @@ static bool RMT_Rx_Forward_Done_Callback(rmt_channel_handle_t channel, const rmt
static bool RMT_Rx_Right_Done_Callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data) static bool RMT_Rx_Right_Done_Callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data)
{ {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
RxNotification_T notice;
notice.count = edata->num_symbols * 2; if (Is_Sensor_Allowed(TAG_SENSOR_RIGHT, &xHigherPriorityTaskWoken) == pdTRUE)
notice.location = TAG_SENSOR_RIGHT; {
RxNotification_T notice = {.count = edata->num_symbols * 2,
.location = TAG_SENSOR_RIGHT};
xQueueSendFromISR(Receive_Queue, &notice, &xHigherPriorityTaskWoken); xQueueSendFromISR(Receive_Queue, &notice, &xHigherPriorityTaskWoken);
}
return xHigherPriorityTaskWoken; return xHigherPriorityTaskWoken;
} }
@ -186,6 +248,13 @@ static void IR_Receive_Task(void *param)
static void Initialize_Receive_Task(void) static void Initialize_Receive_Task(void)
{ {
Tag_Sensor_Mutex = xSemaphoreCreateMutex();
if (Tag_Sensor_Mutex == NULL)
{
KLOG_ERROR(TAG, "Failed to create tag sensor mutex!");
}
IR_Rx_Task_Handle = xTaskCreateStaticPinnedToCore( IR_Rx_Task_Handle = xTaskCreateStaticPinnedToCore(
IR_Receive_Task, // Function that implements the task. IR_Receive_Task, // Function that implements the task.
"IR Rx", // Text name for the task. "IR Rx", // Text name for the task.

View file

@ -1,3 +1,25 @@
/*
* 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 "esp_err.h" #include "esp_err.h"
void Initialize_IR(SemaphoreHandle_t init_complete); void Initialize_IR(SemaphoreHandle_t init_complete);

@ -1 +1 @@
Subproject commit c11206e6255fef994c826fb446a234132571af4f Subproject commit cb7204269140ba9c6dbe44ca5a5dbaf8c031f685

View file

@ -1,8 +1,30 @@
/*
* 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/>.
*/
#ifndef VERSION_H #ifndef VERSION_H
#define VERSION_H #define VERSION_H
#define VERSION_MAJOR 00 #define VERSION_MAJOR 00
#define VERSION_MINOR 38 #define VERSION_MINOR 39
#define STRINGIFY(number) #number #define STRINGIFY(number) #number
#define VERSION_STRING(major, minor) STRINGIFY(major) "." STRINGIFY(minor) #define VERSION_STRING(major, minor) STRINGIFY(major) "." STRINGIFY(minor)

View file

@ -1 +1 @@
Welcome to KTag! SPIFFS version 00.38 Welcome to KTag! SPIFFS version 00.39