From b15b78103938628fd01918c9cdf6012b73973688 Mon Sep 17 00:00:00 2001 From: dqs105 Date: Wed, 16 Sep 2020 19:27:56 +0800 Subject: [PATCH 1/2] Added options for enabling CLKOUT. - CLKOUT can be enabled in Radio settings and status bar. - Fixed a typo(I believe) in ui_navigation. --- firmware/application/apps/ui_settings.cpp | 9 ++++++ firmware/application/apps/ui_settings.hpp | 12 +++++-- firmware/application/clock_manager.cpp | 14 +++++++++ firmware/application/clock_manager.hpp | 2 ++ firmware/application/ui_navigation.cpp | 31 ++++++++++++++++--- firmware/application/ui_navigation.hpp | 3 +- .../common/portapack_persistent_memory.cpp | 15 +++++++++ .../common/portapack_persistent_memory.hpp | 3 ++ 8 files changed, 80 insertions(+), 9 deletions(-) diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 3f5708b3..3d919bbe 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -144,6 +144,7 @@ SetRadioView::SetRadioView( } add_children({ + &check_clkout, &labels_bias, &check_bias, &button_done, @@ -156,6 +157,14 @@ SetRadioView::SetRadioView( form_init(model); + check_clkout.set_value(portapack::persistent_memory::clkout_enabled()); + check_clkout.on_select = [this](Checkbox&, bool v) { + clock_manager.enable_clock_output(v); + portapack::persistent_memory::set_clkout_enabled(v); + StatusRefreshMessage message { }; + EventDispatcher::send_message(message); + }; + check_bias.set_value(portapack::get_antenna_bias()); check_bias.on_select = [this](Checkbox&, bool v) { portapack::set_antenna_bias(v); diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 076ede03..4b9f99d4 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -147,8 +147,14 @@ private: }; Labels labels_correction { - { { 2 * 8, 4 * 16 }, "Frequency correction:", Color::light_grey() }, - { { 6 * 8, 5 * 16 }, "PPM", Color::light_grey() }, + { { 2 * 8, 3 * 16 }, "Frequency correction:", Color::light_grey() }, + { { 6 * 8, 4 * 16 }, "PPM", Color::light_grey() }, + }; + + Checkbox check_clkout { + { 28, (6 * 16 - 4) }, + 4, + "Enable 10MHz CLKOUT" }; Labels labels_bias { @@ -159,7 +165,7 @@ private: }; NumberField field_ppm { - { 2 * 8, 5 * 16 }, + { 2 * 8, 4 * 16 }, 3, { -50, 50 }, 1, diff --git a/firmware/application/clock_manager.cpp b/firmware/application/clock_manager.cpp index 088cf17f..ec08452b 100644 --- a/firmware/application/clock_manager.cpp +++ b/firmware/application/clock_manager.cpp @@ -463,3 +463,17 @@ void ClockManager::stop_audio_pll() { cgu::pll0audio::power_down(); while( cgu::pll0audio::is_locked() ); } + +void ClockManager::enable_clock_output(bool enable) { + if(enable) { + clock_generator.enable_output(clock_generator_output_clkout); + clock_generator.set_ms_frequency(clock_generator_output_clkout, 10000000, si5351_vco_f, 0); + } else { + clock_generator.disable_output(clock_generator_output_clkout); + } + + if(enable) + clock_generator.set_clock_control(clock_generator_output_clkout, si5351_clock_control_common[clock_generator_output_clkout].ms_src(get_reference_clock_generator_pll(reference.source)).clk_pdn(ClockControl::ClockPowerDown::Power_On)); + else + clock_generator.set_clock_control(clock_generator_output_clkout, ClockControl::power_off()); +} diff --git a/firmware/application/clock_manager.hpp b/firmware/application/clock_manager.hpp index 98af620a..0c88bab5 100644 --- a/firmware/application/clock_manager.hpp +++ b/firmware/application/clock_manager.hpp @@ -79,6 +79,8 @@ public: Reference get_reference() const; + void enable_clock_output(bool enable); + private: I2C& i2c0; si5351::Si5351& clock_generator; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index ca6a6334..57ffd403 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -113,7 +113,7 @@ SystemStatusView::SystemStatusView( &button_camera, &button_sleep, &button_bias_tee, - &image_clock_status, + &button_clock_status, &sd_card_status_view, }); @@ -168,6 +168,10 @@ SystemStatusView::SystemStatusView( DisplaySleepMessage message; EventDispatcher::send_message(message); }; + + button_clock_status.on_select = [this](ImageButton&) { + this->on_clk(); + }; } void SystemStatusView::refresh() { @@ -188,11 +192,16 @@ void SystemStatusView::refresh() { } if (portapack::clock_manager.get_reference().source == ClockManager::ReferenceSource::External) { - image_clock_status.set_bitmap(&bitmap_icon_clk_ext); - button_bias_tee.set_foreground(ui::Color::green()); + button_clock_status.set_bitmap(&bitmap_icon_clk_ext); +// button_bias_tee.set_foreground(ui::Color::green()); Typo? } else { - image_clock_status.set_bitmap(&bitmap_icon_clk_int); - button_bias_tee.set_foreground(ui::Color::light_grey()); + button_clock_status.set_bitmap(&bitmap_icon_clk_int); +// button_bias_tee.set_foreground(ui::Color::green()); + } + if(portapack::persistent_memory::clkout_enabled()) { + button_clock_status.set_foreground(ui::Color::green()); + } else { + button_clock_status.set_foreground(ui::Color::light_grey()); } set_dirty(); @@ -302,6 +311,18 @@ void SystemStatusView::on_camera() { } } +void SystemStatusView::on_clk() { + bool v = portapack::persistent_memory::clkout_enabled(); + if(v) { + v = false; + } else { + v = true; + } + portapack::clock_manager.enable_clock_output(v); + portapack::persistent_memory::set_clkout_enabled(v); + refresh(); +} + void SystemStatusView::on_title() { if(nav_.is_top()) nav_.push(); diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index 7edf6a9d..1537ce4e 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -180,7 +180,7 @@ private: Color::dark_grey() }; - Image image_clock_status { + ImageButton button_clock_status { { 27 * 8, 0 * 16, 2 * 8, 1 * 16 }, &bitmap_icon_clk_int, Color::light_grey(), @@ -198,6 +198,7 @@ private: void on_camera(); void on_title(); void refresh(); + void on_clk(); MessageHandlerRegistration message_handler_refresh { Message::ID::StatusRefresh, diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 1ee81ffa..97b9e006 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -63,6 +63,10 @@ using modem_repeat_range_t = range_t; constexpr modem_repeat_range_t modem_repeat_range { 1, 99 }; constexpr int32_t modem_repeat_reset_value { 5 }; +using clkout_config_range_t = range_t; +constexpr clkout_config_range_t clkout_config_range { 0, 1 }; +constexpr uint32_t clkout_config_reset_value { 0 }; + /* struct must pack the same way on M4 and M0 cores. */ struct data_t { int64_t tuned_frequency; @@ -91,6 +95,8 @@ struct data_t { uint32_t pocsag_ignore_address; int32_t tone_mix; + + uint32_t clkout_config; // TODO: Add custom frequency output? }; static_assert(sizeof(data_t) <= backup_ram.size(), "Persistent memory structure too large for VBAT-maintained region"); @@ -287,5 +293,14 @@ void set_pocsag_ignore_address(uint32_t address) { data->pocsag_ignore_address = address; } +bool clkout_enabled() { + clkout_config_range.reset_if_outside(data->clkout_config, clkout_config_reset_value); + return (bool)(data->clkout_config & 1); +} + +void set_clkout_enabled(bool enable) { + data->clkout_config = (uint32_t)enable; +} + } /* namespace persistent_memory */ } /* namespace portapack */ diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index be740edb..6422567a 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -93,6 +93,9 @@ void set_pocsag_last_address(uint32_t address); uint32_t pocsag_ignore_address(); void set_pocsag_ignore_address(uint32_t address); +bool clkout_enabled(); +void set_clkout_enabled(bool enable); + } /* namespace persistent_memory */ } /* namespace portapack */ From 66a841e079f268c2cfa8d47899d2a7e92b31cace Mon Sep 17 00:00:00 2001 From: dqs105 Date: Thu, 17 Sep 2020 12:47:34 +0800 Subject: [PATCH 2/2] combine clkout_config => ui_config --- firmware/common/portapack_persistent_memory.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 97b9e006..e7fcbba6 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -63,10 +63,6 @@ using modem_repeat_range_t = range_t; constexpr modem_repeat_range_t modem_repeat_range { 1, 99 }; constexpr int32_t modem_repeat_reset_value { 5 }; -using clkout_config_range_t = range_t; -constexpr clkout_config_range_t clkout_config_range { 0, 1 }; -constexpr uint32_t clkout_config_reset_value { 0 }; - /* struct must pack the same way on M4 and M0 cores. */ struct data_t { int64_t tuned_frequency; @@ -89,14 +85,12 @@ struct data_t { uint32_t playdead_sequence; // UI - uint32_t ui_config; + uint32_t ui_config; uint32_t pocsag_last_address; uint32_t pocsag_ignore_address; int32_t tone_mix; - - uint32_t clkout_config; // TODO: Add custom frequency output? }; static_assert(sizeof(data_t) <= backup_ram.size(), "Persistent memory structure too large for VBAT-maintained region"); @@ -294,12 +288,11 @@ void set_pocsag_ignore_address(uint32_t address) { } bool clkout_enabled() { - clkout_config_range.reset_if_outside(data->clkout_config, clkout_config_reset_value); - return (bool)(data->clkout_config & 1); + return (data->ui_config & 0x08000000UL); } void set_clkout_enabled(bool enable) { - data->clkout_config = (uint32_t)enable; + data->ui_config = (data->ui_config & ~0x08000000UL) | (enable << 27); } } /* namespace persistent_memory */