From e5e0e19989fccb1b0aa8d38f485e6472bdfd04f3 Mon Sep 17 00:00:00 2001 From: Tommy Vestermark Date: Sun, 28 Jun 2015 23:15:56 +0200 Subject: [PATCH] Add pulse demodulator for PWM. Separate bitbuffer into own file. Made a prototype for a PWM pulse demodulator. Broke out bit_packet functions into own file to avoid circular references and for clean up. Compiles cleanly, but untested. --- include/bitbuffer.h | 47 +++++++++++++++++++++++ include/pulse_demod.h | 26 +++++++++++++ src/CMakeLists.txt | 2 + src/bitbuffer.c | 60 +++++++++++++++++++++++++++++ src/pulse_demod.c | 88 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 223 insertions(+) create mode 100644 include/bitbuffer.h create mode 100644 include/pulse_demod.h create mode 100644 src/bitbuffer.c create mode 100644 src/pulse_demod.c diff --git a/include/bitbuffer.h b/include/bitbuffer.h new file mode 100644 index 00000000..207a3bd5 --- /dev/null +++ b/include/bitbuffer.h @@ -0,0 +1,47 @@ +/** + * Bit buffer + * + * A two-dimensional bit buffer consisting of bytes + * + * Copyright (C) 2015 Tommy Vestermark + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef INCLUDE_BITBUFFER_H_ +#define INCLUDE_BITBUFFER_H_ + +#include + +#define BITBUF_COLS 34 // Number of bytes in a column +#define BITBUF_ROWS 50 + + +/// Bit buffer +typedef struct { + int row_index; // Number of active rows - 1 + int bit_col_index; // Bit index into byte (0 is MSB, 7 is LSB) + int16_t bits_per_row[BITBUF_ROWS]; + uint8_t bits_buffer[BITBUF_ROWS][BITBUF_COLS]; +} bitbuffer_t; + + +/// Clear the content of the bitbuffer +void bitbuffer_clear(bitbuffer_t *bits); + +/// Add a single bit at the end of the bitbuffer (MSB first) +void bitbuffer_add_bit(bitbuffer_t *bits, int bit); + +/// Add a new row to the bitbuffer +void bitbuffer_add_row(bitbuffer_t *bits); + +/// Invert all bits in the bitbuffer (do not invert the empty bits) +//void bitbuffer_invert(bitbuffer_t *bits); + +/// Print the content of the bitbuffer +void bitbuffer_print(const bitbuffer_t *bits); + + +#endif /* INCLUDE_BITBUFFER_H_ */ diff --git a/include/pulse_demod.h b/include/pulse_demod.h new file mode 100644 index 00000000..a2f52678 --- /dev/null +++ b/include/pulse_demod.h @@ -0,0 +1,26 @@ +/** + * Pulse demodulation functions + * + * Binary demodulators (PWM/PPM/Manchester/...) using a pulse data structure as input + * + * Copyright (C) 2015 Tommy Vestermark + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef INCLUDE_PULSE_DEMOD_H_ +#define INCLUDE_PULSE_DEMOD_H_ + +#include +#include "pulse_detect.h" +#include "rtl_433_devices.h" + + +/// Demodulate a plain Pulse Width Modulation signal +/// @return number of events processed +int pulse_demod_pwm_raw(const pulse_data_t *pulses, r_device *device); + + +#endif /* INCLUDE_PULSE_DEMOD_H_ */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c6856abf..f39036a8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,8 @@ ######################################################################## add_executable(rtl_433 rtl_433.c + bitbuffer.c + pulse_demod.c pulse_detect.c devices/silvercrest.c devices/rubicson.c diff --git a/src/bitbuffer.c b/src/bitbuffer.c new file mode 100644 index 00000000..796e33fc --- /dev/null +++ b/src/bitbuffer.c @@ -0,0 +1,60 @@ +/** + * Bit buffer + * + * A two-dimensional bit buffer consisting of bytes + * + * Copyright (C) 2015 Tommy Vestermark + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "bitbuffer.h" +#include +#include + + +void bitbuffer_clear(bitbuffer_t *bits) { + bits->row_index = 0; + bits->bit_col_index = 0; + memset(bits->bits_per_row, 0, BITBUF_ROWS*2); + memset(bits->bits_buffer, 0, BITBUF_ROWS * BITBUF_COLS); +} + + +void bitbuffer_add_bit(bitbuffer_t *bits, int bit) { + uint16_t col_index = bits->bits_per_row[bits->row_index]/8; + if(col_index < BITBUF_COLS) { + bits->bits_buffer[bits->row_index][col_index] |= bit << (7-bits->bit_col_index); + bits->bit_col_index++; + bits->bit_col_index %= 8; // Wrap around + bits->bits_per_row[bits->row_index]++; + } + else { + fprintf(stderr, "ERROR: bitbuffer:: Could not add more columns\n"); + } +} + + +void bitbuffer_add_row(bitbuffer_t *bits) { + if(bits->row_index < BITBUF_ROWS) { + bits->row_index++; + bits->bit_col_index = 0; + } + else { + fprintf(stderr, "ERROR: bitbuffer:: Could not add more rows\n"); + } +} + + +void bitbuffer_print(const bitbuffer_t *bits) { + fprintf(stderr, "bitbuffer:: row_index: %d, bit_col_index: %d\n", bits->row_index, bits->bit_col_index); + for (int row = 0; row <= bits->row_index; ++row) { + fprintf(stderr, "[%02d] {%d} ", row, bits->bits_per_row[row]); + for (int col = 0; col < (bits->bits_per_row[row]+7)/8; ++col) { + fprintf(stderr, "%02x ", bits->bits_buffer[row][col]); + } + fprintf(stderr, "\n"); + } +} diff --git a/src/pulse_demod.c b/src/pulse_demod.c new file mode 100644 index 00000000..742d076b --- /dev/null +++ b/src/pulse_demod.c @@ -0,0 +1,88 @@ +/** + * Pulse demodulation functions + * + * Binary demodulators (PWM/PPM/Manchester/...) using a pulse data structure as input + * + * Copyright (C) 2015 Tommy Vestermark + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "pulse_demod.h" +#include "bitbuffer.h" +#include + +int pulse_demod_pwm_raw(const pulse_data_t *pulses, r_device *device) { + int events = 0; + bitbuffer_t bits = {0}; + for(unsigned n = 0; n < pulses->num_pulses; ++n) { + if(pulses->pulse[n] <= device->short_limit) { + bitbuffer_add_bit(&bits, 1); + } else { + bitbuffer_add_bit(&bits, 0); + } + + if(pulses->gap[n] > device->reset_limit) { + if (device->json_callback) { + events += device->json_callback(bits.bits_buffer, bits.bits_per_row); + bitbuffer_clear(&bits); + } else { + bitbuffer_print(&bits); + } + } else if(pulses->gap[n] >= device->long_limit) { + bitbuffer_add_row(&bits); + } + } + return events; +} +/* +/// Pulse Width Modulation. No startbit removal +static void pwm_raw_decode(struct dm_state *demod, struct protocol_state* p, int16_t *buf, uint32_t len) { + unsigned int i; + for (i = 0; i < len; i++) { + if (p->start_c) p->sample_counter++; + + // Detect Pulse Start (leading edge) + if (!p->pulse_start && (buf[i] > demod->level_limit)) { + p->pulse_start = 1; + p->sample_counter = 0; + // Check for first bit in sequence + if(!p->start_c) { + p->start_c = 1; + } + } + + // Detect Pulse End (trailing edge) + if (p->pulse_start && (buf[i] < demod->level_limit)) { + p->pulse_start = 0; + if (p->sample_counter <= p->short_limit) { + demod_add_bit(p, 1); + } else { + demod_add_bit(p, 0); + } + } + + // Detect Pulse period overrun + if (p->sample_counter == p->long_limit) { + demod_next_bits_packet(p); + } + + // Detect Pulse exceeding reset limit + if (p->sample_counter > p->reset_limit) { + p->sample_counter = 0; + p->start_c = 0; + p->pulse_start = 0; + + if (p->callback) + events+=p->callback(p->bits_buffer, p->bits_per_row); + else + demod_print_bits_packet(p); + + demod_reset_bits_packet(p); + } + } +} + +*/