diff --git a/components/Audio/I2S_Audio.c b/components/Audio/I2S_Audio.c index 89c16b6..efcb9be 100644 --- a/components/Audio/I2S_Audio.c +++ b/components/Audio/I2S_Audio.c @@ -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. + * + * 🛡️ 🃞 + * + * 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 . + */ + #include #include #include @@ -150,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) diff --git a/components/Audio/I2S_Audio.h b/components/Audio/I2S_Audio.h index 3cac360..cba3c70 100644 --- a/components/Audio/I2S_Audio.h +++ b/components/Audio/I2S_Audio.h @@ -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. + * + * 🛡️ 🃞 + * + * 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 . + */ + #include "esp_err.h" void Initialize_Audio(void); diff --git a/components/BLE/BLE.c b/components/BLE/BLE.c index 44d5bef..5b67a7b 100644 --- a/components/BLE/BLE.c +++ b/components/BLE/BLE.c @@ -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. + * + * 🛡️ 🃞 + * + * 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 . + */ + #include +#include #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) diff --git a/components/BLE/BLE.h b/components/BLE/BLE.h index 404c73c..5b50bf5 100644 --- a/components/BLE/BLE.h +++ b/components/BLE/BLE.h @@ -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. + * + * 🛡️ 🃞 + * + * 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 . + */ + #include "esp_err.h" void Initialize_BLE(void); diff --git a/components/BLE/CMakeLists.txt b/components/BLE/CMakeLists.txt index ed6be1e..a9da2bc 100644 --- a/components/BLE/CMakeLists.txt +++ b/components/BLE/CMakeLists.txt @@ -5,6 +5,7 @@ idf_component_register( "." REQUIRES "SystemK" + "System_Events" "driver" "bt" ) diff --git a/components/IR/CMakeLists.txt b/components/IR/CMakeLists.txt index 3b94569..6cb86fb 100644 --- a/components/IR/CMakeLists.txt +++ b/components/IR/CMakeLists.txt @@ -5,5 +5,6 @@ idf_component_register( "." REQUIRES "SystemK" + "System_Events" "driver" ) diff --git a/components/IR/IR.c b/components/IR/IR.c index 3c754da..e1d1ce0 100644 --- a/components/IR/IR.c +++ b/components/IR/IR.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -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) diff --git a/components/IR/IR.h b/components/IR/IR.h index 632b091..73839d2 100644 --- a/components/IR/IR.h +++ b/components/IR/IR.h @@ -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(); \ No newline at end of file diff --git a/components/NVM/SPIFFS.c b/components/NVM/SPIFFS.c index cbccf1d..fe324f1 100644 --- a/components/NVM/SPIFFS.c +++ b/components/NVM/SPIFFS.c @@ -27,7 +27,7 @@ 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)..."); @@ -84,6 +84,4 @@ void Initialize_SPIFFS(SemaphoreHandle_t init_complete) xEventGroupSetBits(Get_System_Events(), SYS_SPIFFS_READY); KLOG_INFO(TAG, "SPIFFS initialized."); - - xSemaphoreGive(init_complete); } \ No newline at end of file diff --git a/components/NVM/SPIFFS.h b/components/NVM/SPIFFS.h index 6f83bd5..24deb03 100644 --- a/components/NVM/SPIFFS.h +++ b/components/NVM/SPIFFS.h @@ -21,6 +21,6 @@ #pragma once -void Initialize_SPIFFS(SemaphoreHandle_t init_complete); +void Initialize_SPIFFS(void); extern const char *DEFAULT_CONFIG_FILE; \ No newline at end of file diff --git a/components/Switches/Switches.c b/components/Switches/Switches.c index 7450ed7..74be7cd 100644 --- a/components/Switches/Switches.c +++ b/components/Switches/Switches.c @@ -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. + * + * 🛡️ 🃞 + * + * 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 . + */ + #include #include #include diff --git a/components/Switches/Switches.h b/components/Switches/Switches.h index 6d1bc5b..62866a0 100644 --- a/components/Switches/Switches.h +++ b/components/Switches/Switches.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. + * + * 🛡️ 🃞 + * + * 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 . + */ void Initialize_Switches(void); diff --git a/components/System_Events/System_Events.c b/components/System_Events/System_Events.c index 393893e..333474c 100644 --- a/components/System_Events/System_Events.c +++ b/components/System_Events/System_Events.c @@ -38,4 +38,22 @@ void Initialize_System_Events(void) EventGroupHandle_t Get_System_Events(void) { return The_System_Events; -} \ No newline at end of file +} + +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; +} diff --git a/components/System_Events/System_Events.h b/components/System_Events/System_Events.h index d35029b..59ccc16 100644 --- a/components/System_Events/System_Events.h +++ b/components/System_Events/System_Events.h @@ -31,11 +31,13 @@ #define SYS_NVS_READY (1 << 0) #define SYS_SPIFFS_READY (1 << 1) #define SYS_USB_FS_PRESENT (1 << 2) -#define SYS_BLE_READY (1 << 3) -#define SYS_AUDIO_READY (1 << 4) -#define SYS_CONFIG_LOADED (1 << 5) +#define SYS_AUDIO_READY (1 << 3) +#define SYS_NEOPIXELS_READY (1 << 4) +#define SYS_BLE_READY (1 << 5) +#define SYS_IR_READY (1 << 6) 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 \ No newline at end of file diff --git a/main/HW_NeoPixels.c b/main/HW_NeoPixels.c index 3d7c584..b235ba0 100644 --- a/main/HW_NeoPixels.c +++ b/main/HW_NeoPixels.c @@ -1,5 +1,28 @@ +/* + * This program source code file is part of the KTag project, a DIY laser tag + * game with customizable features and wide interoperability. + * + * 🛡️ 🃞 + * + * 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 . + */ + #include +#include #include #include #include @@ -18,11 +41,11 @@ static TaskHandle_t xTaskHandle; static muxed_led_strip_handle_t NeoPixel_Out; // GPIO assignments -#define NEOPIXEL_OUT_GPIO GPIO_NUM_48 -#define BARREL_ENABLE_GPIO GPIO_NUM_18 -#define RECEIVER_ENABLE_GPIO GPIO_NUM_45 -#define DISPLAY_ENABLE_GPIO GPIO_NUM_10 -#define EFFECTS_ENABLE_GPIO GPIO_NUM_17 +#define NEOPIXEL_OUT_GPIO GPIO_NUM_48 +#define BARREL_ENABLE_GPIO GPIO_NUM_18 +#define RECEIVER_ENABLE_GPIO GPIO_NUM_45 +#define DISPLAY_ENABLE_GPIO GPIO_NUM_10 +#define EFFECTS_ENABLE_GPIO GPIO_NUM_17 // 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution) #define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000) @@ -127,12 +150,12 @@ static led_strip_rmt_config_t rmt_config_noDMA = { }; static led_strip_spi_config_t spi_config_withDMA __attribute__((unused)) = { - .clk_src = RMT_CLK_SRC_XTAL, // different clock source can lead to different power consumption - .flags.with_dma = true, // Using DMA can improve performance and help drive more LEDs - .spi_bus = SPI2_HOST, // SPI bus ID + .clk_src = RMT_CLK_SRC_XTAL, // different clock source can lead to different power consumption + .flags.with_dma = true, // Using DMA can improve performance and help drive more LEDs + .spi_bus = SPI2_HOST, // SPI bus ID }; -void Initialize_SystemK_NeoPixels(SemaphoreHandle_t init_complete) +void Initialize_SystemK_NeoPixels(void) { xStack = (uint8_t *)heap_caps_calloc(1, NEOPIXELS_STACK_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT | MALLOC_CAP_32BIT); @@ -147,13 +170,14 @@ void Initialize_SystemK_NeoPixels(SemaphoreHandle_t init_complete) &xTaskBuffer, // Variable to hold the task's data structure. APP_CPU_NUM); // Specify the task's core affinity. + xEventGroupSetBits(Get_System_Events(), SYS_NEOPIXELS_READY); KLOG_INFO(TAG, "Initialization complete."); - - xSemaphoreGive(init_complete); } SystemKResult_T HW_NeoPixels_Init(void) { + KLOG_INFO(TAG, "Initializing NeoPixels..."); + if (CONFIG_KTAG_N_NEOPIXEL_CHANNELS > 0) { // Initialize the NeoPixel Out and the Barrel Enable. @@ -220,11 +244,11 @@ color_t HW_NeoPixels_Get_My_Color(void) uint8_t Player_ID; uint8_t Weapon_ID; - (void) SETTINGS_get_uint8_t(SYSTEMK_SETTING_TEAMID, &Team_ID); - (void) SETTINGS_get_uint8_t(SYSTEMK_SETTING_PLAYERID, &Player_ID); - (void) SETTINGS_get_uint8_t(SYSTEMK_SETTING_WEAPONID, &Weapon_ID); + (void)SETTINGS_get_uint8_t(SYSTEMK_SETTING_TEAMID, &Team_ID); + (void)SETTINGS_get_uint8_t(SYSTEMK_SETTING_PLAYERID, &Player_ID); + (void)SETTINGS_get_uint8_t(SYSTEMK_SETTING_WEAPONID, &Weapon_ID); - result = PROTOCOLS_GetColor(GetWeaponFromID(Weapon_ID).Protocol, Team_ID, Player_ID); + result = PROTOCOLS_GetColor(GetWeaponFromID(Weapon_ID).Protocol, Team_ID, Player_ID); return result; } diff --git a/main/HW_NeoPixels.h b/main/HW_NeoPixels.h index 33cadfd..8385a9e 100644 --- a/main/HW_NeoPixels.h +++ b/main/HW_NeoPixels.h @@ -1,6 +1,28 @@ +/* + * This program source code file is part of the KTag project, a DIY laser tag + * game with customizable features and wide interoperability. + * + * 🛡️ 🃞 + * + * 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 . + */ + #ifndef HW_NEOPIXELS_H #define HW_NEOPIXELS_H -void Initialize_SystemK_NeoPixels(SemaphoreHandle_t init_complete); +void Initialize_SystemK_NeoPixels(void); #endif // HW_NEOPIXELS_H \ No newline at end of file diff --git a/main/main.c b/main/main.c index a1741cd..35af61d 100644 --- a/main/main.c +++ b/main/main.c @@ -55,7 +55,6 @@ #include "Reprogramming.h" static const char *TAG = "KTag 2024A"; -static SemaphoreHandle_t init_complete_semaphore; static const uint16_t INITIALIZATION_TIMEOUT_IN_ms = 10 * 1000; void app_main(void) @@ -66,8 +65,6 @@ void app_main(void) Initialize_System_Events(); - init_complete_semaphore = xSemaphoreCreateBinary(); - // Initialize NVS — it is used by both the BLE and WiFi drivers. esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) @@ -86,25 +83,11 @@ void app_main(void) KLOG_ERROR(TAG, "Error initializing NVS: %s", esp_err_to_name(ret)); } - - Initialize_SPIFFS(init_complete_semaphore); - if (xSemaphoreTake(init_complete_semaphore, pdMS_TO_TICKS(INITIALIZATION_TIMEOUT_IN_ms)) != pdTRUE) - { - KLOG_ERROR(TAG, "Timeout initializing SPIFFS!"); - } + Initialize_SPIFFS(); + Wait_For_System_Event(SYS_SPIFFS_READY, "Timeout initializing SPIFFS!", INITIALIZATION_TIMEOUT_IN_ms); Initialize_USB(); - EventBits_t bits = xEventGroupWaitBits( - Get_System_Events(), - SYS_USB_FS_PRESENT, - pdFALSE, - pdTRUE, - pdMS_TO_TICKS(INITIALIZATION_TIMEOUT_IN_ms)); - - if ((bits & SYS_USB_FS_PRESENT) == 0) - { - KLOG_ERROR(TAG, "Timeout initializing USB!"); - } + Wait_For_System_Event(SYS_USB_FS_PRESENT, "Timeout initializing USB!", INITIALIZATION_TIMEOUT_IN_ms); if (OTA_File_Exists() == true) { @@ -115,20 +98,17 @@ void app_main(void) else { Initialize_Audio(); + Wait_For_System_Event(SYS_AUDIO_READY, "Timeout initializing Audio!", INITIALIZATION_TIMEOUT_IN_ms); - Initialize_SystemK_NeoPixels(init_complete_semaphore); - if (xSemaphoreTake(init_complete_semaphore, pdMS_TO_TICKS(INITIALIZATION_TIMEOUT_IN_ms)) != pdTRUE) - { - KLOG_ERROR(TAG, "Timeout initializing NeoPixels!"); - } + Initialize_SystemK_NeoPixels(); + Wait_For_System_Event(SYS_NEOPIXELS_READY, "Timeout initializing NeoPixels!", INITIALIZATION_TIMEOUT_IN_ms); Initialize_BLE(); + Wait_For_System_Event(SYS_BLE_READY, "Timeout initializing BLE!", INITIALIZATION_TIMEOUT_IN_ms); + + Initialize_IR(); + Wait_For_System_Event(SYS_IR_READY, "Timeout initializing IR!", INITIALIZATION_TIMEOUT_IN_ms); - Initialize_IR(init_complete_semaphore); - if (xSemaphoreTake(init_complete_semaphore, pdMS_TO_TICKS(INITIALIZATION_TIMEOUT_IN_ms)) != pdTRUE) - { - KLOG_ERROR(TAG, "Timeout initializing IR!"); - } if (Initialize_SystemK() != SYSTEMK_RESULT_SUCCESS) { KLOG_ERROR(TAG, "Error initializing SystemK!"); @@ -137,7 +117,6 @@ void app_main(void) // Initialize the switches after SystemK, so xQueueEvents will have already been created. Initialize_Switches(); - vSemaphoreDelete(init_complete_semaphore); KLOG_INFO(TAG, "Initialization complete."); }