From 3477a2691a55e0b6dd570c54f2463d8dfaf49a20 Mon Sep 17 00:00:00 2001 From: furrtek Date: Tue, 5 Jan 2016 11:47:46 +0100 Subject: [PATCH] Added missing files, ENUMed modulation modes --- firmware/Makefile | 4 +- firmware/application/m4_startup.cpp | 2 +- firmware/application/main.cpp | 4 +- firmware/application/modules.h | 2 - firmware/application/receiver_model.cpp | 2 +- firmware/application/receiver_model.hpp | 2 +- firmware/application/transmitter_model.cpp | 12 +- firmware/application/transmitter_model.hpp | 8 +- firmware/application/ui_afskrx.cpp | 2 +- firmware/application/ui_afsksetup.cpp | 2 +- firmware/application/ui_jammer.cpp | 4 +- firmware/application/ui_lcr.cpp | 6 +- firmware/application/ui_loadmodule.cpp | 5 +- firmware/application/ui_navigation.cpp | 1 + firmware/application/ui_receiver.cpp | 4 +- firmware/application/ui_receiver.hpp | 15 +-- firmware/application/ui_sigfrx.cpp | 144 +++++++++++++++++++++ firmware/application/ui_sigfrx.hpp | 87 +++++++++++++ firmware/application/ui_whistle.cpp | 4 +- firmware/application/ui_xylos.cpp | 66 +++++++++- firmware/application/ui_xylos.hpp | 13 +- firmware/baseband-tx.bin | Bin 23856 -> 25264 bytes firmware/baseband-tx/audio_dma.cpp | 2 +- firmware/baseband-tx/main.cpp | 32 ++++- firmware/baseband-tx/proc_xylos.cpp | 29 +++-- firmware/baseband-tx/proc_xylos.hpp | 46 ++++--- firmware/baseband.bin | Bin 26904 -> 31992 bytes firmware/baseband/main.cpp | 28 ++-- firmware/baseband/proc_sigfrx.cpp | 69 ++++++++++ firmware/baseband/proc_sigfrx.hpp | 54 ++++++++ firmware/common/message.hpp | 24 +++- firmware/common/modules.h | 2 + firmware/portapack-h1-firmware.bin | Bin 403112 -> 405512 bytes firmware/tools/make_baseband_file.py | 6 +- 34 files changed, 583 insertions(+), 98 deletions(-) delete mode 100644 firmware/application/modules.h create mode 100644 firmware/application/ui_sigfrx.cpp create mode 100644 firmware/application/ui_sigfrx.hpp create mode 100644 firmware/baseband/proc_sigfrx.cpp create mode 100644 firmware/baseband/proc_sigfrx.hpp create mode 100644 firmware/common/modules.h diff --git a/firmware/Makefile b/firmware/Makefile index 337a656d..b7d9459b 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -59,11 +59,11 @@ program: $(TARGET).bin modules sleep 1s hackrf_spiflash -w $(TARGET).bin -modules: +modules: $(TARGET_BASEBAND).bin $(TARGET_BASEBAND_TX).bin $(MAKE_MODULES_FILE) $(MODULES) $(TARGET).bin: modules $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND).bin $(TARGET_BASEBAND_TX).bin $(TARGET_APPLICATION).bin - $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND).bin $(TARGET_APPLICATION).bin $(TARGET).bin + $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND_TX).bin $(TARGET_APPLICATION).bin $(TARGET).bin $(TARGET_BOOTSTRAP).bin: $(TARGET_BOOTSTRAP).elf $(CP) -O binary $(TARGET_BOOTSTRAP).elf $(TARGET_BOOTSTRAP).bin diff --git a/firmware/application/m4_startup.cpp b/firmware/application/m4_startup.cpp index 5924a1fb..59fc511a 100644 --- a/firmware/application/m4_startup.cpp +++ b/firmware/application/m4_startup.cpp @@ -94,7 +94,7 @@ void m4_switch(const char * hash) { // Ask M4 to enter loop in RAM BasebandConfiguration baseband_switch { - .mode = 0xFF, + .mode = SWITCH, .sampling_rate = 0, .decimation_factor = 1, }; diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 94d0a7d6..ab6d387f 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -19,6 +19,8 @@ * Boston, MA 02110-1301, USA. */ +//TODO: Enum modulation modes (baseband) +//TODO: More gfx, cute icons :) //TODO: check jammer bandwidths //TODO: GSM channel detector //TODO: wait_for_switch() in baseband-tx ! @@ -27,7 +29,7 @@ //TODO: Reset baseband if module not found (instead of lockup in RAM loop) //TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule //TODO: LCD backlight PWM -//TODO: BUG: Crash after TX stop +//TODO: BUG: Crash after TX stop (unregister message !) //TODO: Check bw setting in LCR TX //TODO: BUG: Crash after PSN entry in RDS TX //TODO: Dynamically load baseband code depending on mode (disable M4 & interrupts, load, reset) diff --git a/firmware/application/modules.h b/firmware/application/modules.h deleted file mode 100644 index 86c07db7..00000000 --- a/firmware/application/modules.h +++ /dev/null @@ -1,2 +0,0 @@ -const char md5_baseband[16] = {0xce,0x87,0x2b,0x2c,0x9e,0x74,0xe8,0x1c,0x1c,0xe9,0xfc,0xc2,0x40,0xc3,0x32,0xd5,}; -const char md5_baseband_tx[16] = {0x1b,0xef,0x34,0x50,0x45,0xd7,0xae,0x7c,0xb5,0x4f,0x0c,0x5a,0x80,0xa0,0xbc,0x05,}; diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 23087077..406d4108 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -130,7 +130,7 @@ void ReceiverModel::disable() { /* TODO: This is a dumb hack to stop baseband from working so hard. */ BasebandConfigurationMessage message { .configuration = { - .mode = -1, + .mode = NONE, .sampling_rate = 0, .decimation_factor = 1, } diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index 71b4c7db..296d60d8 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -81,7 +81,7 @@ private: uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum }; int32_t vga_gain_db_ { 32 }; BasebandConfiguration baseband_configuration { - .mode = 1, /* TODO: Enum! */ + .mode = NONE, .sampling_rate = 3072000, .decimation_factor = 4, }; diff --git a/firmware/application/transmitter_model.cpp b/firmware/application/transmitter_model.cpp index 9cf18cb0..6ca9c390 100644 --- a/firmware/application/transmitter_model.cpp +++ b/firmware/application/transmitter_model.cpp @@ -80,11 +80,11 @@ void TransmitterModel::set_sampling_rate(uint32_t hz) { update_baseband_configuration(); } -uint32_t TransmitterModel::modulation() const { +mode_type TransmitterModel::modulation() const { return baseband_configuration.mode; } -void TransmitterModel::set_modulation(int32_t v) { +void TransmitterModel::set_modulation(mode_type v) { baseband_configuration.mode = v; update_modulation(); } @@ -114,7 +114,7 @@ void TransmitterModel::disable() { /* TODO: This is a dumb hack to stop baseband from working so hard. */ BasebandConfigurationMessage message { .configuration = { - .mode = -1, + .mode = NONE, .sampling_rate = 0, .decimation_factor = 1, } @@ -152,6 +152,11 @@ void TransmitterModel::update_modulation() { update_baseband_configuration(); } +void TransmitterModel::set_baseband_configuration(const BasebandConfiguration config) { + baseband_configuration = config; + update_baseband_configuration(); +} + void TransmitterModel::update_baseband_configuration() { radio::streaming_disable(); @@ -164,3 +169,4 @@ void TransmitterModel::update_baseband_configuration() { radio::streaming_enable(); } + diff --git a/firmware/application/transmitter_model.hpp b/firmware/application/transmitter_model.hpp index 8cab94f0..d8506935 100644 --- a/firmware/application/transmitter_model.hpp +++ b/firmware/application/transmitter_model.hpp @@ -57,14 +57,16 @@ public: uint32_t sampling_rate() const; void set_sampling_rate(uint32_t hz); - uint32_t modulation() const; - void set_modulation(int32_t v); + mode_type modulation() const; + void set_modulation(mode_type v); uint32_t baseband_oversampling() const; void set_baseband_oversampling(uint32_t v); void enable(); void disable(); + + void set_baseband_configuration(const BasebandConfiguration config); private: bool rf_amp_ { true }; @@ -72,7 +74,7 @@ private: uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum }; int32_t vga_gain_db_ { 8 }; BasebandConfiguration baseband_configuration { - .mode = 16, + .mode = NONE, .sampling_rate = 2280000, .decimation_factor = 1, }; diff --git a/firmware/application/ui_afskrx.cpp b/firmware/application/ui_afskrx.cpp index 31ac5912..fa6b6eba 100644 --- a/firmware/application/ui_afskrx.cpp +++ b/firmware/application/ui_afskrx.cpp @@ -48,7 +48,7 @@ AFSKRXView::AFSKRXView( }; receiver_model.set_baseband_configuration({ - .mode = 6, + .mode = RX_AFSK, .sampling_rate = 3072000, .decimation_factor = 4, }); diff --git a/firmware/application/ui_afsksetup.cpp b/firmware/application/ui_afsksetup.cpp index 19f22de4..2176fb96 100644 --- a/firmware/application/ui_afsksetup.cpp +++ b/firmware/application/ui_afsksetup.cpp @@ -46,7 +46,7 @@ void AFSKSetupView::focus() { } void AFSKSetupView::paint(Painter& painter) { - + (void)painter; } void AFSKSetupView::updfreq(rf::Frequency f) { diff --git a/firmware/application/ui_jammer.cpp b/firmware/application/ui_jammer.cpp index b95b5a22..d7782b9f 100644 --- a/firmware/application/ui_jammer.cpp +++ b/firmware/application/ui_jammer.cpp @@ -50,7 +50,7 @@ JammerView::~JammerView() { } void JammerView::paint(Painter& painter) { - + (void)painter; } void JammerView::updfreq(uint8_t id, rf::Frequency f) { @@ -169,7 +169,7 @@ JammerView::JammerView( .foreground = Color::grey(), }; - transmitter_model.set_modulation(18); + transmitter_model.set_modulation(TX_JAMMER); add_children({ { &text_type, diff --git a/firmware/application/ui_lcr.cpp b/firmware/application/ui_lcr.cpp index 72dda734..d2d9e64b 100644 --- a/firmware/application/ui_lcr.cpp +++ b/firmware/application/ui_lcr.cpp @@ -187,7 +187,7 @@ LCRView::LCRView( .foreground = Color::black(), }; - transmitter_model.set_modulation(16); + transmitter_model.set_modulation(TX_LCR); transmitter_model.set_tuning_frequency(portapack::persistent_memory::tuned_frequency()); memset(litteral, 0, 5*8); memset(rgsb, 0, 5); @@ -275,9 +275,7 @@ LCRView::LCRView( nav.push(new DebugLCRView { nav, lcrstring, checksum }); }; - button_transmit.on_select = [this,&transmitter_model](Button&){ - uint16_t c; - + button_transmit.on_select = [this,&transmitter_model](Button&){ auto& message_map = context().message_map(); make_frame(); diff --git a/firmware/application/ui_loadmodule.cpp b/firmware/application/ui_loadmodule.cpp index a49ab463..d5dafdab 100644 --- a/firmware/application/ui_loadmodule.cpp +++ b/firmware/application/ui_loadmodule.cpp @@ -41,7 +41,7 @@ void LoadModuleView::focus() { } void LoadModuleView::paint(Painter& painter) { - + (void)painter; } void LoadModuleView::on_hide() { @@ -53,7 +53,8 @@ void LoadModuleView::on_show() { auto& message_map = context().message_map(); message_map.register_handler(Message::ID::ReadyForSwitch, [this](Message* const p) { - const auto message = static_cast(p); + (void)p; + // const auto message = static_cast(p); if (m4_load_image()) { text_info.set("Module loaded :)"); _mod_loaded = true; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 74ef82b2..49a9a92f 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -195,6 +195,7 @@ BMPView::BMPView(NavigationView& nav) { } void BMPView::paint(Painter& painter) { + (void)painter; portapack::display.drawBMP({(240-185)/2, 0}, splash_bmp); } diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 41ba3251..046c43b1 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -456,7 +456,7 @@ ReceiverView::ReceiverView( options_modulation.set_by_value(receiver_model.modulation()); options_modulation.on_change = [this](size_t n, OptionsField::value_t v) { (void)n; - this->on_modulation_changed(v); + this->on_modulation_changed((mode_type)v); }; /* options_baseband_oversampling.set_by_value(receiver_model.baseband_oversampling()); @@ -625,7 +625,7 @@ void ReceiverView::on_vga_changed(int32_t v_db) { receiver_model.set_vga(v_db); } -void ReceiverView::on_modulation_changed(int32_t modulation) { +void ReceiverView::on_modulation_changed(mode_type modulation) { /* TODO: This is TERRIBLE!!! */ switch(modulation) { case 3: diff --git a/firmware/application/ui_receiver.hpp b/firmware/application/ui_receiver.hpp index 50353b9d..c5109e89 100644 --- a/firmware/application/ui_receiver.hpp +++ b/firmware/application/ui_receiver.hpp @@ -411,13 +411,12 @@ private: { 19 * 8, 1 * 16 }, 4, { - // TODO: Put ordinals in here... - { " AM ", 0 }, - { "NFM ", 1 }, - { "WFM ", 2 }, - { "AIS ", 3 }, - { "TPMS", 5 }, - { "SPEC", 4 }, + { " AM ", RX_NBAM_AUDIO }, + { "NFM ", RX_NBFM_AUDIO }, + { "WFM ", RX_WBFM_AUDIO }, + { "AIS ", RX_AIS }, + { "TPMS", RX_TPMS }, + { "SPEC", RX_WBSPECTRUM }, } }; /* @@ -464,7 +463,7 @@ private: void on_rf_amp_changed(bool v); void on_lna_changed(int32_t v_db); void on_vga_changed(int32_t v_db); - void on_modulation_changed(int32_t modulation); + void on_modulation_changed(mode_type modulation); void on_show_options_frequency(); void on_show_options_rf_gain(); void on_frequency_step_changed(rf::Frequency f); diff --git a/firmware/application/ui_sigfrx.cpp b/firmware/application/ui_sigfrx.cpp new file mode 100644 index 00000000..514e3963 --- /dev/null +++ b/firmware/application/ui_sigfrx.cpp @@ -0,0 +1,144 @@ +/* + * 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 "ui_sigfrx.hpp" +#include "ui_receiver.hpp" + +#include "ch.h" +#include "evtimer.h" + +#include "ff.h" +#include "hackrf_gpio.hpp" +#include "portapack.hpp" +#include "radio.hpp" +//#include "fox_bmp.hpp" + +#include "hackrf_hal.hpp" +#include "portapack_shared_memory.hpp" +#include "portapack_persistent_memory.hpp" + +#include +#include + +using namespace hackrf::one; + +namespace ui { + +void SIGFRXView::focus() { + button_exit.focus(); +} + +SIGFRXView::~SIGFRXView() { + receiver_model.disable(); +} + +void SIGFRXView::paint(Painter& painter) { + uint8_t i, xp; + + //portapack::display.drawBMP({0, 302-160}, fox_bmp); + portapack::display.fill_rectangle({0,16,240,160-16}, ui::Color::white()); + for (i = 0; i < 6; i++) { + xp = sigfrx_marks[i*3]; + painter.draw_string({ (ui::Coord)sigfrx_marks[(i*3)+1], 144-20 }, style_white, to_string_dec_uint(sigfrx_marks[(i*3)+2]) ); + portapack::display.draw_line({xp, 144-4}, {xp, 144}, ui::Color::black()); + } +} + +void SIGFRXView::on_channel_spectrum(const ChannelSpectrum& spectrum) { + portapack::display.fill_rectangle({0, 144, 240, 4},ui::Color::white()); + + uint8_t xmax = 0, imax = 0; + size_t i; + + for (i=0; i<120; i++) { + if (spectrum.db[i] > xmax) { + xmax = spectrum.db[i]; + imax = i; + } + } + for (i=136; i<256; i++) { + if (spectrum.db[i-16] > xmax) { + xmax = spectrum.db[i-16]; + imax = i-16; + } + } + + if ((imax >= last_channel-2) && (imax <= last_channel+2)) { + if (detect_counter >= 5) { + // Latched ! + } else { + detect_counter++; + } + } else { + if (detect_counter >= 5) text_channel.set("... "); + detect_counter = 0; + } + + last_channel = imax; + + portapack::display.fill_rectangle({(ui::Coord)(imax-2), 144, 4, 4}, ui::Color::red()); +} + +void SIGFRXView::on_show() { + context().message_map().register_handler(Message::ID::ChannelSpectrum, + [this](const Message* const p) { + this->on_channel_spectrum(reinterpret_cast(p)->spectrum); + } + ); +} + +SIGFRXView::SIGFRXView( + NavigationView& nav, + ReceiverModel& receiver_model +) : receiver_model(receiver_model) +{ + receiver_model.set_baseband_configuration({ + .mode = RX_SIGFOX, + .sampling_rate = 3072000, + .decimation_factor = 4, + }); + receiver_model.set_baseband_bandwidth(1750000); + + receiver_model.set_tuning_frequency(868110000); + + receiver_model.set_lna(0); + receiver_model.set_vga(0); + + add_children({ { + &text_type, + &text_channel, + &text_data, + &button_exit + } }); + + text_type.set_style(&style_white); + text_channel.set_style(&style_white); + text_data.set_style(&style_white); + + button_exit.on_select = [&nav](Button&){ + nav.pop(); + }; + + receiver_model.enable(); + +} + +} /* namespace ui */ diff --git a/firmware/application/ui_sigfrx.hpp b/firmware/application/ui_sigfrx.hpp new file mode 100644 index 00000000..aebe474c --- /dev/null +++ b/firmware/application/ui_sigfrx.hpp @@ -0,0 +1,87 @@ +/* + * 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 "ui.hpp" +#include "ui_widget.hpp" +#include "ui_painter.hpp" +#include "ui_menu.hpp" +#include "ui_navigation.hpp" +#include "ui_font_fixed_8x16.hpp" +#include "clock_manager.hpp" +#include "message.hpp" +#include "rf_path.hpp" +#include "max2837.hpp" +#include "volume.hpp" +#include "receiver_model.hpp" + +namespace ui { + +class SIGFRXView : public View { +public: + SIGFRXView(NavigationView& nav, ReceiverModel& receiver_model); + ~SIGFRXView(); + void on_channel_spectrum(const ChannelSpectrum& spectrum); + + void on_show() override; + void focus() override; + void paint(Painter& painter) override; + +private: + ReceiverModel& receiver_model; + + uint8_t last_channel; + uint8_t detect_counter = 0; + + const Style style_white { + .font = font::fixed_8x16, + .background = Color::white(), + .foreground = Color::black() + }; + + const uint16_t sigfrx_marks[18] = { + 10, 8, 0, + 60, 52, 90, + 119, 95, 180, + 121, 122, 220, + 179, 171, 310, + 230, 214, 400 }; + + Text text_type { + { 1 * 8, 1 * 16, 28 * 8, 16 }, + "SIGFOX interceptor. Yap !" + }; + + Text text_channel { + { 1 * 8, 3 * 16, 28 * 8, 16 }, + "PL: " + }; + Text text_data { + { 1 * 8, 4 * 16, 28 * 8, 16 }, + "??: " + }; + + Button button_exit { + { 22 * 8, 160 - 32, 56, 32 }, + "Exit" + }; +}; + +} /* namespace ui */ diff --git a/firmware/application/ui_whistle.cpp b/firmware/application/ui_whistle.cpp index b9c6d765..74f31096 100644 --- a/firmware/application/ui_whistle.cpp +++ b/firmware/application/ui_whistle.cpp @@ -50,7 +50,7 @@ WhistleView::~WhistleView() { } void WhistleView::paint(Painter& painter) { - + (void)painter; } void WhistleView::whistle_th(void *arg) { @@ -72,7 +72,7 @@ WhistleView::WhistleView( msg_t mbox_buffer[3]; chMBInit(&mbox, mbox_buffer, 3); - transmitter_model.set_modulation(17); + transmitter_model.set_modulation(TX_TONE); transmitter_model.set_tuning_frequency(portapack::persistent_memory::tuned_frequency()); add_children({ { diff --git a/firmware/application/ui_xylos.cpp b/firmware/application/ui_xylos.cpp index acf0f942..1083b615 100644 --- a/firmware/application/ui_xylos.cpp +++ b/firmware/application/ui_xylos.cpp @@ -49,7 +49,7 @@ XylosView::~XylosView() { } void XylosView::paint(Painter& painter) { - + (void)painter; } void XylosView::upd_message() { @@ -96,7 +96,37 @@ void XylosView::upd_message() { ccirmessage[20] = 0; + // Display as text text_debug.set(ccirmessage); + + // ASCII to baseband frequency LUT index + for (c=0; c<20; c++) { + if (ccirmessage[c] > '9') + ccirmessage[c] -= 0x37; + else + ccirmessage[c] -= 0x30; + } +} + +void XylosView::journuit() { + uint8_t sr; + + chThdSleepMilliseconds(1000); + + // Invert relay states + sr = options_ra.selected_index(); + if (sr > 0) options_ra.set_selected_index(sr ^ 3); + sr = options_rb.selected_index(); + if (sr > 0) options_rb.set_selected_index(sr ^ 3); + sr = options_rc.selected_index(); + if (sr > 0) options_rc.set_selected_index(sr ^ 3); + + upd_message(); + + portapack::audio_codec.set_headphone_volume(volume_t::decibel(90 - 99) + wolfson::wm8731::headphone_gain_range.max); + shared_memory.xylos_transmit_done = false; + memcpy(shared_memory.xylosdata, ccirmessage, 21); + transmitter_model.enable(); } XylosView::XylosView( @@ -116,7 +146,13 @@ XylosView::XylosView( .foreground = Color::black(), }; - transmitter_model.set_modulation(19); + transmitter_model.set_baseband_configuration({ + .mode = TX_XYLOS, + .sampling_rate = 1536000, + .decimation_factor = 1, + }); + + transmitter_model.set_modulation(TX_XYLOS); // Useless ? add_children({ { &text_title, @@ -141,6 +177,7 @@ XylosView::XylosView( &text_progress, &text_debug, &button_transmit, + &checkbox_cligno, &button_exit } }); @@ -170,9 +207,17 @@ XylosView::XylosView( XylosView::upd_message(); }; checkbox_wcsubfamily.on_select = [this](Checkbox&) { + if (checkbox_wcsubfamily.value() == true) + subfamily_code.hidden(true); + else + subfamily_code.hidden(false); XylosView::upd_message(); }; checkbox_wcid.on_select = [this](Checkbox&) { + if (checkbox_wcid.value() == true) + receiver_code.hidden(true); + else + receiver_code.hidden(false); XylosView::upd_message(); }; options_ra.on_change = [this](size_t n, OptionsField::value_t v) { @@ -207,14 +252,19 @@ XylosView::XylosView( char progress[21]; const auto message = static_cast(p); if (message->n == 25) { + portapack::audio_codec.set_headphone_volume(volume_t::decibel(0 - 99) + wolfson::wm8731::headphone_gain_range.max); transmitter_model.disable(); for (c=0;c<20;c++) progress[c] = ' '; progress[20] = 0; text_progress.set(progress); - txing = false; - button_transmit.set_style(&style_val); - button_transmit.set_text("START"); + if (checkbox_cligno.value() == false) { + txing = false; + button_transmit.set_style(&style_val); + button_transmit.set_text("START"); + } else { + journuit(); + } } else { for (c=0;cn;c++) progress[c] = ' '; @@ -227,9 +277,11 @@ XylosView::XylosView( shared_memory.xylos_transmit_done = false; memcpy(shared_memory.xylosdata, ccirmessage, 21); + + transmitter_model.set_tuning_frequency(xylos_freqs[options_freq.selected_index()]); - transmitter_model.set_tuning_frequency(87700000); //xylos_freqs[options_freq.selected_index()]); - + portapack::audio_codec.set_headphone_volume(volume_t::decibel(90 - 99) + wolfson::wm8731::headphone_gain_range.max); + txing = true; button_transmit.set_style(&style_cancel); button_transmit.set_text("Wait"); diff --git a/firmware/application/ui_xylos.hpp b/firmware/application/ui_xylos.hpp index cf3b2640..93b560c4 100644 --- a/firmware/application/ui_xylos.hpp +++ b/firmware/application/ui_xylos.hpp @@ -38,6 +38,7 @@ class XylosView : public View { public: XylosView(NavigationView& nav, TransmitterModel& transmitter_model); ~XylosView(); + void journuit(); void upd_message(); void focus() override; @@ -45,7 +46,7 @@ public: private: bool txing = false; - const rf::Frequency xylos_freqs[6] = { 31325000, 31387500, 31437500, 31475000, 31687500, 31975000 }; + const rf::Frequency xylos_freqs[7] = { 31325000, 31387500, 31437500, 31475000, 31687500, 31975000, 87000000 }; char ccirmessage[21]; TransmitterModel& transmitter_model; @@ -117,14 +118,15 @@ private: }; OptionsField options_freq { { 16 * 8, 9 * 16 }, - 6, + 7, { { "31.3250", 0 }, { "31.3875", 1 }, { "31.4375", 2 }, { "31.4750", 3 }, { "31.6875", 4 }, - { "31.9750", 5 } + { "31.9750", 5 }, + { "TEST 87", 6 } } }; @@ -182,6 +184,11 @@ private: "START" }; + Checkbox checkbox_cligno { + { 96, 16 * 16 + 4}, + "J/N" + }; + Button button_exit { { 21 * 8, 16 * 16, 64, 32 }, "Exit" diff --git a/firmware/baseband-tx.bin b/firmware/baseband-tx.bin index 96a45193046ba060a1073a8ba4314a313831117e..cd98095ecc9e822ba6454e955b3d9ce983d81885 100644 GIT binary patch delta 5560 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 diff --git a/firmware/baseband-tx/audio_dma.cpp b/firmware/baseband-tx/audio_dma.cpp index 6fa6439b..57ff5bc4 100644 --- a/firmware/baseband-tx/audio_dma.cpp +++ b/firmware/baseband-tx/audio_dma.cpp @@ -121,7 +121,7 @@ constexpr gpdma::channel::Config config_rx() { /* TODO: Clean up terminology around "buffer", "transfer", "samples" */ -constexpr size_t buffer_samples_log2n = 7; +constexpr size_t buffer_samples_log2n = 8; // Bumped to 8, to allow filling at 750Hz constexpr size_t buffer_samples = (1 << buffer_samples_log2n); constexpr size_t transfers_per_buffer_log2n = 2; constexpr size_t transfers_per_buffer = (1 << transfers_per_buffer_log2n); diff --git a/firmware/baseband-tx/main.cpp b/firmware/baseband-tx/main.cpp index 11748f7a..30ce1c29 100755 --- a/firmware/baseband-tx/main.cpp +++ b/firmware/baseband-tx/main.cpp @@ -38,6 +38,8 @@ #include "touch_dma.hpp" +#include "modules.h" + #include "dsp_decimate.hpp" #include "dsp_demodulate.hpp" #include "dsp_fft.hpp" @@ -468,6 +470,23 @@ private: const auto baseband_buffer = new std::array(); + +char ram_loop[32]; +typedef int (*fn_ptr)(void); +fn_ptr loop_ptr; + +void ram_loop_fn(void) { + while(1) {} +} + +void wait_for_switch(void) { + memcpy(&ram_loop[0], reinterpret_cast(&ram_loop_fn), 32); + loop_ptr = reinterpret_cast(&ram_loop[0]); + ReadyForSwitchMessage message; + shared_memory.application_queue.push(message); + (*loop_ptr)(); + return; +} int main(void) { init(); @@ -494,30 +513,33 @@ int main(void) { delete old_p; switch(message->configuration.mode) { - case 15: + case TX_RDS: direction = baseband::Direction::Transmit; baseband_thread.baseband_processor = new RDSProcessor(); break; - case 16: + case TX_LCR: direction = baseband::Direction::Transmit; baseband_thread.baseband_processor = new LCRFSKProcessor(); break; - case 17: + case TX_TONE: direction = baseband::Direction::Transmit; baseband_thread.baseband_processor = new ToneProcessor(); break; - case 18: + case TX_JAMMER: direction = baseband::Direction::Transmit; baseband_thread.baseband_processor = new JammerProcessor(); break; - case 19: + case TX_XYLOS: direction = baseband::Direction::Transmit; baseband_thread.baseband_processor = new XylosProcessor(); break; + + case 0xFF: + wait_for_switch(); default: break; diff --git a/firmware/baseband-tx/proc_xylos.cpp b/firmware/baseband-tx/proc_xylos.cpp index 59afcffa..b97089d3 100644 --- a/firmware/baseband-tx/proc_xylos.cpp +++ b/firmware/baseband-tx/proc_xylos.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * @@ -27,27 +28,29 @@ void XylosProcessor::execute(buffer_c8_t buffer) { + // This is called at 1536000/2048 = 750Hz + + ai = 0; + for (size_t i = 0; i= 9) { s = 0; if (sample_count >= CCIR_TONELENGTH) { if (shared_memory.xylos_transmit_done == false) { - message.n = byte_pos; // Progress + message.n = byte_pos; // Inform UI about progress (just as eye candy) shared_memory.application_queue.push(message); digit = shared_memory.xylosdata[byte_pos++]; } if (!digit) { - message.n = 25; // Done code + message.n = 25; // End of message code shared_memory.xylos_transmit_done = true; shared_memory.application_queue.push(message); digit = 0; } - - if (digit > '9') digit -= 7; - digit -= 0x30; sample_count = 0; } else { @@ -59,10 +62,18 @@ void XylosProcessor::execute(buffer_c8_t buffer) { s++; } - sample = (sine_table_f32[(aphase & 0x03FF0000)>>18]*255); + sample = (sine_table_f32[(aphase & 0x03FF0000)>>18]*255); + + // Audio preview sample generation: 1536000/48000 = 32 + if (as >= 31) { + as = 0; + preview_audio_buffer.p[ai++] = sample * 128; + } else { + as++; + } //FM - frq = sample * 160; // 20kHz wide (?) + frq = sample * 300; // ~10kHz wide phase = (phase + frq); sphase = phase + (256<<16); @@ -72,4 +83,6 @@ void XylosProcessor::execute(buffer_c8_t buffer) { buffer.p[i] = {(int8_t)re,(int8_t)im}; } + + fill_audio_buffer(preview_audio_buffer); } diff --git a/firmware/baseband-tx/proc_xylos.hpp b/firmware/baseband-tx/proc_xylos.hpp index a7a4a78d..a9e2458d 100644 --- a/firmware/baseband-tx/proc_xylos.hpp +++ b/firmware/baseband-tx/proc_xylos.hpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * @@ -24,35 +25,42 @@ #include "baseband_processor.hpp" -#define CCIR_TONELENGTH 22800 -#define PHASEV 294.34 +#define CCIR_TONELENGTH 15360-1 // 1536000/10/10 +#define PHASEV 436.91 // (65536*1024)/1536000*10 class XylosProcessor : public BasebandProcessor { public: void execute(buffer_c8_t buffer) override; private: + int16_t audio_data[64]; + + const buffer_s16_t preview_audio_buffer { + audio_data, + sizeof(int16_t)*64 + }; + uint32_t ccir_phases[16] = { - 1981*PHASEV, - 1124*PHASEV, - 1197*PHASEV, - 1275*PHASEV, - 1358*PHASEV, - 1446*PHASEV, - 1540*PHASEV, - 1640*PHASEV, - 1747*PHASEV, - 1860*PHASEV, - 2400*PHASEV, - 930*PHASEV, - 2247*PHASEV, - 991*PHASEV, - 2110*PHASEV, - 1055*PHASEV + (uint32_t)(1981*PHASEV), + (uint32_t)(1124*PHASEV), + (uint32_t)(1197*PHASEV), + (uint32_t)(1275*PHASEV), + (uint32_t)(1358*PHASEV), + (uint32_t)(1446*PHASEV), + (uint32_t)(1540*PHASEV), + (uint32_t)(1640*PHASEV), + (uint32_t)(1747*PHASEV), + (uint32_t)(1860*PHASEV), + (uint32_t)(2400*PHASEV), + (uint32_t)(930*PHASEV), + (uint32_t)(2247*PHASEV), + (uint32_t)(991*PHASEV), + (uint32_t)(2110*PHASEV), + (uint32_t)(1055*PHASEV) }; int8_t re, im; - uint8_t s; + uint8_t s, as = 0, ai; uint8_t byte_pos = 0; uint8_t digit = 0; uint32_t sample_count = CCIR_TONELENGTH; diff --git a/firmware/baseband.bin b/firmware/baseband.bin index d5656041c1de84757f86619b8904a197adbf8760..99a0ae2d3c5d7977980396d58843822adec4d382 100644 GIT binary patch delta 10650 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 delta 5653 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 W+LOY+tyestH^AS_;p0!i{Qm{vvkv|M diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index 701efba0..bdf520b5 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -41,6 +41,8 @@ #include "touch_dma.hpp" +#include "modules.h" + #include "dsp_decimate.hpp" #include "dsp_demodulate.hpp" #include "dsp_fft.hpp" @@ -57,9 +59,9 @@ #include "proc_am_audio.hpp" #include "proc_nfm_audio.hpp" #include "proc_wfm_audio.hpp" -//#include "proc_ais.hpp" +#include "proc_ais.hpp" #include "proc_wideband_spectrum.hpp" -//#include "proc_tpms.hpp" +#include "proc_tpms.hpp" #include "proc_afskrx.hpp" #include "proc_sigfrx.hpp" @@ -390,46 +392,46 @@ int main(void) { delete old_p; switch(message->configuration.mode) { - case 0: + case RX_NBAM_AUDIO: direction = baseband::Direction::Receive; baseband_thread.baseband_processor = new NarrowbandAMAudio(); break; - case 1: + case RX_NBFM_AUDIO: direction = baseband::Direction::Receive; baseband_thread.baseband_processor = new NarrowbandFMAudio(); break; - case 2: + case RX_WBFM_AUDIO: baseband_thread.baseband_processor = new WidebandFMAudio(); break; - /*case 3: + case RX_AIS: direction = baseband::Direction::Receive; baseband_thread.baseband_processor = new AISProcessor(); - break;*/ + break; - case 4: + case RX_WBSPECTRUM: direction = baseband::Direction::Receive; baseband_thread.baseband_processor = new WidebandSpectrum(); break; - /*case 5: + case RX_TPMS: direction = baseband::Direction::Receive; baseband_thread.baseband_processor = new TPMSProcessor(); - break;*/ + break; - case 6: + case RX_AFSK: direction = baseband::Direction::Receive; baseband_thread.baseband_processor = new AFSKRXProcessor(); break; - case 7: + case RX_SIGFOX: direction = baseband::Direction::Receive; baseband_thread.baseband_processor = new SIGFRXProcessor(); break; - case 0xFF: + case SWITCH: wait_for_switch(); default: diff --git a/firmware/baseband/proc_sigfrx.cpp b/firmware/baseband/proc_sigfrx.cpp new file mode 100644 index 00000000..c6ca3a8e --- /dev/null +++ b/firmware/baseband/proc_sigfrx.cpp @@ -0,0 +1,69 @@ +/* + * 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 "proc_sigfrx.hpp" + +#include +#include + +void SIGFRXProcessor::execute(buffer_c8_t buffer) { + /* Called every 2048/3072000 second -- 1500Hz. */ + + auto decimator_out = decimator.execute(buffer); + + const buffer_c16_t work_baseband_buffer { + (complex16_t*)decimator_out.p, + sizeof(*decimator_out.p) * decimator_out.count + }; + + /* 192kHz complex[64] + * -> 96kHz int16_t[32] */ + //auto channel = channel_filter.execute(decimator_out, work_baseband_buffer); + + // TODO: Feed channel_stats post-decimation data? + feed_channel_spectrum( + decimator_out, + 41000, //decimator_out.sampling_rate * channel_filter_taps.pass_frequency_normalized, + 70000 //decimator_out.sampling_rate * channel_filter_taps.stop_frequency_normalized + ); + + /*const buffer_s16_t work_audio_buffer { + (int16_t*)decimator_out.p, + sizeof(*decimator_out.p) * decimator_out.count + }; + * + auto audio = demod.execute(channel, work_audio_buffer); + + static uint64_t audio_present_history = 0; + const auto audio_present_now = squelch.execute(audio); + audio_present_history = (audio_present_history << 1) | (audio_present_now ? 1 : 0); + const bool audio_present = (audio_present_history != 0); + + if( !audio_present ) { + // Zero audio buffer. + for(size_t i=0; i& channel_filter_taps = taps_64_lp_410_700_tfilter; //taps_64_lp_104_140_tfilter + //dsp::decimate::FIRAndDecimateComplex channel_filter; + dsp::demodulate::FM demod { 48000, 7500 }; + + IIRBiquadFilter audio_hpf { audio_hpf_config }; + FMSquelch squelch; +}; + +#endif diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index bc4af7ba..77181b94 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -159,13 +159,33 @@ public: AudioStatistics statistics; }; +typedef enum { + RX_NBAM_AUDIO = 0, + RX_NBFM_AUDIO, + RX_WBFM_AUDIO, + RX_AIS, + RX_WBSPECTRUM, + RX_TPMS, + RX_AFSK, + RX_SIGFOX, + + TX_RDS, + TX_LCR, + TX_TONE, + TX_JAMMER, + TX_XYLOS, + + NONE, + SWITCH = 0xFF +} mode_type; + struct BasebandConfiguration { - int32_t mode; + mode_type mode; uint32_t sampling_rate; size_t decimation_factor; constexpr BasebandConfiguration( - int32_t mode = -1, + mode_type mode = NONE, uint32_t sampling_rate = 0, size_t decimation_factor = 1 ) : mode { mode }, diff --git a/firmware/common/modules.h b/firmware/common/modules.h new file mode 100644 index 00000000..26dd3977 --- /dev/null +++ b/firmware/common/modules.h @@ -0,0 +1,2 @@ +const char md5_baseband[16] = {0x20,0xb7,0x1a,0x68,0x28,0xda,0xc9,0xb8,0x01,0xb0,0xbd,0x68,0x0d,0xd5,0xd6,0xa7,}; +const char md5_baseband_tx[16] = {0xe5,0x29,0xb9,0xf0,0x81,0x50,0x45,0x69,0x24,0xaf,0xdd,0x4e,0xdb,0xaf,0xd8,0x97,}; diff --git a/firmware/portapack-h1-firmware.bin b/firmware/portapack-h1-firmware.bin index bd6b5d2455cc1f14e80c5d1f36577b4d26de0508..53acde85f2f98c8402c71b82c942cdad6f7add1c 100644 GIT binary patch delta 57671 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Π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 DJk9WA delta 62990 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�uGI4`bg)jo4UE(&U>E&?MBg7nsCK30n@ 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