Refactor bit pattern matching.

Remove AccessCodeCorrelator, Unstuff classes.
This commit is contained in:
Jared Boone 2015-09-28 12:05:36 -07:00
parent f918a774b7
commit 36689f5c45
10 changed files with 116 additions and 150 deletions

View File

@ -140,7 +140,6 @@ CPPSRC = main.cpp \
proc_wideband_spectrum.cpp \
dsp_squelch.cpp \
clock_recovery.cpp \
access_code_correlator.cpp \
packet_builder.cpp \
dsp_fft.cpp \
dsp_fir_taps.cpp \

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of PortaPack.
*
* 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, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "access_code_correlator.hpp"
void AccessCodeCorrelator::configure(
const uint32_t new_code,
const size_t new_code_length,
const size_t new_maximum_hamming_distance
) {
if( new_code_length <= 32 ) {
code = new_code;
mask = mask_value(new_code_length);
maximum_hamming_distance = new_maximum_hamming_distance;
}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of PortaPack.
*
* 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, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __ACCESS_CODE_CORRELATOR_H__
#define __ACCESS_CODE_CORRELATOR_H__
#include <cstdint>
#include <cstddef>
class AccessCodeCorrelator {
public:
void configure(
const uint32_t new_code,
const size_t new_code_length,
const size_t new_maximum_hamming_distance
);
bool operator()(
const uint_fast8_t in
) {
history = (history << 1) | (in & 1);
const auto delta_bits = (history ^ code) & mask;
//const size_t count = __builtin_popcountll(delta_bits);
const size_t count = __builtin_popcountl(delta_bits);
return (count <= maximum_hamming_distance);
}
private:
uint32_t code { 0 };
uint32_t mask { 0 };
uint32_t history { 0 };
size_t maximum_hamming_distance { 0 };
static constexpr uint32_t mask_value(const size_t n) {
return static_cast<uint32_t>((1ULL << n) - 1ULL);
}
};
#endif/*__ACCESS_CODE_CORRELATOR_H__*/

View File

@ -59,7 +59,6 @@
#include "proc_wideband_spectrum.hpp"
#include "clock_recovery.hpp"
#include "access_code_correlator.hpp"
#include "packet_builder.hpp"
#include "message_queue.hpp"

View File

@ -22,11 +22,12 @@
#include "packet_builder.hpp"
void PacketBuilder::configure(
uint32_t unstuffing_pattern,
size_t unstuffing_length,
const BitPattern preamble,
const BitPattern unstuff,
size_t new_payload_length
) {
unstuff.configure(unstuffing_pattern, unstuffing_length);
preamble_pattern = preamble;
unstuff_pattern = unstuff;
if( new_payload_length <= payload.size() ) {
payload_length = new_payload_length;
@ -37,6 +38,5 @@ void PacketBuilder::configure(
void PacketBuilder::reset_state() {
bits_received = 0;
unstuff.reset();
state = State::AccessCodeSearch;
state = State::Preamble;
}

View File

@ -26,37 +26,38 @@
#include <cstddef>
#include <bitset>
#include "symbol_coding.hpp"
#include "bit_pattern.hpp"
class PacketBuilder {
public:
void configure(
uint32_t unstuffing_pattern,
size_t unstuffing_length,
const BitPattern preamble,
const BitPattern unstuffing,
size_t new_payload_length
);
template<typename PayloadHandler>
void execute(
const uint_fast8_t symbol,
const bool access_code_found,
PayloadHandler payload_handler
) {
bit_history.add(symbol);
switch(state) {
case State::AccessCodeSearch:
if( access_code_found ) {
case State::Preamble:
if( found_preamble() ) {
state = State::Payload;
}
break;
case State::Payload:
if( bits_received < payload_length ) {
if( !unstuff.is_stuffing_bit(symbol) ) {
payload[bits_received++] = symbol;
}
} else {
if( found_end_flag() || packet_truncated() ) {
payload_handler(payload, bits_received);
reset_state();
} else {
if( !found_stuffing_bit() ) {
payload[bits_received++] = symbol;
}
}
break;
@ -68,15 +69,35 @@ public:
private:
enum State {
AccessCodeSearch,
Preamble,
Payload,
};
bool packet_truncated() const {
return bits_received > payload.size();
}
bool found_preamble() const {
return bit_history.matches(preamble_pattern);
}
bool found_stuffing_bit() const {
return bit_history.matches(unstuff_pattern);
}
bool found_end_flag() const {
return bit_history.matches(end_flag_pattern);
}
BitHistory bit_history;
BitPattern preamble_pattern { 0b01010101010101010101111110, 26, 1 };
BitPattern unstuff_pattern { 0b111110, 6 };
BitPattern end_flag_pattern { 0b01111110, 8 };
size_t payload_length { 0 };
size_t bits_received { 0 };
State state { State::AccessCodeSearch };
State state { State::Preamble };
std::bitset<256> payload;
symbol_coding::Unstuff unstuff;
void reset_state();
};

View File

@ -45,14 +45,9 @@ FSKProcessor::~FSKProcessor() {
void FSKProcessor::configure(const FSKConfiguration new_configuration) {
// TODO: Matched filter characteristics are hard-coded for the moment. YUCK!
clock_recovery.configure(sampling_rate / 4, new_configuration.symbol_rate);
access_code_correlator.configure(
new_configuration.access_code,
new_configuration.access_code_length,
new_configuration.access_code_tolerance
);
packet_builder.configure(
new_configuration.unstuffing_pattern,
new_configuration.unstuffing_length,
{ new_configuration.access_code, new_configuration.access_code_length, new_configuration.access_code_tolerance },
{ new_configuration.unstuffing_pattern, new_configuration.unstuffing_length },
new_configuration.packet_length
);
}
@ -117,11 +112,9 @@ void FSKProcessor::consume_symbol(
const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0;
const auto decoded_symbol = nrzi_decode(sliced_symbol);
const bool access_code_found = access_code_correlator(decoded_symbol);
packet_builder.execute(
decoded_symbol,
access_code_found,
payload_handler_fn
);
}

View File

@ -31,7 +31,6 @@
#include "clock_recovery.hpp"
#include "symbol_coding.hpp"
#include "access_code_correlator.hpp"
#include "packet_builder.hpp"
#include "message.hpp"
@ -85,7 +84,6 @@ private:
[this](const float symbol) { this->consume_symbol(symbol); }
};
symbol_coding::NRZIDecoder nrzi_decode;
AccessCodeCorrelator access_code_correlator;
PacketBuilder packet_builder;
MessageHandlerMap& message_handlers;

View File

@ -39,33 +39,6 @@ private:
uint_fast8_t last { 0 };
};
class Unstuff {
public:
uint_fast8_t is_stuffing_bit(const uint_fast8_t symbol) {
history = (history << 1) | (symbol & 1);
return (history & mask) == match;
}
void configure(
const uint32_t pattern,
const size_t length
) {
// Ensure that length=0 (unstuffing disabled) never matches.
match = length ? pattern : 1;
mask = (1U << length) - 1;
reset();
}
void reset() {
history = 0;
}
private:
uint32_t history { 0 };
uint32_t match { 0b111110 };
uint32_t mask { 0b111111 };
};
} /* namespace symbol_coding */
#endif/*__SYMBOL_CODING_H__*/

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of PortaPack.
*
* 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, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __BIT_PATTERN_H__
#define __BIT_PATTERN_H__
#include <cstdint>
#include <cstddef>
class BitPattern {
public:
constexpr BitPattern(
const uint32_t code,
const size_t code_length,
const size_t maximum_hanning_distance = 0
) : code_ { code },
mask_ { (1UL << code_length) - 1UL },
maximum_hanning_distance_ { maximum_hanning_distance }
{
}
uint32_t code() const {
return code_;
}
uint32_t mask() const {
return mask_;
}
size_t maximum_hanning_distance() const {
return maximum_hanning_distance_;
}
private:
uint32_t code_;
uint32_t mask_;
size_t maximum_hanning_distance_;
};
class BitHistory {
public:
void add(const uint_fast8_t bit) {
history = (history << 1) | (bit & 1);
}
bool matches(const BitPattern& pattern) const {
const auto delta_bits = (history ^ pattern.code()) & pattern.mask();
const size_t count = __builtin_popcountl(delta_bits);
return (count <= pattern.maximum_hanning_distance());
}
private:
uint32_t history { 0 };
};
#endif/*__BIT_PATTERN_H__*/