32ESPecial Version 1.00 (#9)
This release reworked the initialization code to provide more robust initialization, especially when no USB stick is present. It incorporates [Version 1.0 of SystemK](Software/SystemK#9). This is the first release for the [32ESPecial Blaster Kits](https://link.clubk.club/2025002). Co-authored-by: Joe Kearney <joe@clubk.club> Reviewed-on: #9
This commit is contained in:
parent
14ec8fe280
commit
e12ee17973
67 changed files with 1232 additions and 649 deletions
|
|
@ -5,6 +5,7 @@ idf_component_register(
|
|||
"."
|
||||
REQUIRES
|
||||
"SystemK"
|
||||
"System_Events"
|
||||
"driver"
|
||||
"spiffs"
|
||||
"esp-audio-player"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,27 @@
|
|||
/*
|
||||
* 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 <System_Events.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -149,6 +172,9 @@ void Initialize_Audio(void)
|
|||
{
|
||||
KLOG_ERROR(TAG, "Couldn't create the I2S Audio task.");
|
||||
}
|
||||
|
||||
xEventGroupSetBits(Get_System_Events(), SYS_AUDIO_READY);
|
||||
KLOG_INFO(TAG, "Initialization complete.");
|
||||
}
|
||||
|
||||
esp_err_t Play_Audio_File(const char *filename)
|
||||
|
|
@ -245,21 +271,37 @@ SystemKResult_T Play_Sound_By_Prefix(const char *prefix)
|
|||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
|
||||
|
||||
const char *sounds_dir = "/usb/01";
|
||||
// Check for USB audio files.
|
||||
EventBits_t bits = xEventGroupWaitBits(
|
||||
Get_System_Events(),
|
||||
SYS_USB_FS_PRESENT,
|
||||
pdFALSE,
|
||||
pdTRUE,
|
||||
0);
|
||||
|
||||
char *filename = find_filename(sounds_dir, prefix);
|
||||
|
||||
if (filename != NULL)
|
||||
if ((bits & SYS_USB_FS_PRESENT) == 0)
|
||||
{
|
||||
if (audio_player_get_state() == AUDIO_PLAYER_STATE_PLAYING)
|
||||
{
|
||||
audio_player_stop();
|
||||
}
|
||||
Play_Audio_File(concat_path(sounds_dir, filename));
|
||||
KLOG_ERROR(TAG, "USB file system not present!");
|
||||
result = SYSTEMK_RESULT_FILESYSTEM_NOT_PRESENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SYSTEMK_RESULT_FILE_NOT_FOUND;
|
||||
const char *sounds_dir = "/usb/01";
|
||||
|
||||
char *filename = find_filename(sounds_dir, prefix);
|
||||
|
||||
if (filename != NULL)
|
||||
{
|
||||
if (audio_player_get_state() == AUDIO_PLAYER_STATE_PLAYING)
|
||||
{
|
||||
audio_player_stop();
|
||||
}
|
||||
Play_Audio_File(concat_path(sounds_dir, filename));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SYSTEMK_RESULT_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -304,6 +346,7 @@ void I2SAudioTask(void *pvParameters)
|
|||
|
||||
if (xQueueReceive(xQueueAudio, &action, portMAX_DELAY) == pdPASS)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
|
||||
|
||||
switch (action.ID)
|
||||
{
|
||||
|
|
@ -318,23 +361,23 @@ void I2SAudioTask(void *pvParameters)
|
|||
break;
|
||||
|
||||
case AUDIO_PLAY_STARTUP_SOUND:
|
||||
Play_Sound_By_Prefix("001");
|
||||
result = Play_Sound_By_Prefix("001");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_SHOT_FIRED:
|
||||
Play_Sound_By_Prefix("002");
|
||||
result = Play_Sound_By_Prefix("002");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_TAG_RECEIVED:
|
||||
Play_Sound_By_Prefix("003");
|
||||
result = Play_Sound_By_Prefix("003");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_TAGGED_OUT:
|
||||
Play_Sound_By_Prefix("004");
|
||||
result = Play_Sound_By_Prefix("004");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_MISFIRE:
|
||||
Play_Sound_By_Prefix("005");
|
||||
result = Play_Sound_By_Prefix("005");
|
||||
break;
|
||||
|
||||
case AUDIO_PRONOUNCE_NUMBER_0_TO_100:
|
||||
|
|
@ -347,116 +390,124 @@ void I2SAudioTask(void *pvParameters)
|
|||
{
|
||||
number = 101;
|
||||
}
|
||||
Play_Number_Sound(number);
|
||||
result = Play_Number_Sound(number);
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_MENU_PROMPT:
|
||||
Play_Sound_By_Prefix("006");
|
||||
result = Play_Sound_By_Prefix("006");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_SELECTION_INDICATOR:
|
||||
Play_Sound_By_Prefix("007");
|
||||
result = Play_Sound_By_Prefix("007");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_HEALTH_REMAINING:
|
||||
Play_Sound_By_Prefix("008");
|
||||
result = Play_Sound_By_Prefix("008");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_ELECTRONIC_DANCE_MUSIC:
|
||||
Play_Sound_By_Prefix("009");
|
||||
result = Play_Sound_By_Prefix("009");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_GENERIC_ERROR:
|
||||
Play_Sound_By_Prefix("010");
|
||||
result = Play_Sound_By_Prefix("010");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_VOLUME_PROMPT:
|
||||
Play_Sound_By_Prefix("011");
|
||||
result = Play_Sound_By_Prefix("011");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_RIGHT_HANDED:
|
||||
Play_Sound_By_Prefix("012");
|
||||
result = Play_Sound_By_Prefix("012");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_LEFT_HANDED:
|
||||
Play_Sound_By_Prefix("013");
|
||||
result = Play_Sound_By_Prefix("013");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_GAME_ON:
|
||||
Play_Sound_By_Prefix("014");
|
||||
result = Play_Sound_By_Prefix("014");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_HARDWARE_SETTINGS_PROMPT:
|
||||
Play_Sound_By_Prefix("015");
|
||||
result = Play_Sound_By_Prefix("015");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_GAME_SETTINGS_PROMPT:
|
||||
Play_Sound_By_Prefix("016");
|
||||
result = Play_Sound_By_Prefix("016");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_BONK:
|
||||
Play_Sound_By_Prefix("017");
|
||||
result = Play_Sound_By_Prefix("017");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_NEAR_MISS:
|
||||
Play_Sound_By_Prefix("018");
|
||||
result = Play_Sound_By_Prefix("018");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_PLAYER_ID_PROMPT:
|
||||
Play_Sound_By_Prefix("019");
|
||||
result = Play_Sound_By_Prefix("019");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_TEAM_ID_PROMPT:
|
||||
Play_Sound_By_Prefix("020");
|
||||
result = Play_Sound_By_Prefix("020");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_FRIENDLY_FIRE:
|
||||
KLOG_WARN(TAG, "\"Friendly Fire\" audio is disabled in this build.");
|
||||
//Play_Sound_By_Prefix("021");
|
||||
// result = Play_Sound_By_Prefix("021");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_STARTING_THEME:
|
||||
Play_Sound_By_Prefix("022");
|
||||
result = Play_Sound_By_Prefix("022");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_BOOP:
|
||||
Play_Sound_By_Prefix("023");
|
||||
result = Play_Sound_By_Prefix("023");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_BEEP:
|
||||
Play_Sound_By_Prefix("024");
|
||||
result = Play_Sound_By_Prefix("024");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_REPROGRAMMING:
|
||||
Play_Sound_By_Prefix("025");
|
||||
result = Play_Sound_By_Prefix("025");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_BOMB:
|
||||
Play_Sound_By_Prefix("026");
|
||||
result = Play_Sound_By_Prefix("026");
|
||||
break;
|
||||
|
||||
case AUDIO_PLAY_GAME_OVER:
|
||||
Play_Sound_By_Prefix("027");
|
||||
result = Play_Sound_By_Prefix("027");
|
||||
break;
|
||||
|
||||
default:
|
||||
Play_Audio_File("/spiffs/bad.wav");
|
||||
Play_Audio_File("/spiffs/KTag_broken.mp3");
|
||||
break;
|
||||
}
|
||||
|
||||
if (action.Play_To_Completion == true)
|
||||
if (result == SYSTEMK_RESULT_FILESYSTEM_NOT_PRESENT)
|
||||
{
|
||||
// Allow some time for the audio to start.
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
while (audio_player_get_state() != AUDIO_PLAYER_STATE_IDLE)
|
||||
result = Play_Audio_File("/spiffs/KTag_broken.mp3");
|
||||
}
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
if (action.Play_To_Completion == true)
|
||||
{
|
||||
// Allow some time for the audio to start.
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
KEvent_T command_received_event = {.ID = KEVENT_AUDIO_COMPLETED, .Data = (void *)action.ID};
|
||||
Post_KEvent(&command_received_event);
|
||||
while (audio_player_get_state() != AUDIO_PLAYER_STATE_IDLE)
|
||||
{
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
KEvent_T command_received_event = {.ID = KEVENT_AUDIO_COMPLETED, .Data = (void *)action.ID};
|
||||
Post_KEvent(&command_received_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,26 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
void Initialize_Audio(void);
|
||||
esp_err_t Play_WAV_File(char * filename);
|
||||
esp_err_t Play_WAV_File(char * filename);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,27 @@
|
|||
/*
|
||||
* 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 <System_Events.h>
|
||||
#include "esp_log.h"
|
||||
/* BLE */
|
||||
#include "esp_nimble_hci.h"
|
||||
|
|
@ -204,6 +227,9 @@ void Initialize_BLE(void)
|
|||
ble_store_config_init();
|
||||
|
||||
nimble_port_freertos_init(ble_host_task);
|
||||
|
||||
xEventGroupSetBits(Get_System_Events(), SYS_BLE_READY);
|
||||
KLOG_INFO(TAG, "Initialization complete.");
|
||||
}
|
||||
|
||||
void Disable_BLE(void)
|
||||
|
|
@ -453,4 +479,4 @@ SystemKResult_T BLE_Unquiet(void)
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,26 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
void Initialize_BLE(void);
|
||||
void Disable_BLE(void);
|
||||
void Disable_BLE(void);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ idf_component_register(
|
|||
"."
|
||||
REQUIRES
|
||||
"SystemK"
|
||||
"System_Events"
|
||||
"driver"
|
||||
"bt"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ idf_component_register(
|
|||
"."
|
||||
REQUIRES
|
||||
"SystemK"
|
||||
"System_Events"
|
||||
"driver"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include <SystemK.h>
|
||||
#include <System_Events.h>
|
||||
#include <IR.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/rmt_tx.h>
|
||||
|
|
@ -272,7 +273,7 @@ static void Initialize_Receive_Task(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Initialize_IR(SemaphoreHandle_t init_complete)
|
||||
void Initialize_IR()
|
||||
{
|
||||
KLOG_INFO(TAG, "Initializing IR...");
|
||||
|
||||
|
|
@ -375,7 +376,8 @@ void Initialize_IR(SemaphoreHandle_t init_complete)
|
|||
ESP_ERROR_CHECK(rmt_enable(Right_Rx_Channel));
|
||||
ESP_ERROR_CHECK(rmt_receive(Right_Rx_Channel, &Right_Rxd_RMT_Data, sizeof(Right_Rxd_RMT_Data.pulsetrain), &Rx_Config));
|
||||
|
||||
xSemaphoreGive(init_complete);
|
||||
xEventGroupSetBits(Get_System_Events(), SYS_IR_READY);
|
||||
KLOG_INFO(TAG, "Initialization complete.");
|
||||
}
|
||||
|
||||
static inline void PrintPulseTrainToConsole(TimedPulseTrain_T *train)
|
||||
|
|
@ -440,4 +442,4 @@ void Disable_IR_Transmit()
|
|||
{
|
||||
gpio_set_level(IR_TX_RIGHT_ENABLE, 1);
|
||||
gpio_set_level(IR_TX_LEFT_ENABLE, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,6 @@
|
|||
|
||||
#include "esp_err.h"
|
||||
|
||||
void Initialize_IR(SemaphoreHandle_t init_complete);
|
||||
void Initialize_IR();
|
||||
void Enable_IR_Transmit();
|
||||
void Disable_IR_Transmit();
|
||||
void Disable_IR_Transmit();
|
||||
|
|
|
|||
|
|
@ -94,4 +94,3 @@ esp_err_t muxed_led_strip_del(muxed_led_strip_handle_t strip)
|
|||
ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
return strip->del(strip);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ idf_component_register(
|
|||
"."
|
||||
REQUIRES
|
||||
"SystemK"
|
||||
"System_Events"
|
||||
"spiffs"
|
||||
"driver"
|
||||
"usb"
|
||||
|
|
|
|||
|
|
@ -30,4 +30,4 @@ SystemKResult_T KV_Get_Value_uint32(const char *filename, const char *search_key
|
|||
SystemKResult_T KV_Set_Value_uint32(const char *filename, const char *set_key, uint32_t *set_value);
|
||||
|
||||
SystemKResult_T KV_Get_Value_uint8(const char *filename, const char *search_key, uint8_t *value);
|
||||
SystemKResult_T KV_Set_Value_uint8(const char *filename, const char *set_key, uint8_t *set_value);
|
||||
SystemKResult_T KV_Set_Value_uint8(const char *filename, const char *set_key, uint8_t *set_value);
|
||||
|
|
|
|||
|
|
@ -24,3 +24,5 @@
|
|||
#include "Key_Value.h"
|
||||
#include "SPIFFS.h"
|
||||
#include "USB.h"
|
||||
|
||||
SystemKResult_T Initialize_Settings(void);
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@
|
|||
*/
|
||||
|
||||
#include <SystemK.h>
|
||||
#include <System_Events.h>
|
||||
#include <string.h>
|
||||
#include "esp_spiffs.h"
|
||||
|
||||
static const char *TAG = "SPIFFS";
|
||||
const char *DEFAULT_CONFIG_FILE = "/spiffs/default_config.txt";
|
||||
|
||||
void Initialize_SPIFFS(SemaphoreHandle_t init_complete)
|
||||
void Initialize_SPIFFS(void)
|
||||
{
|
||||
KLOG_INFO(TAG, "Initializing SPI flash file system (SPIFFS)...");
|
||||
|
||||
|
|
@ -80,5 +81,7 @@ void Initialize_SPIFFS(SemaphoreHandle_t init_complete)
|
|||
fclose(f);
|
||||
|
||||
KLOG_INFO(TAG, ">>> %s <<<", buf);
|
||||
xSemaphoreGive(init_complete);
|
||||
}
|
||||
|
||||
xEventGroupSetBits(Get_System_Events(), SYS_SPIFFS_READY);
|
||||
KLOG_INFO(TAG, "SPIFFS initialized.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
void Initialize_SPIFFS(SemaphoreHandle_t init_complete);
|
||||
void Initialize_SPIFFS(void);
|
||||
|
||||
extern const char *DEFAULT_CONFIG_FILE;
|
||||
extern const char *DEFAULT_CONFIG_FILE;
|
||||
|
|
|
|||
|
|
@ -21,95 +21,73 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <SystemK.h>
|
||||
#include <System_Events.h>
|
||||
#include <NVM.h>
|
||||
|
||||
static const uint8_t UNINTIALIZED_UINT8 = UINT8_MAX;
|
||||
static const char *TAG = "Settings";
|
||||
|
||||
// Cache variable declarations
|
||||
// 1 if this device is configured for a right-handed player, 0 otherwise.
|
||||
static uint8_t Cached_Is_Right_Handed = 1;
|
||||
// Value from CONFIG_KTAG_MIN_AUDIO_VOLUME to CONFIG_KTAG_MAX_AUDIO_VOLUME representing the current volume.
|
||||
static uint8_t Cached_Audio_Volume = CONFIG_KTAG_MAX_AUDIO_VOLUME;
|
||||
// Selected team.
|
||||
static uint8_t Cached_Team_ID = BASIC_TEAMS_MINIMUM;
|
||||
// Unique-per-team identification of a player.
|
||||
static uint8_t Cached_Player_ID = 0;
|
||||
// Selected weapon.
|
||||
static uint8_t Cached_Weapon_ID = DUBUQUE_PROTOCOL_ID;
|
||||
// Maximum health for the game.
|
||||
static uint8_t Cached_Max_Health = 100;
|
||||
// Number of special weapons (currently only bombs) obtained when reentering after being tagged out.
|
||||
static uint8_t Cached_N_Special_Weapons_On_Reentry = 1;
|
||||
// Time (in milliseconds) after starting a game before the countdown begins.
|
||||
static uint32_t Cached_T_Start_Game_in_ms = 30000;
|
||||
// Duration of a game (in milliseconds). If this is zero or UINT32_MAX, the game is untimed.
|
||||
static uint32_t Cached_T_Game_Length_in_ms = 600000;
|
||||
// Color in addition to the team color used to identify a player's device. The format is Brightness-Red-Green-Blue, where a brightness of 0xFF indicates a false flag.
|
||||
static uint32_t Cached_Secondary_Color = 0xFE000000;
|
||||
|
||||
static uint8_t Cached_Team_ID = UNINTIALIZED_UINT8;
|
||||
static uint8_t Cached_Player_ID = UNINTIALIZED_UINT8;
|
||||
static uint8_t Cached_Weapon_ID = UNINTIALIZED_UINT8;
|
||||
static uint8_t Cached_Max_Health = UNINTIALIZED_UINT8;
|
||||
static uint8_t Cached_N_Special_Weapons_On_Reentry = UNINTIALIZED_UINT8;
|
||||
|
||||
SystemKResult_T SETTINGS_get_uint8_t(SystemKSettingID_T id, uint8_t *value)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_UNSPECIFIED_FAILURE;
|
||||
char *key = "";
|
||||
uint8_t *cached_value = NULL;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case SYSTEMK_SETTING_IS_RIGHT_HANDED:
|
||||
key = "Is_Right_Handed";
|
||||
*value = Cached_Is_Right_Handed;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_AUDIO_VOLUME:
|
||||
key = "Audio_Volume";
|
||||
*value = Cached_Audio_Volume;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_TEAMID:
|
||||
if (Cached_Team_ID != UNINTIALIZED_UINT8)
|
||||
{
|
||||
*value = Cached_Team_ID;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = "Team_ID";
|
||||
cached_value = &Cached_Team_ID;
|
||||
}
|
||||
*value = Cached_Team_ID;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_PLAYERID:
|
||||
if (Cached_Player_ID != UNINTIALIZED_UINT8)
|
||||
{
|
||||
*value = Cached_Player_ID;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = "Player_ID";
|
||||
cached_value = &Cached_Player_ID;
|
||||
}
|
||||
*value = Cached_Player_ID;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_WEAPONID:
|
||||
if (Cached_Weapon_ID != UNINTIALIZED_UINT8)
|
||||
{
|
||||
*value = Cached_Weapon_ID;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = "Weapon_ID";
|
||||
cached_value = &Cached_Weapon_ID;
|
||||
}
|
||||
*value = Cached_Weapon_ID;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_MAX_HEALTH:
|
||||
if (Cached_Max_Health != UNINTIALIZED_UINT8)
|
||||
{
|
||||
*value = Cached_Max_Health;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = "Max_Health";
|
||||
cached_value = &Cached_Max_Health;
|
||||
}
|
||||
*value = Cached_Max_Health;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_N_SPECIAL_WEAPONS_ON_REENTRY:
|
||||
if (Cached_N_Special_Weapons_On_Reentry != UNINTIALIZED_UINT8)
|
||||
{
|
||||
*value = Cached_N_Special_Weapons_On_Reentry;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = "N_Special_Weapons_On_Reentry";
|
||||
cached_value = &Cached_N_Special_Weapons_On_Reentry;
|
||||
}
|
||||
*value = Cached_N_Special_Weapons_On_Reentry;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -117,30 +95,10 @@ SystemKResult_T SETTINGS_get_uint8_t(SystemKSettingID_T id, uint8_t *value)
|
|||
break;
|
||||
}
|
||||
|
||||
if (result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = KV_Get_Value_uint8(CONFIG_FILE, key, value);
|
||||
|
||||
if (result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, key, value);
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
(void)KV_Set_Value_uint8(CONFIG_FILE, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the cached value, if necessary.
|
||||
if ((cached_value != NULL) && (result == SYSTEMK_RESULT_SUCCESS))
|
||||
{
|
||||
*cached_value = *value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
SystemKResult_T SETTINGS_set_uint8_t(SystemKSettingID_T id, uint8_t value)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
|
||||
|
|
@ -148,10 +106,12 @@ SystemKResult_T SETTINGS_set_uint8_t(SystemKSettingID_T id, uint8_t value)
|
|||
switch (id)
|
||||
{
|
||||
case SYSTEMK_SETTING_IS_RIGHT_HANDED:
|
||||
Cached_Is_Right_Handed = value;
|
||||
result = KV_Set_Value_uint8(CONFIG_FILE, "Is_Right_Handed", &value);
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_AUDIO_VOLUME:
|
||||
Cached_Audio_Volume = value;
|
||||
result = KV_Set_Value_uint8(CONFIG_FILE, "Audio_Volume", &value);
|
||||
break;
|
||||
|
||||
|
|
@ -188,24 +148,26 @@ SystemKResult_T SETTINGS_set_uint8_t(SystemKSettingID_T id, uint8_t value)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
SystemKResult_T SETTINGS_get_uint32_t(SystemKSettingID_T id, uint32_t *value)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
|
||||
char *key = "";
|
||||
SystemKResult_T result = SYSTEMK_RESULT_UNSPECIFIED_FAILURE;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case SYSTEMK_SETTING_DEVICE_TYPE:
|
||||
*value = BLE_DEVICE_TYPE_32ESPECIAL;
|
||||
return result;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_T_START_GAME_in_ms:
|
||||
key = "T_Start_Game_in_ms";
|
||||
*value = Cached_T_Start_Game_in_ms;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_T_GAME_LENGTH_in_ms:
|
||||
key = "T_Game_Length_in_ms";
|
||||
*value = Cached_T_Game_Length_in_ms;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_SECONDARY_COLOR:
|
||||
*value = Cached_Secondary_Color;
|
||||
result = SYSTEMK_RESULT_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -213,21 +175,6 @@ SystemKResult_T SETTINGS_get_uint32_t(SystemKSettingID_T id, uint32_t *value)
|
|||
break;
|
||||
}
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = KV_Get_Value_uint32(CONFIG_FILE, key, value);
|
||||
|
||||
if (result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = KV_Get_Value_uint32(DEFAULT_CONFIG_FILE, key, value);
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
(void)KV_Set_Value_uint32(CONFIG_FILE, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -238,13 +185,20 @@ SystemKResult_T SETTINGS_set_uint32_t(SystemKSettingID_T id, uint32_t value)
|
|||
switch (id)
|
||||
{
|
||||
case SYSTEMK_SETTING_T_START_GAME_in_ms:
|
||||
Cached_T_Start_Game_in_ms = value;
|
||||
result = KV_Set_Value_uint32(CONFIG_FILE, "T_Start_Game_in_ms", &value);
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_T_GAME_LENGTH_in_ms:
|
||||
Cached_T_Game_Length_in_ms = value;
|
||||
result = KV_Set_Value_uint32(CONFIG_FILE, "T_Game_Length_in_ms", &value);
|
||||
break;
|
||||
|
||||
case SYSTEMK_SETTING_SECONDARY_COLOR:
|
||||
Cached_Secondary_Color = value;
|
||||
result = KV_Set_Value_uint32(CONFIG_FILE, "Secondary_Color", &value);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = SYSTEMK_RESULT_WRONG_DATATYPE;
|
||||
break;
|
||||
|
|
@ -253,7 +207,7 @@ SystemKResult_T SETTINGS_set_uint32_t(SystemKSettingID_T id, uint32_t value)
|
|||
return result;
|
||||
}
|
||||
|
||||
SystemKResult_T SETTINGS_get_device_name(char* name)
|
||||
SystemKResult_T SETTINGS_get_device_name(char *name)
|
||||
{
|
||||
char buffer[KV_MAX_VALUE_LENGTH];
|
||||
SystemKResult_T result = KV_Get_Value_string(CONFIG_FILE, "Device_Name", buffer);
|
||||
|
|
@ -267,7 +221,7 @@ SystemKResult_T SETTINGS_get_device_name(char* name)
|
|||
return result;
|
||||
}
|
||||
|
||||
SystemKResult_T SETTINGS_set_device_name(char* name)
|
||||
SystemKResult_T SETTINGS_set_device_name(char *name)
|
||||
{
|
||||
SystemKResult_T result = KV_Set_Value_string(CONFIG_FILE, "Device_Name", name);
|
||||
return result;
|
||||
|
|
@ -278,3 +232,239 @@ SystemKResult_T SETTINGS_Save(void)
|
|||
{
|
||||
return SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SystemKResult_T Initialize_Settings(void)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
|
||||
SystemKResult_T temp_result;
|
||||
uint32_t value_uint32_t;
|
||||
uint8_t value_uint8_t;
|
||||
|
||||
KLOG_INFO(TAG, "Initializing settings...");
|
||||
|
||||
// Initialize Is_Right_Handed
|
||||
temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Is_Right_Handed", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Is_Right_Handed", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint8_t = 1;
|
||||
KLOG_WARN(TAG, "Is_Right_Handed not found in config files; using default value of 1.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Is_Right_Handed", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set Is_Right_Handed in config file.");
|
||||
}
|
||||
}
|
||||
Cached_Is_Right_Handed = value_uint8_t;
|
||||
|
||||
// Initialize Audio_Volume
|
||||
temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Audio_Volume", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Audio_Volume", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint8_t = CONFIG_KTAG_MAX_AUDIO_VOLUME;
|
||||
KLOG_WARN(TAG, "Audio_Volume not found in config files; using default value of CONFIG_KTAG_MAX_AUDIO_VOLUME.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Audio_Volume", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set Audio_Volume in config file.");
|
||||
}
|
||||
}
|
||||
Cached_Audio_Volume = value_uint8_t;
|
||||
|
||||
// Initialize Team_ID
|
||||
temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Team_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Team_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint8_t = BASIC_TEAMS_MINIMUM;
|
||||
KLOG_WARN(TAG, "Team_ID not found in config files; using default value of BASIC_TEAMS_MINIMUM.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Team_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set Team_ID in config file.");
|
||||
}
|
||||
}
|
||||
Cached_Team_ID = value_uint8_t;
|
||||
|
||||
// Initialize Player_ID
|
||||
temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Player_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Player_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint8_t = 0;
|
||||
KLOG_WARN(TAG, "Player_ID not found in config files; using default value of 0.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Player_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set Player_ID in config file.");
|
||||
}
|
||||
}
|
||||
Cached_Player_ID = value_uint8_t;
|
||||
|
||||
// Initialize Weapon_ID
|
||||
temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Weapon_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Weapon_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint8_t = DUBUQUE_PROTOCOL_ID;
|
||||
KLOG_WARN(TAG, "Weapon_ID not found in config files; using default value of DUBUQUE_PROTOCOL_ID.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Weapon_ID", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set Weapon_ID in config file.");
|
||||
}
|
||||
}
|
||||
Cached_Weapon_ID = value_uint8_t;
|
||||
|
||||
// Initialize Max_Health
|
||||
temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Max_Health", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Max_Health", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint8_t = 100;
|
||||
KLOG_WARN(TAG, "Max_Health not found in config files; using default value of 100.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Max_Health", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set Max_Health in config file.");
|
||||
}
|
||||
}
|
||||
Cached_Max_Health = value_uint8_t;
|
||||
|
||||
// Initialize N_Special_Weapons_On_Reentry
|
||||
temp_result = KV_Get_Value_uint8(CONFIG_FILE, "N_Special_Weapons_On_Reentry", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "N_Special_Weapons_On_Reentry", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint8_t = 1;
|
||||
KLOG_WARN(TAG, "N_Special_Weapons_On_Reentry not found in config files; using default value of 1.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint8(CONFIG_FILE, "N_Special_Weapons_On_Reentry", &value_uint8_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set N_Special_Weapons_On_Reentry in config file.");
|
||||
}
|
||||
}
|
||||
Cached_N_Special_Weapons_On_Reentry = value_uint8_t;
|
||||
|
||||
// Initialize T_Start_Game_in_ms
|
||||
temp_result = KV_Get_Value_uint32(CONFIG_FILE, "T_Start_Game_in_ms", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint32(DEFAULT_CONFIG_FILE, "T_Start_Game_in_ms", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint32_t = 30000;
|
||||
KLOG_WARN(TAG, "T_Start_Game_in_ms not found in config files; using default value of 30000.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint32(CONFIG_FILE, "T_Start_Game_in_ms", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set T_Start_Game_in_ms in config file.");
|
||||
}
|
||||
}
|
||||
Cached_T_Start_Game_in_ms = value_uint32_t;
|
||||
|
||||
// Initialize T_Game_Length_in_ms
|
||||
temp_result = KV_Get_Value_uint32(CONFIG_FILE, "T_Game_Length_in_ms", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint32(DEFAULT_CONFIG_FILE, "T_Game_Length_in_ms", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint32_t = 600000;
|
||||
KLOG_WARN(TAG, "T_Game_Length_in_ms not found in config files; using default value of 600000.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint32(CONFIG_FILE, "T_Game_Length_in_ms", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set T_Game_Length_in_ms in config file.");
|
||||
}
|
||||
}
|
||||
Cached_T_Game_Length_in_ms = value_uint32_t;
|
||||
|
||||
// Initialize Secondary_Color
|
||||
temp_result = KV_Get_Value_uint32(CONFIG_FILE, "Secondary_Color", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Try to get from default config
|
||||
temp_result = KV_Get_Value_uint32(DEFAULT_CONFIG_FILE, "Secondary_Color", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
// Use hardcoded default
|
||||
value_uint32_t = 0xFE000000;
|
||||
KLOG_WARN(TAG, "Secondary_Color not found in config files; using default value of 0xFE000000.");
|
||||
}
|
||||
// Save to config file
|
||||
temp_result = KV_Set_Value_uint32(CONFIG_FILE, "Secondary_Color", &value_uint32_t);
|
||||
if (temp_result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
result = temp_result;
|
||||
KLOG_ERROR(TAG, "Failed to set Secondary_Color in config file.");
|
||||
}
|
||||
}
|
||||
Cached_Secondary_Color = value_uint32_t;
|
||||
|
||||
xEventGroupSetBits(Get_System_Events(), SYS_SETTINGS_READY);
|
||||
KLOG_INFO(TAG, "Settings initialized.");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
// From https://github.com/espressif/esp-idf/blob/master/examples/peripherals/usb/host/msc/main/msc_example_main.c
|
||||
|
||||
#include <SystemK.h>
|
||||
#include <System_Events.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
|
@ -55,6 +56,9 @@ static const char *TAG = "USB";
|
|||
static const char *OTA_FILE = "/usb/esp/OTA_URL.txt";
|
||||
const char *CONFIG_FILE = "/usb/esp/config.txt";
|
||||
|
||||
__NOINIT_ATTR uint_fast8_t Restarts;
|
||||
static bool Device_Connected_This_Power_Cycle = false;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USB_STATE_UNINITIALIZED,
|
||||
|
|
@ -260,27 +264,25 @@ static void usb_host_task(void *args)
|
|||
if (usb_host_device_free_all() == ESP_OK)
|
||||
{
|
||||
KLOG_INFO(TAG, "USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS");
|
||||
// break;
|
||||
};
|
||||
}
|
||||
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
|
||||
{
|
||||
KLOG_INFO(TAG, "USB_HOST_LIB_EVENT_FLAGS_ALL_FREE");
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void app_usb_task(void *args)
|
||||
{
|
||||
SemaphoreHandle_t init_complete = args;
|
||||
|
||||
static USB_State_T Current_State = USB_STATE_UNINITIALIZED;
|
||||
static msc_host_device_handle_t msc_device = NULL;
|
||||
static msc_host_vfs_handle_t vfs_handle = NULL;
|
||||
static uint8_t device_address = 1;
|
||||
usb_message_t msg;
|
||||
|
||||
esp_reset_reason() == ESP_RST_POWERON ? Restarts = 0 : Restarts++;
|
||||
|
||||
while (true)
|
||||
{
|
||||
switch (Current_State)
|
||||
|
|
@ -308,14 +310,32 @@ static void app_usb_task(void *args)
|
|||
{
|
||||
device_address = msg.data.new_dev_address;
|
||||
Current_State = USB_STATE_DEVICE_CONNECTED;
|
||||
Device_Connected_This_Power_Cycle = true;
|
||||
Restarts = 0;
|
||||
KLOG_INFO(TAG, "Device connected.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KLOG_ERROR(TAG, "No flash drive detected--rebooting.");
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
esp_restart();
|
||||
if (Device_Connected_This_Power_Cycle == false)
|
||||
{
|
||||
if (Restarts <= 3)
|
||||
{
|
||||
KLOG_ERROR(TAG, "No flash drive detected--rebooting.");
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
esp_restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
static bool warning_sent = false;
|
||||
|
||||
if (warning_sent == false)
|
||||
{
|
||||
KLOG_WARN(TAG, "No flash drive detected after multiple attempts.");
|
||||
warning_sent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -345,7 +365,7 @@ static void app_usb_task(void *args)
|
|||
else
|
||||
{
|
||||
Current_State = USB_STATE_VFS_REGISTERED;
|
||||
xSemaphoreGive(init_complete);
|
||||
xEventGroupSetBits(Get_System_Events(), SYS_USB_FS_PRESENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -360,6 +380,7 @@ static void app_usb_task(void *args)
|
|||
if (msg.id == USB_DEVICE_DISCONNECTED)
|
||||
{
|
||||
Current_State = USB_STATE_PROCESSING_DISCONNECTION;
|
||||
xEventGroupClearBits(Get_System_Events(), SYS_USB_FS_PRESENT);
|
||||
}
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
|
@ -389,7 +410,7 @@ static void app_usb_task(void *args)
|
|||
}
|
||||
}
|
||||
|
||||
void Initialize_USB(SemaphoreHandle_t init_complete)
|
||||
void Initialize_USB(void)
|
||||
{
|
||||
KLOG_INFO(TAG, "Initializing USB file system...");
|
||||
|
||||
|
|
@ -404,7 +425,7 @@ void Initialize_USB(SemaphoreHandle_t init_complete)
|
|||
app_usb_task, // Function that implements the task.
|
||||
"USB NVM", // Text name for the task.
|
||||
STACK_SIZE, // Stack size in bytes, not words.
|
||||
(void *)init_complete, // Parameter passed into the task.
|
||||
NULL, // Parameter passed into the task.
|
||||
tskIDLE_PRIORITY + 2, // Priority at which the task is created.
|
||||
xStack, // Array to use as the task's stack.
|
||||
&xTaskBuffer, // Variable to hold the task's data structure.
|
||||
|
|
@ -446,4 +467,4 @@ void Erase_OTA_File(void)
|
|||
{
|
||||
KLOG_ERROR(TAG, "Error erasing the OTA file: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
void Initialize_USB(SemaphoreHandle_t init_complete);
|
||||
void Initialize_USB(void);
|
||||
|
||||
extern const char *CONFIG_FILE;
|
||||
|
||||
|
|
|
|||
|
|
@ -311,4 +311,4 @@ void Request_Reprogramming_From_USB(void)
|
|||
{
|
||||
KLOG_WARN(TAG, "Reprogramming already in progress.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,4 +19,4 @@
|
|||
* file in the root of this repository. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void Request_Reprogramming_From_USB(void);
|
||||
void Request_Reprogramming_From_USB(void);
|
||||
|
|
|
|||
|
|
@ -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 <driver/gpio.h>
|
||||
#include <iot_button.h>
|
||||
|
|
|
|||
|
|
@ -1,2 +1,23 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
void Initialize_Switches(void);
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 6d8dab53e0c2efbb1aa17b3aaad556dc65005a4d
|
||||
Subproject commit f80cb59828aca6f784adcc898aa2603303c5cf2f
|
||||
8
components/System_Events/CMakeLists.txt
Normal file
8
components/System_Events/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
idf_component_register(
|
||||
SRCS
|
||||
"System_Events.c"
|
||||
INCLUDE_DIRS
|
||||
"."
|
||||
REQUIRES
|
||||
"SystemK"
|
||||
)
|
||||
59
components/System_Events/System_Events.c
Normal file
59
components/System_Events/System_Events.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 © 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 "System_Events.h"
|
||||
|
||||
static EventGroupHandle_t The_System_Events = NULL;
|
||||
|
||||
static const char *TAG = "System Events";
|
||||
|
||||
void Initialize_System_Events(void)
|
||||
{
|
||||
if (The_System_Events == NULL)
|
||||
{
|
||||
The_System_Events = xEventGroupCreate();
|
||||
KLOG_INFO(TAG, "System Events initialized.");
|
||||
}
|
||||
}
|
||||
|
||||
EventGroupHandle_t Get_System_Events(void)
|
||||
{
|
||||
return The_System_Events;
|
||||
}
|
||||
|
||||
bool Wait_For_System_Event(EventBits_t event_bit, const char* timeout_message, uint32_t timeout_ms)
|
||||
{
|
||||
EventBits_t bits = xEventGroupWaitBits(
|
||||
The_System_Events,
|
||||
event_bit,
|
||||
pdFALSE,
|
||||
pdTRUE,
|
||||
pdMS_TO_TICKS(timeout_ms));
|
||||
|
||||
if ((bits & event_bit) == 0)
|
||||
{
|
||||
KLOG_ERROR(TAG, "%s", timeout_message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
44
components/System_Events/System_Events.h
Normal file
44
components/System_Events/System_Events.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 © 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 SYSTEM_EVENTS_H
|
||||
#define SYSTEM_EVENTS_H
|
||||
|
||||
#include <SystemK.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/event_groups.h>
|
||||
|
||||
// System-wide event bits
|
||||
#define SYS_NVS_READY (1 << 0)
|
||||
#define SYS_SPIFFS_READY (1 << 1)
|
||||
#define SYS_USB_FS_PRESENT (1 << 2)
|
||||
#define SYS_AUDIO_READY (1 << 3)
|
||||
#define SYS_NEOPIXELS_READY (1 << 4)
|
||||
#define SYS_BLE_READY (1 << 5)
|
||||
#define SYS_IR_READY (1 << 6)
|
||||
#define SYS_SETTINGS_READY (1 << 7)
|
||||
|
||||
EventGroupHandle_t Get_System_Events(void);
|
||||
void Initialize_System_Events(void);
|
||||
bool Wait_For_System_Event(EventBits_t event_bit, const char* timeout_message, uint32_t timeout_ms);
|
||||
|
||||
#endif // SYSTEM_EVENTS_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue