mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-01-07 13:17:40 +00:00
Merge branch 'eried:next' into next
This commit is contained in:
commit
a26ee84ff8
@ -245,13 +245,9 @@ SetUIView::SetUIView(NavigationView& nav) {
|
|||||||
checkbox_showclock.set_value(!persistent_memory::hide_clock());
|
checkbox_showclock.set_value(!persistent_memory::hide_clock());
|
||||||
checkbox_guireturnflag.set_value(persistent_memory::show_gui_return_icon());
|
checkbox_guireturnflag.set_value(persistent_memory::show_gui_return_icon());
|
||||||
|
|
||||||
uint32_t backlight_timer = persistent_memory::config_backlight_timer();
|
const auto backlight_config = persistent_memory::config_backlight_timer();
|
||||||
if (backlight_timer) {
|
checkbox_bloff.set_value(backlight_config.timeout_enabled());
|
||||||
checkbox_bloff.set_value(true);
|
options_bloff.set_by_value(backlight_config.timeout_enum());
|
||||||
options_bloff.set_by_value(backlight_timer);
|
|
||||||
} else {
|
|
||||||
options_bloff.set_selected_index(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (persistent_memory::clock_with_date()) {
|
if (persistent_memory::clock_with_date()) {
|
||||||
options_clockformat.set_selected_index(1);
|
options_clockformat.set_selected_index(1);
|
||||||
@ -261,10 +257,10 @@ SetUIView::SetUIView(NavigationView& nav) {
|
|||||||
|
|
||||||
|
|
||||||
button_save.on_select = [&nav, this](Button&) {
|
button_save.on_select = [&nav, this](Button&) {
|
||||||
if (checkbox_bloff.value())
|
persistent_memory::set_config_backlight_timer({
|
||||||
persistent_memory::set_config_backlight_timer(options_bloff.selected_index() + 1);
|
(persistent_memory::backlight_timeout_t)options_bloff.selected_index_value(),
|
||||||
else
|
checkbox_bloff.value()
|
||||||
persistent_memory::set_config_backlight_timer(0);
|
});
|
||||||
|
|
||||||
if (checkbox_showclock.value()){
|
if (checkbox_showclock.value()){
|
||||||
if (options_clockformat.selected_index() == 1)
|
if (options_clockformat.selected_index() == 1)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "ui_menu.hpp"
|
#include "ui_menu.hpp"
|
||||||
#include "ui_navigation.hpp"
|
#include "ui_navigation.hpp"
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
|
#include "portapack_persistent_memory.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -210,6 +211,8 @@ private:
|
|||||||
SetFrequencyCorrectionModel form_collect();
|
SetFrequencyCorrectionModel form_collect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using portapack::persistent_memory::backlight_timeout_t;
|
||||||
|
|
||||||
class SetUIView : public View {
|
class SetUIView : public View {
|
||||||
public:
|
public:
|
||||||
SetUIView(NavigationView& nav);
|
SetUIView(NavigationView& nav);
|
||||||
@ -241,13 +244,14 @@ private:
|
|||||||
{ 52, 7 * 16 + 8 },
|
{ 52, 7 * 16 + 8 },
|
||||||
20,
|
20,
|
||||||
{
|
{
|
||||||
{ "5 seconds", 5 },
|
{ "5 seconds", backlight_timeout_t::Timeout5Sec },
|
||||||
{ "15 seconds", 15 },
|
{ "15 seconds", backlight_timeout_t::Timeout15Sec },
|
||||||
{ "30 seconds", 30 },
|
{ "30 seconds", backlight_timeout_t::Timeout30Sec },
|
||||||
{ "1 minute", 60 },
|
{ "1 minute", backlight_timeout_t::Timeout60Sec },
|
||||||
{ "3 minutes", 180 },
|
{ "3 minutes", backlight_timeout_t::Timeout180Sec },
|
||||||
{ "5 minutes", 300 },
|
{ "5 minutes", backlight_timeout_t::Timeout300Sec },
|
||||||
{ "10 minutes", 600 }
|
{ "10 minutes", backlight_timeout_t::Timeout600Sec },
|
||||||
|
{ "1 hour", backlight_timeout_t::Timeout3600Sec },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ namespace ui {
|
|||||||
TouchCalibrationView::TouchCalibrationView(
|
TouchCalibrationView::TouchCalibrationView(
|
||||||
NavigationView& nav
|
NavigationView& nav
|
||||||
) : nav { nav },
|
) : nav { nav },
|
||||||
calibration { touch::default_calibration() }
|
calibration { touch::Calibration() }
|
||||||
{
|
{
|
||||||
add_children({
|
add_children({
|
||||||
&image_calibrate_0,
|
&image_calibrate_0,
|
||||||
|
@ -226,15 +226,17 @@ void EventDispatcher::handle_rtc_tick() {
|
|||||||
|
|
||||||
portapack::temperature_logger.second_tick();
|
portapack::temperature_logger.second_tick();
|
||||||
|
|
||||||
uint32_t backlight_timer = portapack::persistent_memory::config_backlight_timer();
|
const auto backlight_timer = portapack::persistent_memory::config_backlight_timer();
|
||||||
if (backlight_timer) {
|
if (backlight_timer.timeout_enabled()) {
|
||||||
if (portapack::bl_tick_counter == backlight_timer)
|
if (portapack::bl_tick_counter == backlight_timer.timeout_seconds())
|
||||||
set_display_sleep(true);
|
set_display_sleep(true);
|
||||||
else
|
else
|
||||||
portapack::bl_tick_counter++;
|
portapack::bl_tick_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_time::on_tick_second();
|
rtc_time::on_tick_second();
|
||||||
|
|
||||||
|
portapack::persistent_memory::cache::persist();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui::Widget* EventDispatcher::touch_widget(ui::Widget* const w, ui::TouchEvent event) {
|
ui::Widget* EventDispatcher::touch_widget(ui::Widget* const w, ui::TouchEvent event) {
|
||||||
|
@ -215,7 +215,7 @@ static int load_config(){
|
|||||||
static Optional<int> config_value;
|
static Optional<int> config_value;
|
||||||
if(!config_value.is_valid()){
|
if(!config_value.is_valid()){
|
||||||
int8_t value = portapack::persistent_memory::config_cpld();
|
int8_t value = portapack::persistent_memory::config_cpld();
|
||||||
if((value <= 0 || value >= 4) && sd_card::status() == sd_card::Status::Mounted){
|
if((value <= 0 || value >= 5) && sd_card::status() == sd_card::Status::Mounted){
|
||||||
int data = read_file("/hardware/settings.txt");
|
int data = read_file("/hardware/settings.txt");
|
||||||
if(data != -1) {
|
if(data != -1) {
|
||||||
config_value = data;
|
config_value = data;
|
||||||
@ -235,14 +235,19 @@ static PortaPackModel portapack_model() {
|
|||||||
const auto switches_state = get_switches_state();
|
const auto switches_state = get_switches_state();
|
||||||
if (switches_state[(size_t)ui::KeyEvent::Up]){
|
if (switches_state[(size_t)ui::KeyEvent::Up]){
|
||||||
save_config(1);
|
save_config(1);
|
||||||
model = PortaPackModel::R2_20170522;
|
// model = PortaPackModel::R2_20170522; // Commented these out as they should be set down below anyway
|
||||||
}
|
}
|
||||||
else if (switches_state[(size_t)ui::KeyEvent::Down]){
|
else if (switches_state[(size_t)ui::KeyEvent::Down]){
|
||||||
save_config(2);
|
save_config(2);
|
||||||
model = PortaPackModel::R1_20150901;
|
// model = PortaPackModel::R1_20150901;
|
||||||
}
|
}
|
||||||
else if (switches_state[(size_t)ui::KeyEvent::Left]){
|
else if (switches_state[(size_t)ui::KeyEvent::Left]){
|
||||||
save_config(3);
|
save_config(3);
|
||||||
|
// model = PortaPackModel::R1_20150901;
|
||||||
|
}
|
||||||
|
else if (switches_state[(size_t)ui::KeyEvent::Right]){
|
||||||
|
save_config(4);
|
||||||
|
// model = PortaPackModel::R2_20170522;
|
||||||
}
|
}
|
||||||
else if (switches_state[(size_t)ui::KeyEvent::Select]){
|
else if (switches_state[(size_t)ui::KeyEvent::Select]){
|
||||||
save_config(0);
|
save_config(0);
|
||||||
@ -253,6 +258,10 @@ static PortaPackModel portapack_model() {
|
|||||||
model = PortaPackModel::R2_20170522;
|
model = PortaPackModel::R2_20170522;
|
||||||
} else if (load_config() == 2) {
|
} else if (load_config() == 2) {
|
||||||
model = PortaPackModel::R1_20150901;
|
model = PortaPackModel::R1_20150901;
|
||||||
|
} else if (load_config() == 3) {
|
||||||
|
model = PortaPackModel::R1_20150901;
|
||||||
|
} else if (load_config() == 4) {
|
||||||
|
model = PortaPackModel::R2_20170522;
|
||||||
} else {
|
} else {
|
||||||
if( audio_codec_wm8731.detected() ) {
|
if( audio_codec_wm8731.detected() ) {
|
||||||
model = PortaPackModel::R1_20150901; // H1R1
|
model = PortaPackModel::R1_20150901; // H1R1
|
||||||
@ -457,6 +466,9 @@ bool init() {
|
|||||||
i2c0.start(i2c_config_fast_clock);
|
i2c0.start(i2c_config_fast_clock);
|
||||||
chThdSleepMilliseconds(10);
|
chThdSleepMilliseconds(10);
|
||||||
|
|
||||||
|
/* Cache some configuration data from persistent memory. */
|
||||||
|
persistent_memory::cache::init();
|
||||||
|
|
||||||
touch::adc::init();
|
touch::adc::init();
|
||||||
controls_init();
|
controls_init();
|
||||||
chThdSleepMilliseconds(10);
|
chThdSleepMilliseconds(10);
|
||||||
@ -475,7 +487,7 @@ bool init() {
|
|||||||
if( !portapack::cpld::update_if_necessary(portapack_cpld_config()) ) {
|
if( !portapack::cpld::update_if_necessary(portapack_cpld_config()) ) {
|
||||||
chThdSleepMilliseconds(10);
|
chThdSleepMilliseconds(10);
|
||||||
// If using a "2021/12 QFP100", press and hold the left button while booting. Should only need to do once.
|
// If using a "2021/12 QFP100", press and hold the left button while booting. Should only need to do once.
|
||||||
if (load_config() != 3){
|
if (load_config() != 3 && load_config() != 4){
|
||||||
shutdown_base();
|
shutdown_base();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,14 @@ struct serial_format_t {
|
|||||||
parity_enum parity;
|
parity_enum parity;
|
||||||
uint8_t stop_bits;
|
uint8_t stop_bits;
|
||||||
order_enum bit_order;
|
order_enum bit_order;
|
||||||
|
|
||||||
|
constexpr serial_format_t() :
|
||||||
|
data_bits(7),
|
||||||
|
parity(parity_enum::EVEN),
|
||||||
|
stop_bits(1),
|
||||||
|
bit_order(order_enum::LSB_FIRST)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t symbol_count(const serial_format_t& serial_format);
|
size_t symbol_count(const serial_format_t& serial_format);
|
||||||
|
@ -76,14 +76,6 @@ ui::Point Calibration::translate(const DigitizerPoint& p) const {
|
|||||||
return { x_clipped, y_clipped };
|
return { x_clipped, y_clipped };
|
||||||
}
|
}
|
||||||
|
|
||||||
const Calibration default_calibration() {
|
|
||||||
/* Values derived from one PortaPack H1 unit. */
|
|
||||||
return {
|
|
||||||
{ { { 256, 731 }, { 880, 432 }, { 568, 146 } } },
|
|
||||||
{ { { 32, 48 }, { 208, 168 }, { 120, 288 } } }
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
void Manager::feed(const Frame& frame) {
|
void Manager::feed(const Frame& frame) {
|
||||||
// touch_debounce.feed(touch_raw);
|
// touch_debounce.feed(touch_raw);
|
||||||
const auto touch_raw = frame.touch;
|
const auto touch_raw = frame.touch;
|
||||||
|
@ -137,6 +137,15 @@ struct Calibration {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr Calibration() :
|
||||||
|
Calibration(
|
||||||
|
/* Values derived from one PortaPack H1 unit. */
|
||||||
|
{ { { 256, 731 }, { 880, 432 }, { 568, 146 } } },
|
||||||
|
{ { { 32, 48 }, { 208, 168 }, { 120, 288 } } }
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ui::Point translate(const DigitizerPoint& p) const;
|
ui::Point translate(const DigitizerPoint& p) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -149,8 +158,6 @@ private:
|
|||||||
int32_t f;
|
int32_t f;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Calibration default_calibration();
|
|
||||||
|
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
class Filter {
|
class Filter {
|
||||||
public:
|
public:
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include "memory_map.hpp"
|
#include "memory_map.hpp"
|
||||||
using portapack::memory::map::backup_ram;
|
|
||||||
|
#include "crc.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -67,8 +68,193 @@ using clkout_freq_range_t = range_t<uint32_t>;
|
|||||||
constexpr clkout_freq_range_t clkout_freq_range { 10, 60000 };
|
constexpr clkout_freq_range_t clkout_freq_range { 10, 60000 };
|
||||||
constexpr uint32_t clkout_freq_reset_value { 10000 };
|
constexpr uint32_t clkout_freq_reset_value { 10000 };
|
||||||
|
|
||||||
|
enum data_structure_version_enum : uint32_t {
|
||||||
|
VERSION_CURRENT = 0x10000002,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t TOUCH_CALIBRATION_MAGIC = 0x074af82f;
|
||||||
|
|
||||||
|
struct ui_config_t {
|
||||||
|
private:
|
||||||
|
enum bits_t {
|
||||||
|
BacklightTimeoutLSB = 0,
|
||||||
|
BacklightTimeoutEnable = 3,
|
||||||
|
ClkoutFreqLSB = 4,
|
||||||
|
ShowGUIReturnIcon = 20,
|
||||||
|
LoadAppSettings = 21,
|
||||||
|
SaveAppSettings = 22,
|
||||||
|
ShowBiggerQRCode = 23,
|
||||||
|
DisableTouchscreen = 24,
|
||||||
|
HideClock = 25,
|
||||||
|
ClockWithDate = 26,
|
||||||
|
ClkOutEnabled = 27,
|
||||||
|
ConfigSpeaker = 28,
|
||||||
|
StealthMode = 29,
|
||||||
|
ConfigLogin = 30,
|
||||||
|
ConfigSplash = 31,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bits_mask_t : uint32_t {
|
||||||
|
BacklightTimeoutMask = ((1 << 3) - 1) << bits_t::BacklightTimeoutLSB,
|
||||||
|
ClkoutFreqMask = ((1 << 16) - 1) << bits_t::ClkoutFreqLSB,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t values;
|
||||||
|
|
||||||
|
constexpr bool bit_read(const bits_t n) const {
|
||||||
|
return ((values >> n) & 1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void bit_write(const bits_t n, const bool v) {
|
||||||
|
if(bit_read(n) != v) {
|
||||||
|
values ^= 1 << n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
backlight_config_t config_backlight_timer() {
|
||||||
|
const auto timeout_enum = (backlight_timeout_t)((values & bits_mask_t::BacklightTimeoutMask) >> bits_t::BacklightTimeoutLSB);
|
||||||
|
const bool timeout_enabled = bit_read(bits_t::BacklightTimeoutEnable);
|
||||||
|
return backlight_config_t(timeout_enum, timeout_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_config_backlight_timer(const backlight_config_t& new_value) {
|
||||||
|
values = (values & ~bits_mask_t::BacklightTimeoutMask)
|
||||||
|
| ((new_value.timeout_enum() << bits_t::BacklightTimeoutLSB) & bits_mask_t::BacklightTimeoutMask);
|
||||||
|
bit_write(bits_t::BacklightTimeoutEnable, new_value.timeout_enabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr uint32_t clkout_freq() {
|
||||||
|
uint32_t freq = (values & bits_mask_t::ClkoutFreqMask) >> bits_t::ClkoutFreqLSB;
|
||||||
|
if(freq < clkout_freq_range.minimum || freq > clkout_freq_range.maximum) {
|
||||||
|
values = (values & ~bits_mask_t::ClkoutFreqMask) | (clkout_freq_reset_value << bits_t::ClkoutFreqLSB);
|
||||||
|
return clkout_freq_reset_value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_clkout_freq(uint32_t freq) {
|
||||||
|
values = (values & ~bits_mask_t::ClkoutFreqMask) | (clkout_freq_range.clip(freq) << bits_t::ClkoutFreqLSB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ui_config is an uint32_t var storing information bitwise
|
||||||
|
// bits 0-2 store the backlight timer
|
||||||
|
// bits 4-19 (16 bits) store the clkout frequency
|
||||||
|
// bits 21-31 store the different single bit configs depicted below
|
||||||
|
// bit 20 store the display state of the gui return icon, hidden (0) or shown (1)
|
||||||
|
|
||||||
|
constexpr bool show_gui_return_icon() const { // add return icon in touchscreen menue
|
||||||
|
return bit_read(bits_t::ShowGUIReturnIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_gui_return_icon(bool v) {
|
||||||
|
bit_write(bits_t::ShowGUIReturnIcon, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool load_app_settings() const { // load (last saved) app settings on startup of app
|
||||||
|
return bit_read(bits_t::LoadAppSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_load_app_settings(bool v) {
|
||||||
|
bit_write(bits_t::LoadAppSettings, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool save_app_settings() const { // save app settings when closing app
|
||||||
|
return bit_read(bits_t::SaveAppSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_save_app_settings(bool v) {
|
||||||
|
bit_write(bits_t::SaveAppSettings, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool show_bigger_qr_code() const { // show bigger QR code
|
||||||
|
return bit_read(bits_t::ShowBiggerQRCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_show_bigger_qr_code(bool v) {
|
||||||
|
bit_write(bits_t::ShowBiggerQRCode, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool disable_touchscreen() const { // Option to disable touch screen
|
||||||
|
return bit_read(bits_t::DisableTouchscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_disable_touchscreen(bool v) {
|
||||||
|
bit_write(bits_t::DisableTouchscreen, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool hide_clock() const { // clock hidden from main menu
|
||||||
|
return bit_read(bits_t::HideClock);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_clock_hidden(bool v) {
|
||||||
|
bit_write(bits_t::HideClock, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool clock_with_date() const { // show clock with date, if not hidden
|
||||||
|
return bit_read(bits_t::ClockWithDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_clock_with_date(bool v) {
|
||||||
|
bit_write(bits_t::ClockWithDate, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool clkout_enabled() const {
|
||||||
|
return bit_read(bits_t::ClkOutEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_clkout_enabled(bool v) {
|
||||||
|
bit_write(bits_t::ClkOutEnabled, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool config_speaker() const {
|
||||||
|
return bit_read(bits_t::ConfigSpeaker);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_config_speaker(bool v) {
|
||||||
|
bit_write(bits_t::ConfigSpeaker, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool stealth_mode() const {
|
||||||
|
return bit_read(bits_t::StealthMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_stealth_mode(bool v) {
|
||||||
|
bit_write(bits_t::StealthMode, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool config_login() const {
|
||||||
|
return bit_read(bits_t::ConfigLogin);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_config_login(bool v) {
|
||||||
|
bit_write(bits_t::ConfigLogin, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool config_splash() const {
|
||||||
|
return bit_read(bits_t::ConfigSplash);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_config_splash(bool v) {
|
||||||
|
bit_write(bits_t::ConfigSplash, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ui_config_t() :
|
||||||
|
values(
|
||||||
|
(1 << ConfigSplash)
|
||||||
|
| (1 << ConfigSpeaker)
|
||||||
|
| (clkout_freq_reset_value << ClkoutFreqLSB)
|
||||||
|
| (7 << BacklightTimeoutLSB)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* 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 {
|
||||||
|
data_structure_version_enum structure_version;
|
||||||
int64_t tuned_frequency;
|
int64_t tuned_frequency;
|
||||||
int32_t correction_ppb;
|
int32_t correction_ppb;
|
||||||
uint32_t touch_calibration_magic;
|
uint32_t touch_calibration_magic;
|
||||||
@ -89,7 +275,7 @@ struct data_t {
|
|||||||
uint32_t playdead_sequence;
|
uint32_t playdead_sequence;
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
uint32_t ui_config;
|
ui_config_t ui_config;
|
||||||
|
|
||||||
uint32_t pocsag_last_address;
|
uint32_t pocsag_last_address;
|
||||||
uint32_t pocsag_ignore_address;
|
uint32_t pocsag_ignore_address;
|
||||||
@ -98,11 +284,142 @@ struct data_t {
|
|||||||
|
|
||||||
// Hardware
|
// Hardware
|
||||||
uint32_t hardware_config;
|
uint32_t hardware_config;
|
||||||
|
|
||||||
|
constexpr data_t() :
|
||||||
|
structure_version(data_structure_version_enum::VERSION_CURRENT),
|
||||||
|
tuned_frequency(tuned_frequency_reset_value),
|
||||||
|
correction_ppb(ppb_reset_value),
|
||||||
|
touch_calibration_magic(TOUCH_CALIBRATION_MAGIC),
|
||||||
|
touch_calibration(touch::Calibration()),
|
||||||
|
|
||||||
|
modem_def_index(0), // TODO: Unused?
|
||||||
|
serial_format(),
|
||||||
|
modem_bw(15000), // TODO: Unused?
|
||||||
|
afsk_mark_freq(afsk_mark_reset_value),
|
||||||
|
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?
|
||||||
|
|
||||||
|
ui_config(),
|
||||||
|
|
||||||
|
pocsag_last_address(0), // TODO: A better default?
|
||||||
|
pocsag_ignore_address(0), // TODO: A better default?
|
||||||
|
|
||||||
|
tone_mix(tone_mix_reset_value),
|
||||||
|
|
||||||
|
hardware_config(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(data_t) <= backup_ram.size(), "Persistent memory structure too large for VBAT-maintained region");
|
struct backup_ram_t {
|
||||||
|
private:
|
||||||
|
uint32_t regfile[63];
|
||||||
|
uint32_t check_value;
|
||||||
|
|
||||||
static data_t* const data = reinterpret_cast<data_t*>(backup_ram.base());
|
static void copy(const backup_ram_t& src, backup_ram_t& dst) {
|
||||||
|
for(size_t i=0; i<63; i++) {
|
||||||
|
dst.regfile[i] = src.regfile[i];
|
||||||
|
}
|
||||||
|
dst.check_value = src.check_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_from_data_t(const data_t& src, backup_ram_t& dst) {
|
||||||
|
const uint32_t* const src_words = (uint32_t*)&src;
|
||||||
|
const size_t word_count = (sizeof(data_t) + 3) / 4;
|
||||||
|
for(size_t i=0; i<63; i++) {
|
||||||
|
if(i<word_count) {
|
||||||
|
dst.regfile[i] = src_words[i];
|
||||||
|
} else {
|
||||||
|
dst.regfile[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t compute_check_value() {
|
||||||
|
CRC<32> crc { 0x04c11db7, 0xffffffff, 0xffffffff };
|
||||||
|
for(size_t i=0; i<63; i++) {
|
||||||
|
const auto word = regfile[i];
|
||||||
|
crc.process_byte((word >> 0) & 0xff);
|
||||||
|
crc.process_byte((word >> 8) & 0xff);
|
||||||
|
crc.process_byte((word >> 16) & 0xff);
|
||||||
|
crc.process_byte((word >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
return crc.checksum();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* default constructor */
|
||||||
|
backup_ram_t() :
|
||||||
|
check_value(0)
|
||||||
|
{
|
||||||
|
const data_t defaults = data_t();
|
||||||
|
copy_from_data_t(defaults, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy-assignment operator */
|
||||||
|
backup_ram_t& operator=(const backup_ram_t& src) {
|
||||||
|
copy(src, *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate a check value from `this`, and check against
|
||||||
|
* the stored value.
|
||||||
|
*/
|
||||||
|
bool is_valid() {
|
||||||
|
return compute_check_value() == check_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assuming `this` contains valid data, update the checksum
|
||||||
|
* and copy to the destination.
|
||||||
|
*/
|
||||||
|
void persist_to(backup_ram_t& dst) {
|
||||||
|
check_value = compute_check_value();
|
||||||
|
copy(*this, dst);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(backup_ram_t) == memory::map::backup_ram.size());
|
||||||
|
static_assert(sizeof(data_t) <= sizeof(backup_ram_t) - sizeof(uint32_t));
|
||||||
|
|
||||||
|
static backup_ram_t* const backup_ram = reinterpret_cast<backup_ram_t*>(memory::map::backup_ram.base());
|
||||||
|
|
||||||
|
static backup_ram_t cached_backup_ram;
|
||||||
|
static data_t* const data = reinterpret_cast<data_t*>(&cached_backup_ram);
|
||||||
|
|
||||||
|
namespace cache {
|
||||||
|
|
||||||
|
void defaults() {
|
||||||
|
cached_backup_ram = backup_ram_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
if(backup_ram->is_valid()) {
|
||||||
|
// Copy valid persistent data into cache.
|
||||||
|
cached_backup_ram = *backup_ram;
|
||||||
|
|
||||||
|
// Check that structure data we copied into cache is the expected
|
||||||
|
// version. If not, initialize cache to defaults.
|
||||||
|
if(data->structure_version != data_structure_version_enum::VERSION_CURRENT) {
|
||||||
|
// TODO: Can provide version-to-version upgrade functions here,
|
||||||
|
// if we want to be fancy.
|
||||||
|
defaults();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Copy defaults into cache.
|
||||||
|
defaults();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void persist() {
|
||||||
|
cached_backup_ram.persist_to(*backup_ram);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace cache */
|
||||||
|
|
||||||
rf::Frequency tuned_frequency() {
|
rf::Frequency tuned_frequency() {
|
||||||
rf::tuning_range.reset_if_outside(data->tuned_frequency, tuned_frequency_reset_value);
|
rf::tuning_range.reset_if_outside(data->tuned_frequency, tuned_frequency_reset_value);
|
||||||
@ -124,16 +441,14 @@ void set_correction_ppb(const ppb_t new_value) {
|
|||||||
portapack::clock_manager.set_reference_ppb(clipped_value);
|
portapack::clock_manager.set_reference_ppb(clipped_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t touch_calibration_magic = 0x074af82f;
|
|
||||||
|
|
||||||
void set_touch_calibration(const touch::Calibration& new_value) {
|
void set_touch_calibration(const touch::Calibration& new_value) {
|
||||||
data->touch_calibration = new_value;
|
data->touch_calibration = new_value;
|
||||||
data->touch_calibration_magic = touch_calibration_magic;
|
data->touch_calibration_magic = TOUCH_CALIBRATION_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
const touch::Calibration& touch_calibration() {
|
const touch::Calibration& touch_calibration() {
|
||||||
if( data->touch_calibration_magic != touch_calibration_magic ) {
|
if( data->touch_calibration_magic != TOUCH_CALIBRATION_MAGIC ) {
|
||||||
set_touch_calibration(touch::default_calibration());
|
set_touch_calibration(touch::Calibration());
|
||||||
}
|
}
|
||||||
return data->touch_calibration;
|
return data->touch_calibration;
|
||||||
}
|
}
|
||||||
@ -200,122 +515,116 @@ void set_serial_format(const serial_format_t new_value) {
|
|||||||
data->serial_format = new_value;
|
data->serial_format = new_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ui_config is an uint32_t var storing information bitwise
|
|
||||||
// bits 0-2 store the backlight timer
|
|
||||||
// bits 4-19 (16 bits) store the clkout frequency
|
|
||||||
// bits 21-31 store the different single bit configs depicted below
|
|
||||||
// bit 20 store the display state of the gui return icon, hidden (0) or shown (1)
|
|
||||||
|
|
||||||
bool show_gui_return_icon() { // add return icon in touchscreen menue
|
bool show_gui_return_icon() { // add return icon in touchscreen menue
|
||||||
return data->ui_config & (1 << 20);
|
return data->ui_config.show_gui_return_icon();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_app_settings() { // load (last saved) app settings on startup of app
|
bool load_app_settings() { // load (last saved) app settings on startup of app
|
||||||
return data->ui_config & (1 << 21);
|
return data->ui_config.load_app_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool save_app_settings() { // save app settings when closing app
|
bool save_app_settings() { // save app settings when closing app
|
||||||
return data->ui_config & (1 << 22);
|
return data->ui_config.save_app_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool show_bigger_qr_code() { // show bigger QR code
|
bool show_bigger_qr_code() { // show bigger QR code
|
||||||
return data->ui_config & (1 << 23);
|
return data->ui_config.show_bigger_qr_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool disable_touchscreen() { // Option to disable touch screen
|
bool disable_touchscreen() { // Option to disable touch screen
|
||||||
return data->ui_config & (1 << 24);
|
return data->ui_config.disable_touchscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hide_clock() { // clock hidden from main menu
|
bool hide_clock() { // clock hidden from main menu
|
||||||
return data->ui_config & (1 << 25);
|
return data->ui_config.hide_clock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clock_with_date() { // show clock with date, if not hidden
|
bool clock_with_date() { // show clock with date, if not hidden
|
||||||
return data->ui_config & (1 << 26);
|
return data->ui_config.clock_with_date();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clkout_enabled() {
|
bool clkout_enabled() {
|
||||||
return data->ui_config & (1 << 27);
|
return data->ui_config.clkout_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool config_speaker() {
|
bool config_speaker() {
|
||||||
return data->ui_config & (1 << 28);
|
return data->ui_config.config_speaker();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stealth_mode() {
|
bool stealth_mode() {
|
||||||
return data->ui_config & (1 << 29);
|
return data->ui_config.stealth_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool config_login() {
|
bool config_login() {
|
||||||
return data->ui_config & (1 << 30);
|
return data->ui_config.config_login();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool config_splash() {
|
bool config_splash() {
|
||||||
return data->ui_config & (1 << 31);
|
return data->ui_config.config_splash();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t config_cpld() {
|
uint8_t config_cpld() {
|
||||||
return data->hardware_config;
|
return data->hardware_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t config_backlight_timer() {
|
backlight_config_t config_backlight_timer() {
|
||||||
const uint32_t timer_seconds[8] = { 0, 5, 15, 30, 60, 180, 300, 600 };
|
return data->ui_config.config_backlight_timer();
|
||||||
return timer_seconds[data->ui_config & 7]; //first three bits, 8 possible values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_gui_return_icon(bool v) {
|
void set_gui_return_icon(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 20)) | (v << 20);
|
data->ui_config.set_gui_return_icon(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_load_app_settings(bool v) {
|
void set_load_app_settings(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 21)) | (v << 21);
|
data->ui_config.set_load_app_settings(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_save_app_settings(bool v) {
|
void set_save_app_settings(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 22)) | (v << 22);
|
data->ui_config.set_save_app_settings(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_show_bigger_qr_code(bool v) {
|
void set_show_bigger_qr_code(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 23)) | (v << 23);
|
data->ui_config.set_show_bigger_qr_code(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_disable_touchscreen(bool v) {
|
void set_disable_touchscreen(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 24)) | (v << 24);
|
data->ui_config.set_disable_touchscreen(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_clock_hidden(bool v) {
|
void set_clock_hidden(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 25)) | (v << 25);
|
data->ui_config.set_clock_hidden(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_clock_with_date(bool v) {
|
void set_clock_with_date(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 26)) | (v << 26);
|
data->ui_config.set_clock_with_date(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_clkout_enabled(bool v) {
|
void set_clkout_enabled(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 27)) | (v << 27);
|
data->ui_config.set_clkout_enabled(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config_speaker(bool v) {
|
void set_config_speaker(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 28)) | (v << 28);
|
data->ui_config.set_config_speaker(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_stealth_mode(bool v) {
|
void set_stealth_mode(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 29)) | (v << 29);
|
data->ui_config.set_stealth_mode(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config_login(bool v) {
|
void set_config_login(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 30)) | (v << 30);
|
data->ui_config.set_config_login(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config_splash(bool v) {
|
void set_config_splash(bool v) {
|
||||||
data->ui_config = (data->ui_config & ~(1 << 31)) | (v << 31);
|
data->ui_config.set_config_splash(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config_cpld(uint8_t i) {
|
void set_config_cpld(uint8_t i) {
|
||||||
data->hardware_config = i;
|
data->hardware_config = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config_backlight_timer(uint32_t i) {
|
void set_config_backlight_timer(const backlight_config_t& new_value) {
|
||||||
data->ui_config = (data->ui_config & ~7) | (i & 7);
|
data->ui_config.set_config_backlight_timer(new_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void set_config_textentry(uint8_t new_value) {
|
/*void set_config_textentry(uint8_t new_value) {
|
||||||
@ -347,18 +656,11 @@ void set_pocsag_ignore_address(uint32_t address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t clkout_freq() {
|
uint32_t clkout_freq() {
|
||||||
uint16_t freq = (data->ui_config & 0x000FFFF0) >> 4;
|
return data->ui_config.clkout_freq();
|
||||||
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) {
|
void set_clkout_freq(uint32_t freq) {
|
||||||
data->ui_config = (data->ui_config & ~0x000FFFF0) | (clkout_freq_range.clip(freq) << 4);
|
data->ui_config.set_clkout_freq(freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "optional.hpp"
|
||||||
|
|
||||||
#include "rf_path.hpp"
|
#include "rf_path.hpp"
|
||||||
#include "touch.hpp"
|
#include "touch.hpp"
|
||||||
#include "modems.hpp"
|
#include "modems.hpp"
|
||||||
@ -36,6 +38,77 @@ using namespace serializer;
|
|||||||
namespace portapack {
|
namespace portapack {
|
||||||
namespace persistent_memory {
|
namespace persistent_memory {
|
||||||
|
|
||||||
|
enum backlight_timeout_t {
|
||||||
|
Timeout5Sec = 0,
|
||||||
|
Timeout15Sec = 1,
|
||||||
|
Timeout30Sec = 2,
|
||||||
|
Timeout60Sec = 3,
|
||||||
|
Timeout180Sec = 4,
|
||||||
|
Timeout300Sec = 5,
|
||||||
|
Timeout600Sec = 6,
|
||||||
|
Timeout3600Sec = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct backlight_config_t {
|
||||||
|
public:
|
||||||
|
backlight_config_t() :
|
||||||
|
_timeout_enum(backlight_timeout_t::Timeout600Sec),
|
||||||
|
_timeout_enabled(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
backlight_config_t(
|
||||||
|
backlight_timeout_t timeout_enum,
|
||||||
|
bool timeout_enabled
|
||||||
|
) :
|
||||||
|
_timeout_enum(timeout_enum),
|
||||||
|
_timeout_enabled(timeout_enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool timeout_enabled() const {
|
||||||
|
return _timeout_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
backlight_timeout_t timeout_enum() const {
|
||||||
|
return _timeout_enum;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t timeout_seconds() const {
|
||||||
|
switch(timeout_enum()) {
|
||||||
|
case Timeout5Sec: return 5;
|
||||||
|
case Timeout15Sec: return 15;
|
||||||
|
case Timeout30Sec: return 30;
|
||||||
|
case Timeout60Sec: return 60;
|
||||||
|
case Timeout180Sec: return 180;
|
||||||
|
case Timeout300Sec: return 300;
|
||||||
|
default:
|
||||||
|
case Timeout600Sec: return 600;
|
||||||
|
case Timeout3600Sec: return 3600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
backlight_timeout_t _timeout_enum;
|
||||||
|
bool _timeout_enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace cache {
|
||||||
|
|
||||||
|
/* Set values in cache to sensible defaults. */
|
||||||
|
void defaults();
|
||||||
|
|
||||||
|
/* Load cached settings from values in persistent RAM, replacing with defaults
|
||||||
|
* if persistent RAM contents appear to be invalid. */
|
||||||
|
void init();
|
||||||
|
|
||||||
|
/* Calculate a check value for cached settings, and copy the check value and
|
||||||
|
* settings into persistent RAM. Intended to be called periodically to update
|
||||||
|
* persistent settings with current settings. */
|
||||||
|
void persist();
|
||||||
|
|
||||||
|
} /* namespace cache */
|
||||||
|
|
||||||
using ppb_t = int32_t;
|
using ppb_t = int32_t;
|
||||||
|
|
||||||
rf::Frequency tuned_frequency();
|
rf::Frequency tuned_frequency();
|
||||||
@ -86,7 +159,7 @@ bool hide_clock();
|
|||||||
bool clock_with_date();
|
bool clock_with_date();
|
||||||
bool config_login();
|
bool config_login();
|
||||||
bool config_speaker();
|
bool config_speaker();
|
||||||
uint32_t config_backlight_timer();
|
backlight_config_t config_backlight_timer();
|
||||||
bool disable_touchscreen();
|
bool disable_touchscreen();
|
||||||
|
|
||||||
void set_gui_return_icon(bool v);
|
void set_gui_return_icon(bool v);
|
||||||
@ -98,7 +171,7 @@ void set_clock_hidden(bool v);
|
|||||||
void set_clock_with_date(bool v);
|
void set_clock_with_date(bool v);
|
||||||
void set_config_login(bool v);
|
void set_config_login(bool v);
|
||||||
void set_config_speaker(bool v);
|
void set_config_speaker(bool v);
|
||||||
void set_config_backlight_timer(uint32_t i);
|
void set_config_backlight_timer(const backlight_config_t& new_value);
|
||||||
void set_disable_touchscreen(bool v);
|
void set_disable_touchscreen(bool v);
|
||||||
|
|
||||||
//uint8_t ui_config_textentry();
|
//uint8_t ui_config_textentry();
|
||||||
|
@ -95,27 +95,27 @@ struct range_t {
|
|||||||
const T minimum;
|
const T minimum;
|
||||||
const T maximum;
|
const T maximum;
|
||||||
|
|
||||||
const T& clip(const T& value) const {
|
constexpr const T& clip(const T& value) const {
|
||||||
return std::max(std::min(value, maximum), minimum);
|
return std::max(std::min(value, maximum), minimum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_if_outside(T& value, const T& reset_value) const {
|
constexpr void reset_if_outside(T& value, const T& reset_value) const {
|
||||||
if( (value < minimum ) ||
|
if( (value < minimum ) ||
|
||||||
(value > maximum ) ) {
|
(value > maximum ) ) {
|
||||||
value = reset_value;
|
value = reset_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool below_range(const T& value) const {
|
constexpr bool below_range(const T& value) const {
|
||||||
return value < minimum;
|
return value < minimum;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains(const T& value) const {
|
constexpr bool contains(const T& value) const {
|
||||||
// TODO: Subtle gotcha here! Range test doesn't include maximum!
|
// TODO: Subtle gotcha here! Range test doesn't include maximum!
|
||||||
return (value >= minimum) && (value < maximum);
|
return (value >= minimum) && (value < maximum);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool out_of_range(const T& value) const {
|
constexpr bool out_of_range(const T& value) const {
|
||||||
// TODO: Subtle gotcha here! Range test in contains() doesn't include maximum!
|
// TODO: Subtle gotcha here! Range test in contains() doesn't include maximum!
|
||||||
return !contains(value);
|
return !contains(value);
|
||||||
}
|
}
|
||||||
|
2
hackrf
2
hackrf
@ -1 +1 @@
|
|||||||
Subproject commit e6eb4ba29bbe5dc2fcd092e394188bc10a8bad54
|
Subproject commit dfadf6a31c5f5f9817f84f1d28c63243698f7299
|
Loading…
x
Reference in New Issue
Block a user