Compare commits

...

10 Commits

Author SHA1 Message Date
197a1611f5 move firmware into subfolder
Some checks failed
ESP-IDF Build / build (esp32, latest) (push) Failing after 40s
ESP-IDF Build / build (esp32, release-v5.4) (push) Failing after 20s
ESP-IDF Build / build (esp32, release-v5.5) (push) Failing after 18s
ESP-IDF Build / build (esp32c3, latest) (push) Failing after 17s
ESP-IDF Build / build (esp32c3, release-v5.4) (push) Failing after 15s
ESP-IDF Build / build (esp32c3, release-v5.5) (push) Failing after 15s
ESP-IDF Build / build (esp32c5, latest) (push) Failing after 16s
ESP-IDF Build / build (esp32c5, release-v5.4) (push) Failing after 17s
ESP-IDF Build / build (esp32c5, release-v5.5) (push) Failing after 17s
ESP-IDF Build / build (esp32c6, latest) (push) Failing after 16s
ESP-IDF Build / build (esp32c6, release-v5.4) (push) Failing after 17s
ESP-IDF Build / build (esp32c6, release-v5.5) (push) Failing after 16s
ESP-IDF Build / build (esp32h2, latest) (push) Failing after 14s
ESP-IDF Build / build (esp32h2, release-v5.4) (push) Failing after 16s
ESP-IDF Build / build (esp32h2, release-v5.5) (push) Failing after 16s
ESP-IDF Build / build (esp32p4, latest) (push) Failing after 17s
ESP-IDF Build / build (esp32p4, release-v5.4) (push) Failing after 16s
ESP-IDF Build / build (esp32p4, release-v5.5) (push) Failing after 16s
ESP-IDF Build / build (esp32s3, latest) (push) Failing after 16s
ESP-IDF Build / build (esp32s3, release-v5.4) (push) Failing after 16s
ESP-IDF Build / build (esp32s3, release-v5.5) (push) Failing after 16s
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-08-21 00:02:56 +02:00
b340cf4492 switch to ESP32-H2
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-08-16 09:05:39 +02:00
c49922820d updated esp-idf version in github action
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-07-26 14:17:35 +02:00
50898b94f4 code optimize
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-06-13 17:18:39 +02:00
7e1d6b1691 Revert "change persistence namespace"
This reverts commit ef8f6e597e.
2025-06-13 17:08:10 +02:00
e4d5f6a388 update github actions
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-06-13 17:07:17 +02:00
ef8f6e597e change persistence namespace
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-06-13 17:05:18 +02:00
f5bf8f283b updated github action
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-06-13 17:04:49 +02:00
686f82930f reorganize code
create light service, with splitted beacon and outdoor functions

Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-06-08 00:16:20 +02:00
b455d0f94a update github action trigger
Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
2025-06-07 18:01:39 +02:00
51 changed files with 227 additions and 78 deletions

View File

