From bddedbc4eeb4d008b16f55afdd5d3f450f64e6e5 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Fri, 6 Jun 2025 22:18:18 +0200 Subject: [PATCH] code splitting Signed-off-by: Peter Siegmund --- CMakeLists.txt | 2 +- main/CMakeLists.txt | 4 +- main/beacon.c | 181 ++++++++++++++++++++++++++++++++++++++++++++ main/beacon.h | 8 ++ main/main.c | 5 ++ 5 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 main/beacon.c create mode 100644 main/beacon.h diff --git a/CMakeLists.txt b/CMakeLists.txt index edb5f67..55d60c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(miniature_town) +project(lighthouses) diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index e7f6807..f9add97 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,6 @@ -idf_component_register(SRCS "main.c" +idf_component_register(SRCS + "beacon.c" + "main.c" INCLUDE_DIRS "." ) spiffs_create_partition_image(storage ../data FLASH_IN_PROJECT) diff --git a/main/beacon.c b/main/beacon.c new file mode 100644 index 0000000..5f54bda --- /dev/null +++ b/main/beacon.c @@ -0,0 +1,181 @@ +#include "beacon.h" + +#include "driver/gpio.h" +#include "driver/gptimer.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "inttypes.h" + +static const char *TAG = "beacon"; + +typedef struct +{ + uint32_t tick; +} timer_event_t; + +static QueueHandle_t timer_evt_queue = NULL; +gptimer_handle_t gptimer = NULL; + +bool IRAM_ATTR timer_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) +{ + timer_event_t evt = {.tick = edata->count_value}; + + BaseType_t high_task_wakeup = pdFALSE; + xQueueSendFromISR(timer_evt_queue, &evt, &high_task_wakeup); + + return (high_task_wakeup == pdTRUE); +} + +void timer_event_task(void *arg) +{ + timer_event_t evt; + while (true) + { + if (xQueueReceive(timer_evt_queue, &evt, portMAX_DELAY)) + { + static bool level = false; + level = !level; + gpio_set_level(CONFIG_WLED_DIN_PIN, level); + ESP_LOGI(TAG, "Timer Event: count = %" PRIu32 ", GPIO now %s", evt.tick, level ? "HIGH" : "LOW"); + } + } +} + +esp_err_t wled_init(void) +{ + gpio_config_t io_conf = {.pin_bit_mask = (1ULL << CONFIG_WLED_DIN_PIN), + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE}; + esp_err_t ret = gpio_config(&io_conf); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Failed to configure GPIO: %s", esp_err_to_name(ret)); + } + return ret; +} + +esp_err_t beacon_start(void) +{ + if (gptimer == NULL) + { + ESP_LOGE(TAG, "GPTimer not initialized"); + return ESP_ERR_INVALID_STATE; + } + esp_err_t ret = gptimer_start(gptimer); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Failed to start gptimer: %s", esp_err_to_name(ret)); + } + else + { + ESP_LOGI(TAG, "GPTimer started."); + } + return ret; +} + +esp_err_t beacon_stop(void) +{ + if (gptimer == NULL) + { + ESP_LOGE(TAG, "GPTimer not initialized"); + return ESP_ERR_INVALID_STATE; + } + esp_err_t ret = gptimer_stop(gptimer); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Failed to stop gptimer: %s", esp_err_to_name(ret)); + } + else + { + ESP_LOGI(TAG, "GPTimer stopped."); + } + return ret; +} + +esp_err_t beacon_init(void) +{ + esp_err_t ret = ESP_OK; + + timer_evt_queue = xQueueCreate(10, sizeof(timer_event_t)); + if (timer_evt_queue == NULL) + { + ESP_LOGE(TAG, "Failed to create timer event queue"); + ret = ESP_ERR_NO_MEM; + goto exit; + } + + gptimer_config_t timer_config = { + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1000000, // 1 MHz = 1 µs + }; + ret = gptimer_new_timer(&timer_config, &gptimer); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Failed to create new gptimer: %s", esp_err_to_name(ret)); + goto cleanup_queue; + } + + gptimer_event_callbacks_t callbacks = { + .on_alarm = timer_callback, + }; + ret = gptimer_register_event_callbacks(gptimer, &callbacks, NULL); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Failed to register timer callbacks: %s", esp_err_to_name(ret)); + goto cleanup_timer; + } + + ret = gptimer_enable(gptimer); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Failed to enable gptimer: %s", esp_err_to_name(ret)); + goto cleanup_timer; // Timer created but not enabled, can be deleted. + } + + gptimer_alarm_config_t alarm_config = { + .alarm_count = 2000000, // 2.000.000 µs = 2 secs + .reload_count = 0, + .flags.auto_reload_on_alarm = true, + }; + ret = gptimer_set_alarm_action(gptimer, &alarm_config); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Failed to set gptimer alarm action: %s", esp_err_to_name(ret)); + goto cleanup_enabled_timer; // Timer is enabled, disable before deleting. + } + + BaseType_t task_created = xTaskCreate(timer_event_task, "timer_event_task", 4096, NULL, 10, NULL); + if (task_created != pdPASS) + { + ESP_LOGE(TAG, "Failed to create timer event task"); + ret = ESP_ERR_NO_MEM; // Task creation often fails due to insufficient memory + goto cleanup_enabled_timer; + } + + ESP_LOGI(TAG, "Beacon module initialized."); + goto exit; + +cleanup_enabled_timer: + if (gptimer) + { + gptimer_disable(gptimer); // Attempt to disable + } +cleanup_timer: + if (gptimer) + { + gptimer_del_timer(gptimer); + gptimer = NULL; + } +cleanup_queue: + if (timer_evt_queue) + { + vQueueDelete(timer_evt_queue); + timer_evt_queue = NULL; + } +exit: + return ret; +} diff --git a/main/beacon.h b/main/beacon.h new file mode 100644 index 0000000..82dccb6 --- /dev/null +++ b/main/beacon.h @@ -0,0 +1,8 @@ +#pragma once + +#include "esp_err.h" + +esp_err_t beacon_init(void); +esp_err_t beacon_start(void); +esp_err_t beacon_stop(void); +esp_err_t wled_init(void); diff --git a/main/main.c b/main/main.c index cb05851..31bf6c6 100644 --- a/main/main.c +++ b/main/main.c @@ -1,3 +1,8 @@ +#include "beacon.h" + void app_main(void) { + ESP_ERROR_CHECK(beacon_init()); + ESP_ERROR_CHECK(wled_init()); + ESP_ERROR_CHECK(beacon_start()); }