RadioSet: Add various small improvements

This commit is contained in:
Dominic Höglinger 2025-10-04 14:22:39 +02:00
parent 16eba03e49
commit a8fd6927af
7 changed files with 129 additions and 48 deletions

View File

@ -1,5 +1,7 @@
#pragma once
#include <cassert>
template <typename DataType>
class LinkedList {

View File

@ -10,41 +10,12 @@
constexpr const char* TAG = "RadioSet";
// Debug function which colors all children randomly
// TODO: Remove before flight
void clownvomit(lv_obj_t *obj) {
static auto rng = []() {
static int color = 0xC0FE;
const int a = 4711;
const int m = 0x10001;
color = (a * color) % m;
return color;
};
const int darken = 0x0E0E0E;
const int lighten = 0xFEFEFE;
lv_obj_set_style_bg_color(obj, lv_color_hex(rng() & darken), 0);
uint32_t i;
for(i = 0; i < lv_obj_get_child_count(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
lv_obj_set_style_bg_color(child, lv_color_hex(rng() & darken), 0);
lv_obj_set_style_border_color(child, lv_color_hex(rng() | lighten), 0);
lv_obj_set_style_border_width(child, 1, 0);
clownvomit(child);
}
}
/*
void scrollbar_highlight(lv_event_t * e) {
lv_obj_t * obj = lv_event_get_target(e);
}*/
class TermView {
};
void RadioSet::onShow(AppHandle appHandle, lv_obj_t* parent) {
lv_obj_remove_flag(parent, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
@ -75,18 +46,42 @@ void RadioSet::onShow(AppHandle appHandle, lv_obj_t* parent) {
lv_obj_set_style_border_width(wrapper, 0, 0);
lv_obj_remove_flag(wrapper, LV_OBJ_FLAG_SCROLLABLE);
termView = new TermView(wrapper);
settingsView = new SettingsView(wrapper);
auto presetMtEu868LongFast = new Preset("MT EU868 LongFast", MODULATION_LORA);
presetMtEu868LongFast->addParameter(RADIO_FREQUENCY, 869.525);
presetMtEu868LongFast->addParameter(RADIO_POWER, 22.0);
presetMtEu868LongFast->addParameter(RADIO_BOOSTEDGAIN, true);
presetMtEu868LongFast->addParameter(RADIO_BANDWIDTH, 250.0);
presetMtEu868LongFast->addParameter(RADIO_SPREADFACTOR, 11);
presetMtEu868LongFast->addParameter(RADIO_CODINGRATE, 6);
presetMtEu868LongFast->addParameter(RADIO_CODINGRATE, 5);
presetMtEu868LongFast->addParameter(RADIO_SYNCWORD, 0x2B);
presetMtEu868LongFast->addParameter(RADIO_PREAMBLES, 16);
settingsView->addPreset(presetMtEu868LongFast);
settingsView->updatePresets();
for (auto iter = settingsView->radios.begin(); iter != settingsView->radios.end(); iter++) {
termView->addRadio(*iter);
}
showView(View::Terminal);
lv_obj_add_event_cb(uiDropDownMenu, [](lv_event_t * e) {
RadioSet* self = (RadioSet*)lv_event_get_user_data(e);
lv_obj_t* input = lv_event_get_target_obj(e);
switch (lv_dropdown_get_selected(input)) {
case 0:
self->showView(View::Terminal);
break;
case 1:
self->showView(View::Settings);
break;
default:
break;
}
}, LV_EVENT_VALUE_CHANGED, this);
}
@ -99,5 +94,23 @@ RadioSet::~RadioSet() {
}
}
// ????
void RadioSet::showView(View view) {
termView->setVisible(false);
settingsView->setVisible(false);
switch (view) {
case View::Terminal:
termView->setVisible(true);
break;
case View::Settings:
settingsView->setVisible(true);
break;
default:
break;
}
}
// This function is called with any "pure virtual" method, i.e. it should never happen
// TODO: I was wrong about it being related to the STL, it is a core feature that needs
// to be bridged with the tt_init.cpp symbol table
extern "C" void __cxa_pure_virtual() { crash("Entered the Virtual Zone..."); }

View File

@ -1,14 +1,18 @@
#pragma once
#include "SettingsView.h"
#include "TermView.h"
#include "tt_app.h"
#include "tt_hal_radio.h"
#include <lvgl.h>
class TermView;
class RadioSet {
enum class View {
Terminal,
Settings
};
lv_obj_t* mainView = nullptr;
lv_obj_t* uiDropDownMenu = nullptr;
lv_obj_t* progressBar = nullptr;
@ -22,4 +26,6 @@ public:
~RadioSet();
void onShow(AppHandle context, lv_obj_t* parent);
void showView(View view);
};

View File

@ -510,28 +510,25 @@ void SettingsView::queryRadios() {
if(!tt_hal_device_find(DEVICE_TYPE_RADIO, devices, &device_count, MAX_RADIOS)) {
// TT_LOG_W(TAG, "No radios registered with the system?");
} else {
size_t radios_allocated = 0;
for (size_t i = 0; (i < device_count) && (i < MAX_RADIOS); ++i) {
auto radio = tt_hal_radio_alloc(devices[i]);
if (radio) {
// TT_LOG_I(TAG, "Discovered radio \"%s\"", tt_hal_radio_get_name(radio));
radios[radios_allocated] = radio;
radios_allocated++;
radios.pushBack(radio);
} else {
// TT_LOG_E(TAG, "Error allocating radio handle for id=%d", devId);
}
}
radioCount = radios_allocated;
}
}
void SettingsView::getRadioNames(Str &names, const char* const separator) {
int count = 1;
names.clear();
//for (auto radio : radios) {
for (size_t i = 0; i < radioCount; ++i) {
Str name(tt_hal_radio_get_name(radios[i]));
auto last = (i == (radioCount - 1));
for (auto iter = radios.begin(); iter != radios.end(); iter++) {
Str name(tt_hal_radio_get_name(*iter));
auto last = is_last(iter, radios);
if (name == "") {
name.appendf("Unknown Radio %d", count);
}
@ -679,7 +676,6 @@ void SettingsView::selectRadio(int index) {
}
radioSelected = radios[index];
crashassert(radioSelected, "Radio selected not allocated");
for (size_t i = 0; i < MAX_MODEMS; ++i) {
modemsAvailable[i] = MODULATION_NONE;
@ -879,7 +875,7 @@ void SettingsView::deactivateConfig() {
void SettingsView::initUi(lv_obj_t *parent) {
mainPanel = lv_obj_create(parent);
lv_obj_set_size(mainPanel, lv_pct(100), lv_pct(80));
lv_obj_set_size(mainPanel, lv_pct(100), lv_pct(100));
lv_obj_set_flex_flow(mainPanel, LV_FLEX_FLOW_COLUMN);
lv_obj_align(mainPanel, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_set_style_border_width(mainPanel, 0, 0);
@ -887,3 +883,11 @@ void SettingsView::initUi(lv_obj_t *parent) {
deviceForm = initDeviceForm(mainPanel);
}
void SettingsView::setVisible(bool visible) {
if (visible) {
lv_obj_clear_flag(mainPanel, LV_OBJ_FLAG_HIDDEN);
} else {
lv_obj_add_flag(mainPanel, LV_OBJ_FLAG_HIDDEN);
}
}

View File

@ -8,15 +8,12 @@
class ParameterInput;
class SettingsView {
static constexpr size_t MAX_RADIOS = 32;
static constexpr Modulation FIRST_MODULATION = MODULATION_NONE;
static constexpr Modulation LAST_MODULATION = MODULATION_LRFHSS;
static constexpr size_t MAX_RADIOS = 32;
static constexpr size_t MAX_MODEMS = LAST_MODULATION + 1;
static constexpr size_t MAX_PARAMS = RADIO_NARROWGRID + 1;
RadioHandle radios[MAX_RADIOS] = {0};
size_t radioCount = 0;
RadioHandle radioSelected = nullptr;
RadioStateSubscriptionId radioStateSubId = -1;
Modulation modemsAvailable[MAX_MODEMS] = {};
@ -36,9 +33,11 @@ class SettingsView {
lv_obj_t* modemDropdown = nullptr;
lv_obj_t* modemPresetDropdown = nullptr;
lv_obj_t *propertiesForm = nullptr;
lv_obj_t* propertiesForm = nullptr;
public:
LinkedList<RadioHandle> radios;
void addPreset(Preset* preset);
void queryRadios();
void getRadioNames(Str &names, const char* const separator);
@ -65,8 +64,12 @@ public:
void initUi(lv_obj_t *parent);
void setVisible(bool visible);
explicit SettingsView(lv_obj_t *parent) {
queryRadios();
initUi(parent);
}
};

View File

@ -1,5 +1,7 @@
#include "Utils.h"
#include <ctype.h>
#include <tt_app_alertdialog.h>
void crash(const char* const message) {
@ -12,6 +14,22 @@ void crashassert(bool assertion, const char* const message) {
}
}
void hexdump(Str& out, const uint8_t* data, size_t size) {
out.clear();
for (size_t i = 0; i < size; ++i) {
out.appendf("%02X ", data[i]);
}
}
bool isPrintable(const uint8_t* data, size_t size) {
for (size_t i = 0; i < (size - 1); ++i) {
if (!isprint(data[i])) {
return false;
}
}
return true;
}
char *const toString(Modulation m) {
switch (m) {
case MODULATION_NONE:
@ -61,3 +79,28 @@ char *const toString(RadioParameter p) {
crash("Unknown parameter passed.");
return "Unknown";
}
void clownvomit(lv_obj_t *obj) {
static auto rng = []() {
static int color = 0xCCC0FE;
const int a = 4711;
const int m = 0x10001;
color = (a * color) % m;
return color;
};
const int darken = 0x0E0E0E;
const int lighten = 0xFEFEFE;
lv_obj_set_style_bg_color(obj, lv_color_hex(rng() & darken), 0);
uint32_t i;
for(i = 0; i < lv_obj_get_child_count(obj); i++) {
auto light = lv_color_lighten(lv_color_hex(rng()), 100);
auto dark = lv_color_darken(lv_color_hex(rng()), 100);
lv_obj_t * child = lv_obj_get_child(obj, i);
lv_obj_set_style_bg_color(child, dark, 0);
lv_obj_set_style_border_color(child, light, 0);
lv_obj_set_style_border_width(child, 1, 0);
clownvomit(child);
}
}

View File

@ -1,5 +1,8 @@
#pragma once
#include "Str.h"
#include <lvgl.h>
#include <tt_hal_radio.h>
template <typename Iterator>
@ -15,5 +18,12 @@ bool is_last(Iterator i, const Container& c) {
void crash(const char* const message);
void crashassert(bool assertion, const char* const message);
void hexdump(Str& out, const uint8_t* data, size_t size);
bool isPrintable(const uint8_t* data, size_t size);
char *const toString(Modulation m);
char *const toString(RadioParameter p);
// Debug function which colors all children randomly
// TODO: Remove before flight
void clownvomit(lv_obj_t *obj);