@@ -2,6 +2,10 @@ name: ESP-IDF Build
on: on:
push: push:
paths:
- bootloader_components/**
- components/**
- main/**
pull_request: pull_request:
merge_group: merge_group:
schedule: schedule:
@@ -19,7 +23,7 @@ jobs:
build: build:
strategy: strategy:
matrix: matrix:
idf_ver: [release-v5.4, latest] idf_ver: [release-v5.4, release-v5.5, latest]
idf_target: idf_target:
[esp32, esp32c3, esp32c5, esp32c6, esp32h2, esp32p4, esp32s3] [esp32, esp32c3, esp32c5, esp32c6, esp32h2, esp32p4, esp32s3]
@@ -35,14 +39,17 @@ jobs:
with: with:
esp_idf_version: ${{ matrix.idf_ver }} esp_idf_version: ${{ matrix.idf_ver }}
target: ${{ matrix.idf_target }} target: ${{ matrix.idf_target }}
command: idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.release" build
- name: Prepare binary files
run: |
mkdir -p build-release
cp build/flasher_args.json build-release/
cp build/*.bin build-release/
cp build/bootloader/*.bin build-release/
cp build/partition_table/*.bin build-release/
- name: Archive build output artifacts - name: Archive build output artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: lighthouses-${{ matrix.idf_target }}-${{ matrix.idf_ver }} name: lighthouses-${{ matrix.idf_target }}-${{ matrix.idf_ver }}
path: | path: |
build/flasher_args.json build-release/*.*
build/storage.bin
build/ota_data_initial.bin
build/lighthouses.bin
build/bootloader/bootloader.bin
build/partition_table/partition-table.bin

View File

@@ -0,0 +1 @@
[{"node":"I2C1","expanded":false,"format":0,"pinned":false},{"node":"MCPWM1","expanded":false,"format":0,"pinned":false},{"node":"SPI3","expanded":false,"format":0,"pinned":false},{"node":"TIMG1","expanded":false,"format":0,"pinned":false},{"node":"UART1","expanded":false,"format":0,"pinned":false},{"node":"UART2","expanded":false,"format":0,"pinned":false},{"node":"UHCI1","expanded":false,"format":0,"pinned":false},{"node":"AES","expanded":false,"format":0,"pinned":false},{"node":"APB_CTRL","expanded":false,"format":0,"pinned":false},{"node":"APB_SARADC","expanded":false,"format":0,"pinned":false},{"node":"BB","expanded":false,"format":0,"pinned":false},{"node":"ASSIST_DEBUG","expanded":false,"format":0,"pinned":false},{"node":"DMA","expanded":false,"format":0,"pinned":false},{"node":"DS","expanded":false,"format":0,"pinned":false},{"node":"EFUSE","expanded":false,"format":0,"pinned":false},{"node":"EXTMEM","expanded":false,"format":0,"pinned":false},{"node":"GPIO","expanded":false,"format":0,"pinned":false},{"node":"GPIO_SD","expanded":false,"format":0,"pinned":false},{"node":"HMAC","expanded":false,"format":0,"pinned":false},{"node":"I2C0","expanded":false,"format":0,"pinned":false},{"node":"I2S0","expanded":false,"format":0,"pinned":false},{"node":"I2S1","expanded":false,"format":0,"pinned":false},{"node":"INTERRUPT_CORE0","expanded":false,"format":0,"pinned":false},{"node":"INTERRUPT_CORE1","expanded":false,"format":0,"pinned":false},{"node":"IO_MUX","expanded":false,"format":0,"pinned":false},{"node":"LCD_CAM","expanded":false,"format":0,"pinned":false},{"node":"LEDC","expanded":false,"format":0,"pinned":false},{"node":"PCNT","expanded":false,"format":0,"pinned":false},{"node":"PERI_BACKUP","expanded":false,"format":0,"pinned":false},{"node":"MCPWM0","expanded":false,"format":0,"pinned":false},{"node":"RMT","expanded":false,"format":0,"pinned":false},{"node":"RNG","expanded":false,"format":0,"pinned":false},{"node":"RSA","expanded":false,"format":0,"pinned":false},{"node":"RTC_CNTL","expanded":false,"format":0,"pinned":false},{"node":"RTC_I2C","expanded":false,"format":0,"pinned":false},{"node":"RTC_IO","expanded":false,"format":0,"pinned":false},{"node":"SDHOST","expanded":false,"format":0,"pinned":false},{"node":"SENS","expanded":false,"format":0,"pinned":false},{"node":"SENSITIVE","expanded":false,"format":0,"pinned":false},{"node":"SHA","expanded":false,"format":0,"pinned":false},{"node":"SPI0","expanded":false,"format":0,"pinned":false},{"node":"SPI1","expanded":false,"format":0,"pinned":false},{"node":"SPI2","expanded":false,"format":0,"pinned":false},{"node":"SYSTEM","expanded":false,"format":0,"pinned":false},{"node":"SYSTIMER","expanded":false,"format":0,"pinned":false},{"node":"TIMG0","expanded":false,"format":0,"pinned":false},{"node":"TWAI0","expanded":false,"format":0,"pinned":false},{"node":"UART0","expanded":false,"format":0,"pinned":false},{"node":"UHCI0","expanded":false,"format":0,"pinned":false},{"node":"USB0","expanded":false,"format":0,"pinned":false},{"node":"USB_DEVICE","expanded":false,"format":0,"pinned":false},{"node":"USB_WRAP","expanded":false,"format":0,"pinned":false},{"node":"WCL","expanded":false,"format":0,"pinned":false},{"node":"XTS_AES","expanded":false,"format":0,"pinned":false}]

View File

@@ -2,7 +2,7 @@
"configurations": [ "configurations": [
{ {
"name": "ESP-IDF", "name": "ESP-IDF",
"compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc", "compilerPath": "${config:idf.toolsPath}/tools/riscv32-esp-elf/esp-14.2.0_20241119/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
"compileCommands": "${config:idf.buildPath}/compile_commands.json", "compileCommands": "${config:idf.buildPath}/compile_commands.json",
"includePath": [ "includePath": [
"${config:idf.espIdfPath}/components/**", "${config:idf.espIdfPath}/components/**",

47
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,47 @@
{
"idf.cwd": "${workspaceFolder}/firmware",
"idf.sdkconfigFilePath": "${workspaceFolder}/firmware/sdkconfig",
"idf.buildPath": "${workspaceFolder}/firmware/build",
"idf.openOcdConfigs": [
"board/esp32h2-builtin.cfg"
],
"idf.customExtraVars": {
"OPENOCD_SCRIPTS": "/Users/siegmund/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240821/openocd-esp32/share/openocd/scripts",
"ESP_ROM_ELF_DIR": "/Users/siegmund/.espressif/tools/esp-rom-elfs/20230320/",
"IDF_TARGET": "esp32h2"
},
"idf.flashType": "UART",
"files.associations": {
"led_strip.h": "c",
"led_matrix.h": "c",
"stdint.h": "c",
"freertos.h": "c",
"format": "c",
"thread": "c",
"sdkconfig.h": "c",
"task.h": "c",
"remote_control.h": "c",
"ble_svc_gap.h": "c",
"ble_svc_gatt.h": "c",
"nimble_port.h": "c",
"nimble_port_freertos.h": "c",
"esp_nimble_hci.h": "c",
"led_service.h": "c",
"device_service.h": "c",
"ble_hs.h": "c",
"esp_spiffs.h": "c",
"esp_log.h": "c",
"types.h": "c",
"gptimer.h": "c",
"gpio.h": "c",
"beacon.h": "c",
"persistence.h": "c",
"light.h": "c",
"outdoor.h": "c",
"inttypes.h": "c"
},
"idf.port": "/dev/tty.usbmodem2101",
"idf.espIdfPath": "/Users/siegmund/esp/v5.5/esp-idf",
"idf.toolsPath": "/Users/siegmund/.espressif",
"idf.pythonInstallPath": "/opt/homebrew/bin/python3"
}

View File

@@ -6,3 +6,4 @@ sdkconfig.old
.espidf.*.json .espidf.*.json
*.svd *.svd
*.lock *.lock
build-release/

2
firmware/Makefile Normal file
View File

@@ -0,0 +1,2 @@
release:
idf.py -B build-release -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.release" fullclean build

View File

@@ -0,0 +1,8 @@
idf_component_register(SRCS
"beacon.c"
"light.c"
"outdoor.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES
esp_driver_gptimer
)

View File

@@ -4,27 +4,20 @@
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "inttypes.h"
#include "led_strip.h" #include "led_strip.h"
#include "light.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "semaphore.h" #include "semaphore.h"
static const char *TAG = "beacon"; static const char *TAG = "beacon";
typedef struct
{
led_strip_handle_t led_strip;
uint32_t size;
} LedMatrix_t;
static LedMatrix_t led_matrix = {.size = 64};
static SemaphoreHandle_t timer_semaphore; static SemaphoreHandle_t timer_semaphore;
gptimer_handle_t gptimer = NULL; gptimer_handle_t gptimer = NULL;
const uint32_t value = 10; static const uint32_t value = 200;
const uint32_t mod = 3;
bool IRAM_ATTR timer_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *userCtx) static bool IRAM_ATTR beacon_timer_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata,
void *userCtx)
{ {
BaseType_t high_task_wakeup = pdFALSE; BaseType_t high_task_wakeup = pdFALSE;
xSemaphoreGiveFromISR(timer_semaphore, &high_task_wakeup); xSemaphoreGiveFromISR(timer_semaphore, &high_task_wakeup);
@@ -35,22 +28,21 @@ bool IRAM_ATTR timer_callback(gptimer_handle_t timer, const gptimer_alarm_event_
return true; return true;
} }
void timer_event_task(void *arg) static void beacon_timer_event_task(void *arg)
{ {
while (true) while (true)
{ {
if (xSemaphoreTake(timer_semaphore, portMAX_DELAY)) if (xSemaphoreTake(timer_semaphore, portMAX_DELAY))
{ {
LedMatrix_t led_matrix = get_led_matrix();
static bool level = false; static bool level = false;
level = !level; level = !level;
if (led_matrix.led_strip) if (led_matrix.led_strip)
{ {
for (uint32_t i = 0; i < led_matrix.size; i++) for (uint32_t i = 0; i < led_matrix.size; i++)
{ {
if (i % mod == 0) led_strip_set_pixel(led_matrix.led_strip, i, 0, (level) ? value : 0, 0);
{
led_strip_set_pixel(led_matrix.led_strip, i, 0, (level) ? value : 0, 0);
}
} }
led_strip_refresh(led_matrix.led_strip); led_strip_refresh(led_matrix.led_strip);
} }
@@ -59,37 +51,6 @@ void timer_event_task(void *arg)
} }
} }
esp_err_t wled_init(void)
{
led_strip_config_t strip_config = {.strip_gpio_num = CONFIG_WLED_DIN_PIN,
.max_leds = led_matrix.size,
.led_model = LED_MODEL_WS2812,
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_RGB,
.flags = {
.invert_out = false,
}};
led_strip_rmt_config_t rmt_config = {.clk_src = RMT_CLK_SRC_DEFAULT,
.resolution_hz = 0,
.mem_block_symbols = 0,
.flags = {
.with_dma = true,
}};
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_matrix.led_strip));
for (uint32_t i = 0; i < led_matrix.size; i++)
{
if (i % mod != 0)
{
led_strip_set_pixel(led_matrix.led_strip, i, value, value, value);
}
}
led_strip_refresh(led_matrix.led_strip);
return ESP_OK;
}
esp_err_t beacon_start(void) esp_err_t beacon_start(void)
{ {
if (gptimer == NULL) if (gptimer == NULL)
@@ -143,7 +104,7 @@ esp_err_t beacon_init(void)
goto exit; goto exit;
} }
gptimer_event_callbacks_t callbacks = {.on_alarm = timer_callback}; gptimer_event_callbacks_t callbacks = {.on_alarm = beacon_timer_callback};
ret = gptimer_register_event_callbacks(gptimer, &callbacks, NULL); ret = gptimer_register_event_callbacks(gptimer, &callbacks, NULL);
if (ret != ESP_OK) if (ret != ESP_OK)
{ {
@@ -167,7 +128,7 @@ esp_err_t beacon_init(void)
goto cleanupEnabledTimer; goto cleanupEnabledTimer;
} }
BaseType_t task_created = xTaskCreate(timer_event_task, "timer_event_task", 4096, NULL, 10, NULL); BaseType_t task_created = xTaskCreate(beacon_timer_event_task, "beacon_timer_event_task", 4096, NULL, 10, NULL);
if (task_created != pdPASS) if (task_created != pdPASS)
{ {
ESP_LOGE(TAG, "Failed to create timer event task"); ESP_LOGE(TAG, "Failed to create timer event task");

View File

@@ -37,15 +37,3 @@ esp_err_t beacon_start(void);
* - Error codes in case of failure, indicating the specific issue. * - Error codes in case of failure, indicating the specific issue.
*/ */
esp_err_t beacon_stop(void); esp_err_t beacon_stop(void);
/**
* @brief Initializes the WLED module.
*
* This function configures the WLED module for operation, preparing it for subsequent
* usage such as enabling lighting effects or communication.
*
* @return
* - ESP_OK: Initialization completed successfully.
* - Error codes in case of failure, indicating the specific issue.
*/
esp_err_t wled_init(void);

View File

@@ -0,0 +1,27 @@
#pragma once
#include "beacon.h"
#include "led_strip.h"
#include "outdoor.h"
#include "esp_err.h"
typedef struct
{
led_strip_handle_t led_strip;
uint32_t size;
} LedMatrix_t;
LedMatrix_t get_led_matrix(void);
/**
* @brief Initializes the WLED module.
*
* This function configures the WLED module for operation, preparing it for subsequent
* usage such as enabling lighting effects or communication.
*
* @return
* - ESP_OK: Initialization completed successfully.
* - Error codes in case of failure, indicating the specific issue.
*/
esp_err_t wled_init(void);

View File

@@ -0,0 +1,9 @@
#pragma once
#include "esp_err.h"
esp_err_t outdoor_init(void);
esp_err_t outdoor_start(void);
esp_err_t outdoor_stop(void);

View File

@@ -0,0 +1,38 @@
#include "light.h"
#include "sdkconfig.h"
static LedMatrix_t led_matrix = {.size = 1};
LedMatrix_t get_led_matrix(void)
{
return led_matrix;
}
esp_err_t wled_init(void)
{
led_strip_config_t strip_config = {.strip_gpio_num = CONFIG_WLED_DIN_PIN,
.max_leds = led_matrix.size,
.led_model = LED_MODEL_WS2812,
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
.flags = {
.invert_out = false,
}};
led_strip_rmt_config_t rmt_config = {.clk_src = RMT_CLK_SRC_DEFAULT,
.resolution_hz = 0,
.mem_block_symbols = 0,
.flags = {
.with_dma = CONFIG_WLED_DMA_USAGE,
}};
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_matrix.led_strip));
for (uint32_t i = 0; i < led_matrix.size; i++)
{
led_strip_set_pixel(led_matrix.led_strip, i, 0, 0, 0);
}
led_strip_refresh(led_matrix.led_strip);
return ESP_OK;
}

View File

@@ -0,0 +1,16 @@
#include "outdoor.h"
esp_err_t outdoor_init(void)
{
return ESP_OK;
}
esp_err_t outdoor_start(void)
{
return ESP_OK;
}
esp_err_t outdoor_stop(void)
{
return ESP_OK;
}

View File

@@ -14,7 +14,7 @@ static char s_current_filename[256] = {0}; // Buffer to store the current filena
esp_err_t storage_init(void) esp_err_t storage_init(void)
{ {
ESP_LOGI(TAG, "Initializing SPIFFS"); ESP_LOGI(TAG, "Initializing Storage");
esp_vfs_spiffs_conf_t conf = { esp_vfs_spiffs_conf_t conf = {
.base_path = "/storage", // Path where the filesystem will be mounted .base_path = "/storage", // Path where the filesystem will be mounted

View File

@@ -1,5 +1,4 @@
idf_component_register(SRCS idf_component_register(SRCS
"beacon.c"
"main.c" "main.c"
INCLUDE_DIRS "." INCLUDE_DIRS "."
) )

View File

@@ -1,10 +1,21 @@
menu "Warnemuende Lighthouse" menu "Warnemuende Lighthouse"
config WLED_DIN_PIN config WLED_DIN_PIN
int "WLED Data In Pin" int "WLED Data In Pin"
default 14 default 8
help help
The number of the WLED data in pin. The number of the WLED data in pin.
config WLED_USE_DMA
bool "Use DMA for WLED"
default n
help
Use DMA to drive the WLED strip. This is more efficient and allows for smoother animations.
config WLED_DMA_USAGE
int
default 1 if WLED_USE_DMA
default 0 if !WLED_USE_DMA
choice LIGHT_CHARACTERISTIC_CHOICE choice LIGHT_CHARACTERISTIC_CHOICE
prompt "Light characteristic" prompt "Light characteristic"
default LIGHT_CHARACTERISTIC_GREEN default LIGHT_CHARACTERISTIC_GREEN

View File

@@ -0,0 +1,16 @@
## IDF Component Manager Manifest File
dependencies:
## Required IDF version
idf:
version: '>=5.4.0'
# # Put list of dependencies here
# # For components maintained by Espressif:
# component: "~1.0.0"
# # For 3rd party components:
# username/component: ">=1.0.0,<2.0.0"
# username2/component2:
# version: "~1.0.0"
# # For transient dependencies `public` flag can be set.
# # `public` flag doesn't have an effect dependencies of the `main` component.
# # All dependencies of `main` are public by default.
# public: true

View File

@@ -1,26 +1,43 @@
#include "beacon.h" #include "light.h"
#include "persistence.h" #include "persistence.h"
#include "remote_control.h" #include "remote_control.h"
void app_main(void) void app_main(void)
{ {
/// init persistence
persistence_init("lighthouse"); persistence_init("lighthouse");
if (beacon_init() != ESP_OK) /// init WLED
{
printf("Failed to initialize beacon");
return;
}
if (wled_init() != ESP_OK) if (wled_init() != ESP_OK)
{ {
printf("Failed to initialize WLED"); printf("Failed to initialize WLED");
return; return;
} }
/// start beacon service
if (beacon_init() != ESP_OK)
{
printf("Failed to initialize beacon");
return;
}
if (beacon_start() != ESP_OK) if (beacon_start() != ESP_OK)
{ {
printf("Failed to start beacon"); printf("Failed to start beacon");
return; return;
} }
/// start outdoor light service
if (outdoor_init() != ESP_OK)
{
printf("Failed to initialize outdoor");
return;
}
if (outdoor_start() != ESP_OK)
{
printf("Failed to start outdoor");
return;
}
/// activate BLE functions
remote_control_init(); remote_control_init();
} }

View File

@@ -1,2 +1,3 @@
# default ESP target # default ESP target
CONFIG_IDF_TARGET="esp32s3" CONFIG_IDF_TARGET="esp32s3"
CONFIG_WLED_USE_DMA=y

View File