From 480baa97fa6a1bf17f1669956b295cda72b334e8 Mon Sep 17 00:00:00 2001 From: Eduard Iten Date: Mon, 16 Feb 2026 15:06:27 +0100 Subject: [PATCH] sync during ir_recv dev --- firmware/apps/_samples/ir_recv_sim/src/main.c | 13 +- firmware/libs/ir/recv/src/ir_recv.c | 206 ++++++++++-------- 2 files changed, 117 insertions(+), 102 deletions(-) diff --git a/firmware/apps/_samples/ir_recv_sim/src/main.c b/firmware/apps/_samples/ir_recv_sim/src/main.c index 55bf5d9..9c615ab 100644 --- a/firmware/apps/_samples/ir_recv_sim/src/main.c +++ b/firmware/apps/_samples/ir_recv_sim/src/main.c @@ -13,24 +13,25 @@ int main(void) ir_packet_t test_packet = {0}; + /* Test 1: Perfektes Signal */ LOG_INF("Sending perfect packet..."); test_packet.data.fields.type = 1; test_packet.data.fields.id = 42; test_packet.data.fields.value = 15; ir_recv_sim_send_packet(&test_packet, NULL); - k_msleep(100); + k_msleep(1000); LOG_INF("Sending noisy packet with high jitter..."); test_packet.data.fields.id = 255; ir_sim_error_t ext_error = { - .noise_flips_per_8 = 1, /* 2 von 8 Samples pro Block sind falsch */ - .jitter_mark = 1, /* Mark schwankt zwischen 6 und 10 Samples */ - .jitter_space_0 = 1, /* Space0 schwankt zwischen 4 und 12 Samples */ - .jitter_space_1 = 1 /* Space1 schwankt zwischen 14 und 18 Samples */ + .noise_flips_per_8 = 2, /* 2 von 8 Samples pro Block sind falsch */ + .jitter_mark = 2, /* Mark schwankt zwischen 6 und 10 Samples */ + .jitter_space_0 = 4, /* Space0 schwankt zwischen 4 und 12 Samples */ + .jitter_space_1 = 2 /* Space1 schwankt zwischen 14 und 18 Samples */ }; - ir_recv_sim_send_packet(&test_packet, &ext_error); + ir_recv_sim_send_packet(&test_packet, NULL);//&ext_error); return 0; } \ No newline at end of file diff --git a/firmware/libs/ir/recv/src/ir_recv.c b/firmware/libs/ir/recv/src/ir_recv.c index 707d644..6f40603 100644 --- a/firmware/libs/ir/recv/src/ir_recv.c +++ b/firmware/libs/ir/recv/src/ir_recv.c @@ -34,107 +34,122 @@ static uint32_t sim_sample_pos = 0; /* Hilfsfunktion für den Jitter: Liefert einen Zufallswert zwischen -max und +max */ static int get_jitter(uint8_t max_jitter) { - if (max_jitter == 0) return 0; - return (int)(sys_rand32_get() % (max_jitter * 2 + 1)) - max_jitter; + if (max_jitter == 0) + return 0; + return (int)(sys_rand32_get() % (max_jitter * 2 + 1)) - max_jitter; } void ir_recv_sim_send_packet(ir_packet_t *packet, ir_sim_error_t *err) { - /* Blockieren, bis vorheriges Paket abgearbeitet ist */ - while (sim_trigger) { - k_msleep(5); - } + /* Blockieren, bis vorheriges Paket abgearbeitet ist */ + while (sim_trigger) + { + k_msleep(5); + } - ir_packet_t pkt; - memcpy(&pkt, packet, sizeof(ir_packet_t)); - pkt.data.fields.crc = lastertag_crc8(pkt.data.bytes, 2); + ir_packet_t pkt; + memcpy(&pkt, packet, sizeof(ir_packet_t)); + pkt.data.fields.crc = lastertag_crc8(pkt.data.bytes, 2); - ir_sim_error_t default_err = {0}; - if (err == NULL) { - err = &default_err; - } + ir_sim_error_t default_err = {0}; + if (err == NULL) + { + err = &default_err; + } - sim_total_samples = 0; + sim_total_samples = 0; - /* 1. Header Mark */ - int m_len = 32 + get_jitter(err->jitter_mark); - for (int i = 0; i < m_len && sim_total_samples < SIM_MAX_SAMPLES; i++) { - sim_buffer[sim_total_samples++] = 1; - } + /* 1. Header Mark */ + int m_len = 32 + get_jitter(err->jitter_mark); + for (int i = 0; i < m_len && sim_total_samples < SIM_MAX_SAMPLES; i++) + { + sim_buffer[sim_total_samples++] = 1; + } - /* 2. Header Gap */ - int g_len = 8 + get_jitter(err->jitter_space_0); - for (int i = 0; i < g_len && sim_total_samples < SIM_MAX_SAMPLES; i++) { - sim_buffer[sim_total_samples++] = 0; - } + /* 2. Header Gap */ + int g_len = 8 + get_jitter(err->jitter_space_0); + for (int i = 0; i < g_len && sim_total_samples < SIM_MAX_SAMPLES; i++) + { + sim_buffer[sim_total_samples++] = 0; + } - /* 3. Payload Bits (24 Bit) */ - for (int i = 0; i < 24; i++) { - bool bit = (pkt.data.bytes[i / 8] >> (i % 8)) & 1; - - /* Space Phase */ - int s_base = bit ? 16 : 8; - int s_jit = bit ? get_jitter(err->jitter_space_1) : get_jitter(err->jitter_space_0); - int s_len = s_base + s_jit; - for (int j = 0; j < s_len && sim_total_samples < SIM_MAX_SAMPLES; j++) { - sim_buffer[sim_total_samples++] = 0; - } - - /* Mark Phase */ - int bm_len = 8 + get_jitter(err->jitter_mark); - for (int j = 0; j < bm_len && sim_total_samples < SIM_MAX_SAMPLES; j++) { - sim_buffer[sim_total_samples++] = 1; - } - } + /* 3. Payload Bits (24 Bit) */ + for (int i = 0; i < 24; i++) + { + bool bit = (pkt.data.bytes[i / 8] >> (i % 8)) & 1; - /* 4. Rauschen injizieren (Bit Flips) */ - if (err->noise_flips_per_8 > 0) { - for (uint32_t i = 0; i < sim_total_samples; i += 8) { - for (int f = 0; f < err->noise_flips_per_8; f++) { - uint32_t flip_idx = i + (sys_rand32_get() % 8); - if (flip_idx < sim_total_samples) { - sim_buffer[flip_idx] = !sim_buffer[flip_idx]; /* Bit kippen */ - } - } - } - } + /* Space Phase */ + int s_base = bit ? 16 : 8; + int s_jit = bit ? get_jitter(err->jitter_space_1) : get_jitter(err->jitter_space_0); + int s_len = s_base + s_jit; + for (int j = 0; j < s_len && sim_total_samples < SIM_MAX_SAMPLES; j++) + { + sim_buffer[sim_total_samples++] = 0; + } - sim_sample_pos = 0; - sim_trigger = true; + /* Mark Phase */ + int bm_len = 8 + get_jitter(err->jitter_mark); + for (int j = 0; j < bm_len && sim_total_samples < SIM_MAX_SAMPLES; j++) + { + sim_buffer[sim_total_samples++] = 1; + } + } - LOG_DBG("Simulator: Queued (Type: %u, CRC: 0x%02X), Total Samples: %u", - pkt.data.fields.type, pkt.data.fields.crc, sim_total_samples); + /* 4. Rauschen injizieren (Bit Flips) */ + if (err->noise_flips_per_8 > 0) + { + for (uint32_t i = 0; i < sim_total_samples; i += 8) + { + for (int f = 0; f < err->noise_flips_per_8; f++) + { + uint32_t flip_idx = i + (sys_rand32_get() % 8); + if (flip_idx < sim_total_samples) + { + sim_buffer[flip_idx] = !sim_buffer[flip_idx]; /* Bit kippen */ + } + } + } + } + + sim_sample_pos = 0; + sim_trigger = true; + + LOG_DBG("Simulator: Queued (Type: %u, CRC: 0x%02X), Total Samples: %u", + pkt.data.fields.type, pkt.data.fields.crc, sim_total_samples); } void ir_recv_sim_thread(void *p1, void *p2, void *p3) { - while (1) - { - k_usleep(75 * SAMPLES_PER_BUFFER); - if (!sim_trigger) continue; + while (1) + { + k_usleep(75 * SAMPLES_PER_BUFFER); + if (!sim_trigger) + continue; - int16_t *buf = adc_buffers[write_idx]; - for (int i = 0; i < SAMPLES_PER_BUFFER; i++) - { - bool level = 0; - if (sim_sample_pos < sim_total_samples) { - level = sim_buffer[sim_sample_pos++]; - } - - bool active = IS_ENABLED(CONFIG_IR_RECV_INVERT_SIGNAL) ? !level : level; - buf[i * ADC_CHANNELS] = active ? 0x0FFF : 0x0000; - buf[i * ADC_CHANNELS + 3] = 2400; // VBat Dummy - } - write_idx = (write_idx + 1) % BUFFER_COUNT; - k_sem_give(&adc_sem); + int16_t *buf = adc_buffers[write_idx]; + for (int i = 0; i < SAMPLES_PER_BUFFER; i++) + { + bool level = 0; + if (sim_sample_pos < sim_total_samples) + { + level = sim_buffer[sim_sample_pos]; + } + sim_sample_pos++; /* Unbedingtes Inkrement */ - /* Nach dem Puffer noch eine kurze Pause einhalten, um das Paket abzuschließen */ - if (sim_sample_pos >= sim_total_samples + 50) - { - sim_trigger = false; - LOG_INF("Simulation sequence finished."); - } - } + bool active = IS_ENABLED(CONFIG_IR_RECV_INVERT_SIGNAL) ? !level : level; + buf[i * ADC_CHANNELS] = active ? 0x0FFF : 0x0000; + buf[i * ADC_CHANNELS + 3] = 2400; // VBat Dummy + } + write_idx = (write_idx + 1) % BUFFER_COUNT; + k_sem_give(&adc_sem); + + /* Nach dem Puffer noch eine kurze Pause einhalten, um das Paket abzuschließen */ + if (sim_sample_pos >= sim_total_samples + 50) + { + sim_trigger = false; + LOG_INF("Simulation sequence finished."); + } + } } K_THREAD_DEFINE(sim_tid, 1024, ir_recv_sim_thread, NULL, NULL, NULL, 5, 0, 0); #endif @@ -175,7 +190,7 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) /* Energie über 32 Samples (Header) und 8 Samples (Bits) berechnen */ uint8_t energy_32 = __builtin_popcount(ctx->sample_window); - uint8_t energy_8 = __builtin_popcount(ctx->sample_window & 0xFF); + uint8_t energy_8 = __builtin_popcount(ctx->sample_window & 0xFF); switch (ctx->state) { @@ -206,7 +221,7 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) case IR_STATE_FIND_MARK: ctx->timer++; - + if (energy_8 >= 4) { ctx->state = IR_STATE_SYNC_MARK; @@ -232,13 +247,13 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) if (ctx->sync_window >= 10) { - if (ctx->max_energy >= 6) + if (ctx->max_energy >= 6) { - bool bit = (ctx->timer_at_max >= 20); - + bool bit = (ctx->timer_at_max >= 20); + ctx->bit_acc = (ctx->bit_acc >> 1) | (bit ? (1 << 23) : 0); - - LOG_DBG("Bit %u: %d (T_Max:%u, E_Max:%u)", + + LOG_DBG("Bit %u: %d (T_Max:%u, E_Max:%u)", ctx->bit_count, bit, ctx->timer_at_max, ctx->max_energy); if (++ctx->bit_count >= 24) @@ -248,7 +263,6 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) else { ctx->state = IR_STATE_FIND_MARK; - ctx->timer = ctx->timer - ctx->timer_at_max; } @@ -268,12 +282,12 @@ static void process_ir_sample(ir_ctx_t *ctx, int16_t raw) p.data.bytes[2] = (ctx->bit_acc >> 16) & 0xFF; if (lastertag_crc8(p.data.bytes, 2) == p.data.fields.crc) - { - LOG_INF("VALID: Type %u, ID %u, Val %u", - p.data.fields.type, - p.data.fields.id, - p.data.fields.value); - } + { + LOG_INF("VALID: Type %u, ID %u, Val %u", + p.data.fields.type, + p.data.fields.id, + p.data.fields.value); + } else { LOG_WRN("CRC Error! Acc: 0x%06X", ctx->bit_acc);