diff --git a/firmware/application/external/external.cmake b/firmware/application/external/external.cmake index b37b0f08..a84fa931 100644 --- a/firmware/application/external/external.cmake +++ b/firmware/application/external/external.cmake @@ -67,6 +67,12 @@ set(EXTCPPSRC external/extsensors/main.cpp external/extsensors/ui_extsensors.cpp external/extsensors/ui_extsensors.hpp + + #foxhunt + external/foxhunt/main.cpp + external/foxhunt/ui_foxhunt_rx.cpp + external/foxhunt/ui_foxhunt_rx.hpp + ) set(EXTAPPLIST @@ -86,4 +92,5 @@ set(EXTAPPLIST keyfob tetris extsensors + foxhunt_rx ) diff --git a/firmware/application/external/external.ld b/firmware/application/external/external.ld index 3249ea45..c75276f3 100644 --- a/firmware/application/external/external.ld +++ b/firmware/application/external/external.ld @@ -39,6 +39,7 @@ MEMORY ram_external_app_keyfob(rwx) : org = 0xADBD0000, len = 32k ram_external_app_tetris(rwx) : org = 0xADBE0000, len = 32k ram_external_app_extsensors(rwx) : org = 0xADBF0000, len = 32k + ram_external_app_foxhunt_rx(rwx) : org = 0xADC00000, len = 32k } SECTIONS @@ -139,6 +140,12 @@ SECTIONS *(*ui*external_app*extsensors*); } > ram_external_app_extsensors + .external_app_foxhunt_rx : ALIGN(4) SUBALIGN(4) + { + KEEP(*(.external_app.app_foxhunt_rx.application_information)); + *(*ui*external_app*foxhunt_rx*); + } > ram_external_app_foxhunt_rx + } diff --git a/firmware/application/external/foxhunt/main.cpp b/firmware/application/external/foxhunt/main.cpp new file mode 100644 index 00000000..1f652846 --- /dev/null +++ b/firmware/application/external/foxhunt/main.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2024 HTotoo + * + * 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_foxhunt_rx.hpp" +#include "ui_navigation.hpp" +#include "external_app.hpp" + +namespace ui::external_app::foxhunt_rx { +void initialize_app(ui::NavigationView& nav) { + nav.push(); +} +} // namespace ui::external_app::foxhunt_rx + +extern "C" { + +__attribute__((section(".external_app.app_foxhunt_rx.application_information"), used)) application_information_t _application_information_foxhunt_rx = { + /*.memory_location = */ (uint8_t*)0x00000000, + /*.externalAppEntry = */ ui::external_app::foxhunt_rx::initialize_app, + /*.header_version = */ CURRENT_HEADER_VERSION, + /*.app_version = */ VERSION_MD5, + + /*.app_name = */ "Fox hunt", + /*.bitmap_data = */ { + 0x18, + 0x18, + 0x28, + 0x14, + 0x68, + 0x16, + 0x68, + 0x16, + 0xC8, + 0x13, + 0x88, + 0x11, + 0x04, + 0x20, + 0x24, + 0x24, + 0x22, + 0x44, + 0x01, + 0x80, + 0x06, + 0x60, + 0x98, + 0x19, + 0x20, + 0x04, + 0x40, + 0x02, + 0x80, + 0x01, + 0x00, + 0x00, + }, + /*.icon_color = */ ui::Color::yellow().v, + /*.menu_location = */ app_location_t::RX, + + /*.m4_app_tag = portapack::spi_flash::image_tag_am_audio */ {'P', 'A', 'M', 'A'}, + /*.m4_app_offset = */ 0x00000000, // will be filled at compile time +}; +} diff --git a/firmware/application/external/foxhunt/ui_foxhunt_rx.cpp b/firmware/application/external/foxhunt/ui_foxhunt_rx.cpp new file mode 100644 index 00000000..cac19c30 --- /dev/null +++ b/firmware/application/external/foxhunt/ui_foxhunt_rx.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2024 HTotoo + * + * 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_foxhunt_rx.hpp" + +#include "audio.hpp" +#include "rtc_time.hpp" +#include "baseband_api.hpp" +#include "string_format.hpp" +#include "portapack_persistent_memory.hpp" + +using namespace portapack; +using namespace modems; +using namespace ui; + +namespace ui::external_app::foxhunt_rx { + +void FoxhuntRxView::focus() { + field_frequency.focus(); +} + +FoxhuntRxView::FoxhuntRxView(NavigationView& nav) + : nav_{nav} { + baseband::run_image(portapack::spi_flash::image_tag_am_audio); + + add_children({&rssi, + &field_rf_amp, + &field_lna, + &field_vga, + &field_volume, + &field_frequency, + &freq_stats_db, + &rssi_graph, + &geomap, + &clear_markers, + &add_current_marker}); + + clear_markers.on_select = [this](Button&) { + geomap.clear_markers(); + }; + add_current_marker.on_select = [this](Button&) { + GeoMarker tmp{my_lat, my_lon, my_orientation}; + geomap.store_marker(tmp); + }; + geomap.set_mode(DISPLAY); + geomap.set_manual_panning(false); + // geomap.set_enable_additional_zoom(true); + // geomap.set_hide_center_marker(true); //todo hide again after testing + geomap.set_focusable(true); + geomap.clear_markers(); + receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); + field_frequency.set_step(100); + receiver_model.enable(); + audio::output::start(); + rssi_graph.set_nb_columns(64); + geomap.init(); +} + +FoxhuntRxView::~FoxhuntRxView() { + receiver_model.disable(); + baseband::shutdown(); + audio::output::stop(); +} + +void FoxhuntRxView::on_statistics_update(const ChannelStatistics& statistics) { + static int16_t last_max_db = -1000; + rssi_graph.add_values(rssi.get_min(), rssi.get_avg(), rssi.get_max(), statistics.max_db); + // refresh db + if (last_max_db != statistics.max_db) { + last_max_db = statistics.max_db; + freq_stats_db.set("Power: " + to_string_dec_int(statistics.max_db) + " db"); + } + +} /* on_statistic_updates */ + +void FoxhuntRxView::on_gps(const GPSPosDataMessage* msg) { + my_lat = msg->lat; + my_lon = msg->lon; + geomap.update_my_position(msg->lat, msg->lon, msg->altitude); + geomap.move(my_lon, my_lat); + geomap.set_dirty(); +} +void FoxhuntRxView::on_orientation(const OrientationDataMessage* msg) { + my_orientation = msg->angle; + geomap.set_angle(msg->angle); + geomap.update_my_orientation(msg->angle, true); +} + +} // namespace ui::external_app::foxhunt_rx diff --git a/firmware/application/external/foxhunt/ui_foxhunt_rx.hpp b/firmware/application/external/foxhunt/ui_foxhunt_rx.hpp new file mode 100644 index 00000000..ba47086d --- /dev/null +++ b/firmware/application/external/foxhunt/ui_foxhunt_rx.hpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2024 HTotoo + * + * 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_FOXHUNT_RX_H__ +#define __UI_FOXHUNT_RX_H__ + +#include "ui.hpp" +#include "ui_language.hpp" +#include "ui_navigation.hpp" +#include "ui_receiver.hpp" +#include "ui_geomap.hpp" +#include "ui_freq_field.hpp" +#include "ui_record_view.hpp" +#include "app_settings.hpp" +#include "radio_state.hpp" +#include "log_file.hpp" +#include "utility.hpp" + +using namespace ui; + +namespace ui::external_app::foxhunt_rx { + +class FoxhuntRxView : public View { + public: + FoxhuntRxView(NavigationView& nav); + ~FoxhuntRxView(); + + void focus() override; + + std::string title() const override { return "Fox hunt"; }; + + private: + NavigationView& nav_; + RxRadioState radio_state_{}; + app_settings::SettingsManager settings_{ + "rx_foxhunt", app_settings::Mode::RX}; + + RFAmpField field_rf_amp{ + {13 * 8, 0 * 16}}; + LNAGainField field_lna{ + {15 * 8, 0 * 16}}; + VGAGainField field_vga{ + {18 * 8, 0 * 16}}; + RSSI rssi{ + {21 * 8, 0, 6 * 8, 4}}; + AudioVolumeField field_volume{ + {28 * 8, 0 * 16}}; + + RxFrequencyField field_frequency{ + {0 * 8, 0 * 16}, + nav_}; + + // Power: -XXX db + Text freq_stats_db{ + {0 * 8, 2 * 16 + 4, 14 * 8, 14}, + }; + RSSIGraph rssi_graph{ + {0, 50, 240, 30}, + }; + + Button clear_markers{ + {10 * 8, 18, 8 * 8, 16}, + LanguageHelper::currentMessages[LANG_CLEAR]}; + + Button add_current_marker{ + {2, 18, 7 * 8, 16}, + "Mark"}; + + GeoMap geomap{{0, 80, 240, 240}}; + + MessageHandlerRegistration message_handler_gps{ + Message::ID::GPSPosData, + [this](Message* const p) { + const auto message = static_cast(p); + this->on_gps(message); + }}; + MessageHandlerRegistration message_handler_orientation{ + Message::ID::OrientationData, + [this](Message* const p) { + const auto message = static_cast(p); + this->on_orientation(message); + }}; + MessageHandlerRegistration message_handler_stats{ + Message::ID::ChannelStatistics, + [this](const Message* const p) { + this->on_statistics_update(static_cast(p)->statistics); + }}; + + float my_lat = 200; + float my_lon = 200; + uint16_t my_orientation = 400; + + void on_gps(const GPSPosDataMessage* msg); + void on_orientation(const OrientationDataMessage* msg); + void on_statistics_update(const ChannelStatistics& statistics); +}; + +} // namespace ui::external_app::foxhunt_rx + +#endif /*__UI_FOXHUNT_RX_H__*/