diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index abc04a3a..7daa3d5a 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -176,6 +176,7 @@ set(CPPSRC ui_replay_view.cpp ui_rssi.cpp ui_sd_card_status_view.cpp + ui_sd_wipe.cpp # ui_sd_card_debug.cpp ui_setup.cpp ui_soundboard.cpp diff --git a/firmware/application/Makefile b/firmware/application/Makefile index fc52acac..afc6ec3b 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -5027,6 +5027,33 @@ ui_sd_card_status_view.cpp.s: cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_sd_card_status_view.cpp.s .PHONY : ui_sd_card_status_view.cpp.s +ui_sd_wipe.obj: ui_sd_wipe.cpp.obj + +.PHONY : ui_sd_wipe.obj + +# target to build an object file +ui_sd_wipe.cpp.obj: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_sd_wipe.cpp.obj +.PHONY : ui_sd_wipe.cpp.obj + +ui_sd_wipe.i: ui_sd_wipe.cpp.i + +.PHONY : ui_sd_wipe.i + +# target to preprocess a source file +ui_sd_wipe.cpp.i: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_sd_wipe.cpp.i +.PHONY : ui_sd_wipe.cpp.i + +ui_sd_wipe.s: ui_sd_wipe.cpp.s + +.PHONY : ui_sd_wipe.s + +# target to generate assembly for a file +ui_sd_wipe.cpp.s: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_sd_wipe.cpp.s +.PHONY : ui_sd_wipe.cpp.s + ui_setup.obj: ui_setup.cpp.obj .PHONY : ui_setup.obj @@ -5769,6 +5796,9 @@ help: @echo "... ui_sd_card_status_view.obj" @echo "... ui_sd_card_status_view.i" @echo "... ui_sd_card_status_view.s" + @echo "... ui_sd_wipe.obj" + @echo "... ui_sd_wipe.i" + @echo "... ui_sd_wipe.s" @echo "... ui_setup.obj" @echo "... ui_setup.i" @echo "... ui_setup.s" diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index f1209aa7..8011bc1e 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -141,9 +141,9 @@ void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, send_message(&message); } -void set_pocsag() { +void set_pocsag(const pocsag::BitRate bitrate) { const POCSAGConfigureMessage message { - 1200 + bitrate }; send_message(&message); } diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index 1f378f24..22da8e2d 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -24,6 +24,7 @@ #define __BASEBAND_API_H__ #include "message.hpp" +#include "pocsag_packet.hpp" #include "dsp_fir_taps.hpp" @@ -62,7 +63,7 @@ void set_afsk_data(const uint32_t afsk_samples_per_bit, const uint32_t afsk_phas const uint8_t afsk_repeat, const uint32_t afsk_bw, const bool afsk_alt_format); void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat, const uint32_t pause_symbols); -void set_pocsag(); +void set_pocsag(const pocsag::BitRate bitrate); void set_adsb(); void set_rds_data(const uint16_t message_length); //void set_dtmf_data(const uint32_t bw, const uint32_t tone_length, const uint32_t pause_length); diff --git a/firmware/application/pocsag_app.cpp b/firmware/application/pocsag_app.cpp index 0c4208cd..d587dd70 100644 --- a/firmware/application/pocsag_app.cpp +++ b/firmware/application/pocsag_app.cpp @@ -140,7 +140,7 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { logger = std::make_unique(); if (logger) logger->append("pocsag.txt"); - baseband::set_pocsag(); + baseband::set_pocsag(pocsag::BitRate::FSK1200); } POCSAGAppView::~POCSAGAppView() { diff --git a/firmware/application/ui_closecall.hpp b/firmware/application/ui_closecall.hpp index 304e737a..81919909 100644 --- a/firmware/application/ui_closecall.hpp +++ b/firmware/application/ui_closecall.hpp @@ -38,6 +38,11 @@ public: CloseCallView(NavigationView& nav); ~CloseCallView(); + CloseCallView(const CloseCallView&) = delete; + CloseCallView(CloseCallView&&) = delete; + CloseCallView& operator=(const CloseCallView&) = delete; + CloseCallView& operator=(CloseCallView&&) = delete; + void on_show() override; void on_hide() override; void focus() override; diff --git a/firmware/application/ui_encoders.hpp b/firmware/application/ui_encoders.hpp index 8bb9124a..a4f3054a 100644 --- a/firmware/application/ui_encoders.hpp +++ b/firmware/application/ui_encoders.hpp @@ -38,6 +38,11 @@ public: EncodersView(NavigationView& nav); ~EncodersView(); + EncodersView(const EncodersView&) = delete; + EncodersView(EncodersView&&) = delete; + EncodersView& operator=(const EncodersView&) = delete; + EncodersView& operator=(EncodersView&&) = delete; + void focus() override; void on_show() override; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 2ab519cb..d9e8d157 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -33,6 +33,7 @@ #include "ui_about.hpp" #include "ui_adsbtx.hpp" +#include "ui_bht_tx.hpp" #include "ui_closecall.hpp" #include "ui_debug.hpp" #include "ui_encoders.hpp" @@ -43,11 +44,11 @@ #include "ui_numbers.hpp" #include "ui_nuoptix.hpp" #include "ui_rds.hpp" +#include "ui_sd_wipe.hpp" #include "ui_setup.hpp" #include "ui_soundboard.hpp" #include "ui_whipcalc.hpp" #include "ui_whistle.hpp" -#include "ui_bht_tx.hpp" #include "analog_audio_app.hpp" #include "ais_app.hpp" @@ -435,45 +436,6 @@ void BMPView::paint(Painter&) { portapack::display.drawBMP({(240 - 185) / 2, 0}, splash_bmp, false); } -/* WipeSDView ************************************************************/ - -WipeSDView::WipeSDView(NavigationView& nav) : nav_ (nav) { - add_children({ - &text_info, - &progress, - &dummy - }); -} - -WipeSDView::~WipeSDView() { - if (thread) chThdTerminate(thread); -} - -Thread* WipeSDView::thread { nullptr }; - -void WipeSDView::focus() { - BlockDeviceInfo block_device_info; - - dummy.focus(); - - if (!confirmed) { - nav_.push("Warning !", "Wipe first 32MB of SD card ?", YESCANCEL, [this](bool choice) { - if (choice) - confirmed = true; - } - ); - } else { - if (sdcGetInfo(&SDCD1, &block_device_info) == CH_SUCCESS) { - blocks = 32; // Only erase first 32MB (block_device_info.blk_size * uint64_t(block_device_info.blk_num)) / (1024 * 1024); - progress.set_max(blocks); - - thread = chThdCreateFromHeap(NULL, 2048, NORMALPRIO + 10, WipeSDView::static_fn, this); - } else { - nav_.pop(); // Just silently abort for now - } - } -} - /* PlayDeadView **********************************************************/ void PlayDeadView::focus() { diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index 4b2c204e..3aaf1fc8 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -176,62 +176,6 @@ private: }; }; -class WipeSDView : public View { -public: - WipeSDView(NavigationView& nav); - ~WipeSDView(); - void focus() override; - - std::string title() const override { return "SD card wipe"; }; - -private: - NavigationView& nav_; - - bool confirmed = false; - uint32_t blocks; - static Thread* thread; - - static msg_t static_fn(void* arg) { - auto obj = static_cast(arg); - obj->run(); - return 0; - } - - void run() { - uint32_t n, b; - lfsr_word_t v = 1; - const auto buffer = std::make_unique>(); - - for (b = 0; b < blocks; b++) { - progress.set_value(b); - - lfsr_fill(v, - reinterpret_cast(buffer->data()), - sizeof(*buffer.get()) / sizeof(lfsr_word_t)); - - // 1MB - for (n = 0; n < 64; n++) { - if (disk_write(sd_card::fs.drv, buffer->data(), n + (b * 64), 16384 / 512) != RES_OK) nav_.pop(); - } - } - nav_.pop(); - } - - Text text_info { - { 10 * 8, 16 * 8, 10 * 8, 16 }, - "Working..." - }; - - ProgressBar progress { - { 2 * 8, 19 * 8, 26 * 8, 24 } - }; - - Button dummy { - { 240, 0, 0, 0 }, - "" - }; -}; - class PlayDeadView : public View { public: PlayDeadView(NavigationView& nav); diff --git a/firmware/application/ui_nuoptix.hpp b/firmware/application/ui_nuoptix.hpp index ab5012a3..b7cde481 100644 --- a/firmware/application/ui_nuoptix.hpp +++ b/firmware/application/ui_nuoptix.hpp @@ -89,7 +89,7 @@ private: void on_tuning_frequency_changed(rf::Frequency f); void transmit(bool setup); - uint32_t timecode; + uint32_t timecode { 0 }; FrequencyField field_frequency { { 1 * 8, 4 }, diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index df4b280c..41d78313 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -42,7 +42,7 @@ void RecordView::toggle_pwmrssi() { // Send to RSSI widget const PWMRSSIConfigureMessage message { pwmrssi_enabled, - 1000, + 64, 0 }; shared_memory.application_queue.push(message); diff --git a/firmware/application/ui_sd_wipe.cpp b/firmware/application/ui_sd_wipe.cpp new file mode 100644 index 00000000..691bbcba --- /dev/null +++ b/firmware/application/ui_sd_wipe.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * 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 "ui_sd_wipe.hpp" + +namespace ui { + +WipeSDView::WipeSDView(NavigationView& nav) : nav_ (nav) { + add_children({ + &text_info, + &progress, + &dummy + }); +} + +WipeSDView::~WipeSDView() { + if (thread) chThdTerminate(thread); +} + +Thread* WipeSDView::thread { nullptr }; + +void WipeSDView::focus() { + BlockDeviceInfo block_device_info; + + dummy.focus(); + + if (!confirmed) { + nav_.push("Warning !", "Wipe first 32MB of SD card ?", YESCANCEL, [this](bool choice) { + if (choice) + confirmed = true; + } + ); + } else { + if (sdcGetInfo(&SDCD1, &block_device_info) == CH_SUCCESS) { + blocks = 32; // Only erase first 32MB (block_device_info.blk_size * uint64_t(block_device_info.blk_num)) / (1024 * 1024); + progress.set_max(blocks); + + thread = chThdCreateFromHeap(NULL, 2048, NORMALPRIO + 10, WipeSDView::static_fn, this); + } else { + nav_.pop(); // Just silently abort for now + } + } +} + +} /* namespace ui */ diff --git a/firmware/application/ui_sd_wipe.hpp b/firmware/application/ui_sd_wipe.hpp new file mode 100644 index 00000000..43038b9b --- /dev/null +++ b/firmware/application/ui_sd_wipe.hpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * 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 __UI_SE_WIPE_H__ +#define __UI_SE_WIPE_H__ + +#include "ui_widget.hpp" +#include "ui_navigation.hpp" +#include "ff.h" + +#include + +namespace ui { + +class WipeSDView : public View { +public: + WipeSDView(NavigationView& nav); + ~WipeSDView(); + void focus() override; + + std::string title() const override { return "SD card wipe"; }; + +private: + NavigationView& nav_; + + bool confirmed = false; + uint32_t blocks { 0 }; + static Thread* thread; + + static msg_t static_fn(void* arg) { + auto obj = static_cast(arg); + obj->run(); + return 0; + } + + void run() { + uint32_t n, b; + lfsr_word_t v = 1; + const auto buffer = std::make_unique>(); + + for (b = 0; b < blocks; b++) { + progress.set_value(b); + + lfsr_fill(v, + reinterpret_cast(buffer->data()), + sizeof(*buffer.get()) / sizeof(lfsr_word_t)); + + // 1MB + for (n = 0; n < 64; n++) { + if (disk_write(sd_card::fs.drv, buffer->data(), n + (b * 64), 16384 / 512) != RES_OK) nav_.pop(); + } + } + nav_.pop(); + } + + Text text_info { + { 10 * 8, 16 * 8, 10 * 8, 16 }, + "Working..." + }; + + ProgressBar progress { + { 2 * 8, 19 * 8, 26 * 8, 24 } + }; + + Button dummy { + { 240, 0, 0, 0 }, + "" + }; +}; + +} /* namespace ui */ + +#endif/*__UI_SE_WIPE_H__*/ diff --git a/firmware/application/ui_soundboard.hpp b/firmware/application/ui_soundboard.hpp index a21f1864..0eebb0e7 100644 --- a/firmware/application/ui_soundboard.hpp +++ b/firmware/application/ui_soundboard.hpp @@ -41,6 +41,11 @@ public: SoundBoardView(NavigationView& nav); ~SoundBoardView(); + SoundBoardView(const SoundBoardView&) = delete; + SoundBoardView(SoundBoardView&&) = delete; + SoundBoardView& operator=(const SoundBoardView&) = delete; + SoundBoardView& operator=(SoundBoardView&&) = delete; + void focus() override; std::string title() const override { return "Soundboard"; }; diff --git a/firmware/baseband/proc_closecall.hpp b/firmware/baseband/proc_closecall.hpp index 50345afa..efdd9636 100644 --- a/firmware/baseband/proc_closecall.hpp +++ b/firmware/baseband/proc_closecall.hpp @@ -42,9 +42,9 @@ public: private: BasebandThread baseband_thread { 3072000, this, NORMALPRIO + 20, baseband::Direction::Receive }; - SpectrumCollector channel_spectrum; + SpectrumCollector channel_spectrum { }; - std::array spectrum; + std::array spectrum { }; size_t phase = 0; }; diff --git a/firmware/baseband/proc_nfm_audio.cpp b/firmware/baseband/proc_nfm_audio.cpp index 5eedc5f7..66f249ca 100644 --- a/firmware/baseband/proc_nfm_audio.cpp +++ b/firmware/baseband/proc_nfm_audio.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * @@ -49,7 +50,8 @@ void NarrowbandFMAudio::execute(const buffer_c8_t& buffer) { pwmrssi_audio_buffer.p[c] = 32767; else pwmrssi_audio_buffer.p[c] = -32768; - if (synth_acc < 30) // 24kHz / 30 = 800Hz (TODO: use pwmrssi_freq !) + + if (synth_acc < synth_div) // 24kHz / 30 = 800Hz synth_acc++; else synth_acc = 0; @@ -111,8 +113,9 @@ void NarrowbandFMAudio::configure(const NBFMConfigureMessage& message) { void NarrowbandFMAudio::pwmrssi_config(const PWMRSSIConfigureMessage& message) { pwmrssi_enabled = message.enabled; - pwmrssi_freq = message.freq; pwmrssi_avg = message.avg / 3; + synth_div = message.synth_div; + synth_acc = 0; } void NarrowbandFMAudio::capture_config(const CaptureConfigMessage& message) { diff --git a/firmware/baseband/proc_nfm_audio.hpp b/firmware/baseband/proc_nfm_audio.hpp index 7aa411ff..1f2a891a 100644 --- a/firmware/baseband/proc_nfm_audio.hpp +++ b/firmware/baseband/proc_nfm_audio.hpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * @@ -57,7 +58,7 @@ private: audio.size() }; - std::array pwm; + std::array pwm { }; const buffer_s16_t pwmrssi_audio_buffer { (int16_t*)pwm.data(), sizeof(pwm) / sizeof(int16_t) @@ -73,12 +74,12 @@ private: AudioOutput audio_output { }; - SpectrumCollector channel_spectrum; + SpectrumCollector channel_spectrum { }; - unsigned int c, synth_acc = 0; + unsigned int c { 0 }, synth_acc { 0 }; + uint32_t synth_div { 0 }; bool pwmrssi_enabled = false; - uint32_t pwmrssi_freq; - uint32_t pwmrssi_avg; + uint32_t pwmrssi_avg { 0 }; bool configured { false }; void pwmrssi_config(const PWMRSSIConfigureMessage& message); diff --git a/firmware/baseband/proc_pocsag.cpp b/firmware/baseband/proc_pocsag.cpp index bfe3cc0e..6e72137e 100644 --- a/firmware/baseband/proc_pocsag.cpp +++ b/firmware/baseband/proc_pocsag.cpp @@ -29,49 +29,50 @@ #include #include -#define FREQ_SAMP 24000 -#define BAUD 1200 -#define SPHASEINC (0x10000u * BAUD / FREQ_SAMP) +#define POCSAG_AUDIO_RATE 24000 #define POCSAG_SYNC 0x7CD215D8 #define POCSAG_IDLE 0x7A89C197 +#define POCSAG_PREAMBLE_LENGTH 576 +#define POCSAG_BATCH_LENGTH (9 * 32) void POCSAGProcessor::execute(const buffer_c8_t& buffer) { - /* 1.536MHz, 2048 samples */ + // Samplerate is 1.536MHz, gets 2048 samples, called at 750Hz - if( !configured ) return; + if (!configured) return; + // Get 24kHz audio const auto decim_0_out = decim_0.execute(buffer, dst_buffer); const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer); - auto audio = demod.execute(decim_1_out, audio_buffer); - for (c = 0; c < 32; c++) { + // End up with 32 samples + for (uint32_t c = 0; c < 32; c++) { - // Bit = sign - const int32_t audio_sample = audio.p[c] * 32768.0f; // sample_int + const int32_t audio_sample = audio.p[c] * 32768.0f; //const int32_t audio_sample = __SSAT(sample_int, 16); - dcd_shreg <<= 1; - dcd_shreg |= (audio_sample < 0); + slicer_sr <<= 1; + slicer_sr |= (audio_sample < 0); // Detect transitions to adjust clock - if ((dcd_shreg ^ (dcd_shreg >> 1)) & 1) { - if (sphase < (0x8000u-(SPHASEINC/2))) - sphase += SPHASEINC/8; + if ((slicer_sr ^ (slicer_sr >> 1)) & 1) { + if (sphase < (0x8000u - sphase_delta_half)) + sphase += sphase_delta_eighth; else - sphase -= SPHASEINC/8; + sphase -= sphase_delta_eighth; } - sphase += SPHASEINC; + sphase += sphase_delta; + // Symbol time elapsed if (sphase >= 0x10000u) { - sphase &= 0xffffu; + sphase &= 0xFFFFu; rx_data <<= 1; - rx_data |= (dcd_shreg & 1); + rx_data |= (slicer_sr & 1); - switch(rx_state) { + switch (rx_state) { case WAITING: if (rx_data == 0xAAAAAAAA) { @@ -79,12 +80,10 @@ void POCSAGProcessor::execute(const buffer_c8_t& buffer) { sync_timeout = 0; } break; - + case PREAMBLE: - if (sync_timeout < 600) { + if (sync_timeout < POCSAG_PREAMBLE_LENGTH) { sync_timeout++; - - //pocsag_brute_repair(&s->l2.pocsag, &rx_data); if (rx_data == POCSAG_SYNC) { packet.clear(); @@ -94,44 +93,39 @@ void POCSAGProcessor::execute(const buffer_c8_t& buffer) { last_rx_data = rx_data; rx_state = SYNC; } else if (rx_data == POCSAG_IDLE) { + push_packet(pocsag::PacketFlag::IDLE); rx_state = WAITING; } } else { - rx_state = WAITING; // Abort + rx_state = WAITING; // Timed out: abort } break; case SYNC: - if (msg_timeout < 600) { + if (msg_timeout < POCSAG_BATCH_LENGTH) { msg_timeout++; rx_bit++; if (rx_bit >= 32) { rx_bit = 0; + // Got a complete codeword + //pocsag_brute_repair(&s->l2.pocsag, &rx_data); packet.set(frame_counter, rx_data); if ((rx_data == POCSAG_IDLE) && (!(last_rx_data & 0x80000000))) { // SYNC then IDLE always means end of message ? - packet.set_bitrate(pocsag::BitRate::FSK1200); - packet.set_flag(pocsag::PacketFlag::NORMAL); - packet.set_timestamp(Timestamp::now()); - const POCSAGPacketMessage message(packet); - shared_memory.application_queue.push(message); + push_packet(pocsag::PacketFlag::NORMAL); rx_state = WAITING; } else { if (frame_counter < 15) { frame_counter++; } else { // More than 17-1 codewords - packet.set_bitrate(pocsag::BitRate::FSK1200); - packet.set_flag(pocsag::PacketFlag::TOO_LONG); - packet.set_timestamp(Timestamp::now()); - const POCSAGPacketMessage message(packet); - shared_memory.application_queue.push(message); + push_packet(pocsag::PacketFlag::TOO_LONG); rx_state = WAITING; } } @@ -140,11 +134,7 @@ void POCSAGProcessor::execute(const buffer_c8_t& buffer) { } } else { // Timed out (no end of message received) - packet.set_bitrate(pocsag::BitRate::FSK1200); - packet.set_flag(pocsag::PacketFlag::TIMED_OUT); - packet.set_timestamp(Timestamp::now()); - const POCSAGPacketMessage message(packet); - shared_memory.application_queue.push(message); + push_packet(pocsag::PacketFlag::TIMED_OUT); rx_state = WAITING; } break; @@ -156,14 +146,20 @@ void POCSAGProcessor::execute(const buffer_c8_t& buffer) { } } +void POCSAGProcessor::push_packet(pocsag::PacketFlag flag) { + packet.set_bitrate(bitrate); + packet.set_flag(flag); + packet.set_timestamp(Timestamp::now()); + const POCSAGPacketMessage message(packet); + shared_memory.application_queue.push(message); +} + void POCSAGProcessor::on_message(const Message* const message) { if (message->id == Message::ID::POCSAGConfigure) configure(*reinterpret_cast(message)); } void POCSAGProcessor::configure(const POCSAGConfigureMessage& message) { - (void)message; - constexpr size_t decim_0_input_fs = baseband_fs; constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0.decimation_factor; @@ -176,6 +172,11 @@ void POCSAGProcessor::configure(const POCSAGConfigureMessage& message) { decim_1.configure(taps_11k0_decim_1.taps, 131072); demod.configure(demod_input_fs, 4500); + bitrate = message.bitrate; + sphase_delta = 0x10000u * bitrate / POCSAG_AUDIO_RATE; + sphase_delta_half = sphase_delta / 2; // Just for speed + sphase_delta_eighth = sphase_delta / 8; + rx_state = WAITING; configured = true; } diff --git a/firmware/baseband/proc_pocsag.hpp b/firmware/baseband/proc_pocsag.hpp index de070cbe..02580196 100644 --- a/firmware/baseband/proc_pocsag.hpp +++ b/firmware/baseband/proc_pocsag.hpp @@ -1,4 +1,6 @@ /* + * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) + * Copyright (C) 2012-2014 Elias Oenal (multimon-ng@eliasoenal.com) * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2016 Furrtek * @@ -60,37 +62,40 @@ private: BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive }; RSSIThread rssi_thread { NORMALPRIO + 10 }; - std::array dst; + std::array dst { }; const buffer_c16_t dst_buffer { dst.data(), dst.size() }; - std::array audio; + std::array audio { }; const buffer_f32_t audio_buffer { audio.data(), audio.size() }; - dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0; - dsp::decimate::FIRC16xR16x32Decim8 decim_1; + dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0 { }; + dsp::decimate::FIRC16xR16x32Decim8 decim_1 { }; - dsp::demodulate::FM demod; + dsp::demodulate::FM demod { }; - uint32_t sync_timeout; - uint32_t msg_timeout; + uint32_t sync_timeout { 0 }; + uint32_t msg_timeout { 0 }; - uint32_t dcd_shreg; - uint32_t sphase; - uint32_t rx_data; - uint32_t last_rx_data; - uint32_t rx_bit; + uint32_t slicer_sr { 0 }; + uint32_t sphase { 0 }; + uint32_t sphase_delta { 0 }; + uint32_t sphase_delta_half { 0 }; + uint32_t sphase_delta_eighth { 0 }; + uint32_t rx_data { 0 }; + uint32_t last_rx_data { 0 }; + uint32_t rx_bit { 0 }; bool configured = false; - rx_states rx_state; - - size_t c, frame_counter; - - pocsag::POCSAGPacket packet; + rx_states rx_state { WAITING }; + pocsag::BitRate bitrate { pocsag::BitRate::FSK1200 }; + uint32_t frame_counter { 0 }; + pocsag::POCSAGPacket packet { }; + void push_packet(pocsag::PacketFlag flag); void configure(const POCSAGConfigureMessage& message); }; diff --git a/firmware/baseband/proc_wfm_audio.cpp b/firmware/baseband/proc_wfm_audio.cpp index 5771854d..1d375eb8 100644 --- a/firmware/baseband/proc_wfm_audio.cpp +++ b/firmware/baseband/proc_wfm_audio.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * @@ -77,7 +78,8 @@ void WidebandFMAudio::execute(const buffer_c8_t& buffer) { pwmrssi_audio_buffer.p[c] = 32767; else pwmrssi_audio_buffer.p[c] = -32768; - if (synth_acc < 96) // 48kHz / 96 = 500Hz (TODO: use pwmrssi_freq !) + + if (synth_acc < synth_div) // 48kHz / 96 = 500Hz synth_acc++; else synth_acc = 0; @@ -135,7 +137,6 @@ void WidebandFMAudio::configure(const WFMConfigureMessage& message) { channel_spectrum.set_decimation_factor(1); - pwmrssi_enabled = false; synth_acc = 0; configured = true; @@ -143,8 +144,9 @@ void WidebandFMAudio::configure(const WFMConfigureMessage& message) { void WidebandFMAudio::pwmrssi_config(const PWMRSSIConfigureMessage& message) { pwmrssi_enabled = message.enabled; - pwmrssi_freq = message.freq; pwmrssi_avg = message.avg; + synth_div = message.synth_div; + synth_acc = 0; } void WidebandFMAudio::capture_config(const CaptureConfigMessage& message) { diff --git a/firmware/baseband/proc_wfm_audio.hpp b/firmware/baseband/proc_wfm_audio.hpp index 6916a7a1..a5938907 100644 --- a/firmware/baseband/proc_wfm_audio.hpp +++ b/firmware/baseband/proc_wfm_audio.hpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * @@ -55,7 +56,7 @@ private: sizeof(dst) / sizeof(int16_t) }; - std::array pwm; + std::array pwm { }; const buffer_s16_t pwmrssi_audio_buffer { (int16_t*)pwm.data(), sizeof(pwm) / sizeof(int16_t) @@ -77,10 +78,10 @@ private: size_t spectrum_interval_samples = 0; size_t spectrum_samples = 0; - unsigned int c, synth_acc = 0; + unsigned int c { 0 }, synth_acc { 0 }; + uint32_t synth_div { 0 }; bool pwmrssi_enabled = false; - uint32_t pwmrssi_freq; - uint32_t pwmrssi_avg; + uint32_t pwmrssi_avg { 0 }; bool configured { false }; void pwmrssi_config(const PWMRSSIConfigureMessage& message); diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 2c468493..2d6d27fa 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -30,6 +30,7 @@ #include #include +#include "pocsag_packet.hpp" #include "baseband_packet.hpp" #include "ert_packet.hpp" #include "tpms_packet.hpp" @@ -546,17 +547,17 @@ class PWMRSSIConfigureMessage : public Message { public: constexpr PWMRSSIConfigureMessage( const bool enabled, - const uint32_t freq, + const uint32_t synth_div, const int32_t avg ) : Message { ID::PWMRSSIConfigure }, enabled(enabled), - freq(freq), + synth_div(synth_div), avg(avg) { } const bool enabled; - const uint32_t freq; + const uint32_t synth_div; const int32_t avg; }; @@ -678,13 +679,13 @@ public: class POCSAGConfigureMessage : public Message { public: constexpr POCSAGConfigureMessage( - const uint32_t rate + const pocsag::BitRate bitrate ) : Message { ID::POCSAGConfigure }, - rate(rate) + bitrate(bitrate) { } - const uint32_t rate; + const pocsag::BitRate bitrate; }; class ADSBConfigureMessage : public Message { diff --git a/firmware/common/pocsag_packet.hpp b/firmware/common/pocsag_packet.hpp index 4bd057b6..ee078a8c 100644 --- a/firmware/common/pocsag_packet.hpp +++ b/firmware/common/pocsag_packet.hpp @@ -34,13 +34,14 @@ namespace pocsag { enum BitRate : uint32_t { UNKNOWN, - FSK512, - FSK1200, - FSK2400 + FSK512 = 512, + FSK1200 = 1200, + FSK2400 = 2400 }; enum PacketFlag : uint32_t { NORMAL, + IDLE, TIMED_OUT, TOO_LONG }; @@ -81,17 +82,17 @@ public: } void clear() { - for (size_t c = 0; c < 16; c++) + for (uint32_t c = 0; c < 16; c++) codewords[c] = 0; bitrate_ = UNKNOWN; flag_ = NORMAL; } private: - BitRate bitrate_; - PacketFlag flag_; + BitRate bitrate_ { UNKNOWN }; + PacketFlag flag_ { NORMAL }; uint32_t codewords[16]; - Timestamp timestamp_; + Timestamp timestamp_ { }; }; } /* namespace pocsag */