diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index bc21e8be..5289fb5a 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -191,7 +191,6 @@ set(CPPSRC core_control.cpp database.cpp de_bruijn.cpp - #emu_cc1101.cpp rfm69.cpp event_m0.cpp file_reader.cpp @@ -246,7 +245,6 @@ set(CPPSRC hw/touch_adc.cpp ui_baseband_stats_view.cpp ui_navigation.cpp - ui_playdead.cpp ui_record_view.cpp ui_sd_card_status_view.cpp ui/ui_alphanum.cpp @@ -270,28 +268,21 @@ set(CPPSRC ui/ui_bmpview.cpp apps/ais_app.cpp apps/analog_audio_app.cpp - # apps/analog_tv_app.cpp apps/ble_comm_app.cpp apps/ble_rx_app.cpp apps/ble_tx_app.cpp apps/capture_app.cpp apps/ert_app.cpp - # apps/gps_sim_app.cpp - # apps/lge_app.cpp apps/pocsag_app.cpp - # apps/replay_app.cpp apps/soundboard_app.cpp - # apps/tpms_app.cpp apps/ui_about_simple.cpp apps/ui_adsb_rx.cpp - # apps/ui_adsb_tx.cpp #moved to ext apps/ui_aprs_rx.cpp apps/ui_aprs_tx.cpp apps/ui_battinfo.cpp apps/ui_bht_tx.cpp apps/ui_bmp_file_viewer.cpp apps/ui_btle_rx.cpp - # apps/ui_coasterp.cpp apps/ui_debug.cpp apps/ui_debug_max17055.cpp apps/ui_dfu_menu.cpp @@ -302,16 +293,10 @@ set(CPPSRC apps/ui_freqman.cpp apps/ui_fsk_rx.cpp apps/ui_iq_trim.cpp - # apps/ui_jammer.cpp - # apps/ui_keyfob.cpp - # apps/ui_lcr.cpp apps/ui_level.cpp apps/ui_looking_glass_app.cpp apps/ui_mictx.cpp apps/ui_modemsetup.cpp - # apps/ui_morse.cpp - # apps/ui_nrf_rx.cpp - # apps/ui_nuoptix.cpp apps/ui_playlist.cpp apps/ui_pocsag_tx.cpp apps/ui_rds.cpp @@ -325,16 +310,11 @@ set(CPPSRC apps/ui_settings.cpp apps/ui_siggen.cpp apps/ui_sonde.cpp - # apps/ui_spectrum_painter_image.cpp - # apps/ui_spectrum_painter_text.cpp - # apps/ui_spectrum_painter.cpp apps/ui_ss_viewer.cpp - # apps/ui_sstvtx.cpp #moved to ext apps/ui_standalone_view.cpp apps/ui_subghzd.cpp # apps/ui_test.cpp apps/ui_text_editor.cpp - apps/ui_tone_search.cpp apps/ui_touch_calibration.cpp apps/ui_touchtunes.cpp apps/ui_view_wav.cpp @@ -345,14 +325,8 @@ set(CPPSRC protocols/bht.cpp protocols/dcs.cpp protocols/encoders.cpp - # protocols/lcr.cpp protocols/modems.cpp protocols/rds.cpp - # ui_handwrite.cpp - # ui_loadmodule.cpp - # ui_numbers.cpp - # ui_replay_view.cpp - # ui_script.cpp ui_sd_card_debug.cpp config_mode.cpp ${CPLD_20150901_DATA_CPP} diff --git a/firmware/application/apps/replay_app.cpp b/firmware/application/apps/replay_app.cpp deleted file mode 100644 index 832b41c6..00000000 --- a/firmware/application/apps/replay_app.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2016 Furrtek - * Copyleft (ↄ) 2022 NotPike - * - * 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 "replay_app.hpp" -#include "string_format.hpp" - -#include "ui_fileman.hpp" -#include "io_file.hpp" -#include "io_convert.hpp" - -#include "baseband_api.hpp" -#include "metadata_file.hpp" -#include "portapack.hpp" -#include "portapack_persistent_memory.hpp" -#include "utility.hpp" - -using namespace portapack; -namespace fs = std::filesystem; - -namespace ui { - -void ReplayAppView::set_ready() { - ready_signal = true; -} - -void ReplayAppView::on_file_changed(const fs::path& new_file_path) { - file_path = new_file_path; - File::Size file_size{}; - - { // Get the size of the data file. - File data_file; - auto error = data_file.open(file_path); - if (error) { - file_error(); - return; - } - - file_size = data_file.size(); - } - - // Get original record frequency if available. - auto metadata_path = get_metadata_path(file_path); - auto metadata = read_metadata_file(metadata_path); - - if (metadata) { - field_frequency.set_value(metadata->center_frequency); - sample_rate = metadata->sample_rate; - } else { - // TODO: This is interesting because it implies that the - // The capture will just be replayed at the freq set on the - // FrequencyField. Is that an intentional behavior? - sample_rate = 500000; - } - - // UI Fixup. - text_sample_rate.set(unit_auto_scale(sample_rate, 3, 0) + "Hz"); - progressbar.set_max(file_size); - text_filename.set(truncate(file_path.filename().string(), 12)); - - uint8_t sample_size = capture_file_sample_size(current()->path); - auto duration = ms_duration(file_size, sample_rate, sample_size); - text_duration.set(to_string_time_ms(duration)); - - button_play.focus(); -} - -void ReplayAppView::on_tx_progress(const uint32_t progress) { - progressbar.set_value(progress); -} - -void ReplayAppView::focus() { - button_open.focus(); -} - -void ReplayAppView::file_error() { - nav_.display_modal("Error", "File read error."); -} - -bool ReplayAppView::is_active() const { - return (bool)replay_thread; -} - -void ReplayAppView::toggle() { - if (is_active()) { - stop(false); - } else { - start(); - } -} - -void ReplayAppView::start() { - stop(false); - - std::unique_ptr reader; - - auto p = std::make_unique(); - auto open_error = p->open(file_path); - if (open_error.is_valid()) { - file_error(); - return; // Fixes TX bug if there's a file error - } else { - reader = std::move(p); - } - - if (reader) { - button_play.set_bitmap(&bitmap_stop); - baseband::set_sample_rate(sample_rate, OversampleRate::x8); - - replay_thread = std::make_unique( - std::move(reader), - read_size, buffer_count, - &ready_signal, - [](uint32_t return_code) { - ReplayThreadDoneMessage message{return_code}; - EventDispatcher::send_message(message); - }); - } - - transmitter_model.set_sampling_rate(sample_rate * toUType(OversampleRate::x8)); - transmitter_model.set_baseband_bandwidth(baseband_bandwidth); - transmitter_model.enable(); - - if (portapack::persistent_memory::stealth_mode()) { - DisplaySleepMessage message; - EventDispatcher::send_message(message); - } -} - -void ReplayAppView::stop(const bool do_loop) { - if (is_active()) - replay_thread.reset(); - - if (do_loop && check_loop.value()) { - start(); - } else { - transmitter_model.disable(); - button_play.set_bitmap(&bitmap_play); - } - - ready_signal = false; -} - -void ReplayAppView::handle_replay_thread_done(const uint32_t return_code) { - if (return_code == ReplayThread::END_OF_FILE) { - stop(true); - } else if (return_code == ReplayThread::READ_ERROR) { - stop(false); - file_error(); - } - - progressbar.set_value(0); -} - -ReplayAppView::ReplayAppView( - NavigationView& nav) - : nav_(nav) { - baseband::run_image(portapack::spi_flash::image_tag_replay); - - add_children({ - &button_open, - &text_filename, - &text_sample_rate, - &text_duration, - &progressbar, - &field_frequency, - &tx_view, // now it handles previous rfgain, rfamp. - &check_loop, - &button_play, - &waterfall, - }); - - button_play.on_select = [this](ImageButton&) { - this->toggle(); - }; - - button_open.on_select = [this, &nav](Button&) { - auto open_view = nav.push(".C*"); - open_view->on_changed = [this](fs::path new_file_path) { - on_file_changed(new_file_path); - }; - }; -} - -ReplayAppView::~ReplayAppView() { - transmitter_model.disable(); - baseband::shutdown(); -} - -void ReplayAppView::on_hide() { - stop(false); - // TODO: Terrible kludge because widget system doesn't notify Waterfall that - // it's being shown or hidden. - waterfall.on_hide(); - View::on_hide(); -} - -void ReplayAppView::set_parent_rect(const Rect new_parent_rect) { - View::set_parent_rect(new_parent_rect); - - const ui::Rect waterfall_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height}; - waterfall.set_parent_rect(waterfall_rect); -} - -} /* namespace ui */ diff --git a/firmware/application/apps/replay_app.hpp b/firmware/application/apps/replay_app.hpp deleted file mode 100644 index 716fa6cd..00000000 --- a/firmware/application/apps/replay_app.hpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2016 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 __REPLAY_APP_HPP__ -#define __REPLAY_APP_HPP__ - -#include "app_settings.hpp" -#include "radio_state.hpp" -#include "ui_widget.hpp" -#include "ui_navigation.hpp" -#include "ui_receiver.hpp" -#include "ui_freq_field.hpp" -#include "replay_thread.hpp" -#include "ui_spectrum.hpp" -#include "ui_transmitter.hpp" - -#include -#include - -namespace ui { - -class ReplayAppView : public View { - public: - ReplayAppView(NavigationView& nav); - ~ReplayAppView(); - - void on_hide() override; - void set_parent_rect(const Rect new_parent_rect) override; - void focus() override; - - std::string title() const override { return "Replay"; }; - - private: - NavigationView& nav_; - TxRadioState radio_state_{}; - app_settings::SettingsManager settings_{ - "tx_replay", app_settings::Mode::TX}; - - static constexpr ui::Dim header_height = 3 * 16; - - uint32_t sample_rate = 0; - int32_t tx_gain{47}; - bool rf_amp{true}; // aux private var to store temporal, Replay App rf_amp user selection. - static constexpr uint32_t baseband_bandwidth = 2500000; - const size_t read_size{16384}; - const size_t buffer_count{3}; - - void on_file_changed(const std::filesystem::path& new_file_path); - void on_tx_progress(const uint32_t progress); - - void toggle(); - void start(); - void stop(const bool do_loop); - bool is_active() const; - void set_ready(); - void handle_replay_thread_done(const uint32_t return_code); - void file_error(); - - std::filesystem::path file_path{}; - std::unique_ptr replay_thread{}; - bool ready_signal{false}; - - Button button_open{ - {0 * 8, 0 * 16, 10 * 8, 2 * 16}, - "Open file"}; - - Text text_filename{ - {11 * 8, 0 * 16, 12 * 8, 16}, - "-"}; - Text text_sample_rate{ - {24 * 8, 0 * 16, 6 * 8, 16}, - "-"}; - - Text text_duration{ - {11 * 8, 1 * 16, 6 * 8, 16}, - "-"}; - ProgressBar progressbar{ - {18 * 8, 1 * 16, 12 * 8, 16}}; - - TxFrequencyField field_frequency{ - {0 * 8, 2 * 16}, - nav_}; - - TransmitterView2 tx_view{ - {11 * 8, 2 * 16}, - /*short_ui*/ true}; - - Checkbox check_loop{ - {21 * 8, 2 * 16}, - 4, - "Loop", - true}; - ImageButton button_play{ - {28 * 8, 2 * 16, 2 * 8, 1 * 16}, - &bitmap_play, - Theme::getInstance()->fg_green->foreground, - Theme::getInstance()->fg_green->background}; - - spectrum::WaterfallView waterfall{}; - - MessageHandlerRegistration message_handler_replay_thread_error{ - Message::ID::ReplayThreadDone, - [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->handle_replay_thread_done(message.return_code); - }}; - - MessageHandlerRegistration message_handler_fifo_signal{ - Message::ID::RequestSignal, - [this](const Message* const p) { - const auto message = static_cast(p); - if (message->signal == RequestSignalMessage::Signal::FillRequest) { - this->set_ready(); - } - }}; - - MessageHandlerRegistration message_handler_tx_progress{ - Message::ID::TXProgress, - [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->on_tx_progress(message.progress); - }}; -}; - -} /* namespace ui */ - -#endif /*__REPLAY_APP_HPP__*/ diff --git a/firmware/application/apps/ui_about.cpp b/firmware/application/apps/ui_about.cpp deleted file mode 100644 index 681d67ec..00000000 --- a/firmware/application/apps/ui_about.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 "cpld_update.hpp" -#include "portapack.hpp" -#include "event_m0.hpp" - -#include "ui_about.hpp" - -#include "portapack_shared_memory.hpp" -#include "portapack_persistent_memory.hpp" -#include "lpc43xx_cpp.hpp" - -#include -#include - -using namespace lpc43xx; -using namespace portapack; - -namespace ui { - -// This is pretty much WaterfallView but in the opposite direction -CreditsWidget::CreditsWidget( - Rect parent_rect) - : Widget{parent_rect} { -} - -void CreditsWidget::paint(Painter&) { -} - -void CreditsWidget::on_show() { - clear(); - - const auto screen_r = screen_rect(); - display.scroll_set_area(screen_r.top(), screen_r.bottom()); -} - -void CreditsWidget::on_hide() { - display.scroll_disable(); -} - -void CreditsWidget::new_row( - const std::array& pixel_row) { - // Glitch be here (see comment in main.cpp) - const auto draw_y = display.scroll(-1); - - display.draw_pixels( - {{0, draw_y - 1}, {240, 1}}, - pixel_row); -} - -void CreditsWidget::clear() { - display.fill_rectangle( - screen_rect(), - Theme::getInstance()->bg_darkest->background); -} - -void AboutView::update() { - size_t i = 0; - std::array pixel_row; - - slow_down++; - if (slow_down % 3 < 2) return; - - if (!timer) { - if (loop) { - credits_index = 0; - loop = false; - } - - text = credits[credits_index].text; - timer = credits[credits_index].delay; - start_pos = credits[credits_index].start_pos; - - if (timer < 0) { - timer = 240; - loop = true; - } else - timer += 16; - - render_line = 0; - credits_index++; - } else - timer--; - - if (render_line < 16) { - for (const auto c : text) { - const auto glyph = style().font.glyph(c); - - const size_t start = (glyph.size().width() / 8) * render_line; - for (Dim c = 0; c < glyph.size().width(); c++) { - const auto pixel = glyph.pixels()[start + (c >> 3)] & (1U << (c & 0x7)); - pixel_row[start_pos + i + c] = pixel ? Theme::getInstance()->bg_darkest->foreground : Theme::getInstance()->bg_darkest->background; - } - - const auto advance = glyph.advance(); - i += advance.x(); - } - render_line++; - } - - credits_display.new_row(pixel_row); -} - -AboutView::AboutView( - NavigationView& nav) { - add_children({&credits_display, - &button_ok}); - - button_ok.on_select = [&nav](Button&) { - nav.pop(); - }; -} - -void AboutView::focus() { - button_ok.focus(); -} - -} /* namespace ui */ diff --git a/firmware/application/apps/ui_about.hpp b/firmware/application/apps/ui_about.hpp deleted file mode 100644 index e4f5e0c9..00000000 --- a/firmware/application/apps/ui_about.hpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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_ABOUT_H__ -#define __UI_ABOUT_H__ - -#include "ui_widget.hpp" -#include "ui_navigation.hpp" - -#include - -namespace ui { - -class CreditsWidget : public Widget { - public: - CreditsWidget(Rect parent_rect); - - void on_show() override; - void on_hide() override; - - void paint(Painter&) override; - - void new_row(const std::array& pixel_row); - - private: - void clear(); -}; - -class AboutView : public View { - public: - AboutView(NavigationView& nav); - - void focus() override; - - std::string title() const override { return "About"; }; - - private: - void update(); - - uint8_t credits_index{0}; - uint8_t render_line{0}; - Coord start_pos{0}; - uint8_t slow_down{0}; - int32_t timer{0}; - bool loop{false}; - - std::string text{}; - - typedef struct credits_t { - size_t start_pos; - std::string text; - int32_t delay; - } credits_t; - - // TODO: Make this dinamically centered and parse \n as the delay value so it is easy to maintain - const credits_t credits[26] = { - // 012345678901234567890123456789 - {60, "PortaPack Mayhem", 0}, - {60, "PortaPack|HAVOC", 0}, - {11 * 8, "Gurus J. Boone", 0}, - {18 * 8, "M. Ossmann", 16}, - {11 * 8, "HAVOC Furrtek", 16}, - {7 * 8, "POCSAG rx T. Sailer", 0}, - {18 * 8, "E. Oenal", 16}, - {0 * 8, "Radiosonde infos F4GMU", 0}, - {18 * 8, "RS1729", 16}, - {4 * 8, "RDS waveform C. Jacquet", 16}, - {7 * 8, "Xy. infos cLx", 16}, - {2 * 8, "OOK scan trick Samy Kamkar", 16}, - {7 * 8, "World map NASA", 16}, - {0 * 8, "TouchTunes infos Notpike", 16}, - {4 * 8, "Subaru infos Tom", 0}, - {18 * 8, "Wimmenhove", 16}, - {1 * 8, "GPS,TV,BTLE,NRF Shao", 24}, - {6 * 8, "Thanks & donators", 16}, - {1 * 8, "Rainer Matla Keld Norman", 0}, - {1 * 8, " Giorgio C. DC1RDB", 0}, - {1 * 8, " Sigmounte Waax", 0}, - {1 * 8, " Windyoona Channels", 0}, - {1 * 8, " F4GEV Pyr3x", 0}, - {1 * 8, " HB3YOE", 24}, - {11 * 8, "MMXVIII", -1}}; - - CreditsWidget credits_display{ - {0, 16, 240, 240}}; - - Button button_ok{ - {72, 272, 96, 24}, - "OK"}; - - MessageHandlerRegistration message_handler_update{ - Message::ID::DisplayFrameSync, - [this](const Message* const) { - this->update(); - }}; -}; - -} /* namespace ui */ - -#endif /*__UI_ABOUT_H__*/ diff --git a/firmware/application/apps/ui_about_demo.cpp b/firmware/application/apps/ui_about_demo.cpp deleted file mode 100644 index 853b0c4e..00000000 --- a/firmware/application/apps/ui_about_demo.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/* - * 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 - -#include "demofont.hpp" -#include "ymdata.hpp" - -#include "cpld_update.hpp" -#include "portapack.hpp" -#include "audio.hpp" -#include "event_m0.hpp" - -#include "ui_about.hpp" -#include "touch.hpp" -#include "sine_table.hpp" - -#include "portapack_shared_memory.hpp" -#include "portapack_persistent_memory.hpp" -#include "lpc43xx_cpp.hpp" - -#include -#include - -using namespace lpc43xx; -using namespace portapack; - -namespace ui { - -void AboutView::on_show() { - transmitter_model.set_target_frequency(1337000000); // TODO: Change - transmitter_model.set_baseband_configuration({ - .mode = 0, - .sampling_rate = 1536000, - .decimation_factor = 1, - }); - transmitter_model.set_rf_amp(true); - transmitter_model.set_lna(40); - transmitter_model.set_vga(40); - transmitter_model.enable(); - - baseband::set_audiotx_data(32, 50, false, 0); - - // audio::headphone::set_volume(volume_t::decibel(0 - 99) + audio::headphone::volume_range().max); -} - -void AboutView::render_video() { - uint8_t p, r, luma, chroma, cy; - ui::Color cc; - char ch; - float s; - - // Send framebuffer to LCD. Gotta go fast ! - display.render_box({30, 112}, {180, 72}, framebuffer); - - // Clear framebuffer to black - memset(framebuffer, 0, 180 * 72 * sizeof(ui::Color)); - - // Drum hit palette animation - if (drum > 1) drum--; - - // Render copper bars from Y buffer - for (p = 0; p < 72; p++) { - luma = copperbuffer[p] & 0x0F; // 0 is transparent - if (luma) { - chroma = copperbuffer[p] >> 4; - cc = ui::Color(std::min((coppercolor[chroma][0] / luma) * drum, 255), std::min((coppercolor[chroma][1] / luma) * drum, 255), std::min((coppercolor[chroma][2] / luma) * drum, 255)); - for (r = 0; r < 180; r++) - framebuffer[(p * 180) + r] = cc; - } - } - - // Scroll in/out state machine - if (anim_state == 0) { - // Scroll in - if (ofy < 8) { - ofy++; - anim_state = 0; - } else { - anim_state = 1; - } - if (ofx < (int16_t)(180 - (strlen(credits[credits_index].name) * 16) - 8)) { - ofx += 8; - anim_state = 0; - } - } else if (anim_state == 1) { - // Just wait - if (credits_timer == (30 * 3)) { - credits_timer = 0; - anim_state = 2; - } else { - credits_timer++; - } - } else { - // Scroll out - if (credits[credits_index].change == true) { - if (ofy > -24) { - ofy--; - anim_state = 2; - } else { - anim_state = 0; - } - } else { - anim_state = 0; - } - if (ofx < 180) { - ofx += 8; - anim_state = 2; - } - - // Switch to next text - if (anim_state == 0) { - if (credits_index == 9) - credits_index = 0; - else - credits_index++; - ofx = -(strlen(credits[credits_index].name) * 16) - 16; - } - } - - // Sine text ("role") - p = 0; - while ((ch = credits[credits_index].role[p])) { - draw_demoglyph({(ui::Coord)(8 + (p * 16)), (ui::Coord)(ofy + (sine_table_f32[((p * 16) + (phase >> 5)) & 0xFF] * 8))}, ch, paletteA); - p++; - } - - // Scroll text (name) - p = 0; - while ((ch = credits[credits_index].name[p])) { - draw_demoglyph({(ui::Coord)(ofx + (p * 16)), 56}, ch, paletteB); - p++; - } - - // Clear bars Y buffer - memset(copperbuffer, 0, 72); - - // Render bars to Y buffer - for (p = 0; p < 5; p++) { - cy = copperbars[p]; - for (r = 0; r < 16; r++) - copperbuffer[cy + r] = copperluma[r] + (p << 4); - } - - // Animate bars positions - for (p = 0; p < 5; p++) { - s = sine_table_f32[((p * 32) + (phase / 24)) & 0xFF]; - s += sine_table_f32[((p * 16) + (phase / 35)) & 0xFF]; - copperbars[p] = 28 + (uint8_t)(s * 14); - } - - phase += 128; -} - -void AboutView::draw_demoglyph(ui::Point p, char ch, ui::Color* pal) { - uint8_t x, y, c, cl, cr; - uint16_t che; - int16_t lbx, il; - - // Map ASCII to font bitmap - if ((ch >= 32) && (ch < 96)) - che = char_map[ch - 32]; - else - che = 0xFF; - - if (che < 0xFF) { - che = (che * 128) + 48; // Start in bitmap - - il = (180 * p.y) + p.x; // Start il framebuffer - - for (y = 0; y < 16; y++) { - if (p.y + y >= 72) break; // Over bottom of framebuffer, abort - if (p.y + y >= 0) { - for (x = 0; x < 8; x++) { - c = demofont_bin[x + (y * 8) + che]; // Split byte in 2 4BPP pixels - cl = c >> 4; - cr = c & 0x0F; - lbx = p.x + (x * 2); - if (cl && (lbx < 180) && (lbx >= 0)) framebuffer[il] = pal[cl]; - lbx++; - il++; - if (cr && (lbx < 180) && (lbx >= 0)) framebuffer[il] = pal[cr]; - il++; - } - il += 180 - 16; - } else { - il += 180; - } - } - } -} - -void AboutView::render_audio() { - uint8_t i, ymdata; - uint16_t ym_render_cnt; - - // This is heavily inspired by MAME's ay8910.cpp and the YM2149's datasheet - - // Render 1024 music samples - for (ym_render_cnt = 0; ym_render_cnt < 1024; ym_render_cnt++) { - // Update registers at 48000/960 = 50Hz - if (ym_sample_cnt == 0) { - // "Decompress" on the fly and update YM registers - for (i = 0; i < 14; i++) { - if (!ym_regs[i].cnt) { - // New run - ymdata = ymdata_bin[ym_regs[i].ptr++]; - ym_regs[i].cnt = ymdata & 0x7F; - if (ymdata & 0x80) { - ym_regs[i].same = true; - ym_regs[i].value = ymdata_bin[ym_regs[i].ptr++]; - } else { - ym_regs[i].same = false; - } - // Detect drum on channel B - if (i == 3) - if (ym_regs[3].value > 2) drum = 4; - } - if (ym_regs[i].same == false) { - ym_regs[i].value = ymdata_bin[ym_regs[i].ptr++]; - if (i == 13) { - // Update envelope attributes - ym_env_att = (ym_regs[13].value & 4) ? 0x1F : 0x00; - if (!(ym_regs[13].value & 8)) { - ym_env_hold = 1; - ym_env_alt = ym_env_att; - } else { - ym_env_hold = ym_regs[13].value & 1; - ym_env_alt = ym_regs[13].value & 2; - } - // Reset envelope counter - ym_env_step = 0x1F; - ym_env_holding = 0; - ym_env_vol = (ym_env_step ^ ym_env_att); - } - } - ym_regs[i].cnt--; - } - ym_frame++; - } - - // Square wave oscillators - // 2457600/16/48000 = 3.2, but 4 sounds better than 3... - for (i = 0; i < 3; i++) { - ym_osc_cnt[i] += 4; - if (ym_osc_cnt[i] >= (ym_regs[i * 2].value | ((ym_regs[(i * 2) + 1].value & 0x0f) << 8))) { - ym_osc_cnt[i] = 0; - ym_osc_out[i] ^= 1; - } - } - - // Noise generator - ym_noise_cnt += 4; - if (ym_noise_cnt >= ((ym_regs[6].value & 0x1F) * 2)) { - ym_noise_cnt = 0; - ym_rng ^= (((ym_rng & 1) ^ ((ym_rng >> 3) & 1)) << 17); - ym_rng >>= 1; - } - - // Mix tones and noise - for (i = 0; i < 3; i++) - ym_ch[i] = (ym_osc_out[i] | ((ym_regs[7].value >> i) & 1)) & ((ym_rng & 1) | ((ym_regs[7].value >> (i + 3)) & 1)); - - // Envelope generator - if (!ym_env_holding) { - ym_env_cnt += 8; - if (ym_env_cnt >= (ym_regs[11].value | (ym_regs[12].value << 8))) { - ym_env_cnt = 0; - ym_env_step--; - if (ym_env_step < 0) { - if (ym_env_hold) { - if (ym_env_alt) - ym_env_att ^= 0x1F; - ym_env_holding = 1; - ym_env_step = 0; - } else { - if (ym_env_alt && (ym_env_step & 0x20)) - ym_env_att ^= 0x1F; - ym_env_step &= 0x1F; - } - } - } - } - ym_env_vol = (ym_env_step ^ ym_env_att); - - ym_out = 0; - for (i = 0; i < 3; i++) { - if (ym_regs[i + 8].value & 0x10) { - // Envelope mode - ym_out += (ym_ch[i] ? ym_env_vol : 0); - } else { - // Fixed mode - ym_out += (ym_ch[i] ? (ym_regs[i + 8].value & 0x0F) : 0); - } - } - - ym_buffer[ym_render_cnt] = (ym_out * 2) - 45; - - if (ym_sample_cnt < 960) { - ym_sample_cnt++; - } else { - ym_sample_cnt = 0; - } - - // Loop - if (ym_frame == ym_frames) ym_init(); - } -} - -void AboutView::update() { - if (framebuffer) { - // Update 1 out of 2 frames, 60Hz is very laggy - if (refresh_cnt & 1) render_video(); - refresh_cnt++; - } - - // Slowly increase volume to avoid jumpscare - if (headphone_vol < (70 << 2)) { - audio::headphone::set_volume(volume_t::decibel((headphone_vol / 4) - 99) + audio::headphone::volume_range().max); - headphone_vol++; - } -} - -void AboutView::ym_init() { - uint8_t reg; - - for (reg = 0; reg < 14; reg++) { - ym_regs[reg].cnt = 0; - // Pick up start pointers for each YM registers RLE blocks - ym_regs[reg].ptr = ((uint16_t)(ymdata_bin[(reg * 2) + 3]) << 8) + ymdata_bin[(reg * 2) + 2]; - ym_regs[reg].same = false; // Useless ? - ym_regs[reg].value = 0; // Useless ? - } - - ym_frame = 0; -} - -AboutView::AboutView( - NavigationView& nav) { - uint8_t p, c; - - baseband::run_image(portapack::spi_flash::image_tag_audio_tx); - - add_children({{ - &text_title, - &text_firmware, - &text_cpld_hackrf, - &text_cpld_hackrf_status, - &button_ok, - }}); - - if (cpld_hackrf_verify_eeprom()) { - text_cpld_hackrf_status.set(" OK"); - } else { - text_cpld_hackrf_status.set("BAD"); - } - - // Politely ask for about 26kB - framebuffer = (ui::Color*)chHeapAlloc(0x0, 180 * 72 * sizeof(ui::Color)); - - if (framebuffer) { - memset(framebuffer, 0, 180 * 72 * sizeof(ui::Color)); - - // Copy original font palette - c = 0; - for (p = 0; p < 48; p += 3) - paletteA[c++] = ui::Color(demofont_bin[p], demofont_bin[p + 1], demofont_bin[p + 2]); - - // Increase red in another one - c = 0; - for (p = 0; p < 48; p += 3) - paletteB[c++] = ui::Color(std::min(demofont_bin[p] + 64, 255), demofont_bin[p + 1], demofont_bin[p + 2]); - } - - // Init YM synth - ym_frames = ((uint16_t)(ymdata_bin[1]) << 8) + ymdata_bin[0]; - ym_init(); - - button_ok.on_select = [this, &nav](Button&) { - if (framebuffer) chHeapFree(framebuffer); // Do NOT forget this - nav.pop(); - }; -} - -AboutView::~AboutView() { - transmitter_model.disable(); - baseband::shutdown(); -} - -void AboutView::focus() { - button_ok.focus(); -} - -} /* namespace ui */ diff --git a/firmware/application/apps/ui_about_demo.hpp b/firmware/application/apps/ui_about_demo.hpp deleted file mode 100644 index 37342c53..00000000 --- a/firmware/application/apps/ui_about_demo.hpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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_ABOUT_H__ -#define __UI_ABOUT_H__ - -#include "ui_widget.hpp" -#include "ui_menu.hpp" -#include "ui_navigation.hpp" -#include "transmitter_model.hpp" -#include "baseband_api.hpp" - -#include - -namespace ui { - -class AboutView : public View { - public: - AboutView(NavigationView& nav); - ~AboutView(); - - void on_show() override; - void focus() override; - - private: - void ym_init(); - void update(); - void render_video(); - void render_audio(); - void draw_demoglyph(ui::Point p, char ch, ui::Color* pal); - uint16_t debug_cnt = 0; - - typedef struct ymreg_t { - uint8_t value; - uint8_t cnt; - uint16_t ptr; - bool same; - } ymreg_t; - - uint16_t headphone_vol = 5 << 2; - - ymreg_t ym_regs[14]; - uint16_t ym_frames; - uint16_t ym_frame; - uint8_t drum = 0; - uint16_t ym_osc_cnt[3]; - uint32_t ym_rng = 1; - uint16_t ym_noise_cnt; - uint8_t ym_env_att, ym_env_hold, ym_env_alt, ym_env_holding, ym_env_vol; - int8_t ym_env_step; - uint16_t ym_env_cnt; - uint8_t ym_osc_out[3]; - uint8_t ym_ch[3]; - uint8_t ym_out; - uint16_t ym_sample_cnt = 0; - - int8_t ym_buffer[1024]; - - uint8_t refresh_cnt; - ui::Color paletteA[16]; - ui::Color paletteB[16]; - ui::Color* framebuffer; - uint32_t phase = 0; - uint8_t copperbars[5] = {0}; - uint8_t copperbuffer[72] = {0}; - - uint8_t anim_state = 0; - uint8_t credits_index = 0; - uint16_t credits_timer = 0; - - int16_t ofx = -180, ofy = -24; - - const uint8_t char_map[64] = {0xFF, 27, 46, 0xFF, 0xFF, 0xFF, 28, 45, - 58, 59, 0xFF, 43, 40, 57, 26, 42, - 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 41, 0xFF, 0xFF, 0xFF, 0xFF, 44, - 0xFF, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - - const uint8_t copperluma[16] = {8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}; - const uint8_t coppercolor[5][3] = {{255, 0, 0}, - {0, 255, 0}, - {0, 0, 255}, - {255, 0, 255}, - {255, 255, 0}}; - - typedef struct credits_t { - char role[12]; - char name[12]; - bool change; - } credits_t; - - // 0123456789A 0123456789A - const credits_t credits[10] = {{"GURUS", "J. BOONE", false}, - {"GURUS", "M. OSSMANN", true}, - {"BUGS", "FURRTEK", true}, - {"RDS WAVE", "C. JACQUET", true}, - {"POCSAG RX", "T. SAILER", false}, - {"POCSAG RX", "E. OENAL", true}, - {"XYLOS DATA", "CLX", true}, - {"GREETS TO", "SIGMOUNTE", false}, - {"GREETS TO", "WINDYOONA", true}, - {"THIS MUSIC", "BIG ALEC", true}}; - - Text text_title{ - {100, 32, 40, 16}, - "About", - }; - - Text text_firmware{ - {0, 236, 240, 16}, - "Version " VERSION_STRING, - }; - - Text text_cpld_hackrf{ - {0, 252, 11 * 8, 16}, - "HackRF CPLD", - }; - - Text text_cpld_hackrf_status{ - {240 - 3 * 8, 252, 3 * 8, 16}, - "???"}; - - Button button_ok{ - {72, 272, 96, 24}, - "OK"}; - - MessageHandlerRegistration message_handler_update{ - Message::ID::DisplayFrameSync, - [this](const Message* const) { - this->update(); - }}; - - MessageHandlerRegistration message_handler_fifo_signal{ - Message::ID::FIFOSignal, - [this](const Message* const p) { - const auto message = static_cast(p); - if (message->signaltype == 1) { - this->render_audio(); - baseband::set_fifo_data(ym_buffer); - } - }}; -}; - -} /* namespace ui */ - -#endif /*__UI_ABOUT_H__*/ diff --git a/firmware/application/apps/ui_numbers.cpp b/firmware/application/apps/ui_numbers.cpp deleted file mode 100644 index c85bb089..00000000 --- a/firmware/application/apps/ui_numbers.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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_numbers.hpp" -#include "string_format.hpp" - -#include "portapack.hpp" -#include "hackrf_hal.hpp" -#include "portapack_shared_memory.hpp" - -#include -#include - -using namespace portapack; - -namespace ui { - -// TODO: This app takes way too much space, find a way to shrink/simplify or make it an SD card module (loadable) - -void NumbersStationView::focus() { - if (file_error) - nav_.display_modal("No voices", "No valid voices found in\nthe /numbers directory.", ABORT); - else - button_exit.focus(); -} - -NumbersStationView::~NumbersStationView() { - transmitter_model.disable(); - baseband::shutdown(); -} - -NumbersStationView::wav_file_t* NumbersStationView::get_wav(uint32_t index) { - return ¤t_voice->available_wavs[index]; -} - -void NumbersStationView::prepare_audio() { - uint8_t code; - wav_file_t* wav_file; - - if (sample_counter >= sample_length) { - if (segment == ANNOUNCE) { - if (!announce_loop) { - code_index = 0; - segment = MESSAGE; - } else { - wav_file = get_wav(11); - reader->open(current_voice->dir + file_names[wav_file->index].name + ".wav"); - sample_length = wav_file->length; - announce_loop--; - } - } - - if (segment == MESSAGE) { - if (code_index == 25) { - transmitter_model.disable(); - return; - } - - code = symfield_code.get_offset(code_index); - - if (code >= 10) { - memset(audio_buffer, 0, 1024); - if (code == 10) { - pause = 11025; // p: 0.25s @ 44100Hz - } else if (code == 11) { - pause = 33075; // P: 0.75s @ 44100Hz - } else if (code == 12) { - transmitter_model.disable(); - return; - } - } else { - wav_file = get_wav(code); - reader->open(current_voice->dir + file_names[code].name + ".wav"); - sample_length = wav_file->length; - } - code_index++; - } - sample_counter = 0; - } - - if (!pause) { - auto bytes_read = reader->read(audio_buffer, 1024).value(); - - // Unsigned to signed, pretty stupid :/ - for (size_t n = 0; n < bytes_read; n++) - audio_buffer[n] -= 0x80; - for (size_t n = bytes_read; n < 1024; n++) - audio_buffer[n] = 0; - - sample_counter += 1024; - } else { - if (pause >= 1024) { - pause -= 1024; - } else { - sample_counter = sample_length; - pause = 0; - } - } - - baseband::set_fifo_data(audio_buffer); -} - -void NumbersStationView::start_tx() { - // sample_length = sound_sizes[10]; // Announce - sample_counter = sample_length; - - code_index = 0; - announce_loop = 2; - segment = ANNOUNCE; - - prepare_audio(); - - transmitter_model.set_rf_amp(true); - transmitter_model.enable(); - - baseband::set_audiotx_data( - (1536000 / 44100) - 1, // TODO: Read wav file's samplerate - 12000, - 1, - false, - 0); -} - -void NumbersStationView::on_tick_second() { - armed_blink = not armed_blink; - - if (armed_blink) - check_armed.set_style(Theme::getInstance()->fg_red); - else - check_armed.set_style(&style()); - - check_armed.set_dirty(); -} - -void NumbersStationView::on_voice_changed(size_t index) { - std::string code_list; - - for (const auto& wavs : voices[index].available_wavs) - code_list += wavs.code; - - symfield_code.set_symbol_list(code_list); - current_voice = &voices[index]; -} - -bool NumbersStationView::check_wav_validity(const std::string dir, const std::string file) { - if (reader->open("/numbers/" + dir + "/" + file)) { - // Check format (mono, 8 bits) - if ((reader->channels() == 1) && (reader->bits_per_sample() == 8)) - return true; - else - return false; - } else - return false; -} - -NumbersStationView::NumbersStationView( - NavigationView& nav) - : nav_(nav) { - std::vector directory_list; - using option_t = std::pair; - using options_t = std::vector; - options_t voice_options; - voice_t temp_voice{}; - bool valid; - uint32_t c; - // uint8_t y, m, d, dayofweek; - - reader = std::make_unique(); - - // Search for valid voice directories - directory_list = scan_root_directories("/numbers"); - if (!directory_list.size()) { - file_error = true; - return; - } - - for (const auto& dir : directory_list) { - c = 0; - for (const auto& file_name : file_names) { - valid = check_wav_validity(dir.string(), file_name.name + ".wav"); - if ((!valid) && (file_name.required)) { - temp_voice.available_wavs.clear(); - break; // Invalid required file means invalid voice - } else if (valid) { - temp_voice.available_wavs.push_back({file_name.code, c++, 0, 0}); // TODO: Needs length and samplerate - } - } - if (!temp_voice.available_wavs.empty()) { - // Voice can be used, are there accent files ? - c = 0; - for (const auto& file_name : file_names) { - valid = check_wav_validity(dir.string(), file_name.name + "a.wav"); - if ((!valid) && (file_name.required)) { - c = 0; - break; // Invalid required file means accents can't be used - } else if (valid) { - c++; - } - } - - temp_voice.accent = c ? true : false; - temp_voice.dir = dir.string(); - - voices.push_back(temp_voice); - } - } - - if (voices.empty()) { - file_error = true; - return; - } - - baseband::run_image(portapack::spi_flash::image_tag_audio_tx); - - add_children({&labels, - &symfield_code, - &check_armed, - &options_voices, - &text_voice_flags, - //&button_tx_now, - &button_exit}); - - for (const auto& voice : voices) - voice_options.emplace_back(voice.dir.substr(0, 4), 0); - - options_voices.set_options(voice_options); - options_voices.on_change = [this](size_t i, int32_t) { - this->on_voice_changed(i); - }; - options_voices.set_selected_index(0); - - check_armed.set_value(false); - - check_armed.on_select = [this](Checkbox&, bool v) { - if (v) { - armed_blink = false; - signal_token_tick_second = rtc_time::signal_tick_second += [this]() { - this->on_tick_second(); - }; - } else { - check_armed.set_style(&style()); - rtc_time::signal_tick_second -= signal_token_tick_second; - } - }; - - // DEBUG - symfield_code.set_offset(0, 10); - symfield_code.set_offset(1, 3); - symfield_code.set_offset(2, 4); - symfield_code.set_offset(3, 11); - symfield_code.set_offset(4, 6); - symfield_code.set_offset(5, 1); - symfield_code.set_offset(6, 9); - symfield_code.set_offset(7, 7); - symfield_code.set_offset(8, 8); - symfield_code.set_offset(9, 0); - symfield_code.set_offset(10, 12); // End - - /* - dayofweek = rtc_time::current_day_of_week(); - text_title.set(day_of_week[dayofweek]); - */ - - button_exit.on_select = [&nav](Button&) { - nav.pop(); - }; -} - -} /* namespace ui */ diff --git a/firmware/application/apps/ui_numbers.hpp b/firmware/application/apps/ui_numbers.hpp deleted file mode 100644 index bf2cd292..00000000 --- a/firmware/application/apps/ui_numbers.hpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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_NUMBERS_H__ -#define __UI_NUMBERS_H__ - -#include "ui.hpp" -#include "ui_widget.hpp" -#include "ui_receiver.hpp" -#include "ui_navigation.hpp" -#include "rtc_time.hpp" -#include "clock_manager.hpp" -#include "baseband_api.hpp" -#include "utility.hpp" -#include "message.hpp" -#include "file.hpp" -#include "io_wave.hpp" -#include "radio_state.hpp" - -namespace ui { - -class NumbersStationView : public View { - public: - NumbersStationView(NavigationView& nav); - ~NumbersStationView(); - - NumbersStationView(const NumbersStationView&) = delete; - NumbersStationView(NumbersStationView&&) = delete; - NumbersStationView& operator=(const NumbersStationView&) = delete; - NumbersStationView& operator=(NumbersStationView&&) = delete; - - void focus() override; - - std::string title() const override { return "Station"; }; - - private: - NavigationView& nav_; - - TxRadioState radio_state_{ - 0 /* frequency */, - 1750000 /* bandwidth */, - 1536000 /* sampling rate */ - }; - - // Sequencing state machine - enum segments { - IDLE = 0, - ANNOUNCE, - MESSAGE, - SIGNOFF - }; - - typedef struct { - char code; - uint32_t index; - uint32_t length; - uint32_t samplerate; - } wav_file_t; - - struct voice_t { - std::string dir; - std::vector available_wavs; - bool accent; - }; - - std::vector voices{}; - voice_t* current_voice{}; - - struct wav_file_list_t { - std::string name; - bool required; - char code; - }; - - const std::vector file_names = { - {"0", true, '0'}, - {"1", true, '1'}, - {"2", true, '2'}, - {"3", true, '3'}, - {"4", true, '4'}, - {"5", true, '5'}, - {"6", true, '6'}, - {"7", true, '7'}, - {"8", true, '8'}, - {"9", true, '9'}, - {"announce", false, 'A'}}; - - segments segment{IDLE}; - bool armed{false}; - bool file_error{false}; - - // const uint8_t month_table[12] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; - // const char * day_of_week[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; - - std::unique_ptr reader{}; - - uint8_t code_index{0}, announce_loop{0}; - uint32_t sample_counter{0}; - uint32_t sample_length{0}; - int8_t audio_buffer[1024]{}; - uint32_t pause{0}; - bool armed_blink{false}; - SignalToken signal_token_tick_second{}; - - wav_file_t* get_wav(uint32_t index); - bool check_wav_validity(const std::string dir, const std::string file); - void on_voice_changed(size_t index); - void on_tick_second(); - void prepare_audio(); - void start_tx(); - - Labels labels{ - {{2 * 8, 5 * 8}, "Voice: Flags:", Theme::getInstance()->fg_light->foreground}, - {{1 * 8, 8 * 8}, "Code:", Theme::getInstance()->fg_light->foreground}}; - - OptionsField options_voices{ - {8 * 8, 1 * 8}, - 4, - {}}; - Text text_voice_flags{ - {19 * 8, 1 * 8, 2 * 8, 16}, - ""}; - - SymField symfield_code{ - {1 * 8, 10 * 8}, - 25, - SymField::Type::Custom}; - - Checkbox check_armed{ - {2 * 8, 13 * 16}, - 5, - "Armed"}; - - /* - Button button_tx_now { - { 18 * 8, 13 * 16, 10 * 8, 32 }, - "TX now"}; - */ - - Button button_exit{ - {21 * 8, 16 * 16, 64, 32}, - "Exit"}; - - MessageHandlerRegistration message_handler_fifo_signal{ - Message::ID::RequestSignal, - [this](const Message* const p) { - const auto message = static_cast(p); - if (message->signal == RequestSignalMessage::Signal::FillRequest) { - this->prepare_audio(); - } - }}; -}; - -} /* namespace ui */ - -#endif /*__UI_NUMBERS_H__*/ diff --git a/firmware/application/apps/ui_nuoptix.cpp b/firmware/application/apps/ui_nuoptix.cpp deleted file mode 100644 index e4894f2c..00000000 --- a/firmware/application/apps/ui_nuoptix.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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_nuoptix.hpp" - -#include "ch.h" -#include "portapack.hpp" -#include "lfsr_random.hpp" -#include "string_format.hpp" - -#include "portapack_shared_memory.hpp" - -#include -#include - -using namespace portapack; - -namespace ui { - -void NuoptixView::focus() { - number_timecode.focus(); -} - -NuoptixView::~NuoptixView() { - transmitter_model.disable(); - baseband::shutdown(); -} - -void NuoptixView::on_tx_progress(const uint32_t progress, const bool done) { - if (done) - transmit(false); - else - progressbar.set_value(progress); -} - -void NuoptixView::transmit(bool setup) { - uint8_t mod, tone_code; - uint8_t c; - uint8_t dtmf_message[6]; - rtc::RTC datetime; - - if (!tx_mode) { - transmitter_model.disable(); - return; - } - - if (tx_mode == IMPROVISE) - timecode = lfsr_iterate(timecode) % 1999; // Could be 9999 but that would be one long audio track ! - - if (setup) { - progressbar.set_max(6 * 2); - - if (tx_mode == IMPROVISE) { - // Seed from RTC - rtcGetTime(&RTCD1, &datetime); - timecode = datetime.day() + datetime.second(); - } else { - timecode = number_timecode.value(); - } - - transmitter_model.set_rf_amp(true); - transmitter_model.enable(); - - dtmf_message[0] = '*'; // "Pre-tone for restart" method #1 - dtmf_message[1] = 'A'; // "Restart" method #1 - } else { - dtmf_message[0] = '#'; - dtmf_message[1] = (timecode / 1000) % 10; - chThdSleepMilliseconds(92); // 141-49ms - number_timecode.set_value(timecode); - } - - progressbar.set_value(0); - - dtmf_message[2] = (timecode / 100) % 10; - dtmf_message[3] = (timecode / 10) % 10; - dtmf_message[4] = timecode % 10; - - mod = 0; - for (c = 1; c < 5; c++) - if (dtmf_message[c] <= 9) - mod += dtmf_message[c]; - - mod = 10 - (mod % 10); - if (mod == 10) mod = 0; // Is this right ? - - text_mod.set("Mod: " + to_string_dec_uint(mod)); - - dtmf_message[5] = mod; - - for (c = 0; c < 6; c++) { - tone_code = dtmf_message[c]; - - if (tone_code == 'A') - tone_code = 10; - else if (tone_code == 'B') - tone_code = 11; - else if (tone_code == 'C') - tone_code = 12; - else if (tone_code == 'D') - tone_code = 13; - else if (tone_code == '#') - tone_code = 14; - else if (tone_code == '*') - tone_code = 15; - - shared_memory.bb_data.tones_data.message[c * 2] = tone_code; - shared_memory.bb_data.tones_data.message[c * 2 + 1] = 0xFF; // Silence - } - - for (c = 0; c < 16; c++) { - baseband::set_tone(c * 2, dtmf_deltas[c][0], NUOPTIX_TONE_LENGTH); - baseband::set_tone(c * 2 + 1, dtmf_deltas[c][1], NUOPTIX_TONE_LENGTH); - } - shared_memory.bb_data.tones_data.silence = NUOPTIX_TONE_LENGTH; // 49ms tone, 49ms space - - audio::set_rate(audio::Rate::Hz_24000); - - baseband::set_tones_config(transmitter_model.channel_bandwidth(), 0, 6 * 2, true, true); - - timecode++; -} - -NuoptixView::NuoptixView( - NavigationView& nav) { - baseband::run_image(portapack::spi_flash::image_tag_tones); - - add_children({&number_timecode, - &text_timecode, - &text_mod, - &progressbar, - &tx_view}); - - number_timecode.set_value(1); - - tx_view.on_edit_frequency = [this, &nav]() { - auto new_view = nav.push(transmitter_model.target_frequency()); - new_view->on_changed = [this](rf::Frequency f) { - transmitter_model.set_target_frequency(f); - }; - }; - - tx_view.on_start = [this]() { - tx_view.set_transmitting(true); - tx_mode = NORMAL; - transmit(true); - }; - - tx_view.on_stop = [this]() { - tx_view.set_transmitting(false); - tx_mode = IDLE; - }; - - /*button_impro.on_select = [this](Button&){ - if (tx_mode == IMPROVISE) { - tx_mode = IDLE; - button_impro.set_text("IMPROVISE"); - } else if (tx_mode == IDLE) { - tx_mode = IMPROVISE; - button_impro.set_text("STOP"); - transmit(true); - } - };*/ -} - -} // namespace ui diff --git a/firmware/application/apps/ui_nuoptix.hpp b/firmware/application/apps/ui_nuoptix.hpp deleted file mode 100644 index bc7564ca..00000000 --- a/firmware/application/apps/ui_nuoptix.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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_NUOPTIX_H__ -#define __UI_NUOPTIX_H__ - -#include "ui.hpp" -#include "ui_widget.hpp" -#include "baseband_api.hpp" -#include "ui_navigation.hpp" -#include "ui_transmitter.hpp" -#include "rtc_time.hpp" -#include "tonesets.hpp" -#include "message.hpp" -#include "volume.hpp" -#include "audio.hpp" -#include "radio_state.hpp" - -#define NUOPTIX_TONE_LENGTH ((TONES_SAMPLERATE * 0.049) - 1) // 49ms - -namespace ui { - -class NuoptixView : public View { - public: - NuoptixView(NavigationView& nav); - ~NuoptixView(); - - void focus() override; - - std::string title() const override { return "Nuoptix sync"; }; - - private: - enum tx_modes { - IDLE = 0, - NORMAL, - IMPROVISE - }; - - TxRadioState radio_state_{ - 0 /* frequency */, - 1750000 /* bandwidth */, - 1536000 /* sampling rate */ - }; - - tx_modes tx_mode{IDLE}; - - void transmit(bool setup); - void on_tx_progress(const uint32_t progress, const bool done); - - uint32_t timecode{0}; - - Text text_timecode{ - {10 * 8, 2 * 16, 9 * 8, 16}, - "Timecode:"}; - - NumberField number_timecode{ - {13 * 8, 3 * 16}, - 4, - {1, 9999}, - 1, - '0'}; - - Text text_mod{ - {10 * 8, 5 * 16, 6 * 8, 16}, - "Mod: "}; - - ProgressBar progressbar{ - {16, 14 * 16, 208, 16}}; - - /*Button button_impro { - { 64, 184, 112, 40 }, - "IMPROVISE" - };*/ - - TransmitterView tx_view{ - 16 * 16, - 10000, - 15}; - - MessageHandlerRegistration message_handler_tx_progress{ - Message::ID::TXProgress, - [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->on_tx_progress(message.progress, message.done); - }}; -}; - -} /* namespace ui */ - -#endif /*__UI_NUOPTIX_H__*/ diff --git a/firmware/application/apps/ui_recon.cpp b/firmware/application/apps/ui_recon.cpp index 48879ca1..977f9cbb 100644 --- a/firmware/application/apps/ui_recon.cpp +++ b/firmware/application/apps/ui_recon.cpp @@ -28,7 +28,6 @@ #include "file.hpp" #include "file_reader.hpp" #include "tone_key.hpp" -#include "replay_app.hpp" #include "string_format.hpp" #include "ui_fileman.hpp" #include "io_file.hpp" diff --git a/firmware/application/apps/ui_script.cpp b/firmware/application/apps/ui_script.cpp deleted file mode 100644 index a9717195..00000000 --- a/firmware/application/apps/ui_script.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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_script.hpp" - -#include "portapack.hpp" -#include "event_m0.hpp" - -#include - -using namespace portapack; - -namespace ui { - -void ScriptView::on_frequency_select() { - // button_edit_freq.focus(); -} - -void ScriptView::on_edit_freq(rf::Frequency f) { - (void)f; - // frequencies[menu_view.highlighted()].value = f; - setup_list(); -} - -void ScriptView::on_edit_desc(NavigationView& nav) { - (void)nav; -} - -void ScriptView::on_delete() { - // frequencies.erase(frequencies.begin() + menu_view.highlighted()); - setup_list(); -} - -void ScriptView::setup_list() { - // size_t n; - - menu_view.clear(); - - /*for (n = 0; n < frequencies.size(); n++) { - menu_view.add_item({ freqman_item_string(frequencies[n]), Theme::getInstance()->bg_darkest->foreground, nullptr, [this](){ on_frequency_select(); } }); - }*/ - - menu_view.set_parent_rect({0, 0, 240, 168}); - menu_view.set_highlighted(menu_view.highlighted()); // Refresh -} - -void ScriptView::focus() { - menu_view.focus(); -} - -ScriptView::ScriptView( - NavigationView& nav) { - add_children({&menu_view, - &text_edit, - &button_edit_freq, - &button_edit_desc, - &button_del, - &button_exit}); - - setup_list(); - - button_edit_freq.on_select = [this, &nav](Button&) { - /*auto new_view = nav.push(frequencies[menu_view.highlighted()].value); - new_view->on_changed = [this](rf::Frequency f) { - on_edit_freq(f); - };*/ - }; - - button_edit_desc.on_select = [this, &nav](Button&) { - on_edit_desc(nav); - }; - - button_del.on_select = [this, &nav](Button&) { - nav.push("Confirm", "Are you sure?", YESNO, - [this](bool choice) { - if (choice) { - on_delete(); - } - }); - }; - - button_exit.on_select = [this, &nav](Button&) { - nav.pop(); - }; -} - -} // namespace ui diff --git a/firmware/application/apps/ui_script.hpp b/firmware/application/apps/ui_script.hpp deleted file mode 100644 index 0add5de8..00000000 --- a/firmware/application/apps/ui_script.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.hpp" -#include "ui_widget.hpp" -#include "ui_painter.hpp" -#include "ui_menu.hpp" -#include "ui_navigation.hpp" -#include "ui_receiver.hpp" -#include "ui_textentry.hpp" -#include "rtc_time.hpp" - -namespace ui { - -enum script_keyword { - STOP = 0, - WAIT_N, - WAIT_RTC, - IF, - LOOP, - END, - TX, - RX -}; - -struct script_line { - script_keyword keyword; -}; - -class ScriptView : public View { - public: - ScriptView(NavigationView& nav); - - void focus() override; - - std::string title() const override { return "Script editor"; }; - - private: - void on_frequency_select(); - void on_edit_freq(rf::Frequency f); - void on_edit_desc(NavigationView& nav); - void on_delete(); - void setup_list(); - - std::vector script{}; - - MenuView menu_view{ - {0, 0, 240, 168}, - true}; - - Text text_edit{ - {16, 194, 5 * 8, 16}, - "Edit:"}; - Button button_edit_freq{ - {16, 194 + 16, 88, 32}, - "Frequency"}; - Button button_edit_desc{ - {16, 194 + 16 + 34, 88, 32}, - "Description"}; - Button button_del{ - {160, 192, 72, 64}, - "Delete"}; - - Button button_exit{ - {160, 264, 72, 32}, - "Exit"}; -}; - -} /* namespace ui */ diff --git a/firmware/application/apps/ui_tone_search.cpp b/firmware/application/apps/ui_tone_search.cpp deleted file mode 100644 index e17ed52b..00000000 --- a/firmware/application/apps/ui_tone_search.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2018 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_tone_search.hpp" - -#include "baseband_api.hpp" -#include "string_format.hpp" - -using namespace portapack; - -namespace ui { - -void ToneSearchView::focus() { - // field_frequency_min.focus(); -} - -ToneSearchView::~ToneSearchView() { - receiver_model.disable(); - baseband::shutdown(); -} - -ToneSearchView::ToneSearchView( - NavigationView& nav) - : nav_(nav) { - // baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum); - - add_children({ - &labels, - &field_lna, - &field_vga, - &field_rf_amp, - }); -} - -} /* namespace ui */ diff --git a/firmware/application/apps/ui_tone_search.hpp b/firmware/application/apps/ui_tone_search.hpp deleted file mode 100644 index 88499ef5..00000000 --- a/firmware/application/apps/ui_tone_search.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2018 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 "receiver_model.hpp" - -#include "ui_receiver.hpp" - -namespace ui { - -class ToneSearchView : public View { - public: - ToneSearchView(NavigationView& nav); - ~ToneSearchView(); - - void focus() override; - - std::string title() const override { return "Tone search"; }; - - private: - NavigationView& nav_; - - Labels labels{ - {{0 * 8, 0 * 8}, "LNA: VGA: AMP:", Theme::getInstance()->fg_light->foreground}}; - - LNAGainField field_lna{ - {4 * 8, 0 * 16}}; - - VGAGainField field_vga{ - {11 * 8, 0 * 16}}; - - RFAmpField field_rf_amp{ - {18 * 8, 0 * 16}}; - - /* - MessageHandlerRegistration message_handler_frame_sync { - Message::ID::DisplayFrameSync, - [this](const Message* const) { - if( this->fifo ) { - ChannelSpectrum channel_spectrum; - while( fifo->out(channel_spectrum) ) { - this->on_channel_spectrum(channel_spectrum); - } - } - this->do_timers(); - } - };*/ -}; - -} /* namespace ui */ diff --git a/firmware/application/emu_cc1101.cpp b/firmware/application/emu_cc1101.cpp deleted file mode 100644 index de946e8b..00000000 --- a/firmware/application/emu_cc1101.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2017 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 "emu_cc1101.hpp" - -namespace cc1101 { - -void CC1101Emu::whitening_init() { - whitening_pn = 0x1FF; -} - -// See TI app note DN509 -uint8_t CC1101Emu::whiten_byte(uint8_t byte) { - uint_fast8_t new_bit; - - byte ^= (whitening_pn & 0xFF); - - for (size_t step = 0; step < 8; step++) { - new_bit = (whitening_pn & 1) ^ ((whitening_pn >> 5) & 1); - whitening_pn >>= 1; - whitening_pn |= (new_bit << 8); - } - - return byte; -} - -} /* namespace cc1101 */ diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index b0f56fec..a595bae1 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -96,7 +96,6 @@ Continuous (Fox-oring) // Multimon-style stuff: // TODO: DMR detector // TODO: GSM channel detector -// TODO: Playdead amnesia and login // TODO: Setup: Play dead by default ? Enable/disable ? // Old or low-priority stuff: @@ -106,7 +105,6 @@ Continuous (Fox-oring) // TODO: Check more OOK encoders // BUG (fixed ?): No audio in about when shown second time // TODO: Show MD5 mismatches for modules not found, etc... -// TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule // BUG: Description doesn't show up first time going to system>module info (UI drawn on top) // TODO: Two players tic-tac-toe // TODO: Analog TV pong game diff --git a/firmware/application/ui_handwrite.cpp b/firmware/application/ui_handwrite.cpp deleted file mode 100644 index 4ef103bd..00000000 --- a/firmware/application/ui_handwrite.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* - * 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_handwrite.hpp" - -#include "portapack.hpp" -#include "hackrf_hal.hpp" -#include "portapack_shared_memory.hpp" - -#include - -using namespace portapack; - -namespace ui { - -void HandWriteView::paint(Painter& painter) { - _painter = &painter; -} - -HandWriteView::HandWriteView( - NavigationView& nav, - std::string* str, - size_t max_length) - : TextEntryView(nav, str, max_length) { - size_t n; - - // Handwriting alphabet definition here - handwriting = &handwriting_unistroke; - - add_children({&button_case}); - - const auto button_fn = [this](Button& button) { - this->on_button(button); - }; - - n = 0; - for (auto& button : num_buttons) { - add_child(&button); - button.on_select = button_fn; - button.set_parent_rect({static_cast(n * 24), - static_cast(236), - 24, 28}); - const std::string label{ - (char)(n + '0')}; - button.set_text(label); - button.id = n + '0'; - n++; - } - - n = 0; - for (auto& button : special_buttons) { - add_child(&button); - button.on_select = button_fn; - button.set_parent_rect({static_cast(50 + n * 24), - static_cast(270), - 24, 28}); - const std::string label{ - (char)(special_chars[n])}; - button.set_text(label); - button.id = special_chars[n]; - n++; - } - - button_case.on_select = [this, &nav](Button&) { - if (_lowercase == true) { - _lowercase = false; - button_case.set_text("LC"); - } else { - _lowercase = true; - button_case.set_text("UC"); - } - }; - - button_ok.on_select = [this, &nav](Button&) { - if (on_changed) - on_changed(_str); - nav.pop(); - }; - - update_text(); -} - -bool HandWriteView::on_touch(const TouchEvent event) { - if (event.type == ui::TouchEvent::Type::Start) { - stroke_index = 0; - move_wait = 3; - tracing = true; - } - if (event.type == ui::TouchEvent::Type::End) { - tracing = false; - guess_letter(); - } - if (event.type == ui::TouchEvent::Type::Move) { - if (tracing) - current_pos = event.point; - } - return true; -} - -void HandWriteView::clear_zone(const Color color, const bool flash) { - display.fill_rectangle( - {{0, 32}, {240, 216}}, - color); - if (flash) { - flash_timer = 8; - } else { - // Draw grid - _painter->draw_rectangle( - {{0, 32}, {80, 216}}, - Color::grey()); - _painter->draw_rectangle( - {{80, 32}, {80, 216}}, - Color::grey()); - _painter->draw_rectangle( - {{160, 32}, {80, 216}}, - Color::grey()); - _painter->draw_rectangle( - {{0, 104}, {240, 72}}, - Color::grey()); - } -} - -void HandWriteView::guess_letter() { - uint32_t symbol, match, count, stroke_idx, stroke_data; - Condition cond; - Direction dir; - bool matched; - - // Letter guessing - if (stroke_index) { - for (symbol = 0; symbol < handwriting->letter_count; symbol++) { - count = handwriting->letter[symbol].count; - matched = false; - if (count) { - // We have a count match to do - if ((count == 1) && (stroke_index == 1)) matched = true; - if ((count == 2) && (stroke_index == 2)) matched = true; - if ((count == 3) && (stroke_index > 2)) matched = true; - } else { - matched = true; - } - if (matched) { - for (match = 0; match < 3; match++) { - cond = handwriting->letter[symbol].match[match].cond; - dir = handwriting->letter[symbol].match[match].dir; - if ((cond != cond_empty) && (dir != dir_empty)) { - if (cond == last) { - if (stroke_index) - stroke_idx = stroke_index - 1; - else - stroke_idx = 0; - } else if (cond == stroke_a) - stroke_idx = 0; - else if (cond == stroke_b) - stroke_idx = 1; - else if (cond == stroke_c) - stroke_idx = 2; - else - stroke_idx = 3; - if (stroke_idx >= stroke_index) break; - stroke_data = stroke_list[stroke_idx]; - if ((dir & 0xF0) == 0xF0) { - if ((dir & 0x0F) != (stroke_data & 0x0F)) break; - } else if ((dir & 0x0F) == 0x0F) { - if ((dir & 0xF0) != (stroke_data & 0xF0)) break; - } else { - if (dir != (int32_t)stroke_data) break; - } - } - } - if (match == 3) - break; - else - matched = false; - } - } - if (matched) { - if (symbol) { - if (_lowercase) - char_add('a' + symbol - 1); - else - char_add('A' + symbol - 1); - clear_zone(Color::green(), true); // Green flash - } else { - if (_cursor_pos) { - char_delete(); - clear_zone(Color::yellow(), true); // Yellow flash - } else { - clear_zone(Color::red(), true); // Red flash - } - } - } else { - clear_zone(Color::red(), true); // Red flash - } - } else { - // Short tap is space - char_add(' '); - clear_zone(Color::green(), true); // Green flash - } - update_text(); - stroke_index = 0; -} - -void HandWriteView::add_stroke(uint8_t dir) { - if (stroke_index < 8) { - stroke_list[stroke_index] = dir; - stroke_index++; - } else { - guess_letter(); - } -} - -void HandWriteView::sample_pen() { - int16_t diff_x, diff_y; - uint8_t dir, dir_ud, dir_lr, stroke_prev; - - draw_cursor(); - - if (flash_timer) { - if (flash_timer == 1) clear_zone(Color::black(), false); - flash_timer--; - } - - if (!(sample_skip & 1)) { - if (tracing) { - if (move_wait) { - move_wait--; // ~100ms delay to get rid of jitter from touch start - } else { - diff_x = current_pos.x() - last_pos.x(); - diff_y = current_pos.y() - last_pos.y(); - - if (current_pos.y() <= 240) { - display.fill_rectangle( - {{current_pos.x(), current_pos.y()}, {4, 4}}, - Color::grey()); - } - - dir = 0; // UL by default - if (abs(diff_x) > 7) { - if (diff_x > 0) - dir |= 0x01; // R - } else { - dir |= 0x02; // ? - } - if (abs(diff_y) > 7) { - if (diff_y > 0) - dir |= 0x10; // D - } else { - dir |= 0x20; // ? - } - - // Need at least two identical directions to validate stroke - if ((dir & 0x11) == (dir_prev & 0x11)) - dir_cnt++; - else - dir_cnt = 0; - dir_prev = dir; - - if (dir_cnt > 1) { - dir_cnt = 0; - if (stroke_index) { - if ((stroke_list[stroke_index - 1] != dir) && (dir != 0x22)) { - // Register stroke if different from last one - dir_ud = (dir & 0xF0); - dir_lr = (dir & 0x0F); - stroke_prev = stroke_list[stroke_index - 1]; - if (dir_ud == 0x20) { - // LR changed - if ((stroke_prev & 0x0F) != dir_lr) add_stroke(dir); - } else if (dir_lr == 0x02) { - // UD changed - if ((stroke_prev & 0xF0) != dir_ud) add_stroke(dir); - } else { - // Add direction - if (((stroke_prev & 0xF0) == 0x20) && (dir_ud != 0x20)) { - // Add UD - if ((stroke_prev & 0x0F) == dir_lr) { - // Replace totally - stroke_list[stroke_index - 1] = dir; - } else if (dir_lr == 0x02) { - // Merge UD - stroke_list[stroke_index - 1] = dir_ud | (stroke_prev & 0x0F); - } else { - add_stroke(dir); - } - } else if (((stroke_prev & 0x0F) == 0x02) && (dir_lr != 0x02)) { - // Add LR - if ((stroke_prev & 0xF0) == dir_ud) { - // Replace totally - stroke_list[stroke_index - 1] = dir; - } else if (dir_ud == 0x20) { - // Merge LR - stroke_list[stroke_index - 1] = dir_lr | (stroke_prev & 0xF0); - } else { - add_stroke(dir); - } - } else { - add_stroke(dir); - } - } - } - } else { - // Register first stroke - if (dir != 0x22) add_stroke(dir); - } - } - } - - last_pos = current_pos; - } - } - - sample_skip++; -} - -void HandWriteView::on_show() { - clear_zone(Color::black(), false); -} - -void HandWriteView::on_button(Button& button) { - char_add(button.id); - update_text(); -} - -} // namespace ui diff --git a/firmware/application/ui_handwrite.hpp b/firmware/application/ui_handwrite.hpp deleted file mode 100644 index e039fcd8..00000000 --- a/firmware/application/ui_handwrite.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 __UNISTROKE_H__ -#define __UNISTROKE_H__ - -#include "ui.hpp" -#include "ui_widget.hpp" -#include "ui_painter.hpp" -#include "ui_textentry.hpp" -#include "unistroke.hpp" - -namespace ui { - -class HandWriteView : public TextEntryView { - public: - HandWriteView(NavigationView& nav, std::string* str, size_t max_length); - - HandWriteView(const HandWriteView&) = delete; - HandWriteView(HandWriteView&&) = delete; - HandWriteView& operator=(const HandWriteView&) = delete; - HandWriteView& operator=(HandWriteView&&) = delete; - - void paint(Painter& painter) override; - void on_show() override; - bool on_touch(const TouchEvent event) override; - - private: - const char special_chars[5] = {'\'', '.', '?', '!', '='}; - - const HandWriting* handwriting{}; - Painter* _painter{}; - uint8_t dir_cnt{0}; - uint8_t dir_prev{0}; - uint8_t flash_timer{0}; - bool tracing{false}; - uint8_t stroke_index{0}; - uint8_t sample_skip{0}, move_wait{0}; - uint8_t stroke_list[8]; - Point start_pos{}, current_pos{}, last_pos{}; - bool _lowercase = false; - - void sample_pen(); - void add_stroke(uint8_t dir); - void guess_letter(); - void clear_zone(const Color color, const bool flash); - void on_button(Button& button); - - std::array num_buttons{}; - std::array special_buttons{}; - - Button button_case{ - {8, 270, 32, 28}, - "UC"}; - - Button button_ok{ - {190, 270, 40, 28}, - "OK"}; - - MessageHandlerRegistration message_handler_sample{ - Message::ID::DisplayFrameSync, - [this](const Message* const) { - this->sample_pen(); - }}; -}; - -} /* namespace ui */ - -#endif /*__UNISTROKE_H__*/ diff --git a/firmware/application/ui_loadmodule.cpp b/firmware/application/ui_loadmodule.cpp deleted file mode 100644 index 59248887..00000000 --- a/firmware/application/ui_loadmodule.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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_loadmodule.hpp" - -#include "ch.h" - -#include "ff.h" -#include "event_m0.hpp" -#include "hackrf_gpio.hpp" -#include "portapack.hpp" -#include "portapack_shared_memory.hpp" -#include "hackrf_hal.hpp" -#include "string_format.hpp" - -#include "ui_rds.hpp" -#include "ui_xylos.hpp" -#include "ui_epar.hpp" -#include "ui_lcr.hpp" -#include "analog_audio_app.hpp" -#include "ui_soundboard.hpp" -#include "ui_debug.hpp" -#include "ui_closecall.hpp" -#include "ui_audiotx.hpp" -#include "ui_jammer.hpp" - -#include -#include - -using namespace portapack; - -namespace ui { - -void LoadModuleView::focus() { - button_ok.focus(); -} - -void LoadModuleView::on_show() { - char md5_signature[16]; - uint8_t c; - - memcpy(md5_signature, (const void*)(0x10087FF0), 16); - for (c = 0; c < 16; c++) { - if (md5_signature[c] != _hash[c]) break; - } - // text_info.set(to_string_hex(*((unsigned int*)0x10087FF0), 8)); - - if (c == 16) { - text_info.set("Module already loaded :)"); - _mod_loaded = true; - } else { - text_info.set("Loading module"); - loadmodule(); - } -} - -int LoadModuleView::load_image() { - const char magic[6] = {'P', 'P', 'M', ' ', 0x02, 0x00}; - UINT bw; - uint8_t i; - uint32_t cnt; - char md5sum[16]; - FILINFO modinfo; - FIL modfile; - DIR rootdir; - FRESULT res; - - // Scan SD card root directory for files with the right MD5 fingerprint at the right location - if (f_opendir(&rootdir, "/") == FR_OK) { - for (;;) { - res = f_readdir(&rootdir, &modinfo); - if (res != FR_OK || modinfo.fname[0] == 0) break; // Reached last file, abort - // Only care about files with .bin extension - if ((!(modinfo.fattrib & AM_DIR)) && (modinfo.fname[9] == 'B') && (modinfo.fname[10] == 'I') && (modinfo.fname[11] == 'N')) { - res = f_open(&modfile, modinfo.fname, FA_OPEN_EXISTING | FA_READ); - if (res != FR_OK) return 0; - // Magic bytes and version check - f_read(&modfile, &md5sum, 6, &bw); - for (i = 0; i < 6; i++) - if (md5sum[i] != magic[i]) break; - if (i == 6) { - f_lseek(&modfile, 26); - f_read(&modfile, &md5sum, 16, &bw); - for (i = 0; i < 16; i++) - if (md5sum[i] != _hash[i]) break; - // f_read can't read more than 512 bytes at a time ? - if (i == 16) { - f_lseek(&modfile, 512); - for (cnt = 0; cnt < 64; cnt++) { - if (f_read(&modfile, reinterpret_cast(portapack::memory::map::m4_code.base() + (cnt * 512)), 512, &bw)) return 0; - } - f_close(&modfile); - f_closedir(&rootdir); - LPC_RGU->RESET_CTRL[0] = (1 << 13); - return 1; - } - } - f_close(&modfile); - } - } - f_closedir(&rootdir); - } - - return 0; -} - -void LoadModuleView::loadmodule() { - // baseband::shutdown(); - - /*EventDispatcher::message_map().register_handler(Message::ID::ReadyForSwitch, - [this](Message* const p) { - (void)p;*/ - if (load_image()) { - text_infob.set("Module loaded :)"); - _mod_loaded = true; - } else { - text_info.set("Module not found :("); - _mod_loaded = false; - } - // } - //); -} - -LoadModuleView::LoadModuleView( - NavigationView& nav, - const char* hash, - ViewID viewid) { - add_children({&text_info, - &text_infob, - &button_ok}); - - _hash = hash; - - button_ok.on_select = [this, &nav, viewid](Button&) { - nav.pop(); - if (_mod_loaded == true) { - if (viewid == AudioTX) nav.push(); - if (viewid == Xylos) nav.push(); - if (viewid == EPAR) nav.push(); - if (viewid == LCR) nav.push(); - if (viewid == SoundBoard) nav.push(); - if (viewid == AnalogAudio) nav.push(); - if (viewid == RDS) nav.push(); - if (viewid == CloseCall) nav.push(); - if (viewid == Receiver) nav.push(); - if (viewid == Jammer) nav.push(); - } - }; -} - -} /* namespace ui */ diff --git a/firmware/application/ui_loadmodule.hpp b/firmware/application/ui_loadmodule.hpp deleted file mode 100644 index eb6a22c9..00000000 --- a/firmware/application/ui_loadmodule.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.hpp" -#include "ui_widget.hpp" -#include "ui_painter.hpp" -#include "ui_menu.hpp" -#include "ui_navigation.hpp" -#include "core_control.hpp" - -namespace ui { - -enum ViewID { - Receiver, - AudioTX, - CloseCall, - Xylos, - EPAR, - LCR, - SoundBoard, - AnalogAudio, - RDS, - Jammer -}; - -class LoadModuleView : public View { - public: - LoadModuleView(NavigationView& nav, const char* hash, ViewID viewid); - void loadmodule(); - - void on_show() override; - void focus() override; - - private: - int load_image(void); - const char* _hash; - bool _mod_loaded = false; - - Text text_info{ - {8, 64, 224, 16}, - "-"}; - Text text_infob{ - {8, 64 + 16, 224, 16}, - "-"}; - - Button button_ok{ - {88, 128, 64, 32}, - "OK"}; -}; - -} /* namespace ui */ diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index b09245ba..a677de6e 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -24,8 +24,6 @@ #include "ui_navigation.hpp" -// #include "modules.h" - #include "bmp_modal_warning.hpp" #include "bmp_splash.hpp" #include "event_m0.hpp" @@ -35,12 +33,10 @@ #include "ui_about_simple.hpp" #include "ui_adsb_rx.hpp" -// #include "ui_adsb_tx.hpp" //moved to ext #include "ui_aprs_rx.hpp" #include "ui_aprs_tx.hpp" #include "ui_bht_tx.hpp" #include "ui_btle_rx.hpp" -// #include "ui_coasterp.hpp" //moved to ext #include "ui_debug.hpp" #include "ui_encoders.hpp" #include "ui_fileman.hpp" @@ -49,17 +45,10 @@ #include "ui_freqman.hpp" #include "ui_fsk_rx.hpp" #include "ui_iq_trim.hpp" -// #include "ui_jammer.hpp" //moved to ext -// #include "ui_keyfob.hpp" //moved to ext -// #include "ui_lcr.hpp" #include "ui_level.hpp" #include "ui_looking_glass_app.hpp" #include "ui_mictx.hpp" -// #include "ui_morse.hpp" //moved to ext -// #include "ui_nrf_rx.hpp" //moved to ext -// #include "ui_numbers.hpp" -// #include "ui_nuoptix.hpp" -// #include "ui_playdead.hpp" + #include "ui_playlist.hpp" #include "ui_pocsag_tx.hpp" #include "ui_rds.hpp" @@ -72,12 +61,9 @@ #include "ui_settings.hpp" #include "ui_siggen.hpp" #include "ui_sonde.hpp" -// #include "ui_spectrum_painter.hpp" //moved to ext app #include "ui_ss_viewer.hpp" -// #include "ui_sstvtx.hpp" //moved to ext // #include "ui_test.hpp" #include "ui_text_editor.hpp" -#include "ui_tone_search.hpp" #include "ui_touchtunes.hpp" #include "ui_view_wav.hpp" #include "ui_weatherstation.hpp" @@ -88,18 +74,13 @@ #include "ais_app.hpp" #include "analog_audio_app.hpp" -// #include "analog_tv_app.hpp" //moved to ext // #include "ble_comm_app.hpp" #include "ble_rx_app.hpp" #include "ble_tx_app.hpp" #include "capture_app.hpp" #include "ert_app.hpp" -// #include "gps_sim_app.hpp" //moved to ext -// #include "lge_app.hpp" //moved to ext #include "pocsag_app.hpp" -#include "replay_app.hpp" #include "soundboard_app.hpp" -// #include "tpms_app.hpp" //moved to ext #include "core_control.hpp" #include "file.hpp" @@ -142,7 +123,6 @@ static NavigationView::AppMap generate_app_map(const NavigationView::AppList& ap // TODO(u-foka): Check consistency of command names (where we add rx/tx postfix) const NavigationView::AppList NavigationView::appList = { /* HOME ******************************************************************/ - //{"playdead", "Play dead", HOME, Color::red(), &bitmap_icon_playdead, new ViewFactory()}, {nullptr, "Receive", HOME, Color::cyan(), &bitmap_icon_receivers, new ViewFactory()}, {nullptr, "Transmit", HOME, Color::cyan(), &bitmap_icon_transmit, new ViewFactory()}, {"capture", "Capture", HOME, Color::red(), &bitmap_icon_capture, new ViewFactory()}, @@ -154,13 +134,11 @@ const NavigationView::AppList NavigationView::appList = { {nullptr, "Utilities", HOME, Color::cyan(), &bitmap_icon_utilities, new ViewFactory()}, {nullptr, "Settings", HOME, Color::cyan(), &bitmap_icon_setup, new ViewFactory()}, {nullptr, "Debug", HOME, Color::light_grey(), &bitmap_icon_debug, new ViewFactory()}, - //{"about", "About", HOME, Color::cyan(), nullptr, new ViewFactory()}, /* RX ********************************************************************/ {"adsbrx", "ADS-B", RX, Color::green(), &bitmap_icon_adsb, new ViewFactory()}, {"ais", "AIS Boats", RX, Color::green(), &bitmap_icon_ais, new ViewFactory()}, {"aprsrx", "APRS", RX, Color::green(), &bitmap_icon_aprs, new ViewFactory()}, {"audio", "Audio", RX, Color::green(), &bitmap_icon_speaker, new ViewFactory()}, - //{"btle", "BTLE", RX, Color::yellow(), &bitmap_icon_btle, new ViewFactory()}, //{"blecomm", "BLE Comm", RX, ui::Color::orange(), &bitmap_icon_btle, new ViewFactory()}, {"blerx", "BLE Rx", RX, Color::green(), &bitmap_icon_btle, new ViewFactory()}, {"ert", "ERT Meter", RX, Color::green(), &bitmap_icon_ert, new ViewFactory()}, @@ -169,10 +147,8 @@ const NavigationView::AppList NavigationView::appList = { {"radiosonde", "Radiosnde", RX, Color::green(), &bitmap_icon_sonde, new ViewFactory()}, {"recon", "Recon", RX, Color::green(), &bitmap_icon_scanner, new ViewFactory()}, {"search", "Search", RX, Color::yellow(), &bitmap_icon_search, new ViewFactory()}, - //{"tmps", "TPMS Cars", RX, Color::green(), &bitmap_icon_tpms, new ViewFactory()}, {"subghzd", "SubGhzD", RX, Color::yellow(), &bitmap_icon_remote, new ViewFactory()}, {"weather", "Weather", RX, Color::green(), &bitmap_icon_thermometer, new ViewFactory()}, - //{"fskrx", "FSK RX", RX, Color::yellow(), &bitmap_icon_remote, new ViewFactory()}, //{"dmr", "DMR", RX, Color::dark_grey(), &bitmap_icon_dmr, new ViewFactory()}, //{"sigfox", "SIGFOX", RX, Color::dark_grey(), &bitmap_icon_fox, new ViewFactory()}, //{"lora", "LoRa", RX, Color::dark_grey(), &bitmap_icon_lora, new ViewFactory()}, @@ -183,13 +159,10 @@ const NavigationView::AppList NavigationView::appList = { {"aprstx", "APRS TX", TX, ui::Color::green(), &bitmap_icon_aprs, new ViewFactory()}, {"bht", "BHT Xy/EP", TX, ui::Color::green(), &bitmap_icon_bht, new ViewFactory()}, {"bletx", "BLE Tx", TX, ui::Color::green(), &bitmap_icon_btle, new ViewFactory()}, - //{"morse", "Morse", TX, ui::Color::green(), &bitmap_icon_morse, new ViewFactory()}, //moved to ext - //{"nuoptixdtmf", "Nuoptix DTMF", TX, ui::Color::green(), &bitmap_icon_nuoptix, new ViewFactory()}, {"ooktx", "OOK", TX, ui::Color::yellow(), &bitmap_icon_remote, new ViewFactory()}, {"pocsagtx", "POCSAG TX", TX, ui::Color::green(), &bitmap_icon_pocsag, new ViewFactory()}, {"rdstx", "RDS", TX, ui::Color::green(), &bitmap_icon_rds, new ViewFactory()}, {"soundbrd", "Soundbrd", TX, ui::Color::green(), &bitmap_icon_soundboard, new ViewFactory()}, - //{"sstvtx", "SSTV", TX, ui::Color::green(), &bitmap_icon_sstv, new ViewFactory()}, //moved to ext {"touchtune", "TouchTune", TX, ui::Color::green(), &bitmap_icon_touchtunes, new ViewFactory()}, /* UTILITIES *************************************************************/ {"antennalength", "Antenna Length", UTILITIES, Color::green(), &bitmap_icon_tools_antenna, new ViewFactory()}, @@ -200,7 +173,7 @@ const NavigationView::AppList NavigationView::appList = { {nullptr, "SD Over USB", UTILITIES, Color::yellow(), &bitmap_icon_hackrf, new ViewFactory()}, {"signalgen", "Signal Gen", UTILITIES, Color::green(), &bitmap_icon_cwgen, new ViewFactory()}, //{"testapp", "Test App", UTILITIES, Color::dark_grey(), nullptr, new ViewFactory()}, - //{"tonesearch", "Tone Search", UTILITIES, Color::dark_grey(), nullptr, new ViewFactory()}, + {"wavview", "Wav View", UTILITIES, Color::yellow(), &bitmap_icon_soundboard, new ViewFactory()}, // Dangerous apps. {nullptr, "Flash Utility", UTILITIES, Color::red(), &bitmap_icon_temperature, new ViewFactory()}, diff --git a/firmware/application/ui_playdead.cpp b/firmware/application/ui_playdead.cpp deleted file mode 100644 index adf4a2ae..00000000 --- a/firmware/application/ui_playdead.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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_playdead.hpp" -#include "portapack_persistent_memory.hpp" -#include "string_format.hpp" - -using namespace portapack; - -namespace ui { - -void PlayDeadView::focus() { - button_seq_entry.focus(); -} - -void PlayDeadView::paint(Painter& painter) { - if (persistent_memory::config_login()) { - // Blank the whole display - painter.fill_rectangle( - display.screen_rect(), - style().background); - } -} - -PlayDeadView::PlayDeadView(NavigationView& nav) { - rtc::RTC datetime; - - persistent_memory::set_playing_dead(0x5920C1DF); // Enable - - add_children({ - &text_playdead1, - &text_playdead2, - &text_playdead3, - &button_seq_entry, - }); - - // Seed from RTC - rtcGetTime(&RTCD1, &datetime); - text_playdead2.set("0x" + to_string_hex(lfsr_iterate(datetime.second()), 6) + "00"); - - text_playdead3.hidden(true); - - button_seq_entry.on_dir = [this](Button&, KeyEvent key) { - sequence = (sequence << 3) | (static_cast::type>(key) + 1); - return true; - }; - - button_seq_entry.on_select = [this, &nav](Button&) { - if (sequence == persistent_memory::playdead_sequence()) { - persistent_memory::set_playing_dead(0x82175E23); // Disable - if (persistent_memory::config_login()) { - text_playdead3.hidden(false); - } else { - nav.pop(); - nav.push(); - } - } else { - sequence = 0; - } - }; -} - -} /* namespace ui */ diff --git a/firmware/application/ui_playdead.hpp b/firmware/application/ui_playdead.hpp deleted file mode 100644 index 394647e5..00000000 --- a/firmware/application/ui_playdead.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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_PLAYDEAD_H__ -#define __UI_PLAYDEAD_H__ - -#include "ui.hpp" -#include "ui_navigation.hpp" - -namespace ui { - -class PlayDeadView : public View { - public: - PlayDeadView(NavigationView& nav); - - void focus() override; - void paint(Painter& painter) override; - - private: - uint32_t sequence = 0; - - Text text_playdead1{ - {6 * 8, 7 * 16, 14 * 8, 16}, - "\x46irmwa" - "re " - "er\x72o\x72"}; - Text text_playdead2{ - {6 * 8, 9 * 16, 16 * 8, 16}, - ""}; - Text text_playdead3{ - {6 * 8, 12 * 16, 16 * 8, 16}, - "Please reset"}; - - Button button_seq_entry{ - {240, 0, 1, 1}, - ""}; -}; - -} /* namespace ui */ - -#endif /*__UI_PLAYDEAD_H__*/ diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 5c320c03..51be53be 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -424,13 +424,6 @@ set(MODE_CPPSRC ) DeclareTargets(PNFM nfm_audio) -#### No op -# -#set(MODE_CPPSRC -# proc_noop.cpp -#) -#DeclareTargets(PNOP no_operation) - ### OOK set(MODE_CPPSRC @@ -438,12 +431,6 @@ set(MODE_CPPSRC ) DeclareTargets(POOK ook) -#### POCSAG RX -# -#set(MODE_CPPSRC -# proc_pocsag.cpp -#) -#DeclareTargets(PPOC pocsag) ### POCSAG2 RX diff --git a/firmware/baseband/proc_noop.cpp b/firmware/baseband/proc_noop.cpp deleted file mode 100644 index acd06bb5..00000000 --- a/firmware/baseband/proc_noop.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2014 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 "proc_noop.hpp" -#include "event_m4.hpp" - -#include - -void NOOPProcessor::execute(const buffer_c8_t& buffer) { - for (size_t i = 0; i < buffer.count; i++) { - buffer.p[i] = {0, 0}; - } -} - -int main() { - EventDispatcher event_dispatcher{std::make_unique()}; - event_dispatcher.run(); - return 0; -} diff --git a/firmware/baseband/proc_noop.hpp b/firmware/baseband/proc_noop.hpp deleted file mode 100644 index a2532c60..00000000 --- a/firmware/baseband/proc_noop.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2014 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 __PROC_NOOP_H__ -#define __PROC_NOOP_H__ - -#include "baseband_processor.hpp" -#include "baseband_thread.hpp" - -class NOOPProcessor : public BasebandProcessor { - public: - void execute(const buffer_c8_t& buffer) override; - - private: - /* NB: Threads should be the last members in the class definition. */ - BasebandThread baseband_thread{1536000, this, baseband::Direction::Transmit}; -}; - -#endif diff --git a/firmware/baseband/proc_pocsag.cpp b/firmware/baseband/proc_pocsag.cpp deleted file mode 100644 index b05abd49..00000000 --- a/firmware/baseband/proc_pocsag.cpp +++ /dev/null @@ -1,539 +0,0 @@ -/* - * 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 - * Copyright (C) 2016 Kyle Reed - * - * 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_pocsag.hpp" - -#include "dsp_iir_config.hpp" -#include "event_m4.hpp" -#include "audio_dma.hpp" - -#include -#include -#include -#include - -void POCSAGProcessor::execute(const buffer_c8_t& buffer) { - 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); - const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer); - auto audio = demod.execute(channel_out, audio_buffer); - - // If squelching, check for audio before smoothing because smoothing - // causes the squelch noise detection to fail. Likely because squelch - // looks for HF noise and smoothing is basically a lowpass filter. - // NB: Squelch in this processor is only for the the audio output. - // Squelching will likely drop data "noise" and break processing. - if (squelch_.enabled()) { - bool has_audio = squelch_.execute(audio); - squelch_history = (squelch_history << 1) | (has_audio ? 1 : 0); - } - - smooth.Process(audio.p, audio.count); - processDemodulatedSamples(audio.p, 16); - extractFrames(); - - samples_processed += buffer.count; - if (samples_processed >= stat_update_threshold) { - send_stats(); - samples_processed = 0; - } - - // Clear the output before sending to audio chip. - // Only clear the audio buffer when there hasn't been any audio for a while. - if (squelch_.enabled() && squelch_history == 0) { - for (size_t i = 0; i < audio.count; ++i) { - audio.p[i] = 0.0; - } - } - - audio_output.write(audio); -} - -// ==================================================================== -// -// ==================================================================== -int POCSAGProcessor::OnDataWord(uint32_t word, int pos) { - packet.set(pos, word); - return 0; -} - -// ==================================================================== -// -// ==================================================================== -int POCSAGProcessor::OnDataFrame(int len, int baud) { - if (len > 0) { - packet.set_bitrate(baud); - packet.set_flag(pocsag::PacketFlag::NORMAL); - packet.set_timestamp(Timestamp::now()); - const POCSAGPacketMessage message(packet); - shared_memory.application_queue.push(message); - } - return 0; -} - -void POCSAGProcessor::on_message(const Message* const message) { - switch (message->id) { - case Message::ID::POCSAGConfigure: - configure(); - break; - - case Message::ID::NBFMConfigure: { - auto config = reinterpret_cast(message); - squelch_.set_threshold(config->squelch_level / 100.0); - break; - } - - default: - break; - } -} - -void POCSAGProcessor::configure() { - constexpr size_t decim_0_input_fs = baseband_fs; - constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0.decimation_factor; - - constexpr size_t decim_1_input_fs = decim_0_output_fs; - constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor; - - constexpr size_t channel_filter_input_fs = decim_1_output_fs; - const size_t channel_filter_output_fs = channel_filter_input_fs / 2; - - const size_t demod_input_fs = channel_filter_output_fs; - - decim_0.configure(taps_11k0_decim_0.taps); - decim_1.configure(taps_11k0_decim_1.taps); - channel_filter.configure(taps_11k0_channel.taps, 2); - demod.configure(demod_input_fs, 4'500); // FSK +/- 4k5Hz. - - // Smoothing should be roughly sample rate over max baud - // 24k / 3.2k = 7.5 - smooth.SetSize(8); - - // Don't have audio process the stream. - audio_output.configure(false); - - // Set up the frame extraction, limits of baud - setFrameExtractParams(demod_input_fs, 4000, 300, 32); - - // Mark the class as ready to accept data - configured = true; -} - -void POCSAGProcessor::send_stats() const { - POCSAGStatsMessage message(m_fifo.codeword, m_numCode, m_gotSync, getRate()); - shared_memory.application_queue.push(message); -} - -// ----------------------------- -// Frame extractraction methods -// ----------------------------- -#define BAUD_STABLE (104) -#define MAX_CONSEC_SAME (32) -#define MAX_WITHOUT_SINGLE (64) -#define MAX_BAD_TRANS (10) - -#define M_SYNC (0x7cd215d8) -#define M_NOTSYNC (0x832dea27) - -#define M_IDLE (0x7a89c197) - -// ==================================================================== -// -// ==================================================================== -inline int bitsDiff(unsigned long left, unsigned long right) { - unsigned long xord = left ^ right; - int count = 0; - for (int i = 0; i < 32; i++) { - if ((xord & 0x01) != 0) ++count; - xord = xord >> 1; - } - return (count); -} - -// ==================================================================== -// -// ==================================================================== -void POCSAGProcessor::initFrameExtraction() { - m_averageSymbolLen_1024 = m_maxSymSamples_1024; - m_lastStableSymbolLen_1024 = m_minSymSamples_1024; - - m_badTransitions = 0; - m_bitsStart = 0; - m_bitsEnd = 0; - m_inverted = false; - - resetVals(); -} - -// ==================================================================== -// -// ==================================================================== -void POCSAGProcessor::resetVals() { - // Reset the parameters - // -------------------- - m_goodTransitions = 0; - m_badTransitions = 0; - m_averageSymbolLen_1024 = m_maxSymSamples_1024; - m_shortestGoodTrans_1024 = m_maxSymSamples_1024; - m_valMid = 0; - - // And reset the counts - // -------------------- - m_lastTransPos_1024 = 0; - m_lastBitPos_1024 = 0; - m_lastSample = 0; - m_sampleNo = 0; - m_nextBitPos_1024 = m_maxSymSamples_1024; - m_nextBitPosInt = (long)m_nextBitPos_1024; - - // Extraction - m_fifo.numBits = 0; - m_gotSync = false; - m_numCode = 0; -} - -// ==================================================================== -// -// ==================================================================== -void POCSAGProcessor::setFrameExtractParams(long a_samplesPerSec, long a_maxBaud, long a_minBaud, long maxRunOfSameValue) { - m_samplesPerSec = a_samplesPerSec; - m_minSymSamples_1024 = (uint32_t)(1024.0f * (float)a_samplesPerSec / (float)a_maxBaud); - m_maxSymSamples_1024 = (uint32_t)(1024.0f * (float)a_samplesPerSec / (float)a_minBaud); - m_maxRunOfSameValue = maxRunOfSameValue; - - m_shortestGoodTrans_1024 = m_maxSymSamples_1024; - m_averageSymbolLen_1024 = m_maxSymSamples_1024; - m_lastStableSymbolLen_1024 = m_minSymSamples_1024; - - m_nextBitPos_1024 = m_averageSymbolLen_1024 / 2; - m_nextBitPosInt = m_nextBitPos_1024 >> 10; - - initFrameExtraction(); -} - -// ==================================================================== -// -// ==================================================================== -int POCSAGProcessor::processDemodulatedSamples(float* sampleBuff, int noOfSamples) { - bool transition = false; - uint32_t samplePos_1024 = 0; - uint32_t len_1024 = 0; - - // Loop through the block of data - // ------------------------------ - for (int pos = 0; pos < noOfSamples; ++pos) { - m_sample = sampleBuff[pos]; - m_valMid += (m_sample - m_valMid) / 1024.0f; - - ++m_sampleNo; - - // Detect Transition - // ----------------- - transition = !((m_lastSample < m_valMid) ^ (m_sample >= m_valMid)); // use XOR for speed - - // If this is a transition - // ----------------------- - if (transition) { - // Calculate samples since last trans - // ---------------------------------- - int32_t fractional_1024 = (int32_t)(((m_sample - m_valMid) * 1024) / (m_sample - m_lastSample)); - if (fractional_1024 < 0) { - fractional_1024 = -fractional_1024; - } - - samplePos_1024 = (m_sampleNo << 10) - fractional_1024; - len_1024 = samplePos_1024 - m_lastTransPos_1024; - m_lastTransPos_1024 = samplePos_1024; - - // If symbol is large enough to be valid - // ------------------------------------- - if (len_1024 > m_minSymSamples_1024) { - // Check for shortest good transition - // ---------------------------------- - if ((len_1024 < m_shortestGoodTrans_1024) && - (m_goodTransitions < BAUD_STABLE)) // detect change of symbol size - { - int32_t fractionOfShortest_1024 = (len_1024 << 10) / m_shortestGoodTrans_1024; - - // If currently at half the baud rate - // ---------------------------------- - if ((fractionOfShortest_1024 > 410) && (fractionOfShortest_1024 < 614)) // 0.4 and 0.6 - { - m_averageSymbolLen_1024 /= 2; - m_shortestGoodTrans_1024 = len_1024; - } - // If currently at the wrong baud rate - // ----------------------------------- - else if (fractionOfShortest_1024 < 768) // 0.75 - { - m_averageSymbolLen_1024 = len_1024; - m_shortestGoodTrans_1024 = len_1024; - m_goodTransitions = 0; - m_lastSingleBitPos_1024 = samplePos_1024 - len_1024; - } - } - - // Calc the number of bits since events - // ------------------------------------ - int32_t halfSymbol_1024 = m_averageSymbolLen_1024 / 2; - int bitsSinceLastTrans = max((uint32_t)1, (len_1024 + halfSymbol_1024) / m_averageSymbolLen_1024); - int bitsSinceLastSingle = (((m_sampleNo << 10) - m_lastSingleBitPos_1024) + halfSymbol_1024) / m_averageSymbolLen_1024; - - // Check for single bit - // -------------------- - if (bitsSinceLastTrans == 1) { - m_lastSingleBitPos_1024 = samplePos_1024; - } - - // If too long since last transition - // --------------------------------- - if (bitsSinceLastTrans > MAX_CONSEC_SAME) { - resetVals(); - } - // If too long sice last single bit - // -------------------------------- - else if (bitsSinceLastSingle > MAX_WITHOUT_SINGLE) { - resetVals(); - } else { - // If this is a good transition - // ---------------------------- - int32_t offsetFromExtectedTransition_1024 = len_1024 - (bitsSinceLastTrans * m_averageSymbolLen_1024); - if (offsetFromExtectedTransition_1024 < 0) { - offsetFromExtectedTransition_1024 = -offsetFromExtectedTransition_1024; - } - if (offsetFromExtectedTransition_1024 < ((int32_t)m_averageSymbolLen_1024 / 4)) // Has to be within 1/4 of symbol to be good - { - ++m_goodTransitions; - uint32_t bitsCount = min((uint32_t)BAUD_STABLE, m_goodTransitions); - - uint32_t propFromPrevious = m_averageSymbolLen_1024 * bitsCount; - uint32_t propFromCurrent = (len_1024 / bitsSinceLastTrans); - m_averageSymbolLen_1024 = (propFromPrevious + propFromCurrent) / (bitsCount + 1); - m_badTransitions = 0; - // if ( len < m_shortestGoodTrans ){m_shortestGoodTrans = len;} - // Store the old symbol size - if (m_goodTransitions >= BAUD_STABLE) { - m_lastStableSymbolLen_1024 = m_averageSymbolLen_1024; - } - } - } - - // Set the point of the last bit if not yet stable - // ----------------------------------------------- - if ((m_goodTransitions < BAUD_STABLE) || (m_badTransitions > 0)) { - m_lastBitPos_1024 = samplePos_1024 - (m_averageSymbolLen_1024 / 2); - } - - // Calculate the exact positiom of the next bit - // -------------------------------------------- - int32_t thisPlusHalfsymbol_1024 = samplePos_1024 + (m_averageSymbolLen_1024 / 2); - int32_t lastPlusSymbol = m_lastBitPos_1024 + m_averageSymbolLen_1024; - m_nextBitPos_1024 = lastPlusSymbol + ((thisPlusHalfsymbol_1024 - lastPlusSymbol) / 16); - - // Check for bad pos error - // ----------------------- - if (m_nextBitPos_1024 < samplePos_1024) m_nextBitPos_1024 += m_averageSymbolLen_1024; - - // Calculate integer sample after next bit - // --------------------------------------- - m_nextBitPosInt = (m_nextBitPos_1024 >> 10) + 1; - - } // symbol is large enough to be valid - else { - // Bad transition, so reset the counts - // ----------------------------------- - ++m_badTransitions; - if (m_badTransitions > MAX_BAD_TRANS) { - resetVals(); - } - } - } // end of if transition - - // Reached the point of the next bit - // --------------------------------- - if (m_sampleNo >= m_nextBitPosInt) { - // Everything is good so extract a bit - // ----------------------------------- - if (m_goodTransitions > 20) { - // Store value at the center of bit - // -------------------------------- - storeBit(); - } - // Check for long 1 or zero - // ------------------------ - uint32_t bitsSinceLastTrans = ((m_sampleNo << 10) - m_lastTransPos_1024) / m_averageSymbolLen_1024; - if (bitsSinceLastTrans > m_maxRunOfSameValue) { - resetVals(); - } - - // Store the point of the last bit - // ------------------------------- - m_lastBitPos_1024 = m_nextBitPos_1024; - - // Calculate the exact point of the next bit - // ----------------------------------------- - m_nextBitPos_1024 += m_averageSymbolLen_1024; - - // Look for the bit after the next bit pos - // --------------------------------------- - m_nextBitPosInt = (m_nextBitPos_1024 >> 10) + 1; - - } // Reached the point of the next bit - - m_lastSample = m_sample; - - } // Loop through the block of data - - return getNoOfBits(); -} - -// ==================================================================== -// -// ==================================================================== -void POCSAGProcessor::storeBit() { - if (++m_bitsStart >= BIT_BUF_SIZE) { - m_bitsStart = 0; - } - - // Calculate the bit value - float sample = (m_sample + m_lastSample) / 2; - // int32_t sample_1024 = m_sample_1024; - bool bit = sample > m_valMid; - - // If buffer not full - if (m_bitsStart != m_bitsEnd) { - // Decide on output val - if (bit) { - m_bits[m_bitsStart] = 0; - } else { - m_bits[m_bitsStart] = 1; - } - } - // Throw away bits if the buffer is full - else { - if (--m_bitsStart <= -1) { - m_bitsStart = BIT_BUF_SIZE - 1; - } - } -} - -// ==================================================================== -// -// ==================================================================== -int POCSAGProcessor::extractFrames() { - int msgCnt = 0; - // While there is unread data in the bits buffer - //---------------------------------------------- - while (getNoOfBits() > 0) { - m_fifo.codeword = (m_fifo.codeword << 1) + getBit(); - m_fifo.numBits++; - - // If number of bits in fifo equals 32 - //------------------------------------ - if (m_fifo.numBits >= 32) { - // Not got sync - // ------------ - if (!m_gotSync) { - if (bitsDiff(m_fifo.codeword, M_SYNC) <= 2) { - m_inverted = false; - m_gotSync = true; - m_numCode = -1; - m_fifo.numBits = 0; - } else if (bitsDiff(m_fifo.codeword, M_NOTSYNC) <= 2) { - m_inverted = true; - m_gotSync = true; - m_numCode = -1; - m_fifo.numBits = 0; - } else { - // Cause it to load one more bit - m_fifo.numBits = 31; - } - } // Not got sync - else { - // Increment the word count - // ------------------------ - ++m_numCode; // It got set to -1 when a sync was found, now count the 16 words - uint32_t val = m_inverted ? ~m_fifo.codeword : m_fifo.codeword; - OnDataWord(val, m_numCode); - - // If at the end of a 16 word block - // -------------------------------- - if (m_numCode >= 15) { - msgCnt += OnDataFrame(m_numCode + 1, (m_samplesPerSec << 10) / m_lastStableSymbolLen_1024); - m_gotSync = false; - m_numCode = -1; - } - m_fifo.numBits = 0; - } - } // If number of bits in fifo equals 32 - } // While there is unread data in the bits buffer - return msgCnt; -} // extractFrames - -// ==================================================================== -// -// ==================================================================== -short POCSAGProcessor::getBit() { - if (m_bitsEnd != m_bitsStart) { - if (++m_bitsEnd >= BIT_BUF_SIZE) { - m_bitsEnd = 0; - } - return m_bits[m_bitsEnd]; - } else { - return -1; - } -} - -// ==================================================================== -// -// ==================================================================== -int POCSAGProcessor::getNoOfBits() { - int bits = m_bitsEnd - m_bitsStart; - if (bits < 0) { - bits += BIT_BUF_SIZE; - } - return bits; -} - -// ==================================================================== -// -// ==================================================================== -uint32_t POCSAGProcessor::getRate() const { - return ((m_samplesPerSec << 10) + 512) / m_lastStableSymbolLen_1024; -} - -// ==================================================================== -// -// ==================================================================== -int main() { - audio::dma::init_audio_out(); - - EventDispatcher event_dispatcher{std::make_unique()}; - event_dispatcher.run(); - return 0; -} diff --git a/firmware/baseband/proc_pocsag.hpp b/firmware/baseband/proc_pocsag.hpp deleted file mode 100644 index 66e5c47d..00000000 --- a/firmware/baseband/proc_pocsag.hpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * 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 - * Copyright (C) 2023 Kyle Reed - * - * 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_POCSAG_H__ -#define __PROC_POCSAG_H__ - -#include "baseband_processor.hpp" -#include "baseband_thread.hpp" -#include "rssi_thread.hpp" - -#include "dsp_decimate.hpp" -#include "dsp_demodulate.hpp" - -#include "pocsag_packet.hpp" - -#include "pocsag.hpp" -#include "message.hpp" -#include "audio_output.hpp" -#include "portapack_shared_memory.hpp" - -#include -#include -using namespace std; - -// Class used to smooth demodulated waveform prior to decoding -// ----------------------------------------------------------- -template -class SmoothVals { - protected: - ValType* m_lastVals; // Previous N values - int m_size; // The size N - CalcType m_sumVal; // Running sum of lastVals - int m_pos; // Current position in last vals ring buffer - int m_count; // - - public: - SmoothVals() - : m_lastVals(NULL), m_size(1), m_sumVal(0), m_pos(0), m_count(0) { - m_lastVals = new ValType[m_size]; - } - - // -------------------------------------------------- - // -------------------------------------------------- - virtual ~SmoothVals() { - delete[] m_lastVals; - } - - SmoothVals(const SmoothVals&) { - } - - SmoothVals& operator=(const SmoothVals&) { - return *this; - } - - // -------------------------------------------------- - // Set size of smoothing - // -------------------------------------------------- - void SetSize(int size) { - m_size = std::max(size, 1); - m_pos = 0; - delete[] m_lastVals; - m_lastVals = new ValType[m_size]; - m_sumVal = 0; - } - - // -------------------------------------------------- - // Get size of smoothing - // -------------------------------------------------- - int Size() { return m_size; } - - // -------------------------------------------------- - // In place processing - // -------------------------------------------------- - void Process(ValType* valBuff, int numVals) { - ValType tmpVal; - - if (m_count > (1024 * 10)) { - // Recalculate the sum value occasionaly, stops accumulated errors when using float - m_count = 0; - m_sumVal = 0; - for (int i = 0; i < m_size; ++i) { - m_sumVal += (CalcType)m_lastVals[i]; - } - } - - // Use a rolling smoothed value while processing the buffer - for (int buffPos = 0; buffPos < numVals; ++buffPos) { - m_pos++; - if (m_pos >= m_size) { - m_pos = 0; - } - - m_sumVal -= (CalcType)m_lastVals[m_pos]; // Subtract the oldest value - m_lastVals[m_pos] = valBuff[buffPos]; // Store the new value - m_sumVal += (CalcType)m_lastVals[m_pos]; // Add on the new value - - tmpVal = (ValType)(m_sumVal / m_size); // Scale by number of values smoothed - valBuff[buffPos] = tmpVal; - } - - m_count += numVals; - } -}; - -// -------------------------------------------------- -// Class to process base band data to pocsag frames -// -------------------------------------------------- -class POCSAGProcessor : public BasebandProcessor { - public: - void execute(const buffer_c8_t& buffer) override; - void on_message(const Message* const message) override; - - int OnDataFrame(int len, int baud); - int OnDataWord(uint32_t word, int pos); - - private: - static constexpr size_t baseband_fs = 3072000; - static constexpr uint8_t stat_update_interval = 10; - static constexpr uint32_t stat_update_threshold = - baseband_fs / stat_update_interval; - - std::array dst{}; - const buffer_c16_t dst_buffer{ - dst.data(), - dst.size()}; - 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::FIRAndDecimateComplex channel_filter{}; - dsp::demodulate::FM demod{}; - SmoothVals smooth = {}; - - AudioOutput audio_output{}; - - bool configured = false; - pocsag::POCSAGPacket packet{}; - - uint32_t samples_processed = 0; - - void configure(); - void send_stats() const; - - // ---------------------------------------- - // Frame extractraction methods and members - // ---------------------------------------- - void initFrameExtraction(); - struct FIFOStruct { - unsigned long codeword; - int numBits; - }; - -#define BIT_BUF_SIZE (64) - - void resetVals(); - void setFrameExtractParams(long a_samplesPerSec, long a_maxBaud = 8000, long a_minBaud = 200, long maxRunOfSameValue = 32); - - int processDemodulatedSamples(float* sampleBuff, int noOfSamples); - int extractFrames(); - - void storeBit(); - short getBit(); - - int getNoOfBits(); - uint32_t getRate() const; - - uint32_t m_averageSymbolLen_1024{0}; - uint32_t m_lastStableSymbolLen_1024{0}; - - uint32_t m_samplesPerSec{0}; - uint32_t m_goodTransitions{0}; - uint32_t m_badTransitions{0}; - - uint32_t m_sampleNo{0}; - float m_sample{0}; - float m_valMid{0.0f}; - float m_lastSample{0.0f}; - - uint32_t m_lastTransPos_1024{0}; - uint32_t m_lastSingleBitPos_1024{0}; - - uint32_t m_nextBitPosInt{0}; // Integer rounded up version to save on ops - uint32_t m_nextBitPos_1024{0}; - uint32_t m_lastBitPos_1024{0}; - - uint32_t m_shortestGoodTrans_1024{0}; - uint32_t m_minSymSamples_1024{0}; - uint32_t m_maxSymSamples_1024{0}; - uint32_t m_maxRunOfSameValue{0}; - - bitset<(size_t)BIT_BUF_SIZE> m_bits{0}; - long m_bitsStart{0}; - long m_bitsEnd{0}; - - FIFOStruct m_fifo{0, 0}; - bool m_gotSync{false}; - int m_numCode{0}; - bool m_inverted{false}; - - FMSquelch squelch_{}; - uint64_t squelch_history = 0; - - /* NB: Threads should be the last members in the class definition. */ - BasebandThread baseband_thread{baseband_fs, this, baseband::Direction::Receive}; - RSSIThread rssi_thread{}; -}; - -#endif /*__PROC_POCSAG_H__*/ diff --git a/firmware/common/emu_cc1101.hpp b/firmware/common/emu_cc1101.hpp deleted file mode 100644 index 1245a4e8..00000000 --- a/firmware/common/emu_cc1101.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2017 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2017 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 __EMU_CC1101_H__ -#define __EMU_CC1101_H__ - -#include -#include - -#include "utility.hpp" - -namespace cc1101 { - -// Data rate (Bauds) -// Whitening: Everything except preamble and sync word, init value = 111111111 -// Packet format: preamble, sync word, (opt) length, (opt) address, payload, (opt) CRC -// Preamble: 8*n bits of 10101010 -// Sync word: 2 bytes (can be repeated twice) -// Length: 1 byte (address + payload) -// 2-FSK: 0=-dev, 1=+dev -// 4-FSK: 00=-1/3dev, 01=-dev, 10=1/3dev, 11=+dev (preamble and sync are in 2-FSK) -// OOK: PA on or off -// ASK: Power can be adjusted -// FEC: ? - -class CC1101Emu { - public: - // CC1101Emu(); - //~CC1101Emu(); - - enum packet_mode_t { - FIXED_LENGTH, - VARIABLE_LENGTH, - INFINITE_LENGTH - }; - - enum modulation_t { - TWO_FSK, - GFSK, - OOK, - FOUR_FSK, - MSK, - }; - - void set_sync_word(const uint16_t sync_word) { - sync_word_ = sync_word; - }; - void set_address(const uint8_t address) { - address_ = address; - }; - void set_packet_length(const uint8_t packet_length) { - packet_length_ = packet_length; - }; - void set_data_config(const bool CRC, const bool manchester, const bool whitening) { - CRC_ = CRC; - manchester_ = manchester; - whitening_ = whitening; - }; - void set_packet_mode(const packet_mode_t packet_mode) { - packet_mode_ = packet_mode; - }; - void set_modulation(const modulation_t modulation) { - modulation_ = modulation; - } - void set_num_preamble(const uint8_t num_preamble) { // 2, 3, 4, 6, 8, 12, 16, or 24 - num_preamble_ = num_preamble; - }; - void set_deviation(const size_t deviation) { - deviation_ = deviation; - }; - - private: - uint16_t sync_word_{0xD391}; - uint8_t address_{0x00}; - uint8_t packet_length_{0}; - bool CRC_{false}; - bool manchester_{false}; - bool whitening_{true}; - packet_mode_t packet_mode_{VARIABLE_LENGTH}; - modulation_t modulation_{TWO_FSK}; - uint8_t num_preamble_{4}; - size_t deviation_{4000}; - - uint16_t whitening_pn{0x1FF}; - - void whitening_init(); - uint8_t whiten_byte(uint8_t byte); -}; - -} /* namespace cc1101 */ - -#endif /*__EMU_CC1101_H__*/ diff --git a/firmware/common/modules.h b/firmware/common/modules.h deleted file mode 100644 index f2656049..00000000 --- a/firmware/common/modules.h +++ /dev/null @@ -1,36 +0,0 @@ -const char md5_baseband[16] = { - 0xb8, - 0x9e, - 0x9b, - 0x08, - 0x44, - 0x34, - 0x04, - 0x20, - 0x0b, - 0xbc, - 0x60, - 0x7e, - 0x67, - 0x88, - 0x53, - 0xf7, -}; -const char md5_baseband_tx[16] = { - 0xd5, - 0xaf, - 0x76, - 0xd5, - 0xa3, - 0x32, - 0x5d, - 0x9a, - 0x9d, - 0x83, - 0x46, - 0x37, - 0x02, - 0x2d, - 0xd0, - 0x57, -}; diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index a96a7cfd..42c3411f 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -184,10 +184,9 @@ struct data_t { int32_t modem_baudrate; int32_t modem_repeat; - // Play dead unlock (Used?) - uint32_t playdead_magic; - uint32_t playing_dead; - uint32_t playdead_sequence; + uint32_t UNUSED_2; + uint32_t UNUSED_3; + uint32_t UNUSED_4; // UI Config ui_config_t ui_config; @@ -269,11 +268,9 @@ struct data_t { afsk_space_freq(afsk_space_reset_value), modem_baudrate(modem_baudrate_reset_value), modem_repeat(modem_repeat_reset_value), - - playdead_magic(), // TODO: Unused? - playing_dead(), // TODO: Unused? - playdead_sequence(), // TODO: Unused? - + UNUSED_2(0), + UNUSED_3(0), + UNUSED_4(0), ui_config(), pocsag_last_address(0), // TODO: A better default? @@ -1221,9 +1218,6 @@ bool debug_dump() { pmem_dump_file.write_line("afsk_space_freq: " + to_string_dec_int(data->afsk_space_freq)); pmem_dump_file.write_line("modem_baudrate: " + to_string_dec_int(data->modem_baudrate)); pmem_dump_file.write_line("modem_repeat: " + to_string_dec_int(data->modem_repeat)); - pmem_dump_file.write_line("playdead_magic: " + to_string_dec_uint(data->playdead_magic)); - pmem_dump_file.write_line("playing_dead: " + to_string_dec_uint(data->playing_dead)); - pmem_dump_file.write_line("playdead_sequence: " + to_string_dec_uint(data->playdead_sequence)); pmem_dump_file.write_line("pocsag_last_address: " + to_string_dec_uint(data->pocsag_last_address)); pmem_dump_file.write_line("pocsag_ignore_address: " + to_string_dec_uint(data->pocsag_ignore_address)); pmem_dump_file.write_line("tone_mix: " + to_string_dec_uint(data->tone_mix)); diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 19ea9bf1..e13d0b5a 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -189,12 +189,6 @@ void set_modem_baudrate(const int32_t new_value); uint8_t modem_repeat(); void set_modem_repeat(const uint32_t new_value); -uint32_t playing_dead(); -void set_playing_dead(const uint32_t new_value); - -uint32_t playdead_sequence(); -void set_playdead_sequence(const uint32_t new_value); - bool stealth_mode(); void set_stealth_mode(const bool v); diff --git a/firmware/tools/make_baseband_file.py b/firmware/tools/make_baseband_file.py deleted file mode 100755 index 82edbbac..00000000 --- a/firmware/tools/make_baseband_file.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (C) 2016 Furrtek -# -# 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. -# - -import sys -import struct -import md5 - -usage_message = """ -Baseband module package file generator - -Usage: ... -""" - -def read_image(path): - f = open(path, 'rb') - data = f.read() - f.close() - return data - -def write_file(data, path): - f = open(path, 'wb') - f.write(data) - f.close() - -if len(sys.argv) == 1: - print(usage_message) - sys.exit(-1) - -data = bytearray() -h_data = bytearray() -name = bytearray() -info = bytearray() -description = bytearray() -data_default_byte = bytearray((0,)) - -sys.argv = sys.argv[1:] - -# Format for module file: -# Magic (4), Version (2), Length (4), Name (16), MD5 (16), Description (214) -# 0x00 pad bytes (256) -# Module binary (padded to 32768-16) -# MD5 (16) again, so that module code can read it (dirty...) - -for args in sys.argv: - m = md5.new() - data = read_image(args + '/build/' + args + '.bin') - data_r = data - - # Magic bytes - info = 'PPM ' - - # Version - info += struct.pack('H', 2) - - # Length - info += struct.pack('I', len(data)) - - # Module name - name = read_image(args + '/name') - if len(name) > 16: - name = name[0:15] - pad_size = 16 - len(name) - name += (data_default_byte * pad_size) - info += name - - # Module MD5 footprint - m.update(data) - digest = m.digest() - pad_size = 16 - len(digest) - digest += (data_default_byte * pad_size) - info += digest - - # Module description - description = read_image(args + '/description') - if len(description) > 214: - description = description[0:213] - pad_size = 214 - len(description) - description += (data_default_byte * pad_size) - info += description - - # Header padding to fit in SD card sector - info += (data_default_byte * 256) - - # Binary padding - data = info + data - pad_size = (32768 + 512 - 16) - len(data) - data += (data_default_byte * pad_size) - data += digest - write_file(data, args + '.bin') - - # Add to modules.h - md5sum = '' - for byte in digest: - md5sum += '0x' + format(byte, '02x') + ',' - h_data += 'const char md5_' + args.replace('-','_') + '[16] = {' + md5sum + '};\n' - - # Update original binary with MD5 footprint - write_file(data[512:(32768+512)], args + '/build/' + args + '_inc.bin') - -write_file(h_data, 'common/modules.h')