diff --git a/include/bitbuffer.h b/include/bitbuffer.h index 1621948f..b093f833 100644 --- a/include/bitbuffer.h +++ b/include/bitbuffer.h @@ -15,22 +15,21 @@ #include -#define BITBUF_COLS 256 // Number of bytes in a column -#define BITBUF_ROWS 25 -#define BITBUF_MAX_PRINT_BITS 50 // Maximum number of bits to print (in addition to hex values) +#define BITBUF_COLS 256 // Number of bytes in a column +#define BITBUF_ROWS 25 +#define BITBUF_MAX_PRINT_BITS 50 // Maximum number of bits to print (in addition to hex values) typedef uint8_t bitrow_t[BITBUF_COLS]; typedef bitrow_t bitarray_t[BITBUF_ROWS]; /// Bit buffer typedef struct bitbuffer { - uint16_t num_rows; // Number of active rows - uint16_t bits_per_row[BITBUF_ROWS]; // Number of active bits per row - uint16_t syncs_before_row[BITBUF_ROWS]; // Number of sync pulses before row - bitarray_t bb; // The actual bits buffer + uint16_t num_rows; // Number of active rows + uint16_t bits_per_row[BITBUF_ROWS]; // Number of active bits per row + uint16_t syncs_before_row[BITBUF_ROWS]; // Number of sync pulses before row + bitarray_t bb; // The actual bits buffer } bitbuffer_t; - /// Clear the content of the bitbuffer void bitbuffer_clear(bitbuffer_t *bits); @@ -45,7 +44,7 @@ void bitbuffer_add_sync(bitbuffer_t *bits); /// Extract (potentially unaligned) bytes from the bit buffer. Len is bits. void bitbuffer_extract_bytes(bitbuffer_t *bitbuffer, unsigned row, - unsigned pos, uint8_t *out, unsigned len); + unsigned pos, uint8_t *out, unsigned len); /// Invert all bits in the bitbuffer (do not invert the empty bits) void bitbuffer_invert(bitbuffer_t *bits); @@ -71,7 +70,7 @@ void bitbuffer_parse(bitbuffer_t *bits, const char *code); // The pattern starts in the high bit. For example if searching for 011011 // the byte pointed to by 'pattern' would be 0xAC. (011011xx). unsigned bitbuffer_search(bitbuffer_t *bitbuffer, unsigned row, unsigned start, - const uint8_t *pattern, unsigned pattern_bits_len); + const uint8_t *pattern, unsigned pattern_bits_len); // Manchester decoding from one bitbuffer into another, starting at the // specified row and start bit. Decode at most 'max' data bits (i.e. 2*max) @@ -79,7 +78,7 @@ unsigned bitbuffer_search(bitbuffer_t *bitbuffer, unsigned row, unsigned start, // (i.e. returns start + 2*outbuf->bits_per_row[0]). // per IEEE 802.3 conventions, i.e. high-low is a 0 bit, low-high is a 1 bit. unsigned bitbuffer_manchester_decode(bitbuffer_t *inbuf, unsigned row, unsigned start, - bitbuffer_t *outbuf, unsigned max); + bitbuffer_t *outbuf, unsigned max); // Differential Manchester decoding from one bitbuffer into another, starting at the // specified row and start bit. Decode at most 'max' data bits (i.e. 2*max) @@ -100,14 +99,14 @@ int bitbuffer_find_repeated_row(bitbuffer_t *bits, unsigned min_repeats, unsigne /// Return a single bit from a bitrow at bit_idx position static inline uint8_t bitrow_get_bit(const bitrow_t bitrow, unsigned bit_idx) { - return bitrow[bit_idx >> 3] >> (7 - (bit_idx & 7)) & 1; + return bitrow[bit_idx >> 3] >> (7 - (bit_idx & 7)) & 1; } /// Return a single byte from a bitrow at bit_idx position (which may be unaligned) static inline uint8_t bitrow_get_byte(const bitrow_t bitrow, unsigned bit_idx) { - return ((bitrow[(bit_idx >> 3)] << (bit_idx & 7)) | - (bitrow[(bit_idx >> 3) + 1] >> (8 - (bit_idx & 7)))); + return ((bitrow[(bit_idx >> 3)] << (bit_idx & 7)) | + (bitrow[(bit_idx >> 3) + 1] >> (8 - (bit_idx & 7)))); } #endif /* INCLUDE_BITBUFFER_H_ */ diff --git a/src/bitbuffer.c b/src/bitbuffer.c index 315234fa..af5e0429 100644 --- a/src/bitbuffer.c +++ b/src/bitbuffer.c @@ -15,156 +15,158 @@ #include #include - -void bitbuffer_clear(bitbuffer_t *bits) { - bits->num_rows = 0; - memset(bits->bits_per_row, 0, BITBUF_ROWS*2); - memset(bits->bb, 0, BITBUF_ROWS * BITBUF_COLS); +void bitbuffer_clear(bitbuffer_t *bits) +{ + bits->num_rows = 0; + memset(bits->bits_per_row, 0, BITBUF_ROWS * 2); + memset(bits->bb, 0, BITBUF_ROWS * BITBUF_COLS); } - -void bitbuffer_add_bit(bitbuffer_t *bits, int bit) { - if(bits->num_rows == 0) bits->num_rows++; // Add first row automatically - uint16_t col_index = bits->bits_per_row[bits->num_rows-1] / 8; - uint16_t bit_index = bits->bits_per_row[bits->num_rows-1] % 8; - if((col_index < BITBUF_COLS) - && (bits->num_rows <= BITBUF_ROWS) - ) { - bits->bb[bits->num_rows-1][col_index] |= (bit << (7-bit_index)); - bits->bits_per_row[bits->num_rows-1]++; - } - else { -// fprintf(stderr, "ERROR: bitbuffer:: Could not add more columns\n"); // Some decoders may add many columns... - } +void bitbuffer_add_bit(bitbuffer_t *bits, int bit) +{ + if (bits->num_rows == 0) + bits->num_rows++; // Add first row automatically + uint16_t col_index = bits->bits_per_row[bits->num_rows - 1] / 8; + uint16_t bit_index = bits->bits_per_row[bits->num_rows - 1] % 8; + if ((col_index < BITBUF_COLS) && (bits->num_rows <= BITBUF_ROWS)) { + bits->bb[bits->num_rows - 1][col_index] |= (bit << (7 - bit_index)); + bits->bits_per_row[bits->num_rows - 1]++; + } + else { + // fprintf(stderr, "ERROR: bitbuffer:: Could not add more columns\n"); // Some decoders may add many columns... + } } - -void bitbuffer_add_row(bitbuffer_t *bits) { - if(bits->num_rows == 0) bits->num_rows++; // Add first row automatically - if(bits->num_rows < BITBUF_ROWS) { - bits->num_rows++; - } - else { - bits->bits_per_row[bits->num_rows-1] = 0; // Clear last row to handle overflow somewhat gracefully -// fprintf(stderr, "ERROR: bitbuffer:: Could not add more rows\n"); // Some decoders may add many rows... - } +void bitbuffer_add_row(bitbuffer_t *bits) +{ + if (bits->num_rows == 0) + bits->num_rows++; // Add first row automatically + if (bits->num_rows < BITBUF_ROWS) { + bits->num_rows++; + } + else { + bits->bits_per_row[bits->num_rows - 1] = 0; // Clear last row to handle overflow somewhat gracefully + // fprintf(stderr, "ERROR: bitbuffer:: Could not add more rows\n"); // Some decoders may add many rows... + } } - -void bitbuffer_add_sync(bitbuffer_t *bits) { - if (bits->num_rows == 0) bits->num_rows++; // Add first row automatically - if (bits->bits_per_row[bits->num_rows - 1]) { - bitbuffer_add_row(bits); - } - bits->syncs_before_row[bits->num_rows-1]++; +void bitbuffer_add_sync(bitbuffer_t *bits) +{ + if (bits->num_rows == 0) + bits->num_rows++; // Add first row automatically + if (bits->bits_per_row[bits->num_rows - 1]) { + bitbuffer_add_row(bits); + } + bits->syncs_before_row[bits->num_rows - 1]++; } - -void bitbuffer_invert(bitbuffer_t *bits) { - for (unsigned row = 0; row < bits->num_rows; ++row) { - if (bits->bits_per_row[row] > 0) { - const unsigned last_col = (bits->bits_per_row[row]-1) / 8; - const unsigned last_bits = ((bits->bits_per_row[row]-1) % 8) +1; - for (unsigned col = 0; col <= last_col; ++col) { - bits->bb[row][col] = ~bits->bb[row][col]; // Invert - } - bits->bb[row][last_col] ^= 0xFF >> last_bits; // Re-invert unused bits in last byte - } - } +void bitbuffer_invert(bitbuffer_t *bits) +{ + for (unsigned row = 0; row < bits->num_rows; ++row) { + if (bits->bits_per_row[row] > 0) { + const unsigned last_col = (bits->bits_per_row[row] - 1) / 8; + const unsigned last_bits = ((bits->bits_per_row[row] - 1) % 8) + 1; + for (unsigned col = 0; col <= last_col; ++col) { + bits->bb[row][col] = ~bits->bb[row][col]; // Invert + } + bits->bb[row][last_col] ^= 0xFF >> last_bits; // Re-invert unused bits in last byte + } + } } - void bitbuffer_extract_bytes(bitbuffer_t *bitbuffer, unsigned row, - unsigned pos, uint8_t *out, unsigned len) + unsigned pos, uint8_t *out, unsigned len) { - uint8_t *bits = bitbuffer->bb[row]; - if (len == 0) - return; - if ((pos & 7) == 0) { - memcpy(out, bits + (pos / 8), (len + 7) / 8); - } else { - unsigned shift = 8 - (pos & 7); - unsigned bytes = (len + 7) >> 3; - uint8_t *p = out; - uint16_t word; - pos = pos >> 3; // Convert to bytes + uint8_t *bits = bitbuffer->bb[row]; + if (len == 0) + return; + if ((pos & 7) == 0) { + memcpy(out, bits + (pos / 8), (len + 7) / 8); + } + else { + unsigned shift = 8 - (pos & 7); + unsigned bytes = (len + 7) >> 3; + uint8_t *p = out; + uint16_t word; + pos = pos >> 3; // Convert to bytes - word = bits[pos]; + word = bits[pos]; - while (bytes--) { - word <<= 8; - word |= bits[++pos]; - *(p++) = word >> shift; - } - } - if (len & 7) - out[(len - 1) / 8] &= 0xff00 >> (len & 7); // mask off bottom bits + while (bytes--) { + word <<= 8; + word |= bits[++pos]; + *(p++) = word >> shift; + } + } + if (len & 7) + out[(len - 1) / 8] &= 0xff00 >> (len & 7); // mask off bottom bits } // If we make this an inline function instead of a macro, it means we don't // have to worry about using bit numbers with side-effects (bit++). static inline int bit(const uint8_t *bytes, unsigned bit) { - return bytes[bit >> 3] >> (7 - (bit & 7)) & 1; + return bytes[bit >> 3] >> (7 - (bit & 7)) & 1; } unsigned bitbuffer_search(bitbuffer_t *bitbuffer, unsigned row, unsigned start, - const uint8_t *pattern, unsigned pattern_bits_len) + const uint8_t *pattern, unsigned pattern_bits_len) { - uint8_t *bits = bitbuffer->bb[row]; - unsigned len = bitbuffer->bits_per_row[row]; - unsigned ipos = start; - unsigned ppos = 0; // cursor on init pattern + uint8_t *bits = bitbuffer->bb[row]; + unsigned len = bitbuffer->bits_per_row[row]; + unsigned ipos = start; + unsigned ppos = 0; // cursor on init pattern - while (ipos < len && ppos < pattern_bits_len) { - if (bit(bits, ipos) == bit(pattern, ppos)) { - ppos++; - ipos++; - if (ppos == pattern_bits_len) - return ipos - pattern_bits_len; - } else { - ipos -= ppos; - ipos++; - ppos = 0; - } - } + while (ipos < len && ppos < pattern_bits_len) { + if (bit(bits, ipos) == bit(pattern, ppos)) { + ppos++; + ipos++; + if (ppos == pattern_bits_len) + return ipos - pattern_bits_len; + } + else { + ipos -= ppos; + ipos++; + ppos = 0; + } + } - // Not found - return len; + // Not found + return len; } unsigned bitbuffer_manchester_decode(bitbuffer_t *inbuf, unsigned row, unsigned start, - bitbuffer_t *outbuf, unsigned max) + bitbuffer_t *outbuf, unsigned max) { - uint8_t *bits = inbuf->bb[row]; - unsigned int len = inbuf->bits_per_row[row]; - unsigned int ipos = start; + uint8_t *bits = inbuf->bb[row]; + unsigned int len = inbuf->bits_per_row[row]; + unsigned int ipos = start; - if (max && len > start + (max * 2)) - len = start + (max * 2); + if (max && len > start + (max * 2)) + len = start + (max * 2); - while (ipos < len) { - uint8_t bit1, bit2; + while (ipos < len) { + uint8_t bit1, bit2; - bit1 = bit(bits, ipos++); - bit2 = bit(bits, ipos++); + bit1 = bit(bits, ipos++); + bit2 = bit(bits, ipos++); - if (bit1 == bit2) - break; + if (bit1 == bit2) + break; - bitbuffer_add_bit(outbuf, bit2); - } + bitbuffer_add_bit(outbuf, bit2); + } - return ipos; + return ipos; } unsigned bitbuffer_differential_manchester_decode(bitbuffer_t *inbuf, unsigned row, unsigned start, bitbuffer_t *outbuf, unsigned max) { - uint8_t *bits = inbuf->bb[row]; + uint8_t *bits = inbuf->bb[row]; unsigned int len = inbuf->bits_per_row[row]; unsigned int ipos = start; - uint8_t bit1, bit2=0, bit3; + uint8_t bit1, bit2 = 0, bit3; if (max && len > start + (max * 2)) len = start + (max * 2); @@ -179,16 +181,18 @@ unsigned bitbuffer_differential_manchester_decode(bitbuffer_t *inbuf, unsigned r if (bit1 != bit2) { if (bit2 != bit3) { bitbuffer_add_bit(outbuf, 0); - } else { - bit2 = bit1; - ipos -= 1; - break; - } - } else { - bit2 = 1 - bit1; - ipos -= 2; - break; - } + } + else { + bit2 = bit1; + ipos -= 1; + break; + } + } + else { + bit2 = 1 - bit1; + ipos -= 2; + break; + } } while (ipos < len) { @@ -220,7 +224,8 @@ static void print_bitrow(bitrow_t const bitrow, unsigned bit_len, unsigned highe for (unsigned bit = 0; bit < bit_len; ++bit) { if (bitrow[bit / 8] & (0x80 >> (bit % 8))) { fprintf(stderr, "1"); - } else { + } + else { fprintf(stderr, "0"); } if ((bit % 8) == 7) // Add byte separators @@ -236,7 +241,7 @@ static void print_bitbuffer(const bitbuffer_t *bits, int always_binary) unsigned col, row; /* Figure out the longest row of bit to get the highest_indent - */ + */ highest_indent = sizeof("[dd] {dd} ") - 1; for (row = indent_this_row = 0; row < bits->num_rows; ++row) { for (col = indent_this_col = 0; col < (unsigned)(bits->bits_per_row[row] + 7) / 8; ++col) { @@ -280,24 +285,25 @@ void bitrow_debug(bitrow_t const bitrow, unsigned bit_len) void bitbuffer_parse(bitbuffer_t *bits, const char *code) { const char *c; - int data = 0; + int data = 0; int width = -1; - bitbuffer_clear(bits); + bitbuffer_clear(bits); for (c = code; *c; ++c) { if (*c == ' ') { continue; - - } else if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) { + } + else if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) { ++c; continue; - - } else if (*c == '{') { + } + else if (*c == '{') { if (bits->num_rows == 0) { bits->num_rows++; - } else { + } + else { bitbuffer_add_row(bits); } if (width >= 0) { @@ -306,20 +312,22 @@ void bitbuffer_parse(bitbuffer_t *bits, const char *code) width = strtol(c + 1, (char **)&c, 0); continue; - - } else if (*c == '/') { + } + else if (*c == '/') { bitbuffer_add_row(bits); if (width >= 0) { bits->bits_per_row[bits->num_rows - 2] = width; width = -1; } continue; - - } else if (*c >= '0' && *c <= '9') { + } + else if (*c >= '0' && *c <= '9') { data = *c - '0'; - } else if (*c >= 'A' && *c <= 'F') { + } + else if (*c >= 'A' && *c <= 'F') { data = *c - 'A' + 10; - } else if (*c >= 'a' && *c <= 'f') { + } + else if (*c >= 'a' && *c <= 'f') { data = *c - 'a' + 10; } bitbuffer_add_bit(bits, data >> 3 & 0x01); @@ -335,79 +343,82 @@ void bitbuffer_parse(bitbuffer_t *bits, const char *code) } } -int compare_rows(bitbuffer_t *bits, unsigned row_a, unsigned row_b) { - return (bits->bits_per_row[row_a] == bits->bits_per_row[row_b] && - !memcmp(bits->bb[row_a], bits->bb[row_b], - (bits->bits_per_row[row_a] + 7) / 8)); +int compare_rows(bitbuffer_t *bits, unsigned row_a, unsigned row_b) +{ + return (bits->bits_per_row[row_a] == bits->bits_per_row[row_b] + && !memcmp(bits->bb[row_a], bits->bb[row_b], + (bits->bits_per_row[row_a] + 7) / 8)); } -unsigned count_repeats(bitbuffer_t *bits, unsigned row) { - unsigned cnt = 0; - for (int i = 0; i < bits->num_rows; ++i) { - if (compare_rows(bits, row, i)) { - ++cnt; - } - } - return cnt; +unsigned count_repeats(bitbuffer_t *bits, unsigned row) +{ + unsigned cnt = 0; + for (int i = 0; i < bits->num_rows; ++i) { + if (compare_rows(bits, row, i)) { + ++cnt; + } + } + return cnt; } -int bitbuffer_find_repeated_row(bitbuffer_t *bits, unsigned min_repeats, unsigned min_bits) { - for (int i = 0; i < bits->num_rows; ++i) { - if (bits->bits_per_row[i] >= min_bits && - count_repeats(bits, i) >= min_repeats) { - return i; - } - } - return -1; +int bitbuffer_find_repeated_row(bitbuffer_t *bits, unsigned min_repeats, unsigned min_bits) +{ + for (int i = 0; i < bits->num_rows; ++i) { + if (bits->bits_per_row[i] >= min_bits && + count_repeats(bits, i) >= min_repeats) { + return i; + } + } + return -1; } - // Unit testing #ifdef _TEST -int main(int argc, char **argv) { - fprintf(stderr, "bitbuffer:: test\n"); +int main(int argc, char **argv) +{ + fprintf(stderr, "bitbuffer:: test\n"); - bitbuffer_t bits = {0}; + bitbuffer_t bits = {0}; - fprintf(stderr, "TEST: bitbuffer:: The empty buffer\n"); - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: The empty buffer\n"); + bitbuffer_print(&bits); - fprintf(stderr, "TEST: bitbuffer:: Add 1 bit\n"); - bitbuffer_add_bit(&bits, 1); - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: Add 1 bit\n"); + bitbuffer_add_bit(&bits, 1); + bitbuffer_print(&bits); - fprintf(stderr, "TEST: bitbuffer:: Add 1 new row\n"); - bitbuffer_add_row(&bits); - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: Add 1 new row\n"); + bitbuffer_add_row(&bits); + bitbuffer_print(&bits); - fprintf(stderr, "TEST: bitbuffer:: Fill row\n"); - for (int i=0; i < BITBUF_COLS*8; ++i) { - bitbuffer_add_bit(&bits, i%2); - } - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: Fill row\n"); + for (int i = 0; i < BITBUF_COLS * 8; ++i) { + bitbuffer_add_bit(&bits, i % 2); + } + bitbuffer_print(&bits); - fprintf(stderr, "TEST: bitbuffer:: Add row and fill 1 column too many\n"); - bitbuffer_add_row(&bits); - for (int i=0; i <= BITBUF_COLS*8; ++i) { - bitbuffer_add_bit(&bits, i%2); - } - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: Add row and fill 1 column too many\n"); + bitbuffer_add_row(&bits); + for (int i = 0; i <= BITBUF_COLS * 8; ++i) { + bitbuffer_add_bit(&bits, i % 2); + } + bitbuffer_print(&bits); - fprintf(stderr, "TEST: bitbuffer:: invert\n"); - bitbuffer_invert(&bits); - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: invert\n"); + bitbuffer_invert(&bits); + bitbuffer_print(&bits); - fprintf(stderr, "TEST: bitbuffer:: Clear\n"); - bitbuffer_clear(&bits); - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: Clear\n"); + bitbuffer_clear(&bits); + bitbuffer_print(&bits); - fprintf(stderr, "TEST: bitbuffer:: Add 1 row too many\n"); - for (int i=0; i <= BITBUF_ROWS; ++i) { - bitbuffer_add_row(&bits); - } - bitbuffer_add_bit(&bits, 1); - bitbuffer_print(&bits); + fprintf(stderr, "TEST: bitbuffer:: Add 1 row too many\n"); + for (int i = 0; i <= BITBUF_ROWS; ++i) { + bitbuffer_add_row(&bits); + } + bitbuffer_add_bit(&bits, 1); + bitbuffer_print(&bits); - return 0; + return 0; } #endif /* _TEST */