mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-27 09:59:03 +00:00
Support squelch in pocsag (#1415)
* Support squelch in pocsag * Revert smooth threshold
This commit is contained in:
@@ -38,9 +38,7 @@ constexpr iir_biquad_config_t audio_48k_hpf_300hz_config{
|
||||
// scipy.signal.butter(2, 300 / 12000.0, 'highpass', analog=False)
|
||||
constexpr iir_biquad_config_t audio_24k_hpf_300hz_config{
|
||||
{0.94597686f, -1.89195371f, 0.94597686f},
|
||||
{1.00000000f, -1.88903308f, 0.89487434f}
|
||||
|
||||
};
|
||||
{1.00000000f, -1.88903308f, 0.89487434f}};
|
||||
|
||||
// scipy.signal.butter(2, 30 / 12000.0, 'highpass', analog=False)
|
||||
constexpr iir_biquad_config_t audio_24k_hpf_30hz_config{
|
||||
|
||||
@@ -225,30 +225,14 @@ void pocsag_encode(const MessageType type, BCHCode& BCH_code, const uint32_t fun
|
||||
} while (char_idx < message_size);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// Get the number of bits that differ between the two values.
|
||||
// -------------------------------------------------------------------------------
|
||||
inline uint8_t bitsDiff(unsigned long left, unsigned long right) {
|
||||
unsigned long xord = left ^ right;
|
||||
uint8_t count = 0;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if ((xord & 0x01) == 1) ++count;
|
||||
xord = xord >> 1;
|
||||
}
|
||||
|
||||
return (count);
|
||||
// ----------------------------------------------------------------------------
|
||||
// EccContainer
|
||||
// ----------------------------------------------------------------------------
|
||||
EccContainer::EccContainer() {
|
||||
setup_ecc();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------------
|
||||
static uint32_t ecs[32]; /* error correction sequence */
|
||||
static uint32_t bch[1025];
|
||||
static int eccSetup = 0;
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------------
|
||||
void setupecc() {
|
||||
void EccContainer::setup_ecc() {
|
||||
unsigned int srr = 0x3b4;
|
||||
unsigned int i, n, j, k;
|
||||
|
||||
@@ -311,23 +295,12 @@ void setupecc() {
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------------
|
||||
inline int errorCorrection(uint32_t& val) {
|
||||
// Set up the tables the first time
|
||||
if (eccSetup == 0) {
|
||||
setupecc();
|
||||
eccSetup = 1;
|
||||
}
|
||||
|
||||
int EccContainer::error_correct(uint32_t& val) {
|
||||
int i, synd, errl, acc, pari, ecc, b1, b2;
|
||||
|
||||
errl = 0;
|
||||
pari = 0;
|
||||
|
||||
/* run through error detection and correction routine */
|
||||
|
||||
// for (i=0; i<=20; i++)
|
||||
ecc = 0;
|
||||
for (i = 31; i >= 11; --i) {
|
||||
if (val & (1 << i)) {
|
||||
@@ -336,7 +309,6 @@ inline int errorCorrection(uint32_t& val) {
|
||||
}
|
||||
}
|
||||
|
||||
// for (i=21; i<=30; i++)
|
||||
acc = 0;
|
||||
for (i = 10; i >= 1; --i) {
|
||||
acc = acc << 1;
|
||||
@@ -390,8 +362,8 @@ bool pocsag_decode_batch(const POCSAGPacket& batch, POCSAGState& state) {
|
||||
|
||||
// Error correct twice. First time to fix any errors it can,
|
||||
// second time to count number of errors that couldn't be fixed.
|
||||
errorCorrection(codeword);
|
||||
auto error_count = errorCorrection(codeword);
|
||||
state.ecc->error_correct(codeword);
|
||||
auto error_count = state.ecc->error_correct(codeword);
|
||||
|
||||
switch (state.mode) {
|
||||
case STATE_CLEAR:
|
||||
|
||||
@@ -56,23 +56,46 @@ enum MessageType : uint32_t {
|
||||
ALPHANUMERIC
|
||||
};
|
||||
|
||||
/* Holds error correction arrays. This allows the arrays to
|
||||
* be freed when POCSAG is not running, saving ~4kb of RAM. */
|
||||
class EccContainer {
|
||||
public:
|
||||
EccContainer();
|
||||
|
||||
EccContainer(const EccContainer&) = delete;
|
||||
EccContainer(EccContainer&&) = delete;
|
||||
EccContainer& operator=(const EccContainer&) = delete;
|
||||
EccContainer& operator=(EccContainer&&) = delete;
|
||||
|
||||
int error_correct(uint32_t& val);
|
||||
|
||||
private:
|
||||
void setup_ecc();
|
||||
|
||||
/* error correction sequence */
|
||||
uint32_t ecs[32];
|
||||
uint32_t bch[1025];
|
||||
};
|
||||
|
||||
struct POCSAGState {
|
||||
uint8_t codeword_index;
|
||||
uint32_t function;
|
||||
uint32_t address;
|
||||
EccContainer* ecc = nullptr;
|
||||
uint8_t codeword_index = 0;
|
||||
uint32_t function = 0;
|
||||
uint32_t address = 0;
|
||||
Mode mode = STATE_CLEAR;
|
||||
OutputType out_type = EMPTY;
|
||||
uint32_t ascii_data;
|
||||
uint32_t ascii_idx;
|
||||
uint32_t errors;
|
||||
std::string output;
|
||||
uint32_t ascii_data = 0;
|
||||
uint32_t ascii_idx = 0;
|
||||
uint32_t errors = 0;
|
||||
std::string output{};
|
||||
};
|
||||
|
||||
const pocsag::BitRate pocsag_bitrates[4] = {
|
||||
pocsag::BitRate::FSK512,
|
||||
pocsag::BitRate::FSK1200,
|
||||
pocsag::BitRate::FSK2400,
|
||||
pocsag::BitRate::FSK3200};
|
||||
pocsag::BitRate::FSK3200,
|
||||
};
|
||||
|
||||
std::string bitrate_str(BitRate bitrate);
|
||||
std::string flag_str(PacketFlag packetflag);
|
||||
|
||||
Reference in New Issue
Block a user