diff --git a/components/Audio/I2S_Audio.c b/components/Audio/I2S_Audio.c index efcb9be..4ef08cd 100644 --- a/components/Audio/I2S_Audio.c +++ b/components/Audio/I2S_Audio.c @@ -489,9 +489,10 @@ void I2SAudioTask(void *pvParameters) if (result == SYSTEMK_RESULT_FILESYSTEM_NOT_PRESENT) { - Play_Audio_File("/spiffs/KTag_broken.mp3"); + result = Play_Audio_File("/spiffs/KTag_broken.mp3"); } - else if (result == SYSTEMK_RESULT_SUCCESS) + + if (result == SYSTEMK_RESULT_SUCCESS) { if (action.Play_To_Completion == true) { diff --git a/components/NVM/NVM.h b/components/NVM/NVM.h index 01df907..ad5813d 100644 --- a/components/NVM/NVM.h +++ b/components/NVM/NVM.h @@ -24,3 +24,5 @@ #include "Key_Value.h" #include "SPIFFS.h" #include "USB.h" + +SystemKResult_T Initialize_Settings(void); diff --git a/components/NVM/Settings.c b/components/NVM/Settings.c index 59234b5..f496550 100644 --- a/components/NVM/Settings.c +++ b/components/NVM/Settings.c @@ -21,95 +21,73 @@ #include #include +#include #include -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,240 @@ 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; +} + diff --git a/components/SystemK b/components/SystemK index edf80ba..852dd68 160000 --- a/components/SystemK +++ b/components/SystemK @@ -1 +1 @@ -Subproject commit edf80ba83b5924144bba611abdd3a54447ed92b0 +Subproject commit 852dd684ad7e52786e5d75b701a89116c52b7060 diff --git a/components/System_Events/System_Events.h b/components/System_Events/System_Events.h index 59ccc16..878e3da 100644 --- a/components/System_Events/System_Events.h +++ b/components/System_Events/System_Events.h @@ -35,6 +35,7 @@ #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); diff --git a/main/main.c b/main/main.c index 35af61d..9b0069e 100644 --- a/main/main.c +++ b/main/main.c @@ -42,8 +42,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -89,6 +88,9 @@ void app_main(void) Initialize_USB(); Wait_For_System_Event(SYS_USB_FS_PRESENT, "Timeout initializing USB!", INITIALIZATION_TIMEOUT_IN_ms); + Initialize_Settings(); + Wait_For_System_Event(SYS_SETTINGS_READY, "Timeout initializing Settings!", INITIALIZATION_TIMEOUT_IN_ms); + if (OTA_File_Exists() == true) { KLOG_INFO(TAG, "Attempting OTA reprogramming from %s.", Get_OTA_Image_URL());