diff --git a/firmware/application/apps/ui_debug.cpp b/firmware/application/apps/ui_debug.cpp index 9e6897837..29fe8e5fa 100644 --- a/firmware/application/apps/ui_debug.cpp +++ b/firmware/application/apps/ui_debug.cpp @@ -176,12 +176,15 @@ void RegistersWidget::paint(Painter& painter) { void RegistersWidget::draw_legend(const Coord left, Painter& painter) { const auto pos = screen_pos(); + const std::string spaces(config.legend_length(), ' '); + + for (uint32_t i = 0; i < config.registers_per_page; i += config.registers_per_row()) { + uint32_t r = page_number * config.registers_per_page + i; - for (uint32_t i = 0; i < config.registers_count; i += config.registers_per_row()) { const Point offset{ left, static_cast((i / config.registers_per_row()) * row_height)}; - const auto text = to_string_hex(i, config.legend_length()); + const auto text = (r >= config.registers_count) ? spaces : to_string_hex(r, config.legend_length()); painter.draw_string( pos + offset, style().invert(), @@ -193,15 +196,16 @@ void RegistersWidget::draw_values( const Coord left, Painter& painter) { const auto pos = screen_pos(); + const std::string spaces(config.value_length(), ' '); + + for (uint32_t i = 0; i < config.registers_per_page; i++) { + uint32_t r = page_number * config.registers_per_page + i; - for (uint32_t i = 0; i < config.registers_count; i++) { const Point offset = { static_cast(left + config.legend_width() + 8 + (i % config.registers_per_row()) * (config.value_width() + 8)), static_cast((i / config.registers_per_row()) * row_height)}; - const auto value = reg_read(i); - - const auto text = to_string_hex(value, config.value_length()); + const auto text = (r >= config.registers_count) ? spaces : to_string_hex(reg_read(r), config.value_length()); painter.draw_string( pos + offset, style(), @@ -213,7 +217,7 @@ uint32_t RegistersWidget::reg_read(const uint32_t register_number) { if (register_number < config.registers_count) { switch (config.chip_type) { case CT_PMEM: - return portapack::persistent_memory::pmem_data_word((page_number * config.registers_count + register_number) / 4) >> (register_number % 4 * 8); + return portapack::persistent_memory::pmem_data_word(register_number / 4) >> (register_number % 4 * 8); case CT_RFFC5072: return radio::debug::first_if::register_read(register_number); case CT_MAX283X: @@ -272,6 +276,7 @@ RegistersView::RegistersView( button_done.on_select = [&nav](Button&) { nav.pop(); }; registers_widget.set_parent_rect({0, 48, 240, 192}); + registers_widget.set_page(0); text_title.set_parent_rect({(240 - static_cast(title.size()) * 8) / 2, 16, static_cast(title.size()) * 8, 16}); @@ -296,6 +301,13 @@ void RegistersView::focus() { button_done.focus(); } +bool RegistersView::on_encoder(const EncoderEvent delta) { + registers_widget.set_page(std::max(0ul, std::min(registers_widget.page_count() - 1, registers_widget.page() + delta))); + registers_widget.update(); + + return true; +} + /* ControlsSwitchesWidget ************************************************/ void ControlsSwitchesWidget::on_show() { @@ -429,10 +441,10 @@ DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) { const char* max283x = hackrf_r9 ? "MAX2839" : "MAX2837"; const char* si5351x = hackrf_r9 ? "Si5351A" : "Si5351C"; add_items({ - {"RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 16}); }}, - {max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, max283x]() { nav.push(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 10}); }}, - {si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, si5351x]() { nav.push(si5351x, RegistersWidgetConfig{CT_SI5351, 96, 8}); }}, - {audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_bits()}); }}, + {"RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push("RFFC5072", RegistersWidgetConfig{CT_RFFC5072, 31, 31, 16}); }}, + {max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, max283x]() { nav.push(max283x, RegistersWidgetConfig{CT_MAX283X, 32, 32, 10}); }}, + {si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, si5351x]() { nav.push(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }}, + {audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_count(), audio::debug::reg_bits()}); }}, }); set_max_rows(2); // allow wider buttons } @@ -504,8 +516,8 @@ void DebugMemoryDumpView::focus() { /* DebugPmemView *********************************************************/ DebugPmemView::DebugPmemView(NavigationView& nav) - : registers_widget(RegistersWidgetConfig{CT_PMEM, page_size, 8}) { - add_children({&text_page, ®isters_widget, &text_checksum, &text_checksum2, &button_ok}); + : registers_widget(RegistersWidgetConfig{CT_PMEM, PMEM_SIZE_BYTES, page_size, 8}) { + add_children({®isters_widget, &text_checksum, &text_checksum2, &button_ok}); registers_widget.set_parent_rect({0, 32, 240, 192}); @@ -532,7 +544,6 @@ void DebugPmemView::focus() { } void DebugPmemView::update() { - text_page.set(to_string_hex(registers_widget.page() * page_size, 2) + "+"); registers_widget.update(); } diff --git a/firmware/application/apps/ui_debug.hpp b/firmware/application/apps/ui_debug.hpp index 8328a9973..583819980 100644 --- a/firmware/application/apps/ui_debug.hpp +++ b/firmware/application/apps/ui_debug.hpp @@ -142,6 +142,7 @@ typedef enum { struct RegistersWidgetConfig { chip_type_t chip_type; uint32_t registers_count; + uint32_t registers_per_page; uint32_t register_bits; constexpr size_t legend_length() const { @@ -194,6 +195,7 @@ class RegistersWidget : public Widget { void set_page(int32_t value) { page_number = value; } uint32_t page(void) { return page_number; } + uint32_t page_count(void) { return (config.registers_count + config.registers_per_page - 1) / config.registers_per_page; } private: const RegistersWidgetConfig config; @@ -208,8 +210,8 @@ class RegistersWidget : public Widget { class RegistersView : public View { public: RegistersView(NavigationView& nav, const std::string& title, RegistersWidgetConfig&& config); - - void focus(); + void focus() override; + bool on_encoder(const EncoderEvent delta) override; private: Text text_title{}; @@ -364,8 +366,6 @@ class DebugPmemView : public View { static constexpr uint8_t page_size{96}; // Must be multiply of 4 otherwise bit shifting for register view wont work properly static constexpr uint8_t page_count{(portapack::memory::map::backup_ram.size() + page_size - 1) / page_size}; - Text text_page{{16, 16, 208, 16}}; - RegistersWidget registers_widget; Text text_checksum{{16, 232, 208, 16}}; diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 55294cab2..8f83282f6 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -284,11 +284,11 @@ struct data_t { struct backup_ram_t { private: - volatile uint32_t regfile[63]; + volatile uint32_t regfile[PMEM_SIZE_WORDS - 1]; volatile uint32_t check_value; static void copy(const backup_ram_t& src, backup_ram_t& dst) { - for (size_t i = 0; i < 63; i++) { + for (size_t i = 0; i < PMEM_SIZE_WORDS - 1; i++) { dst.regfile[i] = src.regfile[i]; } dst.check_value = src.check_value; @@ -297,7 +297,7 @@ struct backup_ram_t { 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++) { + for (size_t i = 0; i < PMEM_SIZE_WORDS - 1; i++) { if (i < word_count) { dst.regfile[i] = src_words[i]; } else { @@ -308,7 +308,7 @@ struct backup_ram_t { uint32_t compute_check_value() { CRC<32> crc{0x04c11db7, 0xffffffff, 0xffffffff}; - for (size_t i = 0; i < 63; i++) { + for (size_t i = 0; i < PMEM_SIZE_WORDS - 1; i++) { const auto word = regfile[i]; crc.process_byte((word >> 0) & 0xff); crc.process_byte((word >> 8) & 0xff); diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 4c5e50eee..2760322b3 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -39,6 +39,9 @@ // persistant memory from/to sdcard flag file #define PMEM_SETTING_FILE u"/SETTINGS/pmem_settings" +#define PMEM_SIZE_BYTES 256 // total amount of pmem space in bytes, including checksum +#define PMEM_SIZE_WORDS (PMEM_SIZE_BYTES / 4) + using namespace modems; using namespace serializer;