Compare commits

...

12 Commits

Author SHA1 Message Date
Totoo fff63e056a FM Radio ext app (#2428) 2024-12-17 18:53:26 +01:00
sommermorgentraum 42da7443b4 fix gray box & remove multiple line text support for NewButton (#2426) 2024-12-15 18:22:19 +01:00
gullradriel ee10081854 update submodule (#2424) 2024-12-14 18:21:13 +00:00
gullradriel b38d1012fa Fix usb.c and usb_queue.c warnings in our CMakeLists instead of in the files (#2423) 2024-12-14 19:14:39 +01:00
sommermorgentraum 5075349d2d sdcard format detect and warn user (#2420) 2024-12-14 09:39:39 +01:00
gullradriel 8497b62c13 updated submodule (#2422)
Co-authored-by: gullradriel <gullradriel@no-mail.com>
2024-12-14 09:38:45 +01:00
jLynx fdeaf380d1 Update README.md 2024-12-09 20:41:43 +13:00
gullradriel 67eb8e9104 update submodule (#2413) 2024-12-07 15:43:16 +01:00
sommermorgentraum 989414d4df prevent show 1970 when focusing the paging item in fileman app (#2412)
* _

* fix map view button overlap
2024-12-07 13:13:06 +01:00
sommermorgentraum 509bda2472 move Temprature debug app into external (#2411)
* remove commented out code
2024-12-07 12:38:15 +01:00
Erwin Ried f5e6cb0d96 Update README.md
Removing the upper warning of scams, since it has been calm last half year and temporal link after another H2 item was taken down
2024-12-07 11:01:41 +01:00
Bernd Herzog 8e2442f196 Add fresh build of hackrf firmware to firmware zip (#2409)
* added fresh build of hackrf firmware to firmware zip

* refactoring

* refactoring
2024-12-06 13:02:00 +01:00
29 changed files with 815 additions and 236 deletions
@@ -61,6 +61,9 @@ jobs:
- name: Unzip world map
run: |
unzip world_map.zip -d sdcard/ADSB
- name: Prepare Firmware ZIP
run: |
cp build/hackrf/firmware/hackrf_usb/hackrf_usb.dfu flashing/utils/hackrf_one_usb.dfu && cp build/hackrf/firmware/hackrf_usb/hackrf_usb.bin flashing/utils/hackrf_one_usb.bin
- name: Create Firmware ZIP
run: |
zip -j firmware.zip build/firmware/portapack-mayhem-firmware.bin && cd flashing && zip -r ../firmware.zip *
@@ -45,6 +45,9 @@ jobs:
- name: Unzip world map
run: |
unzip world_map.zip -d sdcard/ADSB
- name: Prepare Firmware ZIP
run: |
cp build/hackrf/firmware/hackrf_usb/hackrf_usb.dfu flashing/utils/hackrf_one_usb.dfu && cp build/hackrf/firmware/hackrf_usb/hackrf_usb.bin flashing/utils/hackrf_one_usb.bin
- name: Create Firmware ZIP
run: |
zip -j firmware.zip build/firmware/portapack-mayhem-firmware.bin && cd flashing && zip -r ../firmware.zip *
+1
View File
@@ -69,6 +69,7 @@ add_subdirectory(hackrf/firmware)
set(HACKRF_FIRMWARE_DFU_FILENAME hackrf_usb.dfu)
set(HACKRF_FIRMWARE_BIN_FILENAME hackrf_usb_ram.bin)
set(HACKRF_FIRMWARE_FILENAME hackrf_usb.bin)
set(HACKRF_CPLD_XSVF_FILENAME default.xsvf)
set(HACKRF_PATH ${CMAKE_CURRENT_LIST_DIR}/hackrf)
+9 -9
View File
@@ -1,8 +1,8 @@
<!---
> [!WARNING]
> __IF YOU'VE PAID FOR MAYHEM OR ANY PREPACKAGED VERSIONS, YOU'RE BEING SCAMMED.__
>
> The only legitimate link to our repositories is the [portapack-mayhem](https://github.com/portapack-mayhem/mayhem-firmware) organization on GitHub.
> The only legitimate link to our repositories is the [portapack-mayhem](https://github.com/portapack-mayhem/mayhem-firmware) organization on GitHub.--->
# PortaPack Mayhem
[![Nightly Release](https://github.com/portapack-mayhem/mayhem-firmware/actions/workflows/create_nightly_release.yml/badge.svg?branch=next)](https://github.com/portapack-mayhem/mayhem-firmware/actions/workflows/create_nightly_release.yml) [![CodeScene Code Health](https://codescene.io/projects/8381/status-badges/code-health)](https://codescene.io/projects/8381) [![GitHub All Releases](https://img.shields.io/github/downloads/portapack-mayhem/mayhem-firmware/total)](https://github.com/portapack-mayhem/mayhem-firmware/releases) [![GitHub Releases](https://img.shields.io/github/downloads/portapack-mayhem/mayhem-firmware/latest/total)](https://github.com/portapack-mayhem/mayhem-firmware/releases/latest) [![Docker Hub Pulls](https://img.shields.io/docker/pulls/eried/portapack.svg)](https://hub.docker.com/r/eried/portapack) [![Discord Chat](https://dcbadge.vercel.app/api/server/tuwVMv3?style=flat)](https://discord.gg/tuwVMv3)
@@ -11,15 +11,15 @@ This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/) firmw
[<img src="https://raw.githubusercontent.com/wiki/portapack-mayhem/mayhem-firmware/img/hw_overview_h2_front.png" height="400">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview) [<img src="https://raw.githubusercontent.com/wiki/portapack-mayhem/mayhem-firmware/img/hw_overview_h2_inside.png" height="400">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview#portapack-internals)
*[PortaPack H2+HackRF+battery](https://grabify.link/P9CO0J) (clone) with a custom [3d printed case](https://github.com/portapack-mayhem/mayhem-firmware/wiki/3d-printed-enclosure)*
*[PortaPack H2+HackRF+battery](https://www.ebay.com/itm/116382397447) (clone) with a custom [3d printed case](https://github.com/portapack-mayhem/mayhem-firmware/wiki/3d-printed-enclosure)*
# What is this?
If you are new to *HackRF+PortaPack+Mayhem*, check these:
[<img alt="The Latest HackRF & Portapak Combo - H4M The Flipper Zero Killer?" src="https://img.youtube.com/vi/Ew2qDgm2hf0/maxresdefault.jpg" width="701">](https://grabify.link/6HKX9A)
[<img alt="The Latest HackRF & Portapak Combo - H4M The Flipper Zero Killer?" src="https://img.youtube.com/vi/Ew2qDgm2hf0/maxresdefault.jpg" width="701">](https://share.hackrf.app/6HKX9A)
[<img alt="Its TOO Easy to Accidentally Do Illegal Stuff with This" src="https://img.youtube.com/vi/OPckpjBSAOw/maxresdefault.jpg" width="172">](https://grabify.link/X4D5TF) [<img alt="HackRF Portapack H4M - Getting Started Guide" src="https://img.youtube.com/vi/wzP0zWi85SI/maxresdefault.jpg" width="172">](https://grabify.link/F9MPOO) [<img alt="The new HackRF Portapack H4M" src="https://img.youtube.com/vi/onQRdCITmuk/maxresdefault.jpg" width="172">](https://grabify.link/0JUHZ6) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="172">](https://grabify.link/C0J6ZR)
[<img alt="Its TOO Easy to Accidentally Do Illegal Stuff with This" src="https://img.youtube.com/vi/OPckpjBSAOw/maxresdefault.jpg" width="172">](https://share.hackrf.app/X4D5TF) [<img alt="HackRF Portapack H4M - Getting Started Guide" src="https://img.youtube.com/vi/wzP0zWi85SI/maxresdefault.jpg" width="172">](https://share.hackrf.app/F9MPOO) [<img alt="The new HackRF Portapack H4M" src="https://img.youtube.com/vi/onQRdCITmuk/maxresdefault.jpg" width="172">](https://share.hackrf.app/0JUHZ6) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="172">](https://share.hackrf.app/C0J6ZR)
# Frequently Asked Questions
@@ -27,12 +27,12 @@ This repository expands upon the previous work by many people and aims to consta
## What to buy?
<!---not direct to h4m but to opensourcesdrlab https://grabify.link/TUOLYI--->
:heavy_check_mark: ![Static Badge](https://img.shields.io/badge/NEW-yellow) The fabulous [PortaPack H4M Mayhem](https://grabify.link/0STXCA), featuring numerous improvements and accessories. Sold by our friends at [OpenSourceSDRLab](https://grabify.link/99SAMT). Join their giveaways on discord (check the badge on top).
<!---not direct to h4m but to opensourcesdrlab https://share.hackrf.app/TUOLYI--->
:heavy_check_mark: ![Static Badge](https://img.shields.io/badge/NEW-yellow) The fabulous [PortaPack H4M Mayhem](https://share.hackrf.app/0STXCA), featuring numerous improvements and accessories. Sold by our friends at [OpenSourceSDRLab](https://share.hackrf.app/99SAMT). Join their giveaways on discord (check the badge on top).
:heavy_check_mark: A recommended one is this [PortaPack H2](https://grabify.link/P9CO0J), that includes everything you need with the plastic case "inspired" on [this](https://github.com/portapack-mayhem/mayhem-firmware/wiki/3d-printed-enclosure).
:heavy_check_mark: A recommended one is this [PortaPack H2](https://www.ebay.com/itm/116382397447), that includes everything you need with the plastic case "inspired" on [this](https://github.com/portapack-mayhem/mayhem-firmware/wiki/3d-printed-enclosure).
:heavy_check_mark: Some individuals lean towards the [H2 with a metal enclosure](https://grabify.link/LZPBH9), but its advantages remain debated. Share your insights on our [wiki](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview).
:heavy_check_mark: Some individuals lean towards the [H2 with a metal enclosure](https://share.hackrf.app/LZPBH9), but its advantages remain debated. Share your insights on our [wiki](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview).
:warning: Be cautious , *ask* the seller about compatibility with the latest releases. Look out for the description of the item, if they provide the firmware files for an older version or they have custom setup instructions, this means it might be **NOT compatible**, for example:
+1 -1
View File
@@ -64,7 +64,7 @@ add_custom_command(
add_custom_target(
firmware
DEPENDS ${FIRMWARE_FILENAME} ${HACKRF_FIRMWARE_DFU_FILENAME}
DEPENDS ${FIRMWARE_FILENAME} ${HACKRF_FIRMWARE_DFU_FILENAME} ${HACKRF_FIRMWARE_FILENAME}
)
if(${GCC_VERSION_MISMATCH})
+16 -2
View File
@@ -102,6 +102,21 @@ include(external/external.cmake)
# Define linker script file here
set(LDSCRIPT ${PORTLD}/LPC43xx_M0.ld)
# Special case for these two files:
# Originally these are compiled for M4 support, but in Mayhem we use them with M0
# As a result they are generating a lot of noise warnings
# Since they are not really using the defines stated in the warnings
# Since the only used one (NVIC_USB0_IRQ) is having the same value in both M0 and M4 mode
# => We are faking M4 mode on them
set(NO_WARNINGS_USBFILES
${HACKRF_PATH}/firmware/common/usb.c
${HACKRF_PATH}/firmware/common/usb_queue.c
)
# -DLPC43XX_M4 kills the 'warning: "NVIC_XXXX..." redefined'
# -D__ARM_ARCH_7M__ kills the 'warning: implicit declaration of function __ldrex && __sdrex'
set_source_files_properties(${NO_WARNINGS_USBFILES} PROPERTIES COMPILE_FLAGS "-DLPC43XX_M4 -D__ARM_ARCH_7M__")
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
set(CSRC
@@ -118,8 +133,7 @@ set(CSRC
usb_serial_endpoints.c
usb_serial_device_to_host.c
i2c_device_to_host.c
${HACKRF_PATH}/firmware/common/usb.c
${HACKRF_PATH}/firmware/common/usb_queue.c
${NO_WARNINGS_USBFILES}
${HACKRF_PATH}/firmware/hackrf_usb/usb_device.c
${HACKRF_PATH}/firmware/common/usb_request.c
${HACKRF_PATH}/firmware/common/usb_standard_request.c
-88
View File
@@ -74,91 +74,6 @@ void DebugMemoryView::focus() {
button_done.focus();
}
/* TemperatureWidget *****************************************************/
void TemperatureWidget::paint(Painter& painter) {
const auto logger = portapack::temperature_logger;
const auto rect = screen_rect();
const Color color_background{0, 0, 64};
const Color color_foreground = Theme::getInstance()->fg_green->foreground;
const Color color_reticle{128, 128, 128};
const auto graph_width = static_cast<int>(logger.capacity()) * bar_width;
const Rect graph_rect{
rect.left() + (rect.width() - graph_width) / 2, rect.top() + 8,
graph_width, rect.height()};
const Rect frame_rect{
graph_rect.left() - 1, graph_rect.top() - 1,
graph_rect.width() + 2, graph_rect.height() + 2};
painter.draw_rectangle(frame_rect, color_reticle);
painter.fill_rectangle(graph_rect, color_background);
const auto history = logger.history();
for (size_t i = 0; i < history.size(); i++) {
const Coord x = graph_rect.right() - (history.size() - i) * bar_width;
const auto sample = history[i];
const auto temp = temperature(sample);
const auto y = screen_y(temp, graph_rect);
const Dim bar_height = graph_rect.bottom() - y;
painter.fill_rectangle({x, y, bar_width, bar_height}, color_foreground);
}
if (!history.empty()) {
const auto sample = history.back();
const auto temp = temperature(sample);
const auto last_y = screen_y(temp, graph_rect);
const Coord x = graph_rect.right() + 8;
const Coord y = last_y - 8;
painter.draw_string({x, y}, style(), temperature_str(temp));
}
const auto display_temp_max = display_temp_min + (graph_rect.height() / display_temp_scale);
for (auto temp = display_temp_min; temp <= display_temp_max; temp += 10) {
const int32_t tick_length = 6;
const auto tick_x = graph_rect.left() - tick_length;
const auto tick_y = screen_y(temp, graph_rect);
painter.fill_rectangle({tick_x, tick_y, tick_length, 1}, color_reticle);
const auto text_x = graph_rect.left() - temp_len * 8 - 8;
const auto text_y = tick_y - 8;
painter.draw_string({text_x, text_y}, style(), temperature_str(temp));
}
}
TemperatureWidget::temperature_t TemperatureWidget::temperature(const sample_t sensor_value) const {
// Scaling is different for MAX2837 vs MAX2839 so it's now done in the respective chip-specific module
return sensor_value;
}
std::string TemperatureWidget::temperature_str(const temperature_t temperature) const {
return to_string_dec_int(temperature, temp_len - 2) + STR_DEGREES_C;
}
Coord TemperatureWidget::screen_y(
const temperature_t temperature,
const Rect& rect) const {
int y_raw = rect.bottom() - ((temperature - display_temp_min) * display_temp_scale);
const auto y_limit = std::min(rect.bottom(), std::max(rect.top(), y_raw));
return y_limit;
}
/* TemperatureView *******************************************************/
TemperatureView::TemperatureView(NavigationView& nav) {
add_children({
&text_title,
&temperature_widget,
&button_done,
});
button_done.on_select = [&nav](Button&) { nav.pop(); };
}
void TemperatureView::focus() {
button_done.focus();
}
/* RegistersWidget *******************************************************/
RegistersWidget::RegistersWidget(
@@ -507,12 +422,9 @@ void DebugMenuView::on_populate() {
{"Debug Dump", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { portapack::persistent_memory::debug_dump(); }},
{"M0 Stack Dump", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { stack_dump(); }},
{"Memory Dump", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push<DebugMemoryDumpView>(); }},
//{"Memory Usage", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push<DebugMemoryView>(); }},
{"Peripherals", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals, [this]() { nav_.push<DebugPeripheralsMenuView>(); }},
{"Pers. Memory", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_memory, [this]() { nav_.push<DebugPmemView>(); }},
//{ "Radio State", ui::Theme::getInstance()->bg_darkest->foreground, nullptr, [this](){ nav_.push<NotImplementedView>(); } },
{"SD Card", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_sdcard, [this]() { nav_.push<SDCardDebugView>(); }},
{"Temperature", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_temperature, [this]() { nav_.push<TemperatureView>(); }},
{"Touch Test", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_notepad, [this]() { nav_.push<DebugScreenTest>(); }},
{"Reboot", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_setup, [this]() { nav_.push<DebugReboot>(); }},
{"Ext Module", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push<ExternalModuleView>(); }},
-47
View File
@@ -86,53 +86,6 @@ class DebugMemoryView : public View {
"Done"};
};
class TemperatureWidget : public Widget {
public:
explicit TemperatureWidget(
Rect parent_rect)
: Widget{parent_rect} {
}
void paint(Painter& painter) override;
private:
using sample_t = uint32_t;
using temperature_t = int32_t;
temperature_t temperature(const sample_t sensor_value) const;
Coord screen_y(const temperature_t temperature, const Rect& screen_rect) const;
std::string temperature_str(const temperature_t temperature) const;
static constexpr temperature_t display_temp_min = -10; // Accomodate negative values, present in cold startup cases
static constexpr temperature_t display_temp_scale = 3;
static constexpr int bar_width = 1;
static constexpr int temp_len = 5; // Now scale shows up to 5 chars ("-10ºC")
};
class TemperatureView : public View {
public:
explicit TemperatureView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Temperature"; };
private:
Text text_title{
{76, 16, 240, 16},
"Temperature",
};
TemperatureWidget temperature_widget{
{0, 40, 240, 180},
};
Button button_done{
{72, 264, 96, 24},
"Done"};
};
typedef enum {
CT_PMEM,
CT_RFFC5072,
+10 -3
View File
@@ -751,10 +751,17 @@ FileManagerView::FileManagerView(
text_date.set("Too many files!");
} else {
text_date.set_style(Theme::getInstance()->fg_medium);
if (selected_is_valid())
text_date.set((is_directory(get_selected_full_path()) ? "Created " : "Modified ") + to_string_FAT_timestamp(file_created_date(get_selected_full_path())));
else
if (selected_is_valid()) {
if (get_selected_entry().path == str_back) {
text_date.set("Go page " + std::to_string(pagination + 1 - 1)); // for better explain, pagination start with 0 AKA real page - 1
} else if (get_selected_entry().path == str_next) {
text_date.set("Go page " + std::to_string(pagination + 1 + 1)); // when show this, it should display current AKA (pagination + 1) + 1 AKA next page
} else {
text_date.set((is_directory(get_selected_full_path()) ? "Created " : "Modified ") + to_string_FAT_timestamp(file_created_date(get_selected_full_path())));
}
} else {
text_date.set("");
}
}
};
@@ -95,7 +95,7 @@ FlashUtilityView::FlashUtilityView(NavigationView& nav)
menu_view.add_item({filename.string().substr(0, max_filename_length),
color,
&bitmap_icon_temperature,
&bitmap_icon_peripherals_details,
[this, path](KeyEvent) {
this->firmware_selected(path);
}});
-38
View File
@@ -2531,44 +2531,6 @@ static constexpr Bitmap bitmap_icon_batt_icon{
{16, 16},
bitmap_icon_batt_icon_data};
static constexpr uint8_t bitmap_icon_temperature_data[] = {
0x00,
0x01,
0x80,
0x01,
0x80,
0x05,
0xC0,
0x0D,
0x40,
0x0D,
0xD0,
0x1F,
0x70,
0x15,
0xB0,
0x1A,
0x58,
0x35,
0xB8,
0x3A,
0x58,
0x34,
0x28,
0x28,
0x18,
0x30,
0x30,
0x18,
0x60,
0x0C,
0xC0,
0x07,
};
static constexpr Bitmap bitmap_icon_temperature{
{16, 16},
bitmap_icon_temperature_data};
static constexpr uint8_t bitmap_tab_edge_data[] = {
0x00,
0x01,
+11
View File
@@ -130,6 +130,15 @@ set(EXTCPPSRC
#remote
external/remote/main.cpp
external/remote/ui_remote.cpp
#mcu_temperature
external/mcu_temperature/main.cpp
external/mcu_temperature/mcu_temperature.cpp
#fmradio
external/fmradio/main.cpp
external/fmradio/ui_fmradio.cpp
)
set(EXTAPPLIST
@@ -164,4 +173,6 @@ set(EXTAPPLIST
shoppingcart_lock
flippertx
remote
mcu_temperature
fmradio
)
+15
View File
@@ -54,6 +54,8 @@ MEMORY
ram_external_app_flippertx(rwx) : org = 0xADCD0000, len = 32k
ram_external_app_ook_editor(rwx) : org = 0xADCE0000, len = 32k
ram_external_app_remote(rwx) : org = 0xADCF0000, len = 32k
ram_external_app_mcu_temperature(rwx) : org = 0xADD00000, len = 32k
ram_external_app_fmradio(rwx) : org = 0xADE00000, len = 32k
}
SECTIONS
@@ -244,4 +246,17 @@ SECTIONS
KEEP(*(.external_app.app_remote.application_information));
*(*ui*external_app*remote*);
} > ram_external_app_remote
.external_app_mcu_temperature : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_mcu_temperature.application_information));
*(*ui*external_app*mcu_temperature*);
} > ram_external_app_mcu_temperature
.external_app_fmradio : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_fmradio.application_information));
*(*ui*external_app*fmradio*);
} > ram_external_app_fmradio
}
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2024 HTotoo
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include "ui_fmradio.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::fmradio {
void initialize_app(ui::NavigationView& nav) {
nav.push<FmRadioView>();
}
} // namespace ui::external_app::fmradio
extern "C" {
__attribute__((section(".external_app.app_fmradio.application_information"), used)) application_information_t _application_information_fmradio = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::fmradio::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "FM Radio",
/*.bitmap_data = */ {
0x00,
0x00,
0x00,
0x00,
0x04,
0x20,
0x12,
0x48,
0x8A,
0x51,
0xCA,
0x53,
0xCA,
0x53,
0x8A,
0x51,
0x12,
0x48,
0x84,
0x21,
0xC0,
0x03,
0x40,
0x02,
0x60,
0x06,
0x20,
0x04,
0x30,
0x0C,
0xF0,
0x0F,
},
/*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::RX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_wfm_audio */ {'P', 'W', 'F', 'M'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
+168
View File
@@ -0,0 +1,168 @@
/*
* Copyright (C) 2024 HTotoo
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_fmradio.hpp"
#include "audio.hpp"
#include "rtc_time.hpp"
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
using namespace modems;
using namespace ui;
namespace ui::external_app::fmradio {
void FmRadioView::focus() {
field_frequency.focus();
}
FmRadioView::FmRadioView(NavigationView& nav)
: nav_{nav} {
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
add_children({&rssi,
&field_rf_amp,
&field_lna,
&field_vga,
&field_volume,
&field_frequency,
&btn_fav_save,
&txt_save_help,
&btn_fav_0,
&btn_fav_1,
&btn_fav_2,
&btn_fav_3,
&btn_fav_4,
&btn_fav_5,
&btn_fav_6,
&btn_fav_7,
&btn_fav_8,
&btn_fav_9,
&audio,
&waveform});
txt_save_help.visible(false);
for (uint8_t i = 0; i < 12; ++i) {
if (freq_fav_list[i] == 0) {
freq_fav_list[i] = 87000000;
}
}
if (field_frequency.value() == 0) {
field_frequency.set_value(87000000);
}
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
field_frequency.set_step(25000);
receiver_model.enable();
audio::output::start();
btn_fav_0.on_select = [this](Button&) {
on_btn_clicked(0);
};
btn_fav_1.on_select = [this](Button&) {
on_btn_clicked(1);
};
btn_fav_2.on_select = [this](Button&) {
on_btn_clicked(2);
};
btn_fav_3.on_select = [this](Button&) {
on_btn_clicked(3);
};
btn_fav_4.on_select = [this](Button&) {
on_btn_clicked(4);
};
btn_fav_5.on_select = [this](Button&) {
on_btn_clicked(5);
};
btn_fav_6.on_select = [this](Button&) {
on_btn_clicked(6);
};
btn_fav_7.on_select = [this](Button&) {
on_btn_clicked(7);
};
btn_fav_8.on_select = [this](Button&) {
on_btn_clicked(8);
};
btn_fav_9.on_select = [this](Button&) {
on_btn_clicked(9);
};
btn_fav_save.on_select = [this](Button&) {
save_fav = !save_fav;
txt_save_help.set_text(save_fav ? "Select slot" : "");
txt_save_help.visible(save_fav);
txt_save_help.set_dirty();
};
update_fav_btn_texts();
}
void FmRadioView::on_btn_clicked(uint8_t i) {
if (save_fav) {
save_fav = false;
freq_fav_list[i] = field_frequency.value();
update_fav_btn_texts();
txt_save_help.visible(save_fav);
txt_save_help.set_text("");
txt_save_help.set_dirty();
return;
}
field_frequency.set_value(freq_fav_list[i]);
}
std::string FmRadioView::to_nice_freq(rf::Frequency freq) {
std::string nice = to_string_dec_uint(freq / 1000000);
nice += ".";
nice += to_string_dec_uint((freq / 10000) % 100);
return nice;
}
void FmRadioView::update_fav_btn_texts() {
btn_fav_0.set_text(to_nice_freq(freq_fav_list[0]));
btn_fav_1.set_text(to_nice_freq(freq_fav_list[1]));
btn_fav_2.set_text(to_nice_freq(freq_fav_list[2]));
btn_fav_3.set_text(to_nice_freq(freq_fav_list[3]));
btn_fav_4.set_text(to_nice_freq(freq_fav_list[4]));
btn_fav_5.set_text(to_nice_freq(freq_fav_list[5]));
btn_fav_6.set_text(to_nice_freq(freq_fav_list[6]));
btn_fav_7.set_text(to_nice_freq(freq_fav_list[7]));
btn_fav_8.set_text(to_nice_freq(freq_fav_list[8]));
btn_fav_9.set_text(to_nice_freq(freq_fav_list[9]));
}
FmRadioView::~FmRadioView() {
receiver_model.disable();
baseband::shutdown();
audio::output::stop();
}
void FmRadioView::on_audio_spectrum() {
for (size_t i = 0; i < audio_spectrum_data->db.size(); i++)
audio_spectrum[i] = ((int16_t)audio_spectrum_data->db[i] - 127) * 256;
waveform.set_dirty();
}
} // namespace ui::external_app::fmradio
+150
View File
@@ -0,0 +1,150 @@
/*
* Copyright (C) 2024 HTotoo
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
/*
FUTURE TODO: implement search function.
*/
#ifndef __UI_fmradio_H__
#define __UI_fmradio_H__
#include "ui.hpp"
#include "ui_language.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "ui_geomap.hpp"
#include "ui_freq_field.hpp"
#include "ui_spectrum.hpp"
#include "ui_record_view.hpp"
#include "app_settings.hpp"
#include "radio_state.hpp"
#include "log_file.hpp"
#include "utility.hpp"
using namespace ui;
namespace ui::external_app::fmradio {
#define FMR_BTNGRID_TOP 60
class FmRadioView : public View {
public:
FmRadioView(NavigationView& nav);
FmRadioView& operator=(const FmRadioView&) = delete;
FmRadioView(const FmRadioView&) = delete;
~FmRadioView();
void focus() override;
std::string title() const override { return "FM radio"; };
private:
NavigationView& nav_;
RxRadioState radio_state_{};
int16_t audio_spectrum[128]{0};
bool audio_spectrum_update = false;
AudioSpectrum* audio_spectrum_data{nullptr};
rf::Frequency freq_fav_list[12] = {0};
app_settings::SettingsManager settings_{
"rx_fmradio",
app_settings::Mode::RX,
{{"favlist0"sv, &freq_fav_list[0]},
{"favlist1"sv, &freq_fav_list[1]},
{"favlist2"sv, &freq_fav_list[2]},
{"favlist3"sv, &freq_fav_list[3]},
{"favlist4"sv, &freq_fav_list[4]},
{"favlist5"sv, &freq_fav_list[5]},
{"favlist6"sv, &freq_fav_list[6]},
{"favlist7"sv, &freq_fav_list[7]},
{"favlist8"sv, &freq_fav_list[8]},
{"favlist9"sv, &freq_fav_list[9]},
{"favlist10"sv, &freq_fav_list[10]},
{"favlist11"sv, &freq_fav_list[11]}}};
RFAmpField field_rf_amp{
{13 * 8, 0 * 16}};
LNAGainField field_lna{
{15 * 8, 0 * 16}};
VGAGainField field_vga{
{18 * 8, 0 * 16}};
RSSI rssi{
{21 * 8, 0, 6 * 8, 4}};
AudioVolumeField field_volume{
{28 * 8, 0 * 16}};
RxFrequencyField field_frequency{
{0 * 8, 0 * 16},
nav_};
TextField txt_save_help{
{2, FMR_BTNGRID_TOP + 6 * 34 - 20, 12 * 8, 16},
" "};
Audio audio{
{21 * 8, 10, 6 * 8, 4}};
Waveform waveform{
{0, 20, 30 * 8, 2 * 16},
audio_spectrum,
128,
0,
false,
Theme::getInstance()->bg_darkest->foreground};
Button btn_fav_0{{2, FMR_BTNGRID_TOP + 0 * 34, 10 * 8, 28}, "---"};
Button btn_fav_1{{2 + 15 * 8, FMR_BTNGRID_TOP + 0 * 34, 10 * 8, 28}, "---"};
Button btn_fav_2{{2, FMR_BTNGRID_TOP + 1 * 34, 10 * 8, 28}, "---"};
Button btn_fav_3{{2 + 15 * 8, FMR_BTNGRID_TOP + 1 * 34, 10 * 8, 28}, "---"};
Button btn_fav_4{{2, FMR_BTNGRID_TOP + 2 * 34, 10 * 8, 28}, "---"};
Button btn_fav_5{{2 + 15 * 8, FMR_BTNGRID_TOP + 2 * 34, 10 * 8, 28}, "---"};
Button btn_fav_6{{2, FMR_BTNGRID_TOP + 3 * 34, 10 * 8, 28}, "---"};
Button btn_fav_7{{2 + 15 * 8, FMR_BTNGRID_TOP + 3 * 34, 10 * 8, 28}, "---"};
Button btn_fav_8{{2, FMR_BTNGRID_TOP + 4 * 34, 10 * 8, 28}, "---"};
Button btn_fav_9{{2 + 15 * 8, FMR_BTNGRID_TOP + 4 * 34, 10 * 8, 28}, "---"};
Button btn_fav_save{{2, FMR_BTNGRID_TOP + 6 * 34, 7 * 8, 1 * 28}, "Save"};
bool save_fav = false;
void on_btn_clicked(uint8_t i);
void update_fav_btn_texts();
std::string to_nice_freq(rf::Frequency freq);
void on_audio_spectrum();
MessageHandlerRegistration message_handler_audio_spectrum{
Message::ID::AudioSpectrum,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const AudioSpectrumMessage*>(p);
audio_spectrum_data = message.data;
audio_spectrum_update = true;
}};
MessageHandlerRegistration message_handler_frame_sync{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
if (audio_spectrum_update) {
audio_spectrum_update = false;
on_audio_spectrum();
}
}};
};
} // namespace ui::external_app::fmradio
#endif /*__UI_fmradio_H__*/
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2024 Bernd Herzog
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include "mcu_temperature.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::mcu_temperature {
void initialize_app(ui::NavigationView& nav) {
nav.push<McuTemperatureView>();
}
} // namespace ui::external_app::mcu_temperature
extern "C" {
__attribute__((section(".external_app.app_mcu_temperature.application_information"), used)) application_information_t _application_information_mcu_temperature = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::mcu_temperature::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "Temperature",
/*.bitmap_data = */ {
0x00,
0x00,
0x20,
0x00,
0x70,
0x3E,
0x88,
0x00,
0x88,
0x00,
0x88,
0x3E,
0x88,
0x00,
0x88,
0x00,
0x88,
0x3E,
0x88,
0x00,
0x04,
0x01,
0x74,
0x01,
0x04,
0x01,
0x88,
0x00,
0x70,
0x00,
0x00,
0x00,
},
/*.icon_color = */ ui::Color::cyan().v,
/*.menu_location = */ app_location_t::DEBUG,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
@@ -0,0 +1,91 @@
#include "mcu_temperature.hpp"
#include "ui_painter.hpp"
#include "portapack.hpp"
using namespace portapack;
namespace ui::external_app::mcu_temperature {
void McuTemperatureWidget::paint(Painter& painter) {
const auto logger = portapack::temperature_logger;
const auto rect = screen_rect();
const Color color_background{0, 0, 64};
const Color color_foreground = Theme::getInstance()->fg_green->foreground;
const Color color_reticle{128, 128, 128};
const auto graph_width = static_cast<int>(logger.capacity()) * bar_width;
const Rect graph_rect{
rect.left() + (rect.width() - graph_width) / 2, rect.top() + 8,
graph_width, rect.height()};
const Rect frame_rect{
graph_rect.left() - 1, graph_rect.top() - 1,
graph_rect.width() + 2, graph_rect.height() + 2};
painter.draw_rectangle(frame_rect, color_reticle);
painter.fill_rectangle(graph_rect, color_background);
const auto history = logger.history();
for (size_t i = 0; i < history.size(); i++) {
const Coord x = graph_rect.right() - (history.size() - i) * bar_width;
const auto sample = history[i];
const auto temp = temperature(sample);
const auto y = screen_y(temp, graph_rect);
const Dim bar_height = graph_rect.bottom() - y;
painter.fill_rectangle({x, y, bar_width, bar_height}, color_foreground);
}
if (!history.empty()) {
const auto sample = history.back();
const auto temp = temperature(sample);
const auto last_y = screen_y(temp, graph_rect);
const Coord x = graph_rect.right() + 8;
const Coord y = last_y - 8;
painter.draw_string({x, y}, style(), temperature_str(temp));
}
const auto display_temp_max = display_temp_min + (graph_rect.height() / display_temp_scale);
for (auto temp = display_temp_min; temp <= display_temp_max; temp += 10) {
const int32_t tick_length = 6;
const auto tick_x = graph_rect.left() - tick_length;
const auto tick_y = screen_y(temp, graph_rect);
painter.fill_rectangle({tick_x, tick_y, tick_length, 1}, color_reticle);
const auto text_x = graph_rect.left() - temp_len * 8 - 8;
const auto text_y = tick_y - 8;
painter.draw_string({text_x, text_y}, style(), temperature_str(temp));
}
}
McuTemperatureWidget::temperature_t McuTemperatureWidget::temperature(const sample_t sensor_value) const {
// Scaling is different for MAX2837 vs MAX2839 so it's now done in the respective chip-specific module
return sensor_value;
}
std::string McuTemperatureWidget::temperature_str(const temperature_t temperature) const {
return to_string_dec_int(temperature, temp_len - 2) + STR_DEGREES_C;
}
Coord McuTemperatureWidget::screen_y(
const temperature_t temperature,
const Rect& rect) const {
int y_raw = rect.bottom() - ((temperature - display_temp_min) * display_temp_scale);
const auto y_limit = std::min(rect.bottom(), std::max(rect.top(), y_raw));
return y_limit;
}
McuTemperatureView::McuTemperatureView(NavigationView& nav) {
add_children({
&text_title,
&temperature_widget,
&button_done,
});
button_done.on_select = [&nav](Button&) { nav.pop(); };
}
void McuTemperatureView::focus() {
button_done.focus();
}
} // namespace ui::external_app::mcu_temperature
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __MCU_TEMPERATURE_H__
#define __MCU_TEMPERATURE_H__
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_painter.hpp"
#include "ui_menu.hpp"
#include "ui_navigation.hpp"
#include "rffc507x.hpp"
#include "portapack.hpp"
#include "memory_map.hpp"
#include "irq_controls.hpp"
#include <functional>
#include <utility>
namespace ui::external_app::mcu_temperature {
class McuTemperatureWidget : public Widget {
public:
explicit McuTemperatureWidget(
Rect parent_rect)
: Widget{parent_rect} {
}
void paint(Painter& painter) override;
private:
using sample_t = uint32_t;
using temperature_t = int32_t;
temperature_t temperature(const sample_t sensor_value) const;
Coord screen_y(const temperature_t temperature, const Rect& screen_rect) const;
std::string temperature_str(const temperature_t temperature) const;
static constexpr temperature_t display_temp_min = -10; // Accomodate negative values, present in cold startup cases
static constexpr temperature_t display_temp_scale = 3;
static constexpr int bar_width = 1;
static constexpr int temp_len = 5; // Now scale shows up to 5 chars ("-10ºC")
};
class McuTemperatureView : public View {
public:
explicit McuTemperatureView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Temperature"; };
private:
Text text_title{
{76, 16, 240, 16},
"Temperature",
};
McuTemperatureWidget temperature_widget{
{0, 40, 240, 180},
};
Button button_done{
{72, 264, 96, 24},
"Done"};
};
} // namespace ui::external_app::mcu_temperature
#endif /*__MCU_TEMPERATURE_H__*/
+1 -1
View File
@@ -84,7 +84,7 @@ class RemoteIcons {
&bitmap_icon_sonde,
&bitmap_icon_stealth,
&bitmap_icon_tetra,
&bitmap_icon_temperature};
&bitmap_icon_peripherals_details};
};
// TODO: Use RGB colors instead?
+1 -1
View File
@@ -344,7 +344,7 @@ class GeoMapView : public View {
{0, GeoMap::banner_height, GeoMap::geomap_rect_width, GeoMap::geomap_rect_height}};
Button button_ok{
{20 * 8, 8, 8 * 8, 2 * 16},
{screen_width - 15 * 8, 0, 15 * 8, 1 * 16},
"OK"};
};
+17 -5
View File
@@ -174,7 +174,7 @@ const NavigationView::AppList NavigationView::appList = {
{"wavview", "Wav View", UTILITIES, Color::yellow(), &bitmap_icon_soundboard, new ViewFactory<ViewWavView>()},
// Dangerous apps.
{nullptr, "Flash Utility", UTILITIES, Color::red(), &bitmap_icon_temperature, new ViewFactory<FlashUtilityView>()},
{nullptr, "Flash Utility", UTILITIES, Color::red(), &bitmap_icon_peripherals_details, new ViewFactory<FlashUtilityView>()},
{nullptr, "Wipe SD card", UTILITIES, Color::red(), &bitmap_icon_tools_wipesd, new ViewFactory<WipeSDView>()},
};
@@ -330,6 +330,7 @@ SystemStatusView::SystemStatusView(
audio::output::stop();
audio::output::update_audio_mute();
refresh();
}
@@ -761,10 +762,10 @@ static void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc)
}
// clang-format off
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t notice_pos) {
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos) {
auto externalItems = ExternalItemsMenuLoader::load_external_items(location, nav);
if (externalItems.empty()) {
grid.insert_item({"Notice!",
grid.insert_item({"ExtAppErr",
Theme::getInstance()->error_dark->foreground,
nullptr,
[&nav]() {
@@ -774,7 +775,7 @@ void add_external_items(NavigationView& nav, app_location_t location, BtnGridVie
"see Mayhem wiki and copy apps\n"
"to " + apps_dir.string() + " folder of SD card.");
}},
notice_pos);
error_tile_pos);
} else {
std::sort(externalItems.begin(), externalItems.end(), [](const auto &a, const auto &b)
{
@@ -795,6 +796,12 @@ void add_external_items(NavigationView& nav, app_location_t location, BtnGridVie
}
// clang-format on
bool verify_sdcard_format() {
FATFS* fs = &sd_card::fs;
return (fs->fs_type == FS_FAT32) || !(sd_card::status() == sd_card::Status::Mounted);
/* ^ to satisfy those users that not use an sd*/
}
/* ReceiversMenuView *****************************************************/
ReceiversMenuView::ReceiversMenuView(NavigationView& nav)
@@ -866,8 +873,13 @@ SystemMenuView::SystemMenuView(NavigationView& nav)
}
void SystemMenuView::on_populate() {
if (!verify_sdcard_format()) {
add_item({"SDCard Error", Theme::getInstance()->error_dark->foreground, nullptr, [this]() {
nav_.display_modal("Error", "SD Card is not FAT32,\nformat to FAT32 on PC");
}});
}
add_apps(nav_, *this, HOME);
add_external_items(nav_, app_location_t::HOME, *this, 2);
add_external_items(nav_, app_location_t::HOME, *this, 0);
add_item({"HackRF", Theme::getInstance()->fg_cyan->foreground, &bitmap_icon_hackrf, [this]() { hackrf_mode(nav_); }});
}
+2 -1
View File
@@ -197,6 +197,7 @@ class SystemStatusView : public View {
static constexpr auto default_title = "";
bool batt_was_inited = false; // if the battery was off on tart, but later turned on.
bool batt_info_up = false; // to prevent show multiple batt info dialog
NavigationView& nav_;
Rectangle backdrop{
@@ -322,7 +323,7 @@ class InformationView : public View {
Rectangle backdrop{
{0, 0 * 16, 240, 16},
{33, 33, 33}};
Theme::getInstance()->bg_darker->background};
Text version{
{2, 0, 11 * 8, 16},
+44 -7
View File
@@ -240,21 +240,16 @@ namespace ui {
SDCardDebugView::SDCardDebugView(NavigationView& nav) {
add_children({
&text_title,
&text_csd_title,
&labels,
&text_format,
&text_csd_value_3,
&text_csd_value_2,
&text_csd_value_1,
&text_csd_value_0,
&text_bus_width_title,
&text_bus_width_value,
&text_card_type_title,
&text_card_type_value,
&text_block_size_title,
&text_block_size_value,
&text_block_count_title,
&text_block_count_value,
&text_capacity_title,
&text_capacity_value,
&text_test_write_time_title,
&text_test_write_time_value,
@@ -374,6 +369,14 @@ void SDCardDebugView::on_status(const sd_card::Status) {
text_csd_value_1.set(to_string_hex(csd[1], 8));
text_csd_value_0.set(to_string_hex(csd[0], 8));
text_format.set(fetch_sdcard_format());
if (fetch_sdcard_format().find("FAT32") != std::string::npos) {
// to satisfy the intendent style in this app, the text contains padding space, thus can't use ==
text_format.set_style(Theme::getInstance()->fg_green);
} else {
text_format.set_style(Theme::getInstance()->error_dark);
}
BlockDeviceInfo block_device_info;
if (sdcGetInfo(&SDCD1, &block_device_info) == CH_SUCCESS) {
text_block_size_value.set(to_string_dec_uint(block_device_info.blk_size, 5));
@@ -447,4 +450,38 @@ void SDCardDebugView::on_test() {
}
}
std::string SDCardDebugView::fetch_sdcard_format() {
const size_t max_len = sizeof("Undefined: 255") + 1;
auto padding = [max_len](std::string s) {
if (s.length() < max_len) {
return std::string(max_len - s.length(), ' ') + s;
}
return s;
};
FATFS* fs = &sd_card::fs;
std::string resault;
switch (fs->fs_type) {
case FS_FAT12:
resault = "FAT12";
break;
case FS_FAT16:
resault = "FAT16";
break;
case FS_FAT32:
resault = "FAT32";
break;
case FS_EXFAT: // TODO: a bug from filesystem can't detect exfat, issue not from here
resault = "ExFAT";
break;
default:
resault = "Undefined: " + to_string_dec_uint(fs->fs_type, 1);
break;
}
return padding(resault);
}
} /* namespace ui */
+14 -31
View File
@@ -45,15 +45,23 @@ class SDCardDebugView : public View {
void on_status(const sd_card::Status status);
void on_test();
std::string fetch_sdcard_format();
Labels labels{
{{0 * 8, 1 * 16}, "Format", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "CSD", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 5 * 16}, "Bus width", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 6 * 16}, "Card type", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 8 * 16}, "Block size", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 9 * 16}, "Block count", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 10 * 16}, "Capacity", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 5 * 16}, "Bus width", Theme::getInstance()->fg_light->foreground},
Text text_title{
{(240 - (7 * 8)) / 2, 1 * 16, (7 * 8), 16},
"SD Card",
};
Text text_csd_title{
{0, 3 * 16, (8 * 8), 16},
"CSD",
Text text_format{
{240 - ((sizeof("Undefined: 255") + 1) * 8), 1 * 16, (sizeof("Undefined: 255") + 1) * 8, 16},
"Unknown",
};
Text text_csd_value_3{
@@ -78,11 +86,6 @@ class SDCardDebugView : public View {
static constexpr size_t bus_width_characters = 1;
Text text_bus_width_title{
{0, 5 * 16, (9 * 8), 16},
"Bus width",
};
Text text_bus_width_value{
{240 - (bus_width_characters * 8), 5 * 16, (bus_width_characters * 8), 16},
"",
@@ -90,11 +93,6 @@ class SDCardDebugView : public View {
static constexpr size_t card_type_characters = 13;
Text text_card_type_title{
{0, 6 * 16, (9 * 8), 16},
"Card type",
};
Text text_card_type_value{
{240 - (card_type_characters * 8), 6 * 16, (card_type_characters * 8), 16},
"",
@@ -102,11 +100,6 @@ class SDCardDebugView : public View {
static constexpr size_t block_size_characters = 5;
Text text_block_size_title{
{0, 8 * 16, (10 * 8), 16},
"Block size",
};
Text text_block_size_value{
{240 - (block_size_characters * 8), 8 * 16, (block_size_characters * 8), 16},
"",
@@ -114,11 +107,6 @@ class SDCardDebugView : public View {
static constexpr size_t block_count_characters = 9;
Text text_block_count_title{
{0, 9 * 16, (11 * 8), 16},
"Block count",
};
Text text_block_count_value{
{240 - (block_count_characters * 8), 9 * 16, (block_count_characters * 8), 16},
"",
@@ -126,11 +114,6 @@ class SDCardDebugView : public View {
static constexpr size_t capacity_characters = 10;
Text text_capacity_title{
{0, 10 * 16, (8 * 8), 16},
"Capacity",
};
Text text_capacity_value{
{240 - (capacity_characters * 8), 10 * 16, (capacity_characters * 8), 16},
"",
Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.
Binary file not shown.
+1 -1
Submodule hackrf updated: b30cd13d96...94dfae3f46