feat: project scaffolding with PlatformIO config and boot skeleton

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-03 10:46:23 -04:00
commit 491827bf0d
4 changed files with 150 additions and 0 deletions

7
partitions_custom.csv Normal file
View File

@@ -0,0 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x680000,
app1, app, ota_1, 0x690000, 0x680000,
littlefs, data, spiffs, 0xD10000, 0x80000,
coredump, data, coredump, 0xD90000, 0x10000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x680000
5 app1 app ota_1 0x690000 0x680000
6 littlefs data spiffs 0xD10000 0x80000
7 coredump data coredump 0xD90000 0x10000

33
platformio.ini Normal file
View File

@@ -0,0 +1,33 @@
; PlatformIO configuration for M5Stack PaperColor Immich Frame
[env:m5stack-papercolor]
platform = espressif32 @ 6.12.0
board = esp32s3box
framework = arduino
board_build.partitions = partitions_custom.csv
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
board_build.arduino.memory_type = qio_opi
board_build.filesystem = littlefs
monitor_speed = 115200
upload_speed = 921600
build_flags =
-DESP32S3
-DBOARD_HAS_PSRAM
-DCORE_DEBUG_LEVEL=3
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_MODE=1
lib_deps =
m5stack/M5Unified @ ^0.2.2
m5stack/M5GFX @ ^0.2.5
https://github.com/m5stack/M5PM1.git
mathieucarbou/ESP Async WebServer @ ^3.0.6
bblanchon/ArduinoJson @ ^7.0.0
lib_ignore =
WebServer
[env:native]
platform = native
build_flags = -std=c++17
test_framework = unity
lib_deps =
bblanchon/ArduinoJson @ ^7.0.0

84
src/config.h Normal file
View File

@@ -0,0 +1,84 @@
#pragma once
// --- Pin Definitions ---
// Buttons
#define PIN_BTN_TOP 1 // G1 - Random photo
#define PIN_BTN_UP 9 // G9 - Next photo
#define PIN_BTN_DOWN 10 // G10 - Play/Pause
// RGB LEDs (NeoPixel)
#define PIN_RGB_LED 21
#define NUM_RGB_LEDS 2
// Audio (permanently disabled)
#define PIN_AUDIO_PWR_EN 45
#define PIN_SPK_EN 46
// E-Paper SPI
#define PIN_EPD_CLK 15
#define PIN_EPD_MOSI 13
#define PIN_EPD_CS 44
#define PIN_EPD_DC 43
#define PIN_EPD_BUSY 11
#define PIN_EPD_RST 12
// I2C System Bus (M5PM1, SHT40, RTC)
#define PIN_SYS_SDA 3
#define PIN_SYS_SCL 2
// --- Display ---
#define DISPLAY_WIDTH 600
#define DISPLAY_HEIGHT 400
#define DISPLAY_COLORS 6
// --- Defaults ---
#define DEFAULT_INTERVAL_MIN 5
#define DEFAULT_CYCLE_MODE 0 // 0=random
#define DEFAULT_IMG_QUALITY 0 // 0=preview
#define DEFAULT_META_FLAGS 0x00
#define DEFAULT_META_POS 0 // 0=bottom
#define DEFAULT_LED_BRIGHTNESS 50
#define DEFAULT_IMMICH_URL "https://photos.example.com"
// --- Timing ---
#define BUTTON_DEBOUNCE_MS 50
#define COMBO_HOLD_MS 3000
#define FACTORY_RESET_HOLD_MS 5000
#define BATTERY_CHECK_INTERVAL_MS 60000
#define LED_PULSE_DURATION_MS 100
#define QUEUE_RESYNC_HOURS 24
#define WIFI_CONNECT_TIMEOUT_MS 15000
#define WIFI_MAX_RETRIES 3
// --- Battery Thresholds ---
#define BATTERY_LOW_PCT 25
#define BATTERY_CRITICAL_PCT 10
#define BATTERY_SHUTDOWN_PCT 5
#define BATTERY_WARN_INTERVAL_MS 300000 // 5 min
#define BATTERY_CRIT_INTERVAL_MS 120000 // 2 min
// --- Portrait Pairing ---
#define PORTRAIT_LOOKAHEAD 5
#define PORTRAIT_GAP_PX 8
#define PORTRAIT_WIDTH 267 // (DISPLAY_HEIGHT * 2) / 3
// --- Dither Palette (Spectra 6) ---
// Initial values — calibrate on real hardware
#define PALETTE_BLACK_R 0
#define PALETTE_BLACK_G 0
#define PALETTE_BLACK_B 0
#define PALETTE_WHITE_R 255
#define PALETTE_WHITE_G 255
#define PALETTE_WHITE_B 255
#define PALETTE_RED_R 200
#define PALETTE_RED_G 30
#define PALETTE_RED_B 30
#define PALETTE_GREEN_R 30
#define PALETTE_GREEN_G 160
#define PALETTE_GREEN_B 30
#define PALETTE_BLUE_R 30
#define PALETTE_BLUE_G 30
#define PALETTE_BLUE_B 200
#define PALETTE_YELLOW_R 220
#define PALETTE_YELLOW_G 200
#define PALETTE_YELLOW_B 30

26
src/main.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include <Arduino.h>
#include <M5Unified.h>
#include "config.h"
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
Serial.begin(115200);
Serial.println("[main] Immich Frame booting...");
// Disable audio permanently
pinMode(PIN_AUDIO_PWR_EN, OUTPUT);
digitalWrite(PIN_AUDIO_PWR_EN, LOW);
pinMode(PIN_SPK_EN, OUTPUT);
digitalWrite(PIN_SPK_EN, LOW);
Serial.printf("[main] Free heap: %d, PSRAM: %d\n",
ESP.getFreeHeap(), ESP.getFreePsram());
Serial.println("[main] Boot complete (skeleton)");
}
void loop() {
M5.update();
delay(1000);
}