M5Stack CoreS3でカメラ & LCD表示!Zephyr RTOSで動かしてみた

本サイトはアフィリエイト広告を利用しています。
Zephyr

M5Stack CoreS3の内蔵カメラとLCDをZephyr RTOSで動かしてみました。

CoreS3には、GC0308(DVPカメラ)とILI9342C(LCD)が搭載されています。

今回は、Zephyr RTOS上でカメラ映像を内蔵LCDへリアルタイム描画(約13.4 FPS)するシステムを構築したメモです。

外部PSRAMを使わず、内蔵SRAMのみでDMAダブルバッファリングを実現した工夫も紹介します。

 

スポンサーリンク

M5Stack CoreS3でカメラ & LCD表示!Zephyr RTOSで動かしてみた

M5Stack CoreS3の内蔵カメラとLCDをZephyr RTOSで動かしてみました。

CoreS3には、GC0308(DVPカメラ)とILI9342C(LCD)が搭載されています。

今回は、Zephyr RTOS上でカメラ映像を内蔵LCDへリアルタイム描画(約13.4 FPS)するシステムを構築したメモです。

外部PSRAMを使わず、内蔵SRAMのみでDMAダブルバッファリングを実現した工夫も紹介します。

 

プロジェクト・GitHubのリンク先

GitHubのリンク先は下記です

GitHub - iotengineer22/cores3-camera-zephyr: An open-source implementation, driver, and application suite for the onboard GalaxyCore GC0308 CMOS camera sensor and built-in ILI9342C TFT LCD display on the M5Stack CoreS3 (ESP32-S3) running Zephyr RTOS.
An open-source implementation, driver, and application suite for the onboard GalaxyCore GC0308 CMOS camera sensor and bu...

 

実際のデモ動画は下記です

 

CoreS3のハードウェア構成とインターフェース

M5Stack CoreS3は、ESP32-S3をコアとし、多彩な周辺デバイスがコンパクトに一体化されたデバイスです。

カメラモジュールにはGalaxyCore製のGC0308(0.3MP VGA CMOSセンサ)が採用されています。

ESP32-S3のDVP(Digital Video Port)周辺機能へ、8ビット並列データバスで直接結線されています。

ディスプレイには、2.0インチのカラーTFT液晶(ILI9342C、解像度320x240)がSPI接続されています。

 

ピンアサイン一覧

ESP32-S3と各ペリフェラルの主要な接続構成は以下の通りです。

機能区分 信号名 物理ピン / 制御元 役割・説明
DVPデータバス D0 ~ D7 GPIO 39, 40, 41, 42, 15, 16, 48, 47 8ビット並列画像データ入力バス
DVP同期クロック PCLK / VSYNC / HREF GPIO 45 / 46 / 38 画素クロック、垂直同期、水平有効信号
マスタークロック MCLK オンボード水晶発振器 (X2) カメラ用20MHzマスタークロック(GPIO不要)
I2C制御バス SCL / SDA GPIO 11 / 12 カメラレジスタ制御(7ビットアドレス: 0x21)
リセット制御 RESET AW9523B (P1_0) I2C IOエクスパンダ経由のアクティブLowリセット
カメラ電源系統 VDDCAM / AVDD / DVDD AXP2101 (ALDO3, BLDO1, BLDO2) PMIC制御による3.3V / 2.8V / 3.3V安定給電
LCDディスプレイ SPI / CS / DC / BL SPI2 / AXP2101 (DLDO1) 320x240 LCDパネル(バックライト給電含む)

 

Zephyrでのデバイスツリー設定(.overlay)

Zephyr RTOSからカメラとLCDを制御するため、デバイスツリーオーバーレイを作成します。

ESP32-S3のLCD_CAMペリフェラルをDVPモードとして定義し、各ピンを割り当てます。

また、カメラの初期化に必要なAXP2101の電源レールを常時ONにし、LCDのSPI周波数を設定します。

 

 

画面の歪み・見切れを解決するクロップ設定

実装の初期段階では、画面右側に黒い帯が出たり、画像が斜めに歪む現象が発生しました。

原因を調査したところ、GC0308センサの出力解像度にありました。

センサの受光素子アレイ(648x488)から単純に1/2サブサンプリングを行うと、出力画素数は324x244(158,112バイト)になります。

これをLCDの解像度である320x240(153,600バイト)のDMAバッファにそのまま流し込むと、1行あたり4ピクセル分のズレが累積し、斜めの歪みや画面下部の見切れが発生してしまいます。

 

Hardware Crop Window(ハードウェア切り出し)による解決

ドライバ側でGC0308のPage 0レジスタ(0x46)を設定し、ハードウェアクロップ機能を有効化しました。

X0=0, Y0=0, Width=320, Height=240 を指定し、センサから送出される段階できっちり153,600バイトに成形します。

この調整により、画面全域に歪みのない映像が表示されるようになりました。

 

ゼロPSRAM・内蔵SRAMのみで実現するDMAダブルバッファ

カメラ映像をスムーズに描画するためには、バッファリング設計が非常に重要です。

シングルバッファでは、画面の途中で描画が更新されるテアリングや、色の反転(サイケデリックな色合い)が発生します。

CoreS3には外部PSRAMも搭載されていますが、今回はESP32-S3の内蔵SRAM(DRAM0)のみで完結させるアーキテクチャを採用しました。

 

* ビデオバッファプールの確保: 2面分のフレームバッファ(153.6KB × 2 = 307.2KB)を静的に確保。

* スタック領域の最適化: メインスタックを4KBに抑え、DRAM使用率を98.50%(393.1KB / 399.1KB)に最適化。

* Ping-Pong DMA転送: GDMAがバッファ0へカメラ映像をキャプチャしている間に、CPUとSPIコントローラがバッファ1のデータをLCDへ送信。

さらに、LCDのSPIクロックをデフォルトの20MHzから40MHzへ倍速化しました。

1フレームあたりのLCD転送時間を51msまで短縮でき、安定して約13.4 FPSの描画レートを達成しています。

 

シリアルブートログ取得の工夫(CONFIG_BOOT_DELAY)

ESP32-S3の内蔵USB-Serial/JTAGコントローラは、SoCがリセットされるとPC側で一度切断され、COMポートの再認識(列挙)が行われます。

そのため、PC側のターミナルソフトが再接続する前に、Zephyrの初期ブートログが流れて見落としてしまう問題がありました。

そこで、プロジェクト設定(prj.conf)に3秒のブート遅延を追加しました。

 

 

この設定により、起動バナーの出力が3秒間待機されるため、Tera TermやMobaXtermなどのシリアルコンソールで確実に最初のブートログを取得できます。

 

 

ビルドと書き込み手順(West)

Zephyrの開発環境(west)を用いて、M5Stack CoreS3向けにビルドと書き込みを実行します。

 

仮想環境の有効化

PowerShellでZephyrの仮想環境を立ち上げます。

 

 

アプリケーションのビルド

ターゲットボードに m5stack_cores3/esp32s3/procpu を指定してビルドします。

 

 

CoreS3への書き込み

USB-CケーブルでCoreS3を接続し、ファームウェアを書き込みます。

 

 

性能・リソース測定のまとめ

本システムの実機検証で得られた性能データは以下の通りです。

測定項目 実測値 解説・設計上のポイント
プレビュー解像度 320 x 240 RGB565形式(1画素16ビット、1フレーム153,600バイト)
安定フレームレート ~13.4 FPS フレーム落ちなし、DMAアンダーフローなし
LCD SPIクロック 40 MHz 全画面転送時間を51msに短縮
カメラ画素クロック (PCLK) ~10 MHz フレーム間隔約98ms(生レート約10.2 FPS)
内蔵DRAM使用量 393.1 KB / 399.1 KB 98.50%(内蔵SRAMのみにぴったり収容)
外部PSRAM使用量 0 KB PSRAM依存なし、バス競合ゼロ

 

実際のデモ動画は下記です。

 

 

まとめ

M5Stack CoreS3の内蔵DVPカメラ(GC0308)とLCD(ILI9342C)を、Zephyr RTOS上で動かす実装例を紹介しました。

センサ側のハードウェアクロップ設定によるアライメント調整や、内蔵SRAMのみを使ったDMAダブルバッファリングにより、滑らかなリアルタイム表示が実現できました。

ESP32-S3の内部リソースを極限まで引き出したRTOS制御として、非常に面白い構成となっています。

ソースコードもGitHubに公開していますので、ぜひ試してみてください!

コメント