Add TPMS initial demodulator implementation.

Right now, 2FSK, 19200 baud, +/-38400Hz deviation. No effort is made to check CRC/checksums or decode packets.
This commit is contained in:
Jared Boone
2015-11-10 15:19:56 -08:00
parent 6cdef7026d
commit 9f6c495fef
7 changed files with 227 additions and 0 deletions

View File

@@ -139,6 +139,7 @@ CPPSRC = main.cpp \
proc_wfm_audio.cpp \
proc_ais.cpp \
proc_wideband_spectrum.cpp \
proc_tpms.cpp \
dsp_squelch.cpp \
clock_recovery.cpp \
packet_builder.cpp \

View File

@@ -57,6 +57,7 @@
#include "proc_wfm_audio.hpp"
#include "proc_ais.hpp"
#include "proc_wideband_spectrum.hpp"
#include "proc_tpms.hpp"
#include "clock_recovery.hpp"
#include "packet_builder.hpp"
@@ -319,6 +320,10 @@ int main(void) {
baseband_processor = new WidebandSpectrum();
break;
case 5:
baseband_processor = new TPMSProcessor();
break;
default:
break;
}

View File

@@ -0,0 +1,73 @@
/*
* 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.
*/
#include "proc_tpms.hpp"
#include "portapack_shared_memory.hpp"
#include "i2s.hpp"
using namespace lpc43xx;
void TPMSProcessor::execute(buffer_c8_t buffer) {
/* 2.4576MHz, 2048 samples */
auto decimator_out = decimator.execute(buffer);
/* 76.8kHz, 64 samples */
feed_channel_stats(decimator_out);
/* No spectrum display while FSK decoding.
feed_channel_spectrum(
channel,
decimator_out.sampling_rate * channel_filter_taps.pass_frequency_normalized,
decimator_out.sampling_rate * channel_filter_taps.stop_frequency_normalized
);
*/
for(size_t i=0; i<decimator_out.count; i++) {
// TODO: No idea why implicit cast int16_t->float is not allowed.
const std::complex<float> sample {
static_cast<float>(decimator_out.p[i].real()),
static_cast<float>(decimator_out.p[i].imag())
};
if( mf.execute_once(sample) ) {
clock_recovery(mf.get_output());
}
}
i2s::i2s0::tx_mute();
}
void TPMSProcessor::consume_symbol(
const float raw_symbol
) {
const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0;
packet_builder.execute(sliced_symbol);
}
void TPMSProcessor::payload_handler(
const std::bitset<1024>& payload,
const size_t bits_received
) {
TPMSPacketMessage message;
message.packet.payload = payload;
message.packet.bits_received = bits_received;
shared_memory.application_queue.push(message);
}

View File

@@ -0,0 +1,91 @@
/*
* 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 __PROC_TPMS_H__
#define __PROC_TPMS_H__
#include "baseband_processor.hpp"
#include "channel_decimator.hpp"
#include "matched_filter.hpp"
#include "clock_recovery.hpp"
#include "symbol_coding.hpp"
#include "packet_builder.hpp"
#include "message.hpp"
#include <cstdint>
#include <cstddef>
#include <bitset>
struct NeverMatch {
bool operator()(const BitHistory&, const size_t) const {
return false;
}
};
struct FixedLength {
bool operator()(const BitHistory&, const size_t symbols_received) const {
return symbols_received >= length;
}
const size_t length;
};
// Translate+rectangular filter
// sample=153.6k, deviation=38400, symbol=19200
// Length: 8 taps, 1 symbols, 2 cycles of sinusoid
constexpr std::array<std::complex<float>, 8> rect_taps_153k6_1t_p { {
{ 1.2500000000e-01f, 0.0000000000e+00f }, { 7.6540424947e-18f, 1.2500000000e-01f },
{ -1.2500000000e-01f, 1.5308084989e-17f }, { -2.2962127484e-17f, -1.2500000000e-01f },
{ 1.2500000000e-01f, -3.0616169979e-17f }, { 3.8270212473e-17f, 1.2500000000e-01f },
{ -1.2500000000e-01f, 4.5924254968e-17f }, { -5.3578297463e-17f, -1.2500000000e-01f },
} };
class TPMSProcessor : public BasebandProcessor {
public:
using payload_t = std::bitset<1024>;
void execute(buffer_c8_t buffer) override;
private:
ChannelDecimator decimator { ChannelDecimator::DecimationFactor::By16 };
dsp::matched_filter::MatchedFilter mf { rect_taps_153k6_1t_p, 4 };
clock_recovery::ClockRecovery<clock_recovery::FixedErrorFilter> clock_recovery {
38400, 19200, { 0.0555f },
[this](const float symbol) { this->consume_symbol(symbol); }
};
PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder {
{ 0b010101010101010101010101010110, 30, 1 },
{ },
{ 256 },
[this](const payload_t& payload, const size_t bits_received) {
this->payload_handler(payload, bits_received);
}
};
void consume_symbol(const float symbol);
void payload_handler(const payload_t& payload, const size_t bits_received);
};
#endif/*__PROC_TPMS_H__*/