diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 233b17b42..19b8d8fc4 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -503,10 +503,17 @@ void ReceiverView::on_show() { this->on_packet_ais(*message); } ); + message_map.register_handler(Message::ID::TPMSPacket, + [this](Message* const p) { + const auto message = static_cast(p); + this->on_packet_tpms(*message); + } + ); } void ReceiverView::on_hide() { auto& message_map = context().message_map(); + message_map.unregister_handler(Message::ID::TPMSPacket); message_map.unregister_handler(Message::ID::AISPacket); } @@ -519,6 +526,31 @@ void ReceiverView::on_packet_ais(const AISPacketMessage& message) { } } +void ReceiverView::on_packet_tpms(const TPMSPacketMessage& message) { + auto payload = message.packet.payload; + auto payload_length = message.packet.bits_received; + + for(size_t i=0; i>1] = payload[i+1]; + } else { + payload[i>>1] = 0; + } + } + + std::string hex; + uint8_t c = 0; + for(size_t i=0; i<15*8; i++) { + c = (c << 1) | payload[i]; + if( (i & 7) == 7 ) { + hex += to_string_hex(c, 2); + } + } + + auto console = reinterpret_cast(widget_content.get()); + console->writeln(hex); +} + void ReceiverView::focus() { button_done.focus(); } @@ -547,6 +579,7 @@ void ReceiverView::on_modulation_changed(int32_t modulation) { /* TODO: This is TERRIBLE!!! */ switch(modulation) { case 3: + case 5: receiver_model.set_baseband_configuration({ .mode = modulation, .sampling_rate = 2457600, @@ -579,6 +612,7 @@ void ReceiverView::on_modulation_changed(int32_t modulation) { switch(modulation) { case 3: + case 5: widget_content = std::make_unique(); add_child(widget_content.get()); break; diff --git a/firmware/application/ui_receiver.hpp b/firmware/application/ui_receiver.hpp index aff5ed5bc..237f53c6f 100644 --- a/firmware/application/ui_receiver.hpp +++ b/firmware/application/ui_receiver.hpp @@ -416,6 +416,7 @@ private: { "NFM ", 1 }, { "WFM ", 2 }, { "AIS ", 3 }, + { "TPMS", 5 }, { "SPEC", 4 }, } }; @@ -473,6 +474,7 @@ private: void on_edit_frequency(); void on_packet_ais(const AISPacketMessage& message); + void on_packet_tpms(const TPMSPacketMessage& message); }; } /* namespace ui */ diff --git a/firmware/baseband/Makefile b/firmware/baseband/Makefile index 1e4acdba0..ffb20d12a 100755 --- a/firmware/baseband/Makefile +++ b/firmware/baseband/Makefile @@ -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 \ diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index e3d6e1532..fa9386658 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -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; } diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp new file mode 100644 index 000000000..edabf4681 --- /dev/null +++ b/firmware/baseband/proc_tpms.cpp @@ -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; ifloat is not allowed. + const std::complex sample { + static_cast(decimator_out.p[i].real()), + static_cast(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); +} diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp new file mode 100644 index 000000000..0bde7d687 --- /dev/null +++ b/firmware/baseband/proc_tpms.hpp @@ -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 +#include +#include + +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, 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 { + 38400, 19200, { 0.0555f }, + [this](const float symbol) { this->consume_symbol(symbol); } + }; + PacketBuilder 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__*/ diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index b58e6ad60..ff592ae23 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -43,6 +43,7 @@ public: ChannelSpectrum = 3, AudioStatistics = 4, BasebandConfiguration = 5, + TPMSPacket = 6, Shutdown = 8, AISPacket = 7, MAX @@ -216,6 +217,26 @@ public: AISPacket packet; }; +struct TPMSPacket { + std::bitset<1024> payload; + size_t bits_received; + + TPMSPacket( + ) : bits_received { 0 } + { + } +}; + +class TPMSPacketMessage : public Message { +public: + TPMSPacketMessage( + ) : Message { ID::TPMSPacket } + { + } + + TPMSPacket packet; +}; + class ShutdownMessage : public Message { public: constexpr ShutdownMessage(