mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-14 08:07:37 +00:00
Merge pull request #214 from dqs105/clkout_enable
Add options for enabling CLKOUT.
This commit is contained in:
@@ -144,6 +144,10 @@ SetRadioView::SetRadioView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
&check_clkout,
|
||||||
|
&field_clkout_freq,
|
||||||
|
&labels_clkout_khz,
|
||||||
|
&value_freq_step,
|
||||||
&labels_bias,
|
&labels_bias,
|
||||||
&check_bias,
|
&check_bias,
|
||||||
&button_done,
|
&button_done,
|
||||||
@@ -156,6 +160,39 @@ SetRadioView::SetRadioView(
|
|||||||
|
|
||||||
form_init(model);
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
field_clkout_freq.set_value(portapack::persistent_memory::clkout_freq());
|
||||||
|
value_freq_step.set_style(&style_text);
|
||||||
|
|
||||||
|
field_clkout_freq.on_select = [this](NumberField&) {
|
||||||
|
freq_step_khz++;
|
||||||
|
if(freq_step_khz > 3) {
|
||||||
|
freq_step_khz = 0;
|
||||||
|
}
|
||||||
|
switch(freq_step_khz) {
|
||||||
|
case 0:
|
||||||
|
value_freq_step.set(" |");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
value_freq_step.set(" | ");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
value_freq_step.set(" | ");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
value_freq_step.set("| ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
field_clkout_freq.set_step(pow(10, freq_step_khz));
|
||||||
|
};
|
||||||
|
|
||||||
check_bias.set_value(portapack::get_antenna_bias());
|
check_bias.set_value(portapack::get_antenna_bias());
|
||||||
check_bias.on_select = [this](Checkbox&, bool v) {
|
check_bias.on_select = [this](Checkbox&, bool v) {
|
||||||
portapack::set_antenna_bias(v);
|
portapack::set_antenna_bias(v);
|
||||||
@@ -166,6 +203,8 @@ SetRadioView::SetRadioView(
|
|||||||
button_done.on_select = [this, &nav](Button&){
|
button_done.on_select = [this, &nav](Button&){
|
||||||
const auto model = this->form_collect();
|
const auto model = this->form_collect();
|
||||||
portapack::persistent_memory::set_correction_ppb(model.ppm * 1000);
|
portapack::persistent_memory::set_correction_ppb(model.ppm * 1000);
|
||||||
|
portapack::persistent_memory::set_clkout_freq(model.freq);
|
||||||
|
clock_manager.enable_clock_output(portapack::persistent_memory::clkout_enabled());
|
||||||
nav.pop();
|
nav.pop();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -181,6 +220,7 @@ void SetRadioView::form_init(const SetFrequencyCorrectionModel& model) {
|
|||||||
SetFrequencyCorrectionModel SetRadioView::form_collect() {
|
SetFrequencyCorrectionModel SetRadioView::form_collect() {
|
||||||
return {
|
return {
|
||||||
.ppm = static_cast<int8_t>(field_ppm.value()),
|
.ppm = static_cast<int8_t>(field_ppm.value()),
|
||||||
|
.freq = static_cast<uint32_t>(field_clkout_freq.value()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -114,6 +114,7 @@ private:
|
|||||||
|
|
||||||
struct SetFrequencyCorrectionModel {
|
struct SetFrequencyCorrectionModel {
|
||||||
int8_t ppm;
|
int8_t ppm;
|
||||||
|
uint32_t freq;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SetRadioView : public View {
|
class SetRadioView : public View {
|
||||||
@@ -130,6 +131,7 @@ private:
|
|||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::light_grey(),
|
.foreground = Color::light_grey(),
|
||||||
};
|
};
|
||||||
|
uint8_t freq_step_khz = 3;
|
||||||
|
|
||||||
Text label_source {
|
Text label_source {
|
||||||
{ 0, 1 * 16, 17 * 8, 16 },
|
{ 0, 1 * 16, 17 * 8, 16 },
|
||||||
@@ -147,8 +149,31 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Labels labels_correction {
|
Labels labels_correction {
|
||||||
{ { 2 * 8, 4 * 16 }, "Frequency correction:", Color::light_grey() },
|
{ { 2 * 8, 3 * 16 }, "Frequency correction:", Color::light_grey() },
|
||||||
{ { 6 * 8, 5 * 16 }, "PPM", Color::light_grey() },
|
{ { 6 * 8, 4 * 16 }, "PPM", Color::light_grey() },
|
||||||
|
};
|
||||||
|
|
||||||
|
Checkbox check_clkout {
|
||||||
|
{ 18, (6 * 16 - 4) },
|
||||||
|
13,
|
||||||
|
"Enable CLKOUT"
|
||||||
|
};
|
||||||
|
|
||||||
|
NumberField field_clkout_freq {
|
||||||
|
{ 20 * 8, 6 * 16 },
|
||||||
|
5,
|
||||||
|
{ 10, 60000 },
|
||||||
|
1000,
|
||||||
|
' '
|
||||||
|
};
|
||||||
|
|
||||||
|
Labels labels_clkout_khz {
|
||||||
|
{ { 26 * 8, 6 * 16 }, "kHz", Color::light_grey() }
|
||||||
|
};
|
||||||
|
|
||||||
|
Text value_freq_step {
|
||||||
|
{ 21 * 8, (7 * 16 ), 4 * 8, 16 },
|
||||||
|
"| "
|
||||||
};
|
};
|
||||||
|
|
||||||
Labels labels_bias {
|
Labels labels_bias {
|
||||||
@@ -159,7 +184,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
NumberField field_ppm {
|
NumberField field_ppm {
|
||||||
{ 2 * 8, 5 * 16 },
|
{ 2 * 8, 4 * 16 },
|
||||||
3,
|
3,
|
||||||
{ -50, 50 },
|
{ -50, 50 },
|
||||||
1,
|
1,
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "clock_manager.hpp"
|
#include "clock_manager.hpp"
|
||||||
|
|
||||||
|
#include "portapack_persistent_memory.hpp"
|
||||||
#include "portapack_io.hpp"
|
#include "portapack_io.hpp"
|
||||||
|
|
||||||
#include "hackrf_hal.hpp"
|
#include "hackrf_hal.hpp"
|
||||||
@@ -463,3 +464,21 @@ void ClockManager::stop_audio_pll() {
|
|||||||
cgu::pll0audio::power_down();
|
cgu::pll0audio::power_down();
|
||||||
while( cgu::pll0audio::is_locked() );
|
while( cgu::pll0audio::is_locked() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClockManager::enable_clock_output(bool enable) {
|
||||||
|
if(enable) {
|
||||||
|
clock_generator.enable_output(clock_generator_output_clkout);
|
||||||
|
if(portapack::persistent_memory::clkout_freq() < 1000) {
|
||||||
|
clock_generator.set_ms_frequency(clock_generator_output_clkout, portapack::persistent_memory::clkout_freq() * 128000, si5351_vco_f, 7);
|
||||||
|
} else {
|
||||||
|
clock_generator.set_ms_frequency(clock_generator_output_clkout, portapack::persistent_memory::clkout_freq() * 1000, 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());
|
||||||
|
}
|
||||||
|
@@ -79,6 +79,8 @@ public:
|
|||||||
|
|
||||||
Reference get_reference() const;
|
Reference get_reference() const;
|
||||||
|
|
||||||
|
void enable_clock_output(bool enable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
I2C& i2c0;
|
I2C& i2c0;
|
||||||
si5351::Si5351& clock_generator;
|
si5351::Si5351& clock_generator;
|
||||||
|
@@ -113,7 +113,7 @@ SystemStatusView::SystemStatusView(
|
|||||||
&button_camera,
|
&button_camera,
|
||||||
&button_sleep,
|
&button_sleep,
|
||||||
&button_bias_tee,
|
&button_bias_tee,
|
||||||
&image_clock_status,
|
&button_clock_status,
|
||||||
&sd_card_status_view,
|
&sd_card_status_view,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -168,6 +168,10 @@ SystemStatusView::SystemStatusView(
|
|||||||
DisplaySleepMessage message;
|
DisplaySleepMessage message;
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
button_clock_status.on_select = [this](ImageButton&) {
|
||||||
|
this->on_clk();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemStatusView::refresh() {
|
void SystemStatusView::refresh() {
|
||||||
@@ -188,11 +192,16 @@ void SystemStatusView::refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (portapack::clock_manager.get_reference().source == ClockManager::ReferenceSource::External) {
|
if (portapack::clock_manager.get_reference().source == ClockManager::ReferenceSource::External) {
|
||||||
image_clock_status.set_bitmap(&bitmap_icon_clk_ext);
|
button_clock_status.set_bitmap(&bitmap_icon_clk_ext);
|
||||||
button_bias_tee.set_foreground(ui::Color::green());
|
// button_bias_tee.set_foreground(ui::Color::green()); Typo?
|
||||||
} else {
|
} else {
|
||||||
image_clock_status.set_bitmap(&bitmap_icon_clk_int);
|
button_clock_status.set_bitmap(&bitmap_icon_clk_int);
|
||||||
button_bias_tee.set_foreground(ui::Color::light_grey());
|
// 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();
|
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() {
|
void SystemStatusView::on_title() {
|
||||||
if(nav_.is_top())
|
if(nav_.is_top())
|
||||||
nav_.push<AboutView>();
|
nav_.push<AboutView>();
|
||||||
|
@@ -180,7 +180,7 @@ private:
|
|||||||
Color::dark_grey()
|
Color::dark_grey()
|
||||||
};
|
};
|
||||||
|
|
||||||
Image image_clock_status {
|
ImageButton button_clock_status {
|
||||||
{ 27 * 8, 0 * 16, 2 * 8, 1 * 16 },
|
{ 27 * 8, 0 * 16, 2 * 8, 1 * 16 },
|
||||||
&bitmap_icon_clk_int,
|
&bitmap_icon_clk_int,
|
||||||
Color::light_grey(),
|
Color::light_grey(),
|
||||||
@@ -198,6 +198,7 @@ private:
|
|||||||
void on_camera();
|
void on_camera();
|
||||||
void on_title();
|
void on_title();
|
||||||
void refresh();
|
void refresh();
|
||||||
|
void on_clk();
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_refresh {
|
MessageHandlerRegistration message_handler_refresh {
|
||||||
Message::ID::StatusRefresh,
|
Message::ID::StatusRefresh,
|
||||||
|
@@ -63,6 +63,10 @@ using modem_repeat_range_t = range_t<int32_t>;
|
|||||||
constexpr modem_repeat_range_t modem_repeat_range { 1, 99 };
|
constexpr modem_repeat_range_t modem_repeat_range { 1, 99 };
|
||||||
constexpr int32_t modem_repeat_reset_value { 5 };
|
constexpr int32_t modem_repeat_reset_value { 5 };
|
||||||
|
|
||||||
|
using clkout_freq_range_t = range_t<uint32_t>;
|
||||||
|
constexpr clkout_freq_range_t clkout_freq_range { 10, 60000 };
|
||||||
|
constexpr uint32_t clkout_freq_reset_value { 10000 };
|
||||||
|
|
||||||
/* struct must pack the same way on M4 and M0 cores. */
|
/* struct must pack the same way on M4 and M0 cores. */
|
||||||
struct data_t {
|
struct data_t {
|
||||||
int64_t tuned_frequency;
|
int64_t tuned_frequency;
|
||||||
@@ -287,5 +291,28 @@ void set_pocsag_ignore_address(uint32_t address) {
|
|||||||
data->pocsag_ignore_address = address;
|
data->pocsag_ignore_address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool clkout_enabled() {
|
||||||
|
return (data->ui_config & 0x08000000UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_clkout_enabled(bool enable) {
|
||||||
|
data->ui_config = (data->ui_config & ~0x08000000UL) | (enable << 27);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t clkout_freq() {
|
||||||
|
uint16_t freq = (data->ui_config & 0x000FFFF0) >> 4;
|
||||||
|
if(freq < clkout_freq_range.minimum || freq > clkout_freq_range.maximum) {
|
||||||
|
data->ui_config = (data->ui_config & ~0x000FFFF0) | clkout_freq_reset_value << 4;
|
||||||
|
return clkout_freq_reset_value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_clkout_freq(uint32_t freq) {
|
||||||
|
data->ui_config = (data->ui_config & ~0x000FFFF0) | (clkout_freq_range.clip(freq) << 4);
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace persistent_memory */
|
} /* namespace persistent_memory */
|
||||||
} /* namespace portapack */
|
} /* namespace portapack */
|
||||||
|
@@ -93,6 +93,11 @@ void set_pocsag_last_address(uint32_t address);
|
|||||||
uint32_t pocsag_ignore_address();
|
uint32_t pocsag_ignore_address();
|
||||||
void set_pocsag_ignore_address(uint32_t address);
|
void set_pocsag_ignore_address(uint32_t address);
|
||||||
|
|
||||||
|
bool clkout_enabled();
|
||||||
|
void set_clkout_enabled(bool enable);
|
||||||
|
uint32_t clkout_freq();
|
||||||
|
void set_clkout_freq(uint32_t freq);
|
||||||
|
|
||||||
} /* namespace persistent_memory */
|
} /* namespace persistent_memory */
|
||||||
} /* namespace portapack */
|
} /* namespace portapack */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user