sync during ir_recv dev
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user