mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-22 15:39:04 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15f3d81798 | |||
| fa2791004f | |||
| 50bd08d9ff | |||
| 39134b62c3 | |||
| e5a30b4309 | |||
| 2031a79b34 | |||
| deff646e36 | |||
| 4aa3314906 | |||
| e3da9d4cb2 | |||
| 2f10fe2fe4 | |||
| 5a7b12f920 | |||
| f8a4134973 | |||
| a3ee160e27 | |||
| ade0d6c68f | |||
| 8e9355b57a | |||
| e97ffd42ef | |||
| cccc92cc34 | |||
| 3387b59eab | |||
| 6c5f8a38e0 |
@@ -1,12 +1,18 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
about: Create a report to help us improve the software
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
----
|
||||
|
||||
(Please try the latest nightly release before submitting this. You can find the latest nightly verison here: https://github.com/eried/portapack-mayhem/releases)
|
||||
|
||||
----
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
@@ -21,9 +27,9 @@ A clear and concise description of what you expected to happen.
|
||||
|
||||
**Affected versions**
|
||||
Please write any difference related with the Expected behavior, on the following versions:
|
||||
* Latest Stable Release
|
||||
* Previous one (if any) that did not presented the issue
|
||||
* Old versions available here: https://github.com/eried/Research/tree/master/HackRF/PortaPack/old_legacy_firmware
|
||||
* Latest Stable release:
|
||||
* Latest Nightly release:
|
||||
* Previous working release:
|
||||
|
||||
**Additional**
|
||||
If the bug is difficult to explain, additionally to the text please include images and videos.
|
||||
|
||||
@@ -1,18 +1,39 @@
|
||||
---
|
||||
name: Problem upgrading the firmware
|
||||
about: Deal with the firmware upgrade problems
|
||||
title: Problem upgrading the firmware
|
||||
labels: ''
|
||||
name: Problem upgrading the firmware or booting
|
||||
about: If you are having firmware upgrade or booting problems
|
||||
title: ''
|
||||
labels: 'firmware'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**What is happening?**
|
||||
Describe here why you are unable to upgrade the firmware. Before describing your problems, **do the following**:
|
||||
----
|
||||
Before creating this issue, **do the following**:
|
||||
* Read the Wiki on booting: https://github.com/eried/portapack-mayhem/wiki/Won't-boot
|
||||
* Read: https://github.com/eried/portapack-havoc/wiki/Update-firmware
|
||||
* Watch carefully: https://www.youtube.com/watch?v=_zx4ZvurgOs
|
||||
* (if you are not in Windows) also check: https://www.youtube.com/watch?v=kjFB58Y1TAo
|
||||
|
||||
----
|
||||
|
||||
**Describe the issue**
|
||||
A clear and concise description of what the issue you are facing is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Tap on '....'
|
||||
|
||||
|
||||
**My Hardware**
|
||||
Please specify what PortaPack hardware version you are using.
|
||||
You can find the list of versions here: https://github.com/eried/portapack-mayhem/wiki/PortaPack-Versions
|
||||
|
||||
**Affected versions**
|
||||
Please tell us what version you are running.
|
||||
Also please try the latest nightly release before submitting this.
|
||||
You can find the latest nightly version here https://github.com/eried/portapack-mayhem/releases
|
||||
|
||||
**Were you able to update the firmware before?**
|
||||
Things might be confusing the first time, please check the video available on the link above.
|
||||
|
||||
@@ -20,4 +41,4 @@ Things might be confusing the first time, please check the video available on th
|
||||
If is possible, swap hardware and try again. Also, try different USB cables, even if the one you are using works fine for other purposes.
|
||||
|
||||
**Additional**
|
||||
Add photos and videos of your procedure.
|
||||
If the issue is difficult to explain, additionally to the text please include images and videos.
|
||||
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: v1.5.1
|
||||
tag_name: ${{ steps.version.outputs.version }}
|
||||
release_name: Mayhem firmware ${{ steps.version.outputs.version }}
|
||||
body: |
|
||||
**Stable release - ${{ steps.version.outputs.version }}**
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.5.0
|
||||
v1.5.3
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.5.1
|
||||
v1.5.4
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
@@ -27,56 +27,30 @@
|
||||
#include "portapack.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
namespace std {
|
||||
|
||||
int app_settings::load(std::string application, AppSettings* settings){
|
||||
int app_settings::load(std::string application, AppSettings* settings) {
|
||||
|
||||
if (portapack::persistent_memory::load_app_settings()) {
|
||||
file_path = folder+"/"+application+".ini";
|
||||
|
||||
auto error = settings_file.open(file_path);
|
||||
if (!error.is_valid()) {
|
||||
auto error = settings_file.read(file_content, 256);
|
||||
|
||||
// Retrieve settings
|
||||
auto position1 = strstr(file_content, "baseband_bandwidth=");
|
||||
if (position1) {
|
||||
position1 += 19;
|
||||
settings->baseband_bandwidth=strtoll(position1, nullptr, 10);
|
||||
}
|
||||
|
||||
auto position2 = strstr(file_content, "rx_frequency=");
|
||||
if (position2) {
|
||||
position2 += 13;
|
||||
settings->rx_frequency=strtoll(position2, nullptr, 10);
|
||||
}
|
||||
|
||||
auto position3 = strstr(file_content, "lna=");
|
||||
if (position3) {
|
||||
position3 += 4;
|
||||
settings->lna=strtoll(position3, nullptr, 10);
|
||||
}
|
||||
|
||||
auto position4 = strstr(file_content, "rx_amp=");
|
||||
if (position4) {
|
||||
position4 += 7;
|
||||
settings->rx_amp=strtoll(position4, nullptr, 10);
|
||||
}
|
||||
|
||||
auto position5 = strstr(file_content, "sampling_rate=");
|
||||
if (position5) {
|
||||
position5 += 13;
|
||||
settings->sampling_rate=strtoll(position5, nullptr, 10);
|
||||
}
|
||||
|
||||
|
||||
auto position6 = strstr(file_content, "vga=");
|
||||
if (position6) {
|
||||
position6 += 4;
|
||||
settings->vga=strtoll(position6, nullptr, 10);
|
||||
}
|
||||
auto error = settings_file.read(file_content, std::min((int)settings_file.size(), MAX_FILE_CONTENT_SIZE));
|
||||
|
||||
settings->baseband_bandwidth=std::app_settings::read_long_long(file_content, "baseband_bandwidth=");
|
||||
settings->channel_bandwidth=std::app_settings::read_long_long(file_content, "channel_bandwidth=");
|
||||
settings->lna=std::app_settings::read_long_long(file_content, "lna=");
|
||||
settings->modulation=std::app_settings::read_long_long(file_content, "modulation=");
|
||||
settings->rx_amp=std::app_settings::read_long_long(file_content, "rx_amp=");
|
||||
settings->rx_frequency=std::app_settings::read_long_long(file_content, "rx_frequency=");
|
||||
settings->sampling_rate=std::app_settings::read_long_long(file_content, "sampling_rate=");
|
||||
settings->vga=std::app_settings::read_long_long(file_content, "vga=");
|
||||
settings->tx_amp=std::app_settings::read_long_long(file_content, "tx_amp=");
|
||||
settings->tx_frequency=std::app_settings::read_long_long(file_content, "tx_frequency=");
|
||||
settings->tx_gain=std::app_settings::read_long_long(file_content, "tx_gain=");
|
||||
rc = SETTINGS_OK;
|
||||
}
|
||||
else rc = SETTINGS_UNABLE_TO_LOAD;
|
||||
@@ -85,7 +59,7 @@ int app_settings::load(std::string application, AppSettings* settings){
|
||||
return(rc);
|
||||
}
|
||||
|
||||
int app_settings::save(std::string application, AppSettings* settings){
|
||||
int app_settings::save(std::string application, AppSettings* settings) {
|
||||
|
||||
if (portapack::persistent_memory::save_app_settings()) {
|
||||
file_path = folder+"/"+application+".ini";
|
||||
@@ -95,12 +69,16 @@ int app_settings::save(std::string application, AppSettings* settings){
|
||||
if (!error.is_valid()) {
|
||||
// Save common setting
|
||||
settings_file.write_line("baseband_bandwidth="+to_string_dec_uint(portapack::receiver_model.baseband_bandwidth()));
|
||||
settings_file.write_line("channel_bandwidth="+to_string_dec_uint(portapack::transmitter_model.channel_bandwidth()));
|
||||
settings_file.write_line("lna="+to_string_dec_uint(portapack::receiver_model.lna()));
|
||||
settings_file.write_line("rx_amp="+to_string_dec_uint(portapack::receiver_model.rf_amp()));
|
||||
settings_file.write_line("sampling_rate="+to_string_dec_uint(portapack::receiver_model.sampling_rate()));
|
||||
settings_file.write_line("tx_amp="+to_string_dec_uint(portapack::transmitter_model.rf_amp()));
|
||||
settings_file.write_line("tx_gain="+to_string_dec_uint(portapack::transmitter_model.tx_gain()));
|
||||
settings_file.write_line("vga="+to_string_dec_uint(portapack::receiver_model.vga()));
|
||||
// Save other settings from struct
|
||||
settings_file.write_line("rx_frequency="+to_string_dec_uint(settings->rx_frequency));
|
||||
settings_file.write_line("tx_frequency="+to_string_dec_uint(settings->tx_frequency));
|
||||
|
||||
rc = SETTINGS_OK;
|
||||
}
|
||||
@@ -110,4 +88,15 @@ int app_settings::save(std::string application, AppSettings* settings){
|
||||
return(rc);
|
||||
}
|
||||
|
||||
|
||||
long long int app_settings::read_long_long(char* file_content, const char* setting_text) {
|
||||
auto position = strstr(file_content, (char *)setting_text);
|
||||
if (position) {
|
||||
position += strlen((char *)setting_text);
|
||||
setting_value = strtoll(position, nullptr, 10);
|
||||
}
|
||||
return(setting_value);
|
||||
}
|
||||
|
||||
|
||||
} /* namespace std */
|
||||
|
||||
@@ -46,13 +46,18 @@ public:
|
||||
#define SETTINGS_DISABLED -3 // load/save settings disabled in settings
|
||||
|
||||
|
||||
// store settings that can't be set directly, but have to be stored in app
|
||||
|
||||
struct AppSettings {
|
||||
uint32_t baseband_bandwidth;
|
||||
uint32_t channel_bandwidth;
|
||||
uint8_t lna;
|
||||
uint8_t modulation;
|
||||
uint8_t rx_amp;
|
||||
uint32_t rx_frequency;
|
||||
uint32_t sampling_rate;
|
||||
uint8_t tx_amp;
|
||||
uint32_t tx_frequency;
|
||||
uint8_t tx_gain;
|
||||
uint8_t vga;
|
||||
};
|
||||
|
||||
@@ -62,12 +67,16 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
#define MAX_FILE_CONTENT_SIZE 1000
|
||||
|
||||
char file_content[257] = {};
|
||||
char file_content[MAX_FILE_CONTENT_SIZE] = {};
|
||||
std::string file_path = "";
|
||||
std::string folder = "SETTINGS";
|
||||
int rc = SETTINGS_OK;
|
||||
File settings_file { };
|
||||
File settings_file { };
|
||||
long long int setting_value {} ;
|
||||
|
||||
long long int read_long_long(char* file_content, const char* setting_text);
|
||||
|
||||
|
||||
}; // class app_settings
|
||||
|
||||
@@ -139,7 +139,6 @@ AnalogAudioView::AnalogAudioView(
|
||||
}
|
||||
else field_frequency.set_value(receiver_model.tuning_frequency());
|
||||
|
||||
|
||||
//Filename Datetime and Frequency
|
||||
record_view.set_filename_date_frequency(true);
|
||||
|
||||
@@ -170,6 +169,7 @@ AnalogAudioView::AnalogAudioView(
|
||||
|
||||
const auto modulation = receiver_model.modulation();
|
||||
options_modulation.set_by_value(toUType(modulation));
|
||||
|
||||
options_modulation.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
this->on_modulation_changed(static_cast<ReceiverModel::Mode>(v));
|
||||
};
|
||||
@@ -193,7 +193,7 @@ AnalogAudioView::AnalogAudioView(
|
||||
audio::output::start();
|
||||
|
||||
update_modulation(static_cast<ReceiverModel::Mode>(modulation));
|
||||
on_modulation_changed(static_cast<ReceiverModel::Mode>(modulation));
|
||||
on_modulation_changed(static_cast<ReceiverModel::Mode>(modulation));
|
||||
}
|
||||
|
||||
size_t AnalogAudioView::get_spec_bw_index() {
|
||||
@@ -412,9 +412,6 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||
}
|
||||
}
|
||||
|
||||
/*void AnalogAudioView::squelched() {
|
||||
if (exit_on_squelch) nav_.pop();
|
||||
}*/
|
||||
|
||||
void AnalogAudioView::handle_coded_squelch(const uint32_t value) {
|
||||
float diff, min_diff = value;
|
||||
|
||||
@@ -39,10 +39,14 @@ using namespace portapack;
|
||||
namespace ui {
|
||||
|
||||
void LGEView::focus() {
|
||||
options_trame.focus();
|
||||
options_frame.focus();
|
||||
}
|
||||
|
||||
LGEView::~LGEView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_lge", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -70,10 +74,10 @@ void LGEView::generate_frame_touche() {
|
||||
std::vector<uint8_t> data { 0x46, 0x28, 0x01, 0x45, 0x27, 0x01, 0x44, 0x23 };
|
||||
|
||||
console.write("\n\x1B\x07Touche:\x1B\x10");
|
||||
generate_lge_frame(0x96, (field_joueur.value() << 8) | field_salle.value(), 0x0001, data);
|
||||
generate_lge_frame(0x96, (field_player.value() << 8) | field_room.value(), 0x0001, data);
|
||||
}
|
||||
|
||||
void LGEView::generate_frame_pseudo() {
|
||||
void LGEView::generate_frame_nickname() {
|
||||
// 0040.48s:
|
||||
// 30 02 1A 00 19 00 FF 00 02 19 42 52 45 42 49 53 20 00 00 00 00 00 00 00 00 00
|
||||
// 04 01 B0 04 7F 1F 11 33 40 1F 22 01 07 00 00 01 07 00 00 63 05 00 00 99 A2
|
||||
@@ -90,15 +94,15 @@ void LGEView::generate_frame_pseudo() {
|
||||
};
|
||||
uint32_t c;
|
||||
|
||||
//data_header[2] = field_salle.value(); // ?
|
||||
//data_footer[0] = field_salle.value(); // ?
|
||||
//data_header[2] = field_room.value(); // ?
|
||||
//data_footer[0] = field_room.value(); // ?
|
||||
|
||||
data.insert(data.begin(), data_header.begin(), data_header.end());
|
||||
|
||||
data.push_back(field_joueur.value());
|
||||
data.push_back(field_player.value());
|
||||
|
||||
c = 0;
|
||||
for (auto &ch : pseudo) {
|
||||
for (auto &ch : nickname) {
|
||||
data.push_back(ch);
|
||||
c++;
|
||||
}
|
||||
@@ -108,16 +112,16 @@ void LGEView::generate_frame_pseudo() {
|
||||
while (++c < 16)
|
||||
data.push_back(0x00);
|
||||
|
||||
data.push_back(field_equipe.value());
|
||||
data.push_back(field_team.value());
|
||||
|
||||
data.insert(data.end(), data_footer.begin(), data_footer.end());
|
||||
|
||||
console.write("\n\x1B\x0ESet pseudo:\x1B\x10");
|
||||
console.write("\n\x1B\x0ESet nickname:\x1B\x10");
|
||||
|
||||
generate_lge_frame(0x02, 0x001A, field_joueur.value(), data);
|
||||
generate_lge_frame(0x02, 0x001A, field_player.value(), data);
|
||||
}
|
||||
|
||||
void LGEView::generate_frame_equipe() {
|
||||
void LGEView::generate_frame_team() {
|
||||
// 0041.83s:
|
||||
// 3D 03 FF FF FF FF 02 03 01 52 4F 55 47 45 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
// 02 56 45 52 54 45 00 00 00 00 00 00 00 00 00 00 00 01 03 42 4C 45 55 45 00 00
|
||||
@@ -129,10 +133,10 @@ void LGEView::generate_frame_equipe() {
|
||||
|
||||
data.insert(data.begin(), data_header.begin(), data_header.end());
|
||||
|
||||
data.push_back(field_equipe.value());
|
||||
data.push_back(field_team.value());
|
||||
|
||||
c = 0;
|
||||
for (auto &ch : pseudo) {
|
||||
for (auto &ch : nickname) {
|
||||
data.push_back(ch);
|
||||
c++;
|
||||
}
|
||||
@@ -140,14 +144,14 @@ void LGEView::generate_frame_equipe() {
|
||||
while (c++ < 16)
|
||||
data.push_back(0x00);
|
||||
|
||||
data.push_back(field_equipe.value() - 1); // Color ?
|
||||
data.push_back(field_team.value() - 1); // Color ?
|
||||
|
||||
console.write("\n\x1B\x0ASet equipe:\x1B\x10");
|
||||
console.write("\n\x1B\x0ASet team:\x1B\x10");
|
||||
|
||||
generate_lge_frame(0x03, data);
|
||||
}
|
||||
|
||||
void LGEView::generate_frame_broadcast_pseudo() {
|
||||
void LGEView::generate_frame_broadcast_nickname() {
|
||||
// 0043.86s:
|
||||
// 3D 04 FF FF FF FF 02 03 19 42 52 45 42 49 53 20 00 00 00 00 00 00 00 00 00 04
|
||||
// 07 50 4F 4E 45 59 20 00 00 00 00 00 00 00 00 00 00 05 1B 41 42 42 59 20 00 00
|
||||
@@ -159,10 +163,10 @@ void LGEView::generate_frame_broadcast_pseudo() {
|
||||
|
||||
data.insert(data.begin(), data_header.begin(), data_header.end());
|
||||
|
||||
data.push_back(field_joueur.value());
|
||||
data.push_back(field_player.value());
|
||||
|
||||
c = 0;
|
||||
for (auto &ch : pseudo) {
|
||||
for (auto &ch : nickname) {
|
||||
data.push_back(ch);
|
||||
c++;
|
||||
}
|
||||
@@ -172,9 +176,9 @@ void LGEView::generate_frame_broadcast_pseudo() {
|
||||
while (++c < 16)
|
||||
data.push_back(0x00);
|
||||
|
||||
data.push_back(field_equipe.value());
|
||||
data.push_back(field_team.value());
|
||||
|
||||
console.write("\n\x1B\x09" "Broadcast pseudo:\x1B\x10");
|
||||
console.write("\n\x1B\x09" "Broadcast nickname:\x1B\x10");
|
||||
|
||||
generate_lge_frame(0x04, data);
|
||||
}
|
||||
@@ -184,14 +188,14 @@ void LGEView::generate_frame_start() {
|
||||
// 0A 05 FF FF FF FF 02 EC FF FF FF A3 35
|
||||
std::vector<uint8_t> data { 0x02, 0xEC, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
//data[0] = field_salle.value(); // ?
|
||||
//data[0] = field_room.value(); // ?
|
||||
|
||||
console.write("\n\x1B\x0DStart:\x1B\x10");
|
||||
generate_lge_frame(0x05, data);
|
||||
}
|
||||
|
||||
void LGEView::generate_frame_gameover() {
|
||||
std::vector<uint8_t> data { (uint8_t)field_salle.value() };
|
||||
std::vector<uint8_t> data { (uint8_t)field_room.value() };
|
||||
|
||||
console.write("\n\x1B\x0CGameover:\x1B\x10");
|
||||
generate_lge_frame(0x0D, data);
|
||||
@@ -203,7 +207,7 @@ void LGEView::generate_frame_collier() {
|
||||
// Custom
|
||||
// 0C 00 13 37 13 37 id flags channel playerid zapduty zaptime checksum CRC CRC
|
||||
// channel: field_channel
|
||||
// playerid: field_joueur
|
||||
// playerid: field_player
|
||||
// zapduty: field_power
|
||||
// zaptime: field_duration
|
||||
|
||||
@@ -218,8 +222,8 @@ void LGEView::generate_frame_collier() {
|
||||
std::vector<uint8_t> data {
|
||||
id,
|
||||
flags,
|
||||
(uint8_t)field_salle.value(),
|
||||
(uint8_t)field_joueur.value(),
|
||||
(uint8_t)field_room.value(),
|
||||
(uint8_t)field_player.value(),
|
||||
(uint8_t)field_power.value(),
|
||||
(uint8_t)(field_duration.value() * 10)
|
||||
};
|
||||
@@ -285,11 +289,11 @@ LGEView::LGEView(NavigationView& nav) {
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&options_trame,
|
||||
&field_salle,
|
||||
&button_texte,
|
||||
&field_equipe,
|
||||
&field_joueur,
|
||||
&options_frame,
|
||||
&field_room,
|
||||
&button_text,
|
||||
&field_team,
|
||||
&field_player,
|
||||
&field_id,
|
||||
&field_power,
|
||||
&field_duration,
|
||||
@@ -300,20 +304,29 @@ LGEView::LGEView(NavigationView& nav) {
|
||||
&tx_view
|
||||
});
|
||||
|
||||
field_salle.set_value(1);
|
||||
field_equipe.set_value(1);
|
||||
field_joueur.set_value(1);
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_lge", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
field_room.set_value(1);
|
||||
field_team.set_value(1);
|
||||
field_player.set_value(1);
|
||||
field_id.set_value(1);
|
||||
field_power.set_value(1);
|
||||
field_duration.set_value(2);
|
||||
|
||||
button_texte.on_select = [this, &nav](Button&) {
|
||||
button_text.on_select = [this, &nav](Button&) {
|
||||
text_prompt(
|
||||
nav,
|
||||
pseudo,
|
||||
nickname,
|
||||
15,
|
||||
[this](std::string& buffer) {
|
||||
button_texte.set_text(buffer);
|
||||
button_text.set_text(buffer);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -326,15 +339,15 @@ LGEView::LGEView(NavigationView& nav) {
|
||||
|
||||
tx_view.on_start = [this]() {
|
||||
if (tx_mode == IDLE) {
|
||||
auto i = options_trame.selected_index_value();
|
||||
auto i = options_frame.selected_index_value();
|
||||
if (i == 0)
|
||||
generate_frame_touche();
|
||||
else if (i == 1)
|
||||
generate_frame_pseudo();
|
||||
generate_frame_nickname();
|
||||
else if (i == 2)
|
||||
generate_frame_equipe();
|
||||
generate_frame_team();
|
||||
else if (i == 3)
|
||||
generate_frame_broadcast_pseudo();
|
||||
generate_frame_broadcast_nickname();
|
||||
else if (i == 4)
|
||||
generate_frame_start();
|
||||
else if (i == 5)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "message.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "app_settings.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@@ -48,15 +49,19 @@ private:
|
||||
SINGLE,
|
||||
ALL
|
||||
};
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
|
||||
RFM69 rfm69 { 5, 0x2DD4, true, true };
|
||||
RFM69 rfm69 { 5, 0x2DD4, true, true };
|
||||
|
||||
uint32_t frame_size { 0 };
|
||||
uint32_t repeats { 0 };
|
||||
uint32_t channel_index { 0 };
|
||||
std::string pseudo { "ABCDEF" };
|
||||
std::string nickname { "ABCDEF" };
|
||||
|
||||
rf::Frequency channels[3] = { 868067000, 868183000, 868295000 };
|
||||
|
||||
@@ -68,9 +73,9 @@ private:
|
||||
}
|
||||
void generate_lge_frame(const uint8_t command, const uint16_t address_a, const uint16_t address_b, std::vector<uint8_t>& data);
|
||||
void generate_frame_touche();
|
||||
void generate_frame_pseudo();
|
||||
void generate_frame_equipe();
|
||||
void generate_frame_broadcast_pseudo();
|
||||
void generate_frame_nickname();
|
||||
void generate_frame_team();
|
||||
void generate_frame_broadcast_nickname();
|
||||
void generate_frame_start();
|
||||
void generate_frame_gameover();
|
||||
void generate_frame_collier();
|
||||
@@ -79,28 +84,28 @@ private:
|
||||
|
||||
Labels labels {
|
||||
//{ { 7 * 8, 1 * 8 }, "NO FUN ALLOWED !", Color::red() },
|
||||
{ { 1 * 8, 1 * 8 }, "Trame:", Color::light_grey() },
|
||||
{ { 1 * 8, 3 * 8 }, "Salle:", Color::light_grey() },
|
||||
{ { 14 * 8, 3 * 8 }, "Texte:", Color::light_grey() },
|
||||
{ { 0 * 8, 5 * 8 }, "Equipe:", Color::light_grey() },
|
||||
{ { 0 * 8, 7 * 8 }, "Joueur:", Color::light_grey() },
|
||||
{ { 0 * 8, 10 * 8 }, "Collier:", Color::light_grey() },
|
||||
{ { 1 * 8, 1 * 8 }, "Frame:", Color::light_grey() },
|
||||
{ { 2 * 8, 3 * 8 }, "Room:", Color::light_grey() },
|
||||
{ { 14 * 8, 3 * 8 }, "Text:", Color::light_grey() },
|
||||
{ { 2 * 8, 5 * 8 }, "Team:", Color::light_grey() },
|
||||
{ { 0 * 8, 7 * 8 }, "Player:", Color::light_grey() },
|
||||
{ { 0 * 8, 10 * 8 }, "Vest:", Color::light_grey() },
|
||||
{ { 4 * 8, 12 * 8 }, "ID:", Color::light_grey() },
|
||||
{ { 3 * 8, 14 * 8 }, "Pow: /10", Color::light_grey() },
|
||||
{ { 1 * 8, 16 * 8 }, "Duree: x100ms", Color::light_grey() }
|
||||
{ { 2 * 8, 16 * 8 }, "Time: x100ms", Color::light_grey() }
|
||||
};
|
||||
|
||||
OptionsField options_trame {
|
||||
OptionsField options_frame {
|
||||
{ 7 * 8, 1 * 8 },
|
||||
13,
|
||||
{
|
||||
{ "Touche", 0 },
|
||||
{ "Set pseudo", 1 },
|
||||
{ "Set equipe", 2 },
|
||||
{ "Brdcst pseudo", 3 },
|
||||
{ "Key", 0 },
|
||||
{ "Set nickname", 1 },
|
||||
{ "Set team", 2 },
|
||||
{ "Brdcst nick", 3 },
|
||||
{ "Start", 4 },
|
||||
{ "Game over", 5 },
|
||||
{ "Set collier", 6 }
|
||||
{ "Set vest", 6 }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -111,7 +116,7 @@ private:
|
||||
true
|
||||
};
|
||||
|
||||
NumberField field_salle {
|
||||
NumberField field_room {
|
||||
{ 7 * 8, 3 * 8 },
|
||||
1,
|
||||
{ 1, 2 },
|
||||
@@ -119,12 +124,12 @@ private:
|
||||
'0'
|
||||
};
|
||||
|
||||
Button button_texte {
|
||||
Button button_text {
|
||||
{ 14 * 8, 5 * 8, 16 * 8, 3 * 8 },
|
||||
"ABCDEF"
|
||||
};
|
||||
|
||||
NumberField field_equipe {
|
||||
NumberField field_team {
|
||||
{ 7 * 8, 5 * 8 },
|
||||
1,
|
||||
{ 1, 6 },
|
||||
@@ -132,7 +137,7 @@ private:
|
||||
'0'
|
||||
};
|
||||
|
||||
NumberField field_joueur {
|
||||
NumberField field_player {
|
||||
{ 7 * 8, 7 * 8 },
|
||||
2,
|
||||
{ 1, 50 },
|
||||
|
||||
@@ -87,6 +87,8 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
|
||||
}
|
||||
else field_frequency.set_value(receiver_model.tuning_frequency());
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
||||
|
||||
receiver_model.set_sampling_rate(3072000);
|
||||
receiver_model.set_baseband_bandwidth(1750000);
|
||||
receiver_model.enable();
|
||||
|
||||
@@ -240,6 +240,15 @@ SoundBoardView::SoundBoardView(
|
||||
&button_next_page,
|
||||
&tx_view
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_soundboard", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
refresh_list();
|
||||
|
||||
@@ -280,6 +289,10 @@ SoundBoardView::SoundBoardView(
|
||||
}
|
||||
|
||||
SoundBoardView::~SoundBoardView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_soundboard", &app_settings);
|
||||
|
||||
stop();
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "lfsr_random.hpp"
|
||||
#include "io_wave.hpp"
|
||||
#include "tone_key.hpp"
|
||||
#include "app_settings.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@@ -49,6 +50,10 @@ public:
|
||||
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
enum tx_modes {
|
||||
NORMAL = 0,
|
||||
|
||||
@@ -313,6 +313,7 @@ ADSBRxView::~ADSBRxView() {
|
||||
// save app settings
|
||||
settings.save("rx_adsb", &app_settings);
|
||||
|
||||
//TODO: once all apps keep there own settin previous frequency logic can be removed
|
||||
receiver_model.set_tuning_frequency(prevFreq);
|
||||
rtc_time::signal_tick_second -= signal_token_tick_second;
|
||||
receiver_model.disable();
|
||||
|
||||
@@ -284,6 +284,11 @@ void ADSBTxView::focus() {
|
||||
}
|
||||
|
||||
ADSBTxView::~ADSBTxView() {
|
||||
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_adsb", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -334,8 +339,16 @@ ADSBTxView::ADSBTxView(
|
||||
&view_squawk,
|
||||
&text_frame,
|
||||
&tx_view
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_adsb", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
tx_view.on_edit_frequency = [this, &nav]() {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "ui_transmitter.hpp"
|
||||
#include "message.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "app_settings.hpp"
|
||||
#include "portapack.hpp"
|
||||
|
||||
using namespace adsb;
|
||||
@@ -189,6 +190,10 @@ private:
|
||||
-1,
|
||||
-1
|
||||
};*/
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
//tx_modes tx_mode = IDLE;
|
||||
NavigationView& nav_;
|
||||
|
||||
@@ -43,6 +43,10 @@ void APRSTXView::focus() {
|
||||
}
|
||||
|
||||
APRSTXView::~APRSTXView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_aprs", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -66,7 +70,7 @@ void APRSTXView::start_tx() {
|
||||
1200,
|
||||
2200,
|
||||
1,
|
||||
10000, //transmitter_model.channel_bandwidth(),
|
||||
10000, //APRS uses fixed 10k bandwidth
|
||||
8
|
||||
);
|
||||
}
|
||||
@@ -95,6 +99,15 @@ APRSTXView::APRSTXView(NavigationView& nav) {
|
||||
&tx_view
|
||||
});
|
||||
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_aprs", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
button_set.on_select = [this, &nav](Button&) {
|
||||
text_prompt(
|
||||
nav,
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "message.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "app_settings.hpp"
|
||||
#include "portapack.hpp"
|
||||
|
||||
namespace ui {
|
||||
@@ -40,17 +41,14 @@ public:
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "APRS TX (beta)"; };
|
||||
std::string title() const override { return "APRS TX"; };
|
||||
|
||||
private:
|
||||
/*enum tx_modes {
|
||||
IDLE = 0,
|
||||
SINGLE,
|
||||
SEQUENCE
|
||||
};
|
||||
|
||||
tx_modes tx_mode = IDLE;*/
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
std::string payload { "" };
|
||||
|
||||
void start_tx();
|
||||
@@ -103,7 +101,7 @@ private:
|
||||
TransmitterView tx_view {
|
||||
16 * 16,
|
||||
5000,
|
||||
10
|
||||
0 // disable setting bandwith, since APRS used fixed 10k bandwidth
|
||||
};
|
||||
|
||||
MessageHandlerRegistration message_handler_tx_progress {
|
||||
|
||||
@@ -96,9 +96,9 @@ void BHTView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||
if (target_system == XYLOS) {
|
||||
if (done) {
|
||||
if (tx_mode == SINGLE) {
|
||||
if (checkbox_cligno.value()) {
|
||||
if (checkbox_flashing.value()) {
|
||||
// TODO: Thread !
|
||||
chThdSleepMilliseconds(field_tempo.value() * 1000); // Dirty :(
|
||||
chThdSleepMilliseconds(field_speed.value() * 1000); // Dirty :(
|
||||
view_xylos.flip_relays();
|
||||
start_tx();
|
||||
} else
|
||||
@@ -120,9 +120,9 @@ void BHTView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||
} else {
|
||||
view_EPAR.half = false;
|
||||
if (tx_mode == SINGLE) {
|
||||
if (checkbox_cligno.value()) {
|
||||
if (checkbox_flashing.value()) {
|
||||
// TODO: Thread !
|
||||
chThdSleepMilliseconds(field_tempo.value() * 1000); // Dirty :(
|
||||
chThdSleepMilliseconds(field_speed.value() * 1000); // Dirty :(
|
||||
view_EPAR.flip_relays();
|
||||
start_tx();
|
||||
} else
|
||||
@@ -140,6 +140,10 @@ void BHTView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||
}
|
||||
|
||||
BHTView::~BHTView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_bht", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
}
|
||||
|
||||
@@ -150,13 +154,22 @@ BHTView::BHTView(NavigationView& nav) {
|
||||
&view_xylos,
|
||||
&view_EPAR,
|
||||
&checkbox_scan,
|
||||
&checkbox_cligno,
|
||||
&field_tempo,
|
||||
&checkbox_flashing,
|
||||
&field_speed,
|
||||
&progressbar,
|
||||
&tx_view
|
||||
});
|
||||
|
||||
field_tempo.set_value(1);
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_bht", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
field_speed.set_value(1);
|
||||
|
||||
tx_view.on_edit_frequency = [this, &nav]() {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "message.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "encoders.hpp"
|
||||
#include "app_settings.hpp"
|
||||
#include "portapack.hpp"
|
||||
|
||||
namespace ui {
|
||||
@@ -50,11 +51,11 @@ public:
|
||||
private:
|
||||
Labels labels {
|
||||
{ { 8 * 8, 1 * 8 }, "Header:", Color::light_grey() },
|
||||
{ { 4 * 8, 3 * 8 }, "Code ville:", Color::light_grey() },
|
||||
{ { 7 * 8, 5 * 8 }, "Famille:", Color::light_grey() },
|
||||
{ { 2 * 8, 7 * 8 + 2 }, "Sous-famille:", Color::light_grey() },
|
||||
{ { 2 * 8, 11 * 8 }, "ID recepteur:", Color::light_grey() },
|
||||
{ { 2 * 8, 14 * 8 }, "Relais:", Color::light_grey() }
|
||||
{ { 4 * 8, 3 * 8 }, "City code:", Color::light_grey() },
|
||||
{ { 7 * 8, 5 * 8 }, "Family:", Color::light_grey() },
|
||||
{ { 2 * 8, 7 * 8 + 2 }, "Subfamily:", Color::light_grey() },
|
||||
{ { 2 * 8, 11 * 8 }, "Receiver ID:", Color::light_grey() },
|
||||
{ { 2 * 8, 14 * 8 }, "Relay:", Color::light_grey() }
|
||||
};
|
||||
|
||||
NumberField field_header_a {
|
||||
@@ -98,8 +99,8 @@ private:
|
||||
|
||||
Checkbox checkbox_wcsubfamily {
|
||||
{ 20 * 8, 6 * 8 + 6 },
|
||||
6,
|
||||
"Toutes"
|
||||
3,
|
||||
"All"
|
||||
};
|
||||
|
||||
NumberField field_receiver {
|
||||
@@ -111,8 +112,8 @@ private:
|
||||
};
|
||||
Checkbox checkbox_wcid {
|
||||
{ 20 * 8, 10 * 8 + 4 },
|
||||
4,
|
||||
"Tous"
|
||||
3,
|
||||
"All"
|
||||
};
|
||||
|
||||
std::array<ImageOptionsField, 4> relay_states { };
|
||||
@@ -139,9 +140,9 @@ public:
|
||||
|
||||
private:
|
||||
Labels labels {
|
||||
{ { 4 * 8, 1 * 8 }, "Code ville:", Color::light_grey() },
|
||||
{ { 8 * 8, 3 * 8 }, "Groupe:", Color::light_grey() },
|
||||
{ { 8 * 8, 7 * 8 }, "Relais:", Color::light_grey() }
|
||||
{ { 4 * 8, 1 * 8 }, "City code:", Color::light_grey() },
|
||||
{ { 8 * 8, 3 * 8 }, "Group:", Color::light_grey() },
|
||||
{ { 8 * 8, 7 * 8 }, "Relay:", Color::light_grey() }
|
||||
};
|
||||
|
||||
NumberField field_city {
|
||||
@@ -181,6 +182,10 @@ public:
|
||||
std::string title() const override { return "BHT Xy/EP TX"; };
|
||||
|
||||
private:
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
void on_tx_progress(const uint32_t progress, const bool done);
|
||||
void start_tx();
|
||||
void stop_tx();
|
||||
@@ -220,12 +225,12 @@ private:
|
||||
"Scan"
|
||||
};
|
||||
|
||||
Checkbox checkbox_cligno {
|
||||
Checkbox checkbox_flashing {
|
||||
{ 16 * 8, 25 * 8 },
|
||||
6,
|
||||
"Cligno"
|
||||
8,
|
||||
"Flashing"
|
||||
};
|
||||
NumberField field_tempo {
|
||||
NumberField field_speed {
|
||||
{ 26 * 8, 25 * 8 + 4 },
|
||||
2,
|
||||
{ 1, 99 },
|
||||
|
||||
@@ -37,6 +37,10 @@ void CoasterPagerView::focus() {
|
||||
}
|
||||
|
||||
CoasterPagerView::~CoasterPagerView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_coaster", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -119,6 +123,15 @@ CoasterPagerView::CoasterPagerView(NavigationView& nav) {
|
||||
&tx_view
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_coaster", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
// Bytes to nibbles
|
||||
for (c = 0; c < 16; c++)
|
||||
sym_data.set_sym(c, (data_init[c >> 1] >> ((c & 1) ? 0 : 4)) & 0x0F);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "message.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "app_settings.hpp"
|
||||
#include "portapack.hpp"
|
||||
|
||||
namespace ui {
|
||||
@@ -50,6 +51,10 @@ private:
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
void start_tx();
|
||||
void generate_frame();
|
||||
void on_tx_progress(const uint32_t progress, const bool done);
|
||||
|
||||
@@ -203,6 +203,10 @@ void EncodersView::focus() {
|
||||
}
|
||||
|
||||
EncodersView::~EncodersView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_ook", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -335,6 +339,15 @@ EncodersView::EncodersView(
|
||||
&tx_view
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_ook", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
tx_view.on_edit_frequency = [this, &nav]() {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(transmitter_model.tuning_frequency());
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "transmitter_model.hpp"
|
||||
#include "encoders.hpp"
|
||||
#include "de_bruijn.hpp"
|
||||
#include "app_settings.hpp"
|
||||
|
||||
using namespace encoders;
|
||||
|
||||
@@ -169,6 +170,10 @@ private:
|
||||
SCAN
|
||||
};
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
uint8_t repeat_index { 0 };
|
||||
uint8_t repeat_min { 0 };
|
||||
|
||||
@@ -136,6 +136,9 @@ void KeyfobView::focus() {
|
||||
}
|
||||
|
||||
KeyfobView::~KeyfobView() {
|
||||
// save app settings
|
||||
settings.save("tx_keyfob", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -214,6 +217,13 @@ KeyfobView::KeyfobView(
|
||||
&tx_view
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_keyfob", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
frame[0] = 0x55;
|
||||
update_symfields();
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "ui.hpp"
|
||||
#include "ui_transmitter.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "app_settings.hpp"
|
||||
#include "encoders.hpp"
|
||||
|
||||
using namespace encoders;
|
||||
@@ -41,6 +42,10 @@ public:
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
// 1013210ns / bit
|
||||
static constexpr uint32_t subaru_samples_per_bit = (OOK_SAMPLERATE * 0.00101321);
|
||||
static constexpr uint32_t repeats = 4;
|
||||
|
||||
@@ -39,6 +39,10 @@ void LCRView::focus() {
|
||||
}
|
||||
|
||||
LCRView::~LCRView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_lcr", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -173,6 +177,15 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
&tx_view
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_lcr", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
options_scanlist.set_selected_index(0);
|
||||
|
||||
const auto button_set_am_fn = [this, &nav](Button& button) {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "message.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "app_settings.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@@ -81,6 +82,10 @@ private:
|
||||
SCAN
|
||||
};
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
uint8_t scan_count { 0 }, scan_index { 0 };
|
||||
uint32_t scan_progress { 0 };
|
||||
|
||||
@@ -97,6 +97,10 @@ void MorseView::focus() {
|
||||
}
|
||||
|
||||
MorseView::~MorseView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_morse", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -203,6 +207,15 @@ MorseView::MorseView(
|
||||
&tx_view
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_morse", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
// Default settings
|
||||
field_speed.set_value(15); // 15wps
|
||||
field_tone.set_value(700); // 700Hz FM tone
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_transmitter.hpp"
|
||||
|
||||
#include "app_settings.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "message.hpp"
|
||||
#include "volume.hpp"
|
||||
@@ -67,6 +67,10 @@ private:
|
||||
std::string message { };
|
||||
uint32_t time_units { 0 };
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
enum modulation_t {
|
||||
CW = 0,
|
||||
FM = 1
|
||||
|
||||
@@ -38,6 +38,10 @@ void POCSAGTXView::focus() {
|
||||
}
|
||||
|
||||
POCSAGTXView::~POCSAGTXView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_pocsag", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -141,6 +145,15 @@ POCSAGTXView::POCSAGTXView(
|
||||
&tx_view
|
||||
});
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_pocsag", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
options_bitrate.set_selected_index(1); // 1200bps
|
||||
options_type.set_selected_index(0); // Address only
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "bch_code.hpp"
|
||||
#include "message.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "app_settings.hpp"
|
||||
#include "pocsag.hpp"
|
||||
|
||||
using namespace pocsag;
|
||||
@@ -62,6 +63,10 @@ private:
|
||||
5, 31, 21, 2
|
||||
};
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
void on_set_text(NavigationView& nav);
|
||||
void on_tx_progress(const uint32_t progress, const bool done);
|
||||
bool start_tx();
|
||||
|
||||
@@ -175,6 +175,10 @@ void RDSView::focus() {
|
||||
}
|
||||
|
||||
RDSView::~RDSView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_rds", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -226,11 +230,17 @@ RDSView::RDSView(
|
||||
&view_radiotext,
|
||||
&view_datetime,
|
||||
&view_audio,
|
||||
//&options_countrycode,
|
||||
//&options_coverage,
|
||||
&tx_view,
|
||||
});
|
||||
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_rds", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
check_TP.set_value(true);
|
||||
|
||||
sym_pi_code.set_sym(0, 0xF);
|
||||
@@ -242,8 +252,6 @@ RDSView::RDSView(
|
||||
};
|
||||
|
||||
options_pty.set_selected_index(0); // None
|
||||
//options_countrycode.set_selected_index(18); // Baguette du fromage
|
||||
//options_coverage.set_selected_index(0); // Local
|
||||
|
||||
tx_view.on_edit_frequency = [this, &nav]() {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "ui_transmitter.hpp"
|
||||
#include "ui_textentry.hpp"
|
||||
#include "ui_tabview.hpp"
|
||||
|
||||
#include "app_settings.hpp"
|
||||
#include "rds.hpp"
|
||||
|
||||
using namespace rds;
|
||||
@@ -150,6 +150,11 @@ private:
|
||||
NavigationView& nav_;
|
||||
RDS_flags rds_flags { };
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
|
||||
std::vector<RDSGroup> frame_psn { };
|
||||
std::vector<RDSGroup> frame_radiotext { };
|
||||
std::vector<RDSGroup> frame_datetime { };
|
||||
|
||||
@@ -540,7 +540,7 @@ size_t ScannerView::change_mode(uint8_t new_mod) { //Before this, do a scan_thre
|
||||
field_bw.set_selected_index(0);
|
||||
receiver_model.set_am_configuration(field_bw.selected_index());
|
||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_am_configuration(n); };
|
||||
receiver_model.set_sampling_rate(2000000);receiver_model.set_baseband_bandwidth(2000000);
|
||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
||||
break;
|
||||
case WFM:
|
||||
bw.emplace_back("16k", 0);
|
||||
|
||||
@@ -245,13 +245,9 @@ SetUIView::SetUIView(NavigationView& nav) {
|
||||
checkbox_showclock.set_value(!persistent_memory::hide_clock());
|
||||
checkbox_guireturnflag.set_value(persistent_memory::show_gui_return_icon());
|
||||
|
||||
uint32_t backlight_timer = persistent_memory::config_backlight_timer();
|
||||
if (backlight_timer) {
|
||||
checkbox_bloff.set_value(true);
|
||||
options_bloff.set_by_value(backlight_timer);
|
||||
} else {
|
||||
options_bloff.set_selected_index(0);
|
||||
}
|
||||
const auto backlight_config = persistent_memory::config_backlight_timer();
|
||||
checkbox_bloff.set_value(backlight_config.timeout_enabled());
|
||||
options_bloff.set_by_value(backlight_config.timeout_enum());
|
||||
|
||||
if (persistent_memory::clock_with_date()) {
|
||||
options_clockformat.set_selected_index(1);
|
||||
@@ -261,11 +257,11 @@ SetUIView::SetUIView(NavigationView& nav) {
|
||||
|
||||
|
||||
button_save.on_select = [&nav, this](Button&) {
|
||||
if (checkbox_bloff.value())
|
||||
persistent_memory::set_config_backlight_timer(options_bloff.selected_index() + 1);
|
||||
else
|
||||
persistent_memory::set_config_backlight_timer(0);
|
||||
|
||||
persistent_memory::set_config_backlight_timer({
|
||||
(persistent_memory::backlight_timeout_t)options_bloff.selected_index_value(),
|
||||
checkbox_bloff.value()
|
||||
});
|
||||
|
||||
if (checkbox_showclock.value()){
|
||||
if (options_clockformat.selected_index() == 1)
|
||||
persistent_memory::set_clock_with_date(true);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "ui_menu.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ff.h"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -210,6 +211,8 @@ private:
|
||||
SetFrequencyCorrectionModel form_collect();
|
||||
};
|
||||
|
||||
using portapack::persistent_memory::backlight_timeout_t;
|
||||
|
||||
class SetUIView : public View {
|
||||
public:
|
||||
SetUIView(NavigationView& nav);
|
||||
@@ -241,13 +244,14 @@ private:
|
||||
{ 52, 7 * 16 + 8 },
|
||||
20,
|
||||
{
|
||||
{ "5 seconds", 5 },
|
||||
{ "15 seconds", 15 },
|
||||
{ "30 seconds", 30 },
|
||||
{ "1 minute", 60 },
|
||||
{ "3 minutes", 180 },
|
||||
{ "5 minutes", 300 },
|
||||
{ "10 minutes", 600 }
|
||||
{ "5 seconds", backlight_timeout_t::Timeout5Sec },
|
||||
{ "15 seconds", backlight_timeout_t::Timeout15Sec },
|
||||
{ "30 seconds", backlight_timeout_t::Timeout30Sec },
|
||||
{ "1 minute", backlight_timeout_t::Timeout60Sec },
|
||||
{ "3 minutes", backlight_timeout_t::Timeout180Sec },
|
||||
{ "5 minutes", backlight_timeout_t::Timeout300Sec },
|
||||
{ "10 minutes", backlight_timeout_t::Timeout600Sec },
|
||||
{ "1 hour", backlight_timeout_t::Timeout3600Sec },
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -88,6 +88,10 @@ void SSTVTXView::paint(Painter&) {
|
||||
}
|
||||
|
||||
SSTVTXView::~SSTVTXView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_sstv", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@@ -215,6 +219,15 @@ SSTVTXView::SSTVTXView(
|
||||
options_t mode_options;
|
||||
uint32_t c;
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_sstv", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
// Search for valid bitmaps
|
||||
file_list = scan_root_files(u"/sstv", u"*.bmp");
|
||||
if (!file_list.size()) {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "sstv.hpp"
|
||||
#include "file.hpp"
|
||||
#include "bmp.hpp"
|
||||
#include "app_settings.hpp"
|
||||
|
||||
using namespace sstv;
|
||||
|
||||
@@ -58,7 +59,10 @@ private:
|
||||
NavigationView& nav_;
|
||||
|
||||
sstv_scanline scanline_buffer { };
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
bool file_error { false };
|
||||
File bmp_file { };
|
||||
bmp_header_t bmp_header { };
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace ui {
|
||||
TouchCalibrationView::TouchCalibrationView(
|
||||
NavigationView& nav
|
||||
) : nav { nav },
|
||||
calibration { touch::default_calibration() }
|
||||
calibration { touch::Calibration() }
|
||||
{
|
||||
add_children({
|
||||
&image_calibrate_0,
|
||||
|
||||
@@ -226,15 +226,17 @@ void EventDispatcher::handle_rtc_tick() {
|
||||
|
||||
portapack::temperature_logger.second_tick();
|
||||
|
||||
uint32_t backlight_timer = portapack::persistent_memory::config_backlight_timer();
|
||||
if (backlight_timer) {
|
||||
if (portapack::bl_tick_counter == backlight_timer)
|
||||
const auto backlight_timer = portapack::persistent_memory::config_backlight_timer();
|
||||
if (backlight_timer.timeout_enabled()) {
|
||||
if (portapack::bl_tick_counter == backlight_timer.timeout_seconds())
|
||||
set_display_sleep(true);
|
||||
else
|
||||
portapack::bl_tick_counter++;
|
||||
}
|
||||
|
||||
rtc_time::on_tick_second();
|
||||
|
||||
portapack::persistent_memory::cache::persist();
|
||||
}
|
||||
|
||||
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;
|
||||
if(!config_value.is_valid()){
|
||||
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");
|
||||
if(data != -1) {
|
||||
config_value = data;
|
||||
@@ -235,14 +235,19 @@ static PortaPackModel portapack_model() {
|
||||
const auto switches_state = get_switches_state();
|
||||
if (switches_state[(size_t)ui::KeyEvent::Up]){
|
||||
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]){
|
||||
save_config(2);
|
||||
model = PortaPackModel::R1_20150901;
|
||||
// model = PortaPackModel::R1_20150901;
|
||||
}
|
||||
else if (switches_state[(size_t)ui::KeyEvent::Left]){
|
||||
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]){
|
||||
save_config(0);
|
||||
@@ -253,6 +258,10 @@ static PortaPackModel portapack_model() {
|
||||
model = PortaPackModel::R2_20170522;
|
||||
} else if (load_config() == 2) {
|
||||
model = PortaPackModel::R1_20150901;
|
||||
} else if (load_config() == 3) {
|
||||
model = PortaPackModel::R1_20150901;
|
||||
} else if (load_config() == 4) {
|
||||
model = PortaPackModel::R2_20170522;
|
||||
} else {
|
||||
if( audio_codec_wm8731.detected() ) {
|
||||
model = PortaPackModel::R1_20150901; // H1R1
|
||||
@@ -457,6 +466,9 @@ bool init() {
|
||||
i2c0.start(i2c_config_fast_clock);
|
||||
chThdSleepMilliseconds(10);
|
||||
|
||||
/* Cache some configuration data from persistent memory. */
|
||||
persistent_memory::cache::init();
|
||||
|
||||
touch::adc::init();
|
||||
controls_init();
|
||||
chThdSleepMilliseconds(10);
|
||||
@@ -475,7 +487,7 @@ bool init() {
|
||||
if( !portapack::cpld::update_if_necessary(portapack_cpld_config()) ) {
|
||||
chThdSleepMilliseconds(10);
|
||||
// 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();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,14 @@ struct serial_format_t {
|
||||
parity_enum parity;
|
||||
uint8_t stop_bits;
|
||||
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);
|
||||
|
||||
@@ -76,14 +76,6 @@ ui::Point Calibration::translate(const DigitizerPoint& p) const {
|
||||
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) {
|
||||
// touch_debounce.feed(touch_raw);
|
||||
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;
|
||||
|
||||
private:
|
||||
@@ -149,8 +158,6 @@ private:
|
||||
int32_t f;
|
||||
};
|
||||
|
||||
const Calibration default_calibration();
|
||||
|
||||
template<size_t N>
|
||||
class Filter {
|
||||
public:
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
#include "utility.hpp"
|
||||
|
||||
#include "memory_map.hpp"
|
||||
using portapack::memory::map::backup_ram;
|
||||
|
||||
#include "crc.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#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 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 data_t {
|
||||
data_structure_version_enum structure_version;
|
||||
int64_t tuned_frequency;
|
||||
int32_t correction_ppb;
|
||||
uint32_t touch_calibration_magic;
|
||||
@@ -89,7 +275,7 @@ struct data_t {
|
||||
uint32_t playdead_sequence;
|
||||
|
||||
// UI
|
||||
uint32_t ui_config;
|
||||
ui_config_t ui_config;
|
||||
|
||||
uint32_t pocsag_last_address;
|
||||
uint32_t pocsag_ignore_address;
|
||||
@@ -98,11 +284,142 @@ struct data_t {
|
||||
|
||||
// Hardware
|
||||
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::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);
|
||||
}
|
||||
|
||||
static constexpr uint32_t touch_calibration_magic = 0x074af82f;
|
||||
|
||||
void set_touch_calibration(const 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() {
|
||||
if( data->touch_calibration_magic != touch_calibration_magic ) {
|
||||
set_touch_calibration(touch::default_calibration());
|
||||
if( data->touch_calibration_magic != TOUCH_CALIBRATION_MAGIC ) {
|
||||
set_touch_calibration(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;
|
||||
}
|
||||
|
||||
// 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
|
||||
return data->ui_config & (1 << 20);
|
||||
bool show_gui_return_icon() { // add return icon in touchscreen menue
|
||||
return data->ui_config.show_gui_return_icon();
|
||||
}
|
||||
|
||||
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
|
||||
return data->ui_config & (1 << 22);
|
||||
return data->ui_config.save_app_settings();
|
||||
}
|
||||
|
||||
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
|
||||
return data->ui_config & (1 << 24);
|
||||
return data->ui_config.disable_touchscreen();
|
||||
}
|
||||
|
||||
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
|
||||
return data->ui_config & (1 << 26);
|
||||
return data->ui_config.clock_with_date();
|
||||
}
|
||||
|
||||
bool clkout_enabled() {
|
||||
return data->ui_config & (1 << 27);
|
||||
return data->ui_config.clkout_enabled();
|
||||
}
|
||||
|
||||
bool config_speaker() {
|
||||
return data->ui_config & (1 << 28);
|
||||
return data->ui_config.config_speaker();
|
||||
}
|
||||
|
||||
bool stealth_mode() {
|
||||
return data->ui_config & (1 << 29);
|
||||
return data->ui_config.stealth_mode();
|
||||
}
|
||||
|
||||
bool config_login() {
|
||||
return data->ui_config & (1 << 30);
|
||||
return data->ui_config.config_login();
|
||||
}
|
||||
|
||||
bool config_splash() {
|
||||
return data->ui_config & (1 << 31);
|
||||
return data->ui_config.config_splash();
|
||||
}
|
||||
|
||||
uint8_t config_cpld() {
|
||||
return data->hardware_config;
|
||||
}
|
||||
|
||||
uint32_t config_backlight_timer() {
|
||||
const uint32_t timer_seconds[8] = { 0, 5, 15, 30, 60, 180, 300, 600 };
|
||||
return timer_seconds[data->ui_config & 7]; //first three bits, 8 possible values
|
||||
backlight_config_t config_backlight_timer() {
|
||||
return data->ui_config.config_backlight_timer();
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
data->ui_config = (data->ui_config & ~(1 << 24)) | (v << 24);
|
||||
data->ui_config.set_disable_touchscreen(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) {
|
||||
data->ui_config = (data->ui_config & ~(1 << 26)) | (v << 26);
|
||||
data->ui_config.set_clock_with_date(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) {
|
||||
data->ui_config = (data->ui_config & ~(1 << 28)) | (v << 28);
|
||||
data->ui_config.set_config_speaker(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) {
|
||||
data->ui_config = (data->ui_config & ~(1 << 30)) | (v << 30);
|
||||
data->ui_config.set_config_login(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) {
|
||||
data->hardware_config = i;
|
||||
}
|
||||
|
||||
void set_config_backlight_timer(uint32_t i) {
|
||||
data->ui_config = (data->ui_config & ~7) | (i & 7);
|
||||
void set_config_backlight_timer(const backlight_config_t& new_value) {
|
||||
data->ui_config.set_config_backlight_timer(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() {
|
||||
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;
|
||||
}
|
||||
return data->ui_config.clkout_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 "optional.hpp"
|
||||
|
||||
#include "rf_path.hpp"
|
||||
#include "touch.hpp"
|
||||
#include "modems.hpp"
|
||||
@@ -36,6 +38,77 @@ using namespace serializer;
|
||||
namespace portapack {
|
||||
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;
|
||||
|
||||
rf::Frequency tuned_frequency();
|
||||
@@ -86,7 +159,7 @@ bool hide_clock();
|
||||
bool clock_with_date();
|
||||
bool config_login();
|
||||
bool config_speaker();
|
||||
uint32_t config_backlight_timer();
|
||||
backlight_config_t config_backlight_timer();
|
||||
bool disable_touchscreen();
|
||||
|
||||
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_config_login(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);
|
||||
|
||||
//uint8_t ui_config_textentry();
|
||||
|
||||
@@ -95,27 +95,27 @@ struct range_t {
|
||||
const T minimum;
|
||||
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);
|
||||
}
|
||||
|
||||
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 ) ||
|
||||
(value > maximum ) ) {
|
||||
value = reset_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool below_range(const T& value) const {
|
||||
constexpr bool below_range(const T& value) const {
|
||||
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!
|
||||
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!
|
||||
return !contains(value);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ outfile.write(struct.pack('H', im.size[1]))
|
||||
print("Generating: \t" + outfile.name + "\n from\t\t" + im.filename + "\n please wait...");
|
||||
|
||||
for y in range (0, im.size[1]):
|
||||
line = ''
|
||||
line = b''
|
||||
for x in range (0, im.size[0]):
|
||||
# RRRRRGGGGGGBBBBB
|
||||
pixel_lcd = (pix[x, y][0] >> 3) << 11
|
||||
@@ -47,8 +47,8 @@ for y in range (0, im.size[1]):
|
||||
# pixel_lcd = (pix[x, y][0] >> 5) << 5
|
||||
# pixel_lcd |= (pix[x, y][1] >> 5) << 2
|
||||
# pixel_lcd |= (pix[x, y][2] >> 6)
|
||||
line += str(struct.pack('H', pixel_lcd))
|
||||
outfile.write(line.encode('utf-8'))
|
||||
line += struct.pack('H', pixel_lcd)
|
||||
outfile.write(line)
|
||||
print(str(y) + '/' + str(im.size[1]) + '\r', end="")
|
||||
|
||||
print("Ready.");
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
Submodule hackrf updated: e6eb4ba29b...dfadf6a31c
Reference in New Issue
Block a user