Files
planar-EL512.256-H/components/el512/el512_display.h
T
mangavalkandClaude Opus 5.5 f3212ea969 el512: refresh health counters and quiet warnings
The panel driver counts ring refills, the largest gap between refills,
frame swaps, swap timeouts and I2S TX FIFO underruns (takeStats()). The
ESPHome component checks them every 10 s and logs a warning only when the
ESP32 side of the signal had a problem, plus a debug summary per minute.

Measured with Wi-Fi on: ~4600 refills/s, max gap < 0.4 ms (lead 1.7 ms),
no underruns or timeouts, so remaining blinks come from the signal being
disturbed on the wires (Wi-Fi transmit bursts), not from the refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 20:52:10 +02:00

72 lines
2.8 KiB
C++

#pragma once
#include "el512_helpers.h"
#include "el512_panel.h"
#include "esphome/components/display/display_buffer.h"
#include "esphome/core/component.h"
#include "still_alive.h"
namespace esphome::el512 {
// ESPHome display for the Planar EL512.256-H. Drawing goes into the panel
// driver's back buffer; every update() hands it to the refresh in one piece.
class EL512Display : public display::DisplayBuffer {
public:
void set_pins(int vclk, int vid, int tvid, int hs, int vs, int enable, int low_power) {
this->pins_ = {(int8_t) vclk, (int8_t) vid, (int8_t) tvid, (int8_t) hs,
(int8_t) vs, (int8_t) enable, (int8_t) low_power};
}
void setup() override;
void loop() override;
void update() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::PROCESSOR; }
void fill(Color color) override;
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_BINARY; }
// Display on/off (ENABLE) and low-power mode (_LOWPWR), e.g. from template switches.
void set_enabled(bool on);
void set_low_power(bool on);
bool is_enabled() const { return this->enabled_; }
bool is_low_power() const { return this->low_power_; }
bool has_enable_pin() const { return this->pins_.enable >= 0; }
bool has_low_power_pin() const { return this->pins_.lowpwr_n >= 0; }
// Portal end-credits show. Showing this page restarts it; while it is the
// active page the display redraws as the show advances, and when it ends the
// previous page comes back. Draw it from that page's lambda with
// draw_still_alive().
void set_still_alive_page(display::DisplayPage *page) { this->still_alive_page_ = page; }
void draw_still_alive();
// Show the Still Alive page and start the show from the top (also when it is
// already playing).
void play_still_alive();
bool is_still_alive_playing() const {
return this->still_alive_page_ != nullptr && this->get_active_page() == this->still_alive_page_;
}
// When to start the music, in ms after the page was shown.
uint32_t still_alive_song_start_ms() const { return el512sa::StillAlivePlayer::songStartMs(); }
protected:
void draw_absolute_pixel_internal(int x, int y, Color color) override;
void check_refresh_health_();
int get_width_internal() override { return EL512Panel::WIDTH; }
int get_height_internal() override { return EL512Panel::HEIGHT; }
EL512Pins pins_{18, 19, 21, 22, 23, -1, -1};
EL512Panel *panel_{nullptr};
bool enabled_{true};
bool low_power_{false};
uint32_t health_checked_{0};
uint32_t health_logged_{0};
display::DisplayPage *still_alive_page_{nullptr};
display::DisplayPage *still_alive_return_{nullptr};
bool still_alive_was_active_{false};
el512sa::StillAlivePlayer still_alive_;
};
} // namespace esphome::el512