New variant variants/m5stack_cardputer_adv for the Cardputer-Adv (ESP32-S3, 8 MB) with the Cap LoRa-1262 (SX1262 + GNSS): - Envs: companion_radio_ble, companion_radio_usb, repeater, room_server. - Board: enables the Cap's antenna path via the PI4IOE5V6408 on the internal I2C bus (Wire1, G8/G9); Wire stays on the Grove port. LoRa and microSD share FSPI because the display owns SPI3. TCXO 1.8 V. - Companion UI adapted from MultiMote/meshcore-cardputer-adv (MIT, LICENSE.MultiMote), running on the standard companion so the USB terminal CLI stays available. Contacts/identity stay in internal SPIFFS; the microSD card is optional (chat history, keyboard layouts). - Sticky Shift, one-shot Fn with Fn+letter shortcuts, top button (G0) sends a flood advert, brightness control. - Text size setting (Normal/Large/Extra large) with DejaVu Sans fonts generated by tools/gen_vlw_font.py; layouts derive from the font size. - Power save maps to the companion's powersaving pref; the UI vetoes light sleep while the screen is on. Low-battery power-off at 3.4 V. - win_long_cmdline.py: Windows-only -iprefix include shortening so the ESP32 compile command stays under the 32,767-character limit. Shared companion changes are guarded by CARDPUTER_ADV_UI: main.cpp selects CardputerDataStore/CardputerUITask/CardputerMesh, and MyMesh.h maps the_mesh to the subclass like the PSRAM storage path does. Tested on hardware (910.525 MHz mesh): radio RX/TX, USB CLI, BLE, UI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
41 lines
1.4 KiB
C++
41 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include <DataStore.h>
|
|
#include "globals.h"
|
|
#include "RingBuffer.h"
|
|
|
|
//** Custom node preferences, persisted to file. Power saving is the
|
|
// companion's own powersaving_enabled pref (shared with the CLI). */
|
|
struct __attribute__((packed)) CustomNodePrefs {
|
|
float battery_correction;
|
|
uint8_t brightness;
|
|
uint8_t text_level; // CardputerDisplay::TextLevel
|
|
};
|
|
|
|
struct HistoryMessage {
|
|
char text[MAX_MESSAGE_LENGTH];
|
|
bool out;
|
|
};
|
|
|
|
using ChatHistory = RingBuffer<HistoryMessage, CHAT_HISTORY_RINGBUF_SIZE>;
|
|
|
|
// Contacts, channels and node prefs stay on the primary (internal) FS managed
|
|
// by DataStore. Cardputer UI prefs live there too; per-chat history is kept
|
|
// only when a microSD card is mounted.
|
|
class CardputerDataStore : public DataStore {
|
|
private:
|
|
FILESYSTEM *_fs;
|
|
FILESYSTEM *_history_fs = nullptr;
|
|
|
|
public:
|
|
CardputerDataStore(FILESYSTEM &fs, mesh::RTCClock &clock) : DataStore(fs, clock), _fs(&fs) {}
|
|
|
|
// Call after the SD card is mounted (or not); nullptr disables history.
|
|
void beginCustom(FILESYSTEM *history_fs);
|
|
bool hasHistory() const { return _history_fs != nullptr; }
|
|
void loadCustomPrefs(CustomNodePrefs &prefs);
|
|
void saveCustomPrefs(const CustomNodePrefs &prefs);
|
|
void storeMessage(const uint8_t pkey[PUB_KEY_SIZE], const char *text, bool is_sent, bool is_channel);
|
|
void loadMessages(const uint8_t pkey[PUB_KEY_SIZE], bool is_channel, ChatHistory &history);
|
|
};
|