Fixes
This commit is contained in:
parent
315ae3ce34
commit
582149309b
@ -229,6 +229,26 @@ dependencies:
|
|||||||
registry_url: https://components.espressif.com
|
registry_url: https://components.espressif.com
|
||||||
type: service
|
type: service
|
||||||
version: 1.1.2
|
version: 1.1.2
|
||||||
|
espressif/esp_tinyusb:
|
||||||
|
component_hash:
|
||||||
|
6f1f0c140990bf27a86611e3c1f47f9fa8468bffc3bf1eb6d551cb09f31f8908
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.0'
|
||||||
|
- name: espressif/tinyusb
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: public
|
||||||
|
version: '>=0.17.0~2'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
targets:
|
||||||
|
- esp32s2
|
||||||
|
- esp32s3
|
||||||
|
- esp32p4
|
||||||
|
- esp32h4
|
||||||
|
version: 2.0.1~1
|
||||||
espressif/esp_wifi_remote:
|
espressif/esp_wifi_remote:
|
||||||
component_hash:
|
component_hash:
|
||||||
e5cb66acbf9b3e115dab6b8e1262a5473e7de6e4106d32a2a8ca7384bd21fc00
|
e5cb66acbf9b3e115dab6b8e1262a5473e7de6e4106d32a2a8ca7384bd21fc00
|
||||||
@ -306,6 +326,22 @@ dependencies:
|
|||||||
registry_url: https://components.espressif.com
|
registry_url: https://components.espressif.com
|
||||||
type: service
|
type: service
|
||||||
version: 1.6.54
|
version: 1.6.54
|
||||||
|
espressif/tinyusb:
|
||||||
|
component_hash:
|
||||||
|
5ea9d3b6d6b0734a0a0b3491967aa0e1bece2974132294dbda5dd2839b247bfa
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
targets:
|
||||||
|
- esp32s2
|
||||||
|
- esp32s3
|
||||||
|
- esp32p4
|
||||||
|
- esp32h4
|
||||||
|
version: 0.19.0~2
|
||||||
espressif/wifi_remote_over_eppp:
|
espressif/wifi_remote_over_eppp:
|
||||||
component_hash:
|
component_hash:
|
||||||
e1b4c485ed5afe36615b9b555dfdcbe4be33898dc3732b5bedf235bba45bd286
|
e1b4c485ed5afe36615b9b555dfdcbe4be33898dc3732b5bedf235bba45bd286
|
||||||
@ -369,10 +405,11 @@ direct_dependencies:
|
|||||||
- espressif/esp_lcd_touch_gt911
|
- espressif/esp_lcd_touch_gt911
|
||||||
- espressif/esp_lvgl_adapter
|
- espressif/esp_lvgl_adapter
|
||||||
- espressif/esp_lvgl_port
|
- espressif/esp_lvgl_port
|
||||||
|
- espressif/esp_tinyusb
|
||||||
- espressif/esp_wifi_remote
|
- espressif/esp_wifi_remote
|
||||||
- idf
|
- idf
|
||||||
- lvgl/lvgl
|
- lvgl/lvgl
|
||||||
- waveshare/esp_lcd_jd9365_10_1
|
- waveshare/esp_lcd_jd9365_10_1
|
||||||
manifest_hash: 0e36b3139b75b9c8d45ce136355b7427d1e8020070f386f167b627461b004349
|
manifest_hash: 77a45d81439c2b8bff313cb08784154731b4451f54eecd31bcd4c2fc83b0f096
|
||||||
target: esp32p4
|
target: esp32p4
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
idf_component_register(SRCS "KnxWorker.cpp" "Nvs.cpp" "main.cpp" "Display.cpp" "Touch.cpp" "Gui.cpp" "Wifi.cpp" "LvglIdle.c" "Gui/WifiSetting.cpp" "Gui/EthSetting.cpp" "Hardware/Eth.cpp" "WidgetManager.cpp" "WebServer.cpp" "SdCard.cpp"
|
idf_component_register(SRCS "KnxWorker.cpp" "Nvs.cpp" "main.cpp" "Display.cpp" "Touch.cpp" "Gui.cpp" "Wifi.cpp" "LvglIdle.c" "Gui/WifiSetting.cpp" "Gui/EthSetting.cpp" "Hardware/Eth.cpp" "WidgetManager.cpp" "WebServer.cpp" "SdCard.cpp"
|
||||||
PRIV_REQUIRES spi_flash esp_driver_ppa esp_lcd
|
PRIV_REQUIRES spi_flash esp_driver_ppa esp_lcd usb
|
||||||
REQUIRES esp_mm esp_eth esp_driver_ppa esp_timer lvgl knx ethernet_init esp_wifi_remote esp_netif esp_event nvs_flash esp_http_server fatfs sdmmc json
|
REQUIRES esp_mm esp_eth esp_driver_ppa esp_timer lvgl knx ethernet_init esp_wifi_remote esp_netif esp_event nvs_flash esp_http_server fatfs sdmmc json tinyusb
|
||||||
INCLUDE_DIRS "")
|
INCLUDE_DIRS "")
|
||||||
|
|||||||
109
main/SdCard.cpp
109
main/SdCard.cpp
@ -3,11 +3,14 @@
|
|||||||
#include "esp_vfs_fat.h"
|
#include "esp_vfs_fat.h"
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
|
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||||
|
#include "tinyusb.h"
|
||||||
|
#include "tinyusb_msc.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
static const char* TAG = "SdCard";
|
static const char* TAG = "SdCard";
|
||||||
|
|
||||||
// ESP32-P4 Waveshare Board SDMMC Pins
|
// ESP32-P4 Waveshare Board SDMMC Pins (from official docs)
|
||||||
#define SDMMC_CLK_GPIO 43
|
#define SDMMC_CLK_GPIO 43
|
||||||
#define SDMMC_CMD_GPIO 44
|
#define SDMMC_CMD_GPIO 44
|
||||||
#define SDMMC_D0_GPIO 39
|
#define SDMMC_D0_GPIO 39
|
||||||
@ -15,6 +18,12 @@ static const char* TAG = "SdCard";
|
|||||||
#define SDMMC_D2_GPIO 41
|
#define SDMMC_D2_GPIO 41
|
||||||
#define SDMMC_D3_GPIO 42
|
#define SDMMC_D3_GPIO 42
|
||||||
|
|
||||||
|
// SD card power control LDO channel (from Waveshare example)
|
||||||
|
#define SD_PWR_CTRL_LDO_CHANNEL 4
|
||||||
|
|
||||||
|
static sdmmc_card_t* s_card = nullptr;
|
||||||
|
static sd_pwr_ctrl_handle_t s_pwr_ctrl_handle = nullptr;
|
||||||
|
|
||||||
SdCard& SdCard::instance() {
|
SdCard& SdCard::instance() {
|
||||||
static SdCard inst;
|
static SdCard inst;
|
||||||
return inst;
|
return inst;
|
||||||
@ -26,46 +35,62 @@ bool SdCard::init() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initializing SD card");
|
ESP_LOGI(TAG, "Initializing SD card (SDMMC 4-wire mode)");
|
||||||
|
|
||||||
// Configure SDMMC host
|
// Configure SDMMC host
|
||||||
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
||||||
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
|
host.max_freq_khz = SDMMC_FREQ_DEFAULT; // 20 MHz
|
||||||
|
|
||||||
// Configure SDMMC slot with GPIO pins
|
// Initialize SD card power control via internal LDO
|
||||||
|
sd_pwr_ctrl_ldo_config_t ldo_config = {
|
||||||
|
.ldo_chan_id = SD_PWR_CTRL_LDO_CHANNEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_err_t ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &s_pwr_ctrl_handle);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to create SD power control driver: %s", esp_err_to_name(ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
host.pwr_ctrl_handle = s_pwr_ctrl_handle;
|
||||||
|
ESP_LOGI(TAG, "SD power control LDO initialized (channel %d)", SD_PWR_CTRL_LDO_CHANNEL);
|
||||||
|
|
||||||
|
// Configure SDMMC slot with official Waveshare pinout
|
||||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||||
|
slot_config.width = 4;
|
||||||
slot_config.clk = static_cast<gpio_num_t>(SDMMC_CLK_GPIO);
|
slot_config.clk = static_cast<gpio_num_t>(SDMMC_CLK_GPIO);
|
||||||
slot_config.cmd = static_cast<gpio_num_t>(SDMMC_CMD_GPIO);
|
slot_config.cmd = static_cast<gpio_num_t>(SDMMC_CMD_GPIO);
|
||||||
slot_config.d0 = static_cast<gpio_num_t>(SDMMC_D0_GPIO);
|
slot_config.d0 = static_cast<gpio_num_t>(SDMMC_D0_GPIO);
|
||||||
slot_config.d1 = static_cast<gpio_num_t>(SDMMC_D1_GPIO);
|
slot_config.d1 = static_cast<gpio_num_t>(SDMMC_D1_GPIO);
|
||||||
slot_config.d2 = static_cast<gpio_num_t>(SDMMC_D2_GPIO);
|
slot_config.d2 = static_cast<gpio_num_t>(SDMMC_D2_GPIO);
|
||||||
slot_config.d3 = static_cast<gpio_num_t>(SDMMC_D3_GPIO);
|
slot_config.d3 = static_cast<gpio_num_t>(SDMMC_D3_GPIO);
|
||||||
slot_config.width = 4; // 4-bit mode
|
|
||||||
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
||||||
|
|
||||||
// Mount FAT filesystem
|
// Mount FAT filesystem
|
||||||
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
|
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
|
||||||
.format_if_mount_failed = true,
|
.format_if_mount_failed = false,
|
||||||
.max_files = 5,
|
.max_files = 5,
|
||||||
.allocation_unit_size = 16 * 1024
|
.allocation_unit_size = 16 * 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
sdmmc_card_t* card;
|
ESP_LOGI(TAG, "Mounting SD card...");
|
||||||
esp_err_t ret = esp_vfs_fat_sdmmc_mount(MOUNT_POINT, &host, &slot_config, &mount_config, &card);
|
ret = esp_vfs_fat_sdmmc_mount(MOUNT_POINT, &host, &slot_config, &mount_config, &s_card);
|
||||||
|
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
if (ret == ESP_FAIL) {
|
if (ret == ESP_FAIL) {
|
||||||
ESP_LOGE(TAG, "Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true.");
|
ESP_LOGE(TAG, "Failed to mount filesystem.");
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "Failed to initialize the card (%s). Make sure SD card lines have pull-up resistors.", esp_err_to_name(ret));
|
ESP_LOGE(TAG, "Failed to initialize SD card (%s).", esp_err_to_name(ret));
|
||||||
}
|
}
|
||||||
|
// Clean up power control on failure
|
||||||
|
sd_pwr_ctrl_del_on_chip_ldo(s_pwr_ctrl_handle);
|
||||||
|
s_pwr_ctrl_handle = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mounted_ = true;
|
mounted_ = true;
|
||||||
|
|
||||||
// Print card info
|
// Print card info
|
||||||
sdmmc_card_print_info(stdout, card);
|
sdmmc_card_print_info(stdout, s_card);
|
||||||
ESP_LOGI(TAG, "SD card mounted at %s", MOUNT_POINT);
|
ESP_LOGI(TAG, "SD card mounted at %s", MOUNT_POINT);
|
||||||
|
|
||||||
// Create directories if they don't exist
|
// Create directories if they don't exist
|
||||||
@ -87,3 +112,65 @@ bool SdCard::init() {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SdCard::enableUsbMsc() {
|
||||||
|
if (usbMscActive_) {
|
||||||
|
ESP_LOGW(TAG, "USB MSC already active");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s_card) {
|
||||||
|
ESP_LOGE(TAG, "SD card not initialized");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Enabling USB Mass Storage mode...");
|
||||||
|
|
||||||
|
// Unmount filesystem first (so PC has exclusive access)
|
||||||
|
if (mounted_) {
|
||||||
|
ESP_LOGI(TAG, "Unmounting SD card from filesystem...");
|
||||||
|
esp_err_t ret = esp_vfs_fat_sdcard_unmount(MOUNT_POINT, s_card);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to unmount SD card: %s", esp_err_to_name(ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mounted_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize TinyUSB
|
||||||
|
ESP_LOGI(TAG, "Initializing TinyUSB...");
|
||||||
|
const tinyusb_config_t cfg = {
|
||||||
|
.external_phy = false,
|
||||||
|
};
|
||||||
|
esp_err_t ret = tinyusb_driver_install(&tusb_cfg);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to install TinyUSB driver: %s", esp_err_to_name(ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize MSC storage with SD card
|
||||||
|
ESP_LOGI(TAG, "Initializing USB MSC with SD card...");
|
||||||
|
const tinyusb_msc_sdmmc_config_t msc_cfg = {
|
||||||
|
.card = s_card,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = tinyusb_msc_storage_init_sdmmc(&msc_cfg);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to initialize MSC storage: %s", esp_err_to_name(ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mount MSC storage
|
||||||
|
ret = tinyusb_msc_storage_mount(MOUNT_POINT);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to mount MSC storage: %s", esp_err_to_name(ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
usbMscActive_ = true;
|
||||||
|
ESP_LOGI(TAG, "USB Mass Storage mode enabled!");
|
||||||
|
ESP_LOGI(TAG, "Connect USB cable to access SD card from PC.");
|
||||||
|
ESP_LOGI(TAG, "Reboot device to return to normal mode.");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@ -5,6 +5,12 @@ public:
|
|||||||
static SdCard& instance();
|
static SdCard& instance();
|
||||||
bool init();
|
bool init();
|
||||||
bool isMounted() const { return mounted_; }
|
bool isMounted() const { return mounted_; }
|
||||||
|
bool isUsbMscActive() const { return usbMscActive_; }
|
||||||
|
|
||||||
|
// Enable USB Mass Storage mode (unmounts SD from ESP, exposes via USB)
|
||||||
|
// Returns true if successful. Requires reboot to return to normal mode.
|
||||||
|
bool enableUsbMsc();
|
||||||
|
|
||||||
static constexpr const char* MOUNT_POINT = "/sdcard";
|
static constexpr const char* MOUNT_POINT = "/sdcard";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -14,4 +20,5 @@ private:
|
|||||||
SdCard& operator=(const SdCard&) = delete;
|
SdCard& operator=(const SdCard&) = delete;
|
||||||
|
|
||||||
bool mounted_ = false;
|
bool mounted_ = false;
|
||||||
|
bool usbMscActive_ = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "KnxWorker.hpp"
|
#include "KnxWorker.hpp"
|
||||||
#include "Gui.hpp"
|
#include "Gui.hpp"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "esp_system.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -109,6 +110,24 @@ void WebServer::start() {
|
|||||||
};
|
};
|
||||||
httpd_register_uri_handler(server_, &getKnxAddresses);
|
httpd_register_uri_handler(server_, &getKnxAddresses);
|
||||||
|
|
||||||
|
// POST /api/usb-mode - Enable USB Mass Storage mode
|
||||||
|
httpd_uri_t postUsbMode = {
|
||||||
|
.uri = "/api/usb-mode",
|
||||||
|
.method = HTTP_POST,
|
||||||
|
.handler = postUsbModeHandler,
|
||||||
|
.user_ctx = nullptr
|
||||||
|
};
|
||||||
|
httpd_register_uri_handler(server_, &postUsbMode);
|
||||||
|
|
||||||
|
// GET /api/status - Get system status
|
||||||
|
httpd_uri_t getStatus = {
|
||||||
|
.uri = "/api/status",
|
||||||
|
.method = HTTP_GET,
|
||||||
|
.handler = getStatusHandler,
|
||||||
|
.user_ctx = nullptr
|
||||||
|
};
|
||||||
|
httpd_register_uri_handler(server_, &getStatus);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "HTTP server started successfully");
|
ESP_LOGI(TAG, "HTTP server started successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,3 +343,32 @@ esp_err_t WebServer::getKnxAddressesHandler(httpd_req_t* req) {
|
|||||||
httpd_resp_send(req, buf, strlen(buf));
|
httpd_resp_send(req, buf, strlen(buf));
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t WebServer::postUsbModeHandler(httpd_req_t* req) {
|
||||||
|
ESP_LOGI(TAG, "Enabling USB Mass Storage mode");
|
||||||
|
|
||||||
|
bool success = SdCard::instance().enableUsbMsc();
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
httpd_resp_set_type(req, "application/json");
|
||||||
|
const char* response = "{\"status\":\"ok\",\"message\":\"USB MSC enabled. Connect USB cable to access SD card. Reboot to return to normal mode.\"}";
|
||||||
|
httpd_resp_send(req, response, strlen(response));
|
||||||
|
} else {
|
||||||
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to enable USB MSC");
|
||||||
|
}
|
||||||
|
|
||||||
|
return success ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t WebServer::getStatusHandler(httpd_req_t* req) {
|
||||||
|
char buf[256];
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"{\"sdMounted\":%s,\"usbMscActive\":%s}",
|
||||||
|
SdCard::instance().isMounted() ? "true" : "false",
|
||||||
|
SdCard::instance().isUsbMscActive() ? "true" : "false"
|
||||||
|
);
|
||||||
|
|
||||||
|
httpd_resp_set_type(req, "application/json");
|
||||||
|
httpd_resp_send(req, buf, strlen(buf));
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|||||||
@ -27,6 +27,8 @@ private:
|
|||||||
static esp_err_t postSaveHandler(httpd_req_t* req);
|
static esp_err_t postSaveHandler(httpd_req_t* req);
|
||||||
static esp_err_t postResetHandler(httpd_req_t* req);
|
static esp_err_t postResetHandler(httpd_req_t* req);
|
||||||
static esp_err_t getKnxAddressesHandler(httpd_req_t* req);
|
static esp_err_t getKnxAddressesHandler(httpd_req_t* req);
|
||||||
|
static esp_err_t postUsbModeHandler(httpd_req_t* req);
|
||||||
|
static esp_err_t getStatusHandler(httpd_req_t* req);
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
static const char* getContentType(const char* filepath);
|
static const char* getContentType(const char* filepath);
|
||||||
|
|||||||
@ -20,3 +20,4 @@ dependencies:
|
|||||||
espressif/esp_lcd_touch_gt911: '*'
|
espressif/esp_lcd_touch_gt911: '*'
|
||||||
espressif/esp_lvgl_adapter: '*'
|
espressif/esp_lvgl_adapter: '*'
|
||||||
espressif/esp_wifi_remote: '*'
|
espressif/esp_wifi_remote: '*'
|
||||||
|
espressif/esp_tinyusb: ^2.0.1
|
||||||
@ -166,6 +166,8 @@
|
|||||||
color: #cdd6f4;
|
color: #cdd6f4;
|
||||||
}
|
}
|
||||||
button.secondary:hover { background: #585b70; }
|
button.secondary:hover { background: #585b70; }
|
||||||
|
button.usb { background: #fab387; }
|
||||||
|
button.usb:hover { background: #f9e2af; }
|
||||||
/* Status */
|
/* Status */
|
||||||
.status {
|
.status {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -196,6 +198,7 @@
|
|||||||
<h1>GUI Editor</h1>
|
<h1>GUI Editor</h1>
|
||||||
<span style="color:#6c7086">KNX Display Konfiguration</span>
|
<span style="color:#6c7086">KNX Display Konfiguration</span>
|
||||||
<div class="header-buttons">
|
<div class="header-buttons">
|
||||||
|
<button class="usb" onclick="enableUsbMode()">USB-Modus</button>
|
||||||
<button class="secondary" onclick="resetConfig()">Zuruecksetzen</button>
|
<button class="secondary" onclick="resetConfig()">Zuruecksetzen</button>
|
||||||
<button onclick="saveConfig()">Speichern & Anwenden</button>
|
<button onclick="saveConfig()">Speichern & Anwenden</button>
|
||||||
</div>
|
</div>
|
||||||
@ -612,6 +615,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function enableUsbMode() {
|
||||||
|
if (!confirm('USB-Modus aktivieren?\n\nDie SD-Karte wird als USB-Laufwerk am PC verfuegbar.\nZum Beenden: Geraet neu starten.')) return;
|
||||||
|
try {
|
||||||
|
const resp = await fetch('/api/usb-mode', {method: 'POST'});
|
||||||
|
const data = await resp.json();
|
||||||
|
if (data.status === 'ok') {
|
||||||
|
showStatus('USB-Modus aktiv! SD-Karte am PC verfuegbar.');
|
||||||
|
alert('USB Mass Storage aktiviert!\n\nVerbinden Sie das USB-Kabel mit Ihrem PC.\nDie SD-Karte erscheint als Wechseldatentraeger.\n\nZum Beenden: Geraet neu starten.');
|
||||||
|
} else {
|
||||||
|
showStatus('USB-Modus fehlgeschlagen', true);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showStatus('Fehler beim Aktivieren des USB-Modus', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showStatus(msg, isError = false) {
|
function showStatus(msg, isError = false) {
|
||||||
const el = document.getElementById('status');
|
const el = document.getElementById('status');
|
||||||
el.textContent = msg;
|
el.textContent = msg;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user