ESP-IDF v5.3.2 firmware for the CrowPanel 2.1" rotary display. Builds clean;
nothing has been run on hardware yet.
Hardware verified against Elecrow's own source for this board and
cross-checked against their ESPHome config, per PRD 8.1. Three corrections to
the PRD's pinout, all documented in docs/HARDWARE.md:
- touch is CST826 at 0x15, not CST816 (chip ID reads 0x11, not 0xB4)
- the ST7701S needs a 3-wire SPI bus on GPIO 16/2/1 that the PRD omitted;
without it the init sequence cannot be sent and the panel stays black
- the backlight is GPIO6
Two further departures from the PRD, both forced by facts on the ground:
- Transport is MQTT, not HTTP. zigbee2mqtt has no REST endpoint for live
sensor state. Subscribing to the broker also gets retained topics, so
every room's last reading arrives on connect rather than after a poll.
- The furnace is 2-wire R/W with no C, not 3-wire. The board needs its own
5V supply. The thermostat's 5 CPH setting is enforced as a minimum
12-minute period between heat-call starts, which a minimum off-time alone
does not achieve.
All of PRD section 5 is implemented in the relay layer itself: fail-open,
watchdog-gated output, max on-time, min off-time, cycle-rate limit, startup
lockout, and the stale-data fallback ladder down to open-loop freeze
protection. The one gap that cannot be closed in software — the PCF8574 not
resetting when the ESP32 does — is documented rather than papered over.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
56 lines
1.8 KiB
C
56 lines
1.8 KiB
C
/*
|
|
* ST7701S + RGB panel, 480x480 round.
|
|
*
|
|
* Two things about the configuration here are deliberate and load-bearing:
|
|
*
|
|
* No bounce buffers. The bounce-buffer refill ISR reads PSRAM, which shares
|
|
* the cache with flash on the S3, so any NVS write while the panel runs faults
|
|
* with "Cache disabled but cached memory region accessed" (PRD 8.2). This
|
|
* project writes settings to NVS at runtime, so instead of pausing the panel
|
|
* around every write we simply do not use bounce buffers: the LCD DMA reads
|
|
* the framebuffer out of PSRAM directly and never touches the cache.
|
|
*
|
|
* Two framebuffers. Writing into the framebuffer currently being scanned
|
|
* races the LCD's reads, and the corruption persists because LVGL does not
|
|
* know those pixels are wrong and never reinvalidates them (PRD 8.2). With
|
|
* num_fbs=2 the panel driver swaps whole buffers instead.
|
|
*
|
|
* 480x480x2 bytes x 2 buffers is ~920KB of the 8MB PSRAM.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include "esp_err.h"
|
|
#include "esp_lcd_panel_ops.h"
|
|
|
|
#define DISPLAY_H_RES 480
|
|
#define DISPLAY_V_RES 480
|
|
|
|
/*
|
|
* Bring up the panel: expander power/reset sequencing, 3-wire SPI init,
|
|
* RGB bus, backlight.
|
|
*
|
|
* Requires i2c_bus_init() and pcf8574_init() to have run. PRD 8.2 also wants
|
|
* WiFi up before this point.
|
|
*/
|
|
esp_err_t display_init(void);
|
|
|
|
/* The esp_lcd panel handle, for the LVGL port. */
|
|
esp_lcd_panel_handle_t display_panel(void);
|
|
|
|
/* Both framebuffers, for LVGL to render into directly. */
|
|
esp_err_t display_get_framebuffers(void **fb0, void **fb1);
|
|
|
|
/* Backlight, 0-100. */
|
|
void display_set_backlight(uint8_t percent);
|
|
|
|
/*
|
|
* Fill the screen with vertical colour bars, bypassing LVGL.
|
|
*
|
|
* This is the PRD phase-2 check: it proves the init sequence, the RGB bus and
|
|
* the timings independently of anything LVGL does.
|
|
*/
|
|
void display_test_pattern(void);
|