DEKI/ENGINE ドキュメント
deki-display 0.20.2
Deki パッケージリファレンス
deki-display

Deki 独自のディスプレイライブラリ。趣味のボードでよく使われる画面を動かし、タッチを読み、どのフレームも丸ごと送ります。

リポジトリ: github.com/dekiengine/deki-display · 最新リリース: 0.20.0 · エンジン 0.20.0 以降が必要 · 依存: deki-spi, deki-gpio, deki-i2c, deki-input, deki-rendering

DekiEditor --packages-add deki-display <project> か、パッケージマネージャーからインストールします。エンジン自身のコンポーネントと C++ API は Deki のドキュメントにあります。

エディターでは Display と表示されます。

コンポーネント

コンポーネント カテゴリ 説明
DisplayPanelComponent ディスプレイ Deki 独自のディスプレイライブラリで、SPI、クアッド SPI、または 8 ビット・16 ビットのパラレルバス経由のディスプレイパネル (ST7789、ILI9341、GC9A01 など) を駆動し、エンジンに渡します。
TouchPanelComponent ディスプレイ Deki 独自のディスプレイライブラリでパネルのタッチコントローラー (I2C の GT911、CST816、FT5x06、SPI の XPT2046) を読み取り、ポインター入力にします。

機能フラグ

ビルドから外せる部分です。define を持つ機能はその define で切り替わり、それ以外はコンポーネントと一緒に取り除かれます。

機能 define デフォルト
Display Panel DEKI_FEATURE_DISPLAY_PANEL オン
Touch Panel DEKI_FEATURE_DISPLAY_TOUCH オン

コンポーネントリファレンス

DisplayPanelComponent

Deki 独自のディスプレイライブラリで、SPI、クアッド SPI、または 8 ビット・16 ビットのパラレルバス経由のディスプレイパネル (ST7789、ILI9341、GC9A01 など) を駆動し、エンジンに渡します。

インスペクターでの名前: ディスプレイパネルコンポーネント · カテゴリ: ディスプレイ · 型: DekiDisplay::DisplayPanelComponent

プロパティ 型 デフォルト 制約 説明
controller enum "ST7789" ST7789, RM67162, ILI9341, ST7735, ST7735S, GC9A01, ST7789P3, ST7796, ILI9488, SSD1351, CO5300 パネルのコントローラー IC
initSequence string "" このパネルモジュールを起動するコマンドで、コントローラーの既定のものの代わりに使います。パネルの電圧、VCOM、ガンマはコントローラーではなくモジュールごとに決まるので、ボードがここで設定します。1 行または ';' ごとに 1 コマンドで、16 進数のコマンドバイト、続いてパラメーターのバイト、必要なら 'delay <ms>' を書きます。'#' 以降はコメントです。空の場合はコントローラーの既定のものを使います
panelWidth int32 240 1 から 1024 回転前の表示される幅 (ピクセル)
panelHeight int32 320 1 から 1024 回転前の表示される高さ (ピクセル)
rotation enum "Landscape" Portrait, Landscape, Portrait180, Landscape270, PortraitMirror, LandscapeMirror, Portrait180Mirror, Landscape270Mirror パネルの向き
offsetX int32 0 コントローラーのメモリ上で表示部分が始まる位置、横方向 (原点が 0 でないパネル用)
offsetY int32 0 コントローラーのメモリ上で表示部分が始まる位置、縦方向
invertColor bool false パネルの色を反転します (ほとんどの IPS パネルではオンが必要です)
rgbOrder bool false パネルが赤を先に受け取ります。オフにするとコントローラーの BGR 順を設定します
busType enum "SPI" SPI, QSPI, Parallel8, Parallel16 パネルの配線方法です。データ/コマンドピンのある SPI (ほとんどの LCD)、クアッド SPI (RM67162 などの AMOLED パネル。IO2 と IO3 のある SPI Bus が必要です)、または 8 ビット・16 ビットのパラレルバス (8080。このコンポーネントが自分で開始します)
spiHost int32 1 0 から 3。busType が許すときに表示 パネルが接続されている SPI ホストです。それを開始する SPI Bus コンポーネントと同じ番号で指定します (ESP32-S3 では 1 = SPI2、2 = SPI3)
spiWriteHz int32 40000000 busType が許すときに表示 パネルの SPI クロックです。80 MHz は ESP32-S3 の最速で、ほとんどの ST7789 モジュールが対応します
parallelWriteHz int32 20000000 busType が許すときに表示 パラレルバスのライトストローブの周波数です。ほとんどのパネルは 20 MHz に対応し、配線の短いものはそれ以上でも動きます
dcPin int32 -1 -1 から 48。busType が許すときに表示 データ/コマンドピン (DC、RS とも呼びます)
wrPin int32 -1 -1 から 48。busType が許すときに表示 ライトストローブのピン (WR)
rdPin int32 -1 -1 から 48。busType が許すときに表示 リードストローブのピン (RD)。High に保ち、パネルには書き込みだけを行います (-1 = ボード上で High に固定)
d0Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D0
d1Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D1
d2Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D2
d3Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D3
d4Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D4
d5Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D5
d6Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D6
d7Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D7
d8Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D8
d9Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D9
d10Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D10
d11Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D11
d12Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D12
d13Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D13
d14Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D14
d15Pin int32 -1 -1 から 48。busType が許すときに表示 データ線 D15
csPin int32 -1 -1 から 48 チップセレクトのピン (-1 = Low に固定)
rstPin int32 -1 -1 から 48 リセットピン (-1 = 未接続)
tePin int32 -1 -1 から 48 パネルのティアリングエフェクト (TE) 出力です (-1 = 未接続)。接続すると、フレームがティアリングしなくなります。各フレームはパネルがリフレッシュを始めた時点で送り始め、パネル自身の行の順に送ります。回転した画面は送るときに回転し、列のストリップで描画します
scanlineSync bool true busType が許すときに表示 TE 線が配線されていない場合、代わりにパネルの走査線を読み取り、フレームがティアリングしないようにします。読み戻せないパネルには描いた順に送り、起動ログにそう出ます
spiReadHz int32 10000000 scanlineSync が許すときに表示 パネルを読み戻すときの SPI クロックで、書き込みより遅くします (ST7789 は 10 MHz で確実に読み取れます)
readsOnMosi bool false scanlineSync が許すときに表示 パネルが MISO ではなくデータ入力線で応答します (LilyGO T-Deck のように SDA が双方向)
blPin int32 -1 -1 から 48 バックライトのピン (-1 = なし)。点灯中は High に保ちます。パルス数で減光するバックライトドライバー (LilyGO T-Deck のもの) には、まさにこれが必要です
blInvert bool false ピンが Low のときにバックライトが点灯します
memoryWidth int32 0 0 から 1024 コントローラーのメモリ上の幅で、表示される幅より大きい場合があります (0 = コントローラーの値)
memoryHeight int32 0 0 から 1024 コントローラーのメモリ上の高さ (0 = コントローラーの値)
usePsram bool false フレームバッファーを内部 RAM ではなく PSRAM に置きます。画面 1 枚分の内部 RAM が空きますが、描画は遅くなります
doubleBuffer bool false フレームバッファーを 2 つ使い、フレームごとに切り替えます
asyncPresent bool true 次のフレームを描いている間に、チップのもう一方のコアから各フレームを送ります。1 フレームにかかる時間は、描画と送信の合計ではなく長いほうになります。デュアルコアのチップと外部メモリ (PSRAM) 2 フレーム分が必要で、ない場合は描いた順に送り、起動ログにそう出ます

TouchPanelComponent

Deki 独自のディスプレイライブラリでパネルのタッチコントローラー (I2C の GT911、CST816、FT5x06、SPI の XPT2046) を読み取り、ポインター入力にします。

インスペクターでの名前: タッチパネルコンポーネント · カテゴリ: ディスプレイ · 型: DekiDisplay::TouchPanelComponent

プロパティ 型 デフォルト 制約 説明
controller enum "GT911" GT911, CST816, FT5x06, XPT2046 タッチコントローラー IC
i2cPort int32 0 0 から 3。controller が許すときに表示 接続されている I2C ポート (このコンポーネントより前に、I2C Bus コンポーネントでそのポートを開始しておく必要があります)
i2cAddress int32 0 0 から 127。controller が許すときに表示 I2C アドレスです。0 にするとコントローラーの通常のアドレスを使います (GT911: 0x5D、応答がなければ 0x14。CST816: 0x15。FT5x06: 0x38)
spiHost int32 1 0 から 3。controller が許すときに表示 接続されている SPI ホストです。それを開始する SPI Bus コンポーネントと同じ番号で指定します (多くはディスプレイと同じです)
csPin int32 -1 -1 から 48。controller が許すときに表示 チップセレクトのピン
spiHz int32 1000000 controller が許すときに表示 タッチコントローラーの SPI クロックです。XPT2046 は 1 MHz でよく読み取れ、最大 2.5 MHz まで対応します
intPin int32 -1 -1 から 48 割り込みピン: 読み取るタッチの報告があるとき、または押されている間 (XPT2046 の PENIRQ)、コントローラーが Low にします (-1 = 未配線、毎フレーム読み取ります)
rstPin int32 -1 -1 から 48。controller が許すときに表示 リセットピン (-1 = 未接続)
xMin int32 0 タッチコントローラーが返す生の X の最小値です。ディスプレイを回転する前のパネルの幅方向の値です (静電容量式: 0。XPT2046 は 300 前後から始まり、キャリブレーションが必要です)
xMax int32 239 タッチコントローラーが返す生の X の最大値です。ディスプレイを回転する前のパネルの幅方向の値です (240x320 のパネルを横向きで表示する場合: 239)
yMin int32 0 タッチコントローラーが返す生の Y の最小値です。ディスプレイを回転する前のパネルの高さ方向の値です
yMax int32 319 タッチコントローラーが返す生の Y の最大値です。ディスプレイを回転する前のパネルの高さ方向の値です (240x320 のパネルを横向きで表示する場合: 319)
offsetRotation enum "None" None, CW_90, CW_180, CW_270, Mirror, Mirror_CW_90, Mirror_CW_180, Mirror_CW_270 パネルに対するタッチコントローラーの向きで、ディスプレイの回転に加算されます。コントローラーがパネル自身の向きで座標を返す場合はなし

変更履歴

変更履歴は英語です。

0.20.0

Changed

  • minEngine 0.20.0: built against engine 0.20.0. A build of this package from before does not load and is rebuilt.

Added

  • The package: DisplayPanelComponent, which starts a panel on a deki-spi bus from the boot scene and gives the engine PanelDisplay, a Deki::IDisplay presenting whole frames and changed rectangles with the UI overlay blended over them; PanelController, a MIPI DCS controller driven by a table per controller (ST7789 first, its start-up and MADCTL ported from LovyanGFX); SpiPanelIO, 4-wire SPI with pixels queued for DMA; and initSequence, a board's own start-up for its panel module, as text.
  • Async present (asyncPresent): each frame is sent from the other core while the next is drawn. A whole frame is copied, swapped into the wire's byte order as it is copied, to one of two copies in external DMA memory, and sent from there by DMA in parts as long as the bus takes, with no bands in internal RAM; a strip is copied to one of two copies in internal DMA memory and swapped in place a chunk at a time. The worker holds the bus across back-to-back frames and strips, with each one's window commands queued behind the one before, so the wire does not wait between them; a copy goes back to the drawing core as soon as its last part is sent. The platform runs the worker through PanelDisplay::SetWorkerBackend (deki-esp32-integration: a FreeRTOS task pinned to the other core). On a LilyGO T-Deck Plus at 80 MHz with the frame rate uncapped: 63.2 fps in whole frames with 83.6 KB of internal RAM free, 61.0 in strips of 40 rows (LovyanGFX: 62.6 with 73.8 KB, and 60.2).
  • Touch: TouchPanelComponent starts a GT911 (GT911Touch, ported from LovyanGFX's driver) on a deki-i2c bus, shared with whatever else is on it, and gives deki-input PanelTouchInput: a press, moves and a release at screen pixels, turned with the display by TouchMapper (LovyanGFX's default calibration and rotation, so a board's touch bounds carry over). Without an INT pin, a point that stops changing is released and not pressed again until it moves.
  • QSPI panels: DisplayPanelComponent's busType QSPI drives an AMOLED through QspiPanelIO (each register write framed 0x02, pixels 0x32 on four lines, as LovyanGFX frames them). The RM67162 is the first: its start-up, MADCTL and offsets ported from LovyanGFX, rows widened to even, and brightness by command where an LCD has a backlight.
  • The CST816S/T touch controller (TouchController::CST816). It sleeps, and does not answer on I2C, until touched: it is set up when it first answers, and a read it does not answer is no touch.
  • Async present works with render buffers (usePsram, doubleBuffer) too: the worker sends a copy, so the engine never draws into what is being sent.
  • Tear-free presenting: DisplayPanelComponent's tePin, the panel's tearing-effect output. A panel refreshes its own rows one after another, and a frame written while the refresh passes shows half of each frame. With TE on (0x35), each frame starts as the panel starts a refresh, and goes in the panel's own row order, which a write outruns the refresh in. A screen shown turned is turned as it is sent: the controller stays at its own orientation, and the renderer is asked for strips of columns in the order the panel refreshes them (deki-rendering's IScanOrderedDisplay). With async present the worker does the turning, a band at a time while the band before it is on the wire. Whole frames and strips both. A TE line that never pulses is said once in the log, and frames go on without waiting. On a LilyGO T-Display S3 AMOLED (its panel refreshes at 59.6 Hz): 59.5 fps in strips with no tearing, and 28.6 in whole frames, which take 25 ms to draw in PSRAM.
  • More controllers, each a table ported from LovyanGFX 1.2.29: ILI9341, ST7735 (the B version), ST7735S (the R version), GC9A01, ST7789P3, ST7796, ILI9488 and SSD1351 on SPI or a parallel bus, and the CO5300 AMOLED on QSPI. A controller names its own commands (ControllerCommands): the SSD1351's window is a byte a coordinate, its column and row commands trade places when turned, and its remap takes MADCTL's place. The GC9A01 opens its rows before a turned window's columns, as LovyanGFX does. Checked against LovyanGFX's bytes in tests; none has run on a board yet.
  • 18 bits a pixel: the ILI9488 takes no RGB565 over SPI, so its pixels go out as RGB666 through Rgb666PanelIO, which widens each piece into its own DMA buffers while the piece before is sent, and COLMOD is 0x66.
  • Parallel panels: busType Parallel8 and Parallel16, an 8080 bus of 8 or 16 data lines with DC, WR and RD pins and its write clock (parallelWriteHz). The platform drives the bus (ParallelBus, a factory it registers; ParallelPanelIO speaks to it), and the component starts it itself. On 16 lines a pixel goes as memory holds it, so a little-endian frame needs no byte swap.
  • Touch: the FT5x06 family (FT5206, FT6206, FT6336 and others) on I2C, and the XPT2046 resistive controller on SPI, both ported from LovyanGFX. The XPT2046's raw readings need calibrating in the touch bounds. A controller whose count or pressure says when the finger has gone (ITouchController::MayRepeatLastTouch false) is not released for holding still.
  • Tear-free: a frame that missed its refresh's start is started for the longest write any frame has taken (PanelDisplay::LongestWriteUs), not the shorter of the last two. The frame that opens a new scene is late (the scene loads in it) and changes the whole screen, while the frames before it changed a little: started for theirs, it began too late, the refresh caught it, and the screen tore across.
  • Tear-free with no TE line: scanlineSync reads the panel's scanline (Get_Scanline, 0x45) back through the panel IO (IPanelIO::Read) at its own clock (spiReadHz), on MISO or, with readsOnMosi, on the panel's data line. ScanlineClock finds two refresh starts, where the count drops from the last row to the blanking (it holds there; the low byte rolling over at row 256 does not), and keeps the clock right with each start it catches. On a LilyGO T-Deck Plus: 60.2 Hz found, every demo scene at 60 fps with frames in step with the refresh.
  • A frame that takes about a refresh to go out, or up to two, is started just behind the refresh rather than at once (PanelDisplay::WritesBehind): it never catches the refresh's rows up, and the next refresh shows it whole. Before, such a frame was taken to tear wherever it started.
  • A turned frame is read a screen row at a time while it is turned, a run of neighbouring pixels from each, instead of one pixel per screen row: a whole frame in PSRAM, turned on the way out, went from 47.8 fps to 60 on the T-Deck Plus.
  • asyncPresent and scanlineSync are on by default: a board gets frames sent from the other core, and tear-free frames without a TE line, where it can. Where it cannot (one core, no PSRAM for the copies, a panel that cannot be read back) frames are sent as they are drawn, and the boot log says so as information, not an error. Scenes that set them keep what they set.

それ以前のリリース: CHANGELOG.md


パッケージのリフレクションデータから生成しています (エンジン 0.20.2)。プロパティ名はシーンファイルで使われるキーです。名前を変えても別名が残ります (互換性)。