mirror of
https://github.com/ratspeak/ratdeck.git
synced 2026-10-14 21:57:15 +00:00
rsdeck: dual-boot launcher, RNode mode, build pipeline
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "config/BoardConfig.h"
|
||||
#include "config/Config.h"
|
||||
#include "platform/RsDeckModeSwitch.h"
|
||||
#include "hal/Display.h"
|
||||
#include "hal/TouchInput.h"
|
||||
#include "hal/Trackball.h"
|
||||
@@ -1073,6 +1074,12 @@ void setup() {
|
||||
Serial.printf("[BOOT] Reset: %s (%d)\n", reasonStr, (int)reason);
|
||||
Serial.printf("[BOOT] Heap: %lu PSRAM: %lu\n",
|
||||
(unsigned long)ESP.getFreeHeap(), (unsigned long)ESP.getPsramSize());
|
||||
|
||||
// Dual-boot layout: re-arm the launcher so the next reset shows the chooser.
|
||||
auto launcherBoot = rs_deck::returnToLauncherNextBoot();
|
||||
if (!launcherBoot.ok) {
|
||||
Serial.printf("[BOOT] Launcher return unavailable: %s\n", launcherBoot.message);
|
||||
}
|
||||
if (!psramFound() || heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM) < 1024 * 1024) {
|
||||
Serial.printf("[BOOT] FATAL: PSRAM unavailable or too fragmented (largest=%lu)\n",
|
||||
(unsigned long)heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM));
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
// Boot-mode selection for the rsDeck dual-boot layout (launcher/standalone/rnode
|
||||
// in ota_0/1/2). On the legacy single-app layout ota_0 is the running standalone,
|
||||
// so re-arming the launcher is a harmless self-select.
|
||||
namespace rs_deck {
|
||||
|
||||
enum class FirmwareMode : uint8_t {
|
||||
Launcher,
|
||||
Standalone,
|
||||
RNode,
|
||||
};
|
||||
|
||||
struct SwitchResult {
|
||||
bool ok;
|
||||
const char* message;
|
||||
};
|
||||
|
||||
inline esp_partition_subtype_t modeSubtype(FirmwareMode mode) {
|
||||
switch (mode) {
|
||||
case FirmwareMode::Launcher:
|
||||
return ESP_PARTITION_SUBTYPE_APP_OTA_0;
|
||||
case FirmwareMode::Standalone:
|
||||
return ESP_PARTITION_SUBTYPE_APP_OTA_1;
|
||||
case FirmwareMode::RNode:
|
||||
return ESP_PARTITION_SUBTYPE_APP_OTA_2;
|
||||
}
|
||||
return ESP_PARTITION_SUBTYPE_APP_OTA_0;
|
||||
}
|
||||
|
||||
inline const esp_partition_t* modePartition(FirmwareMode mode) {
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, modeSubtype(mode), nullptr);
|
||||
}
|
||||
|
||||
inline const char* modeName(FirmwareMode mode) {
|
||||
switch (mode) {
|
||||
case FirmwareMode::Launcher:
|
||||
return "Launcher";
|
||||
case FirmwareMode::Standalone:
|
||||
return "Standalone";
|
||||
case FirmwareMode::RNode:
|
||||
return "RNode";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
inline SwitchResult setNextBoot(FirmwareMode mode) {
|
||||
const esp_partition_t* target = modePartition(mode);
|
||||
if (!target) {
|
||||
return {false, "target partition not found"};
|
||||
}
|
||||
|
||||
esp_err_t err = esp_ota_set_boot_partition(target);
|
||||
if (err != ESP_OK) {
|
||||
return {false, esp_err_to_name(err)};
|
||||
}
|
||||
|
||||
return {true, "boot partition updated"};
|
||||
}
|
||||
|
||||
inline SwitchResult returnToLauncherNextBoot() {
|
||||
return setNextBoot(FirmwareMode::Launcher);
|
||||
}
|
||||
|
||||
// Snake_case aliases for the launcher and RNode helper.
|
||||
inline esp_partition_subtype_t mode_subtype(FirmwareMode mode) { return modeSubtype(mode); }
|
||||
inline const esp_partition_t* mode_partition(FirmwareMode mode) { return modePartition(mode); }
|
||||
inline const char* mode_name(FirmwareMode mode) { return modeName(mode); }
|
||||
inline SwitchResult set_next_boot(FirmwareMode mode) { return setNextBoot(mode); }
|
||||
inline SwitchResult return_to_launcher_next_boot() { return returnToLauncherNextBoot(); }
|
||||
|
||||
} // namespace rs_deck
|
||||
Reference in New Issue
Block a user