diff options
| -rw-r--r-- | .clangd | 2 | ||||
| -rw-r--r-- | .gitignore | 6 | ||||
| -rw-r--r-- | CMakeLists.txt | 8 | ||||
| -rw-r--r-- | README.md | 100 | ||||
| -rw-r--r-- | main/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | main/app_main.cpp | 22 | ||||
| -rw-r--r-- | partitions.csv | 6 | ||||
| -rw-r--r-- | sdkconfig.defaults | 31 |
8 files changed, 177 insertions, 0 deletions
@@ -0,0 +1,2 @@ +CompileFlags: + CompilationDatabase: build/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e597f25 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +build/ +sdkconfig +sdkconfig.old +dependencies.lock +managed_components/ +/.cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5281b89 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) + +set(PROJECT_VER "0.1") +set(PROJECT_VER_NUMBER 1) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(scrypted-viewport) diff --git a/README.md b/README.md new file mode 100644 index 0000000..22b102e --- /dev/null +++ b/README.md @@ -0,0 +1,100 @@ +# Scrypted Viewport v1 Technical Design Specification + +Version: 1.0 + +## Overview + +Scrypted Viewport is an Ethernet-powered ambient display appliance optimized for Scrypted camera and doorbell events. + +Design goals: +- No Matter +- No HomeKit +- No polling +- No configuration UI +- No authentication +- No rendering engine +- No business logic on the device + +Scrypted owns rendering, overlays, camera selection and interaction logic. + +Scrypted Viewport owns Ethernet, JPEG decode, display, touch input and callback delivery. + +## Hardware + +### Controller +Waveshare ESP32-P4-ETH-POE + +### Display +5" 800x480 IPS Capacitive Touch MIPI DSI display + +## Boot + +Power +-> DHCP +-> mDNS (_scrypted-viewport._tcp.local) +-> Wait + +## Resolution + +800x480 native. + +Scrypted always renders 800x480 JPEGs. + +## API + +GET /health + +POST /config +{ + "display":"mudroom", + "callback":"http://scrypted.local:11080/api/viewport/touch" +} + +POST /frame +Content-Type: image/jpeg + +POST /sleep + +POST /brightness +{ + "brightness":75 +} + +## Touch Callback + +{ + "display":"mudroom", + "event":"tap", + "timestamp":1730000000 +} + +Supported: +- tap +- long_press +- swipe_left +- swipe_right + +## Build + +```sh +source ~/Dev/code/git/esp32/env.sh +cd ~/Dev/code/git/esp32/projects/esp32-poe-scrypted-viewport +idf.py set-target esp32p4 +idf.py build +idf.py -p /dev/cu.usbmodem* flash monitor +``` + +## Philosophy + +Scrypted Viewport is a thin network framebuffer appliance. + +ESP: +- DHCP +- mDNS +- HTTP server +- JPEG decode +- framebuffer +- touch +- callback + +Everything else belongs in Scrypted. diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..e088a07 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRC_DIRS "." + INCLUDE_DIRS ".") diff --git a/main/app_main.cpp b/main/app_main.cpp new file mode 100644 index 0000000..55dbd5d --- /dev/null +++ b/main/app_main.cpp @@ -0,0 +1,22 @@ +#include <esp_log.h> +#include <esp_event.h> +#include <esp_netif.h> +#include <nvs_flash.h> + +static const char *TAG = "viewport"; + +extern "C" void app_main(void) +{ + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + ESP_LOGI(TAG, "Scrypted Viewport boot"); + + // TODO: Ethernet (ESP32-P4 EMAC + Waveshare PoE PHY) + // TODO: mDNS _scrypted-viewport._tcp.local + // TODO: HTTP server: /health /config /frame /sleep /brightness + // TODO: MIPI-DSI panel init (800x480 IPS) + // TODO: JPEG decode -> framebuffer + // TODO: Capacitive touch -> callback POST +} diff --git a/partitions.csv b/partitions.csv new file mode 100644 index 0000000..19a82fa --- /dev/null +++ b/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, , 0x1000, +otadata, data, ota, , 0x2000, +ota_0, app, ota_0, 0x20000, 0x300000, +ota_1, app, ota_1, , 0x300000, diff --git a/sdkconfig.defaults b/sdkconfig.defaults new file mode 100644 index 0000000..3f88f72 --- /dev/null +++ b/sdkconfig.defaults @@ -0,0 +1,31 @@ +CONFIG_IDF_TARGET="esp32p4" + +# Partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" + +# PSRAM (required for 800x480 framebuffer + JPEG decode) +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 + +# Ethernet (Waveshare ESP32-P4-ETH-POE: internal EMAC + external PHY) +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y + +# LWIP / mDNS +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y +CONFIG_MDNS_MAX_INTERFACES=1 + +# HTTP server +CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 +CONFIG_HTTPD_MAX_URI_LEN=512 + +# Main task stack — JPEG decode is hungry +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 + +# Log level +CONFIG_LOG_DEFAULT_LEVEL_INFO=y |
