sync during ir_recv dev
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s

This commit is contained in:
2026-02-16 17:09:15 +01:00
parent 2a4d007805
commit f012ce9fe0
12 changed files with 83 additions and 38 deletions

View File

@@ -17,7 +17,7 @@
reg = <0>;
zephyr,gain = "ADC_GAIN_1_4";
zephyr,reference = "ADC_REF_VDD_1_4";
zephyr,acquisition-time = <ADC_ACQ_TIME_MICROSECONDS(15)>;
zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 15)>;
zephyr,input-positive = <NRF_SAADC_AIN0>; /* 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 = <ADC_ACQ_TIME_MICROSECONDS(15)>;
zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 15)>;
zephyr,input-positive = <NRF_SAADC_AIN1>; /* 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 = <ADC_ACQ_TIME_MICROSECONDS(15)>;
zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 15)>;
zephyr,input-positive = <NRF_SAADC_AIN2>; /* 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 = <ADC_ACQ_TIME_MICROSECONDS(15)>;
zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 15)>;
zephyr,input-positive = <NRF_SAADC_AIN3>; /* Pin P0.05 */
zephyr,resolution = <12>;
};

View File

@@ -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

View File

@@ -3,11 +3,11 @@
#include <lasertag_utils.h>
#include <ir_recv.h>
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();

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -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()

View File

@@ -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
endif

View File

@@ -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 <zephyr/drivers/adc.h>
#include <nrfx_timer.h>
#include <helpers/nrfx_gppi.h>
#include <hal/nrf_saadc.h>
/* 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");

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()