diff --git a/firmware/apps/_samples/ir_recv_adc/boards/nrf52840dk_nrf52840.overlay b/firmware/apps/_samples/ir_recv_adc/boards/nrf52840dk_nrf52840.overlay index a74527e..b004eb7 100644 --- a/firmware/apps/_samples/ir_recv_adc/boards/nrf52840dk_nrf52840.overlay +++ b/firmware/apps/_samples/ir_recv_adc/boards/nrf52840dk_nrf52840.overlay @@ -17,7 +17,7 @@ reg = <0>; zephyr,gain = "ADC_GAIN_1_4"; zephyr,reference = "ADC_REF_VDD_1_4"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; zephyr,input-positive = ; /* Pin P0.02 */ zephyr,resolution = <12>; }; @@ -26,7 +26,7 @@ reg = <1>; zephyr,gain = "ADC_GAIN_1_4"; zephyr,reference = "ADC_REF_VDD_1_4"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; zephyr,input-positive = ; /* Pin P0.03 */ zephyr,resolution = <12>; }; @@ -35,7 +35,7 @@ reg = <2>; zephyr,gain = "ADC_GAIN_1_4"; zephyr,reference = "ADC_REF_VDD_1_4"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; zephyr,input-positive = ; /* Pin P0.04 */ zephyr,resolution = <12>; }; @@ -44,7 +44,7 @@ reg = <3>; zephyr,gain = "ADC_GAIN_1_4"; zephyr,reference = "ADC_REF_VDD_1_4"; - zephyr,acquisition-time = ; + zephyr,acquisition-time = ; zephyr,input-positive = ; /* Pin P0.05 */ zephyr,resolution = <12>; }; diff --git a/firmware/apps/_samples/ir_recv_adc/prj.conf b/firmware/apps/_samples/ir_recv_adc/prj.conf index 6dd22e8..3408127 100644 --- a/firmware/apps/_samples/ir_recv_adc/prj.conf +++ b/firmware/apps/_samples/ir_recv_adc/prj.conf @@ -14,12 +14,12 @@ CONFIG_IR_RECV=y CONFIG_IR_RECV_LOG_LEVEL_DBG=y CONFIG_IR_RECV_INVERT_SIGNAL=y -# # Thread Analyzer aktivieren -# CONFIG_THREAD_ANALYZER=y -# CONFIG_THREAD_ANALYZER_AUTO=y -# CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=5 +# Thread Analyzer aktivieren +CONFIG_THREAD_ANALYZER=y +CONFIG_THREAD_ANALYZER_AUTO=y +CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=5 -# # CPU-Laufzeit-Statistiken aktivieren -# CONFIG_THREAD_RUNTIME_STATS=y -# CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=y +# CPU-Laufzeit-Statistiken aktivieren +CONFIG_THREAD_RUNTIME_STATS=y +CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=y diff --git a/firmware/apps/_samples/ir_recv_adc/src/main.c b/firmware/apps/_samples/ir_recv_adc/src/main.c index fc8fe49..2f6a5fc 100644 --- a/firmware/apps/_samples/ir_recv_adc/src/main.c +++ b/firmware/apps/_samples/ir_recv_adc/src/main.c @@ -3,11 +3,11 @@ #include #include -LOG_MODULE_REGISTER(ir_recv_sim, LOG_LEVEL_INF); +LOG_MODULE_REGISTER(ir_recv_adc, LOG_LEVEL_INF); int main(void) { - LOG_INF("Starting IR receive simulator application..."); + LOG_INF("Starting IR receive ADC application..."); lasertag_utils_init(); ir_recv_init(); diff --git a/firmware/libs/ble_mgmt/CMakeLists.txt b/firmware/libs/ble_mgmt/CMakeLists.txt index 87323c2..fa095c1 100644 --- a/firmware/libs/ble_mgmt/CMakeLists.txt +++ b/firmware/libs/ble_mgmt/CMakeLists.txt @@ -1,5 +1,5 @@ if(CONFIG_BLE_MGMT) zephyr_library() - zephyr_sources(src/ble_mgmt.c) + zephyr_library_sources(src/ble_mgmt.c) zephyr_include_directories(include) endif() \ No newline at end of file diff --git a/firmware/libs/fs_mgmt/CMakeLists.txt b/firmware/libs/fs_mgmt/CMakeLists.txt index 5c85514..d4c5abb 100644 --- a/firmware/libs/fs_mgmt/CMakeLists.txt +++ b/firmware/libs/fs_mgmt/CMakeLists.txt @@ -1,6 +1,6 @@ if(CONFIG_FS_MGMT) zephyr_library() - zephyr_sources(src/fs_mgmt.c) + zephyr_library_sources(src/fs_mgmt.c) zephyr_include_directories(include) if(CONFIG_FILE_SYSTEM_LITTLEFS) diff --git a/firmware/libs/game_mgmt/CMakeLists.txt b/firmware/libs/game_mgmt/CMakeLists.txt index f2a772a..9ad4cf6 100644 --- a/firmware/libs/game_mgmt/CMakeLists.txt +++ b/firmware/libs/game_mgmt/CMakeLists.txt @@ -1,5 +1,5 @@ if(CONFIG_GAME_MGMT) zephyr_library() - zephyr_sources(src/game_mgmt.c) + zephyr_library_sources(src/game_mgmt.c) zephyr_include_directories(include) endif() \ No newline at end of file diff --git a/firmware/libs/ir/recv/CMakeLists.txt b/firmware/libs/ir/recv/CMakeLists.txt index 8ac1824..970800e 100644 --- a/firmware/libs/ir/recv/CMakeLists.txt +++ b/firmware/libs/ir/recv/CMakeLists.txt @@ -1,5 +1,6 @@ if(CONFIG_IR_RECV) zephyr_library() - zephyr_sources(src/ir_recv.c) + zephyr_library_sources(src/ir_recv.c) zephyr_include_directories(include) + zephyr_library_link_libraries_ifdef(CONFIG_NRFX nrfx) endif() diff --git a/firmware/libs/ir/recv/Kconfig b/firmware/libs/ir/recv/Kconfig index 5303d41..d33ccba 100644 --- a/firmware/libs/ir/recv/Kconfig +++ b/firmware/libs/ir/recv/Kconfig @@ -1,11 +1,19 @@ menuconfig IR_RECV bool "IR Receiver" - select ADC - select DMA help Enable support for receiving IR signals using the ADC and DMA. if IR_RECV + config IR_RECV_HW_DEPENDENCIES + bool + default y if !IR_RECV_SIMULATOR + select ADC + select NRFX_GPPI + select NRFX_TIMER + select NRFX_TIMER1 + select NRFX_PPI + select NRFX_SAADC + config IR_RECV_SIMULATOR bool "Enable IR receiver simulator" select ENTROPY_GENERATOR @@ -36,4 +44,4 @@ if IR_RECV module = IR_RECV module-str = ir_recv source "subsys/logging/Kconfig.template.log_config" -endif \ No newline at end of file +endif diff --git a/firmware/libs/ir/recv/src/ir_recv.c b/firmware/libs/ir/recv/src/ir_recv.c index 6c44863..4325d6b 100644 --- a/firmware/libs/ir/recv/src/ir_recv.c +++ b/firmware/libs/ir/recv/src/ir_recv.c @@ -167,6 +167,9 @@ K_THREAD_DEFINE(sim_tid, 1024, ir_recv_sim_thread, NULL, NULL, NULL, 5, 0, 0); #ifndef CONFIG_IR_RECV_SIMULATOR #include +#include +#include +#include /* ADC-Kanäle dynamisch aus dem DeviceTree (zephyr,user) laden */ static const struct adc_dt_spec adc_channels[] = { @@ -176,34 +179,61 @@ static const struct adc_dt_spec adc_channels[] = { ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 3) }; -static void hw_adc_setup(void) +static int hw_adc_setup(void) { + int err; for (int i = 0; i < ARRAY_SIZE(adc_channels); i++) { - if (!adc_is_ready_dt(&adc_channels[i])) { + if (err) { LOG_ERR("ADC controller for channel %d not ready", i); - return; + return err; } - int err = adc_channel_setup_dt(&adc_channels[i]); - if (err < 0) { + err = adc_channel_setup_dt(&adc_channels[i]); + if (err) { LOG_ERR("Could not setup channel %d (err: %d)", i, err); - return; + return err; } } - LOG_INF("Hardware ADC configured via DeviceTree (EasyDMA Mode)."); + LOG_DBG("Hardware ADC configured via DeviceTree (EasyDMA Mode)."); + return 0; } +/* Wir reservieren uns Timer 1 für den ADC-Takt */ +static nrfx_timer_t adc_timer = NRFX_TIMER_INSTANCE(1); + void hw_adc_thread(void *p1, void *p2, void *p3) { - hw_adc_setup(); + /* 1. Hardware Timer auf 1 MHz einstellen */ + nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG(NRF_TIMER_FREQ_1MHz); + timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32; + nrfx_timer_init(&adc_timer, &timer_cfg, NULL); + + /* Compare-Event bei exakt 75 µs auslösen und Timer danach automatisch nullen */ + nrfx_timer_extended_compare(&adc_timer, NRF_TIMER_CC_CHANNEL0, 75, + NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false); + /* 2. PPI: Verbinde das Timer-Event direkt in Hardware mit dem ADC-Sample-Trigger */ + nrfx_gppi_handle_t ppi_handle; + int err = nrfx_gppi_conn_alloc( + nrfx_timer_event_address_get(&adc_timer, NRF_TIMER_EVENT_COMPARE0), + nrf_saadc_task_address_get(NRF_SAADC, NRF_SAADC_TASK_SAMPLE), + &ppi_handle); + if (err != 0) { + LOG_ERR("GPPI connection alloc failed: %d", err); + return; + } + + /* Alles einschalten */ + nrfx_gppi_conn_enable(ppi_handle); + nrfx_timer_enable(&adc_timer); + + /* 3. Zephyr ADC-Sequenz (Ohne Software-Intervall!) */ struct adc_sequence_options options = { .extra_samplings = SAMPLES_PER_BUFFER - 1, - .interval_us = 0, /* Kontinuierliches Sampling ohne Pause */ + .interval_us = 0, }; struct adc_sequence sequence = { .options = &options, - /* Dynamische Maske aus den geladenen DeviceTree-Spezifikationen */ .channels = BIT(adc_channels[0].channel_id) | BIT(adc_channels[1].channel_id) | BIT(adc_channels[2].channel_id) | @@ -217,8 +247,11 @@ void hw_adc_thread(void *p1, void *p2, void *p3) while (1) { sequence.buffer = adc_buffers[write_idx]; - /* Der Pointer adc_channels[0].dev zeigt auf den Haupt-ADC-Controller */ + /* Zephyr setzt den DMA-Speicher auf und wartet auf das Ende der 32 Samples. + * Den Startschuss für jedes einzelne Sample feuert ab sofort im Hintergrund + * das PPI-Modul exakt alle 75µs ab. Die CPU schläft hier tief und fest! */ int err = adc_read(adc_channels[0].dev, &sequence); + if (err < 0) { LOG_ERR("ADC read error: %d", err); k_msleep(10); @@ -432,6 +465,14 @@ int ir_recv_init(void) { channels[i].state = IR_STATE_IDLE; } + + #ifndef CONFIG_IR_RECV_SIMULATOR + int err = hw_adc_setup(); + if (err) { + return err; + } + #endif + LOG_DBG("IR Receiver initialized. Mode: %s", IS_ENABLED(CONFIG_IR_RECV_SIMULATOR) ? "Simulator" : "Hardware"); diff --git a/firmware/libs/ir/send/CMakeLists.txt b/firmware/libs/ir/send/CMakeLists.txt index 956ee18..7421b9b 100644 --- a/firmware/libs/ir/send/CMakeLists.txt +++ b/firmware/libs/ir/send/CMakeLists.txt @@ -1,5 +1,5 @@ if(CONFIG_IR_SEND) zephyr_library() - zephyr_sources(src/ir_send.c) + zephyr_library_sources(src/ir_send.c) zephyr_include_directories(include) endif() diff --git a/firmware/libs/lasertag_utils/CMakeLists.txt b/firmware/libs/lasertag_utils/CMakeLists.txt index 1d43725..638641f 100644 --- a/firmware/libs/lasertag_utils/CMakeLists.txt +++ b/firmware/libs/lasertag_utils/CMakeLists.txt @@ -1,10 +1,5 @@ if(CONFIG_LASERTAG_UTILS) - # Register this as a Zephyr library zephyr_library() - - # Add source files zephyr_library_sources(src/lasertag_utils.c) - - # Export the include directory to all applications zephyr_include_directories(include) endif() \ No newline at end of file diff --git a/firmware/libs/thread_mgmt/CMakeLists.txt b/firmware/libs/thread_mgmt/CMakeLists.txt index b64f237..35c906a 100644 --- a/firmware/libs/thread_mgmt/CMakeLists.txt +++ b/firmware/libs/thread_mgmt/CMakeLists.txt @@ -1,5 +1,5 @@ if(CONFIG_THREAD_MGMT) zephyr_library() - zephyr_sources(src/thread_mgmt.c) + zephyr_library_sources(src/thread_mgmt.c) zephyr_include_directories(include) endif() \ No newline at end of file