mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-20 14:39:01 +00:00
Improve SD Card Status Display and Error Handling (#3079)
Summary: Fixed SD card mount error detection by enabling immediate mounting, made the status icon clickable to access settings, and added real-time status display (including filesystem type) in the SD card settings page. Changes: - Changed f_mount() to immediate mounting for error detection - Made SD card status icon clickable, linking to an enhanced sd card settings page that now includes live display of card status and filesystem type - Removed "SDCard Error" menu item
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include "ui_external_items_menu_loader.hpp"
|
||||
#include "ui_ss_viewer.hpp"
|
||||
#include "ui_fileman.hpp"
|
||||
#include "ui_sd_card_debug.hpp"
|
||||
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
@@ -446,7 +447,11 @@ void SetUIView::focus() {
|
||||
/* SetSDCardView *********************************************/
|
||||
|
||||
SetSDCardView::SetSDCardView(NavigationView& nav) {
|
||||
add_children({&labels,
|
||||
add_children({&status_labels,
|
||||
&text_card_status,
|
||||
&text_filesystem_type,
|
||||
&button_more_info,
|
||||
&labels,
|
||||
&checkbox_sdcard_speed,
|
||||
&button_test_sdcard_high_speed,
|
||||
&text_sdcard_test_status,
|
||||
@@ -455,6 +460,10 @@ SetSDCardView::SetSDCardView(NavigationView& nav) {
|
||||
|
||||
checkbox_sdcard_speed.set_value(pmem::config_sdcard_high_speed_io());
|
||||
|
||||
button_more_info.on_select = [&nav, this](Button&) {
|
||||
nav.push<SDCardDebugView>();
|
||||
};
|
||||
|
||||
button_test_sdcard_high_speed.on_select = [&nav, this](Button&) {
|
||||
pmem::set_config_sdcard_high_speed_io(true, false);
|
||||
text_sdcard_test_status.set("!! HIGH SPEED MODE ON !!");
|
||||
@@ -472,7 +481,79 @@ SetSDCardView::SetSDCardView(NavigationView& nav) {
|
||||
}
|
||||
|
||||
void SetSDCardView::focus() {
|
||||
button_save.focus();
|
||||
button_cancel.focus();
|
||||
}
|
||||
|
||||
void SetSDCardView::on_show() {
|
||||
sd_card_status_signal_token = sd_card::status_signal += [this](const sd_card::Status) {
|
||||
update_sd_card_status();
|
||||
};
|
||||
|
||||
update_sd_card_status();
|
||||
}
|
||||
|
||||
void SetSDCardView::on_hide() {
|
||||
sd_card::status_signal -= sd_card_status_signal_token;
|
||||
}
|
||||
|
||||
void SetSDCardView::update_sd_card_status() {
|
||||
using sd_card::Status;
|
||||
|
||||
const auto status = sd_card::status();
|
||||
|
||||
// Update card status text
|
||||
switch (status) {
|
||||
case Status::NotPresent:
|
||||
text_card_status.set("Not Inserted");
|
||||
text_filesystem_type.set("---");
|
||||
break;
|
||||
case Status::Present:
|
||||
text_card_status.set("Inserted");
|
||||
text_filesystem_type.set("---");
|
||||
break;
|
||||
case Status::Mounted:
|
||||
text_card_status.set("Mounted");
|
||||
// Determine filesystem type
|
||||
{
|
||||
const auto fs_type = sd_card::fs.fs_type;
|
||||
std::string fs_name;
|
||||
switch (fs_type) {
|
||||
case FS_FAT12:
|
||||
fs_name = "FAT12";
|
||||
break;
|
||||
case FS_FAT16:
|
||||
fs_name = "FAT16";
|
||||
break;
|
||||
case FS_FAT32:
|
||||
fs_name = "FAT32";
|
||||
break;
|
||||
case FS_EXFAT:
|
||||
fs_name = "exFAT";
|
||||
break;
|
||||
default:
|
||||
fs_name = "Unknown";
|
||||
break;
|
||||
}
|
||||
text_filesystem_type.set(fs_name);
|
||||
}
|
||||
break;
|
||||
case Status::ConnectError:
|
||||
text_card_status.set("Connect Error");
|
||||
text_filesystem_type.set("---");
|
||||
break;
|
||||
case Status::MountError:
|
||||
text_card_status.set("Mount Error");
|
||||
text_filesystem_type.set("---");
|
||||
break;
|
||||
case Status::IOError:
|
||||
text_card_status.set("I/O Error");
|
||||
text_filesystem_type.set("---");
|
||||
break;
|
||||
default:
|
||||
text_card_status.set("Unknown");
|
||||
text_filesystem_type.set("---");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* SetConverterSettingsView ******************************/
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "ui_navigation.hpp"
|
||||
#include "bitmap.hpp"
|
||||
#include "ff.h"
|
||||
#include "sd_card.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "irq_controls.hpp"
|
||||
|
||||
@@ -424,36 +425,60 @@ class SetSDCardView : public View {
|
||||
public:
|
||||
SetSDCardView(NavigationView& nav);
|
||||
|
||||
void on_show() override;
|
||||
void on_hide() override;
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "SD Card"; };
|
||||
|
||||
private:
|
||||
SignalToken sd_card_status_signal_token{};
|
||||
// Status section (top half)
|
||||
Labels status_labels{
|
||||
{{10, 24}, "Card Status:", Theme::getInstance()->fg_light->foreground},
|
||||
{{10, 48}, "Filesystem:", Theme::getInstance()->fg_light->foreground}};
|
||||
|
||||
Text text_card_status{
|
||||
{120, 24, 110, 16},
|
||||
""};
|
||||
|
||||
Text text_filesystem_type{
|
||||
{120, 48, 110, 16},
|
||||
""};
|
||||
|
||||
Button button_more_info{
|
||||
{UI_POS_X_CENTER(20), 90, UI_POS_WIDTH(20), UI_POS_HEIGHT(2)},
|
||||
"More Info"};
|
||||
|
||||
// Settings section (bottom half)
|
||||
Labels labels{
|
||||
// 01234567890123456789012345678
|
||||
{{UI_POS_X_CENTER(26), 120 - 48}, " HIGH SPEED SDCARD IO ", Theme::getInstance()->fg_light->foreground},
|
||||
{{UI_POS_X_CENTER(26), 120 - 32}, " May or may not work !! ", Theme::getInstance()->fg_light->foreground}};
|
||||
{{UI_POS_X_CENTER(26), 140}, " HIGH SPEED SDCARD IO ", Theme::getInstance()->fg_light->foreground},
|
||||
{{UI_POS_X_CENTER(26), 156}, " May or may not work !! ", Theme::getInstance()->fg_light->foreground}};
|
||||
|
||||
Checkbox checkbox_sdcard_speed{
|
||||
{UI_POS_X_CENTER(26), 120},
|
||||
{UI_POS_X_CENTER(26), 180},
|
||||
20,
|
||||
"enable high speed IO"};
|
||||
|
||||
Button button_test_sdcard_high_speed{
|
||||
{UI_POS_X_CENTER(27), 152, UI_POS_WIDTH(27), UI_POS_HEIGHT(2)},
|
||||
{UI_POS_X_CENTER(27), 210, UI_POS_WIDTH(27), UI_POS_HEIGHT(2)},
|
||||
"TEST BUTTON (NO PMEM SAVE)"};
|
||||
|
||||
Text text_sdcard_test_status{
|
||||
{UI_POS_X_CENTER(28), 198, UI_POS_WIDTH(28), UI_POS_HEIGHT(1)},
|
||||
{UI_POS_X_CENTER(28), 256, UI_POS_WIDTH(28), UI_POS_HEIGHT(1)},
|
||||
""};
|
||||
|
||||
Button button_save{
|
||||
{UI_POS_X_CENTER(12) - UI_POS_WIDTH(8), UI_POS_Y_BOTTOM(4), UI_POS_WIDTH(12), UI_POS_HEIGHT(2)},
|
||||
{UI_POS_X_CENTER(12) - UI_POS_WIDTH(8), UI_POS_Y_BOTTOM(4), 12 * 8, 32},
|
||||
"Save"};
|
||||
|
||||
Button button_cancel{
|
||||
{UI_POS_X_CENTER(16) + UI_POS_WIDTH(8), UI_POS_Y_BOTTOM(4), UI_POS_WIDTH(12), UI_POS_HEIGHT(2)},
|
||||
{UI_POS_X_CENTER(12) + UI_POS_WIDTH(8), UI_POS_Y_BOTTOM(4), 12 * 8, 32},
|
||||
"Cancel"};
|
||||
|
||||
void update_sd_card_status();
|
||||
};
|
||||
|
||||
class SetConverterSettingsView : public View {
|
||||
|
||||
@@ -36,7 +36,7 @@ bool card_present = false;
|
||||
Status status_{Status::NotPresent};
|
||||
|
||||
FRESULT mount() {
|
||||
return f_mount(&fs, reinterpret_cast<const TCHAR*>(_T("")), 0);
|
||||
return f_mount(&fs, reinterpret_cast<const TCHAR*>(_T("")), 1);
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
@@ -301,6 +301,10 @@ SystemStatusView::SystemStatusView(
|
||||
this->on_clk();
|
||||
};
|
||||
|
||||
sd_card_status_view.on_select = [this](ImageButton&) {
|
||||
this->on_sd_card();
|
||||
};
|
||||
|
||||
// Initialize toggle buttons
|
||||
toggle_speaker.set_value(pmem::config_speaker_disable());
|
||||
toggle_mute.set_value(pmem::config_audio_mute());
|
||||
@@ -507,6 +511,16 @@ void SystemStatusView::on_clk() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
void SystemStatusView::on_sd_card() {
|
||||
if (!nav_.is_valid()) return;
|
||||
if (sd_info_up) return;
|
||||
sd_info_up = true;
|
||||
nav_.push<SetSDCardView>();
|
||||
nav_.set_on_pop([this]() {
|
||||
sd_info_up = false;
|
||||
});
|
||||
}
|
||||
|
||||
void SystemStatusView::on_title() {
|
||||
if (nav_.is_top())
|
||||
nav_.push<AboutView>();
|
||||
@@ -806,12 +820,6 @@ 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 || fs->fs_type == FS_EXFAT) || !(sd_card::status() == sd_card::Status::Mounted);
|
||||
/* ^ to satisfy those users that not use an sd*/
|
||||
}
|
||||
|
||||
/* ReceiversMenuView *****************************************************/
|
||||
|
||||
ReceiversMenuView::ReceiversMenuView(NavigationView& nav)
|
||||
@@ -913,12 +921,6 @@ void SystemMenuView::on_populate() {
|
||||
add_apps(nav_, *this, HOME);
|
||||
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_); }});
|
||||
if (!verify_sdcard_format()) { // Moved to the end... after sd status change event, fstype wasn't populated fast enough..
|
||||
insert_item({"SDCard Error", Theme::getInstance()->error_dark->foreground, nullptr, [this]() {
|
||||
nav_.display_modal("Error", "SD Card is not exFAT/FAT32");
|
||||
}},
|
||||
0, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* SystemView ************************************************************/
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace ui {
|
||||
|
||||
void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc);
|
||||
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos, bool show_error_tile = true);
|
||||
bool verify_sdcard_format();
|
||||
|
||||
enum modal_t {
|
||||
INFO = 0,
|
||||
@@ -202,6 +201,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
|
||||
bool sd_info_up = false; // to prevent show multiple sd info dialog
|
||||
|
||||
NavigationView& nav_;
|
||||
|
||||
@@ -303,6 +303,7 @@ class SystemStatusView : public View {
|
||||
void on_title();
|
||||
void refresh();
|
||||
void on_clk();
|
||||
void on_sd_card();
|
||||
void on_tx_disabled();
|
||||
void rtc_battery_workaround();
|
||||
void on_battery_data(const BatteryStateMessage* msg);
|
||||
|
||||
@@ -83,7 +83,7 @@ const Color color_sd_card(const sd_card::Status status) {
|
||||
|
||||
SDCardStatusView::SDCardStatusView(
|
||||
const Rect parent_rect)
|
||||
: Image{parent_rect, &bitmap_sd_card_unknown, detail::color_sd_card_unknown, Theme::getInstance()->bg_dark->background} {
|
||||
: ImageButton{parent_rect, &bitmap_sd_card_unknown, detail::color_sd_card_unknown, Theme::getInstance()->bg_dark->background} {
|
||||
}
|
||||
|
||||
void SDCardStatusView::on_show() {
|
||||
@@ -101,7 +101,7 @@ void SDCardStatusView::paint(Painter& painter) {
|
||||
set_bitmap(&detail::bitmap_sd_card(status));
|
||||
set_foreground(detail::color_sd_card(status));
|
||||
|
||||
Image::paint(painter);
|
||||
ImageButton::paint(painter);
|
||||
}
|
||||
|
||||
void SDCardStatusView::on_status(const sd_card::Status) {
|
||||
|
||||
@@ -26,10 +26,11 @@
|
||||
#include "theme.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "sd_card.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace ui {
|
||||
|
||||
class SDCardStatusView : public Image {
|
||||
class SDCardStatusView : public ImageButton {
|
||||
public:
|
||||
SDCardStatusView(const Rect parent_rect);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user