プログラミング
35ドルのバックカメラディスプレイ(AMT630A)のリバースエンジニアリング
Reverse-engineering a $35 backup camera display (AMT630A) (github.com)
要約
AMT630AベースのコンポジットビデオLCDモニターボードのオン・スクリーン・ディスプレイ(OSD)エンジンを制御するためのArduino/ESP32ライブラリが公開されました。このライブラリは、テキスト、カスタムグリフ、ビットマップ、パレットアニメーション、ウィンドウ操作など、OSDの機能をArduino APIとして提供します。また、隠しファクトリーメニューへのアクセスを自動化する機能も含まれており、ハードウェアの解析とライブラリ開発に関する詳細が解説されています。
全文翻訳
AMT630A OSD Arduino/ESP32ライブラリは、AMT630AベースのコンポジットビデオLCDモニターボードのハードウェアオン・スクリーン・ディスプレイ(OSD)エンジンを制御するためのものです。バージョン0.7.0
プロジェクトビデオ YouTubeで視聴
このライブラリは、AMT630Aの5つのハードウェアOSDウィンドウを、テキスト、カスタムグリフ、16色4bppビットマップ、パレットアニメーション、不透明度/ビデオブレンド、スケーリング、点滅領域、ウィンドウ移動のための実用的なArduino APIとして公開します。また、Pythonの画像コンバーターと、ハードウェアでテストされた3ボタンモニターファームウェアの隠しファクトリーメニューに入るためのオプションの自動化も含まれています。
ハードウェアステータス:
このプロジェクトは、実際のAMT630Aモニターボードのハードウェアテストとリバースエンジニアリングに基づいています。すべてのAMT630A製品が同じファームウェア、パネルタイミング、キーパッド回路、または公開されたI2C接続を使用しているとは限りません。ハードウェア/ファームウェア固有とマークされた機能は、そのように扱う必要があります。
機能
独立して配置可能な5つのAMT630A OSDウィンドウ。
LargeFont(16x22セルジオメトリ)およびSmallFont(10x16セルジオメトリ)。
テキスト描画、前景/背景色、中央揃え文字列、バー、長方形、および生のグリフID。
共有512セルIndex RAM割り当ておよび検査ヘルパー。
Font RAMに格納されたLargeFontカスタムグリフ。
16x22 LargeFont互換タイルを使用した4bppビットマップリソース。
4096ワード/8192バイトFont RAMビットマップアロケーター。
グローバル16エントリビットマップパレット、RGBヘルパー、パレット0の透明度、およびパレットアニメーション。
グローバルOSD/ビデオブレンド、不透明度、および明るさコントロール。
ウィンドウごとの1x-4x水平および垂直スケーリング。
ハードウェア点滅領域サポート。
軽量ウィンドウ移動およびバッチ更新API。
RGB444対応量子化、共有パレット、メモリ制限、プレビュー出力を備えたPython GIF/PNG/JPEG/BMPからArduinoビットマップへのコンバーター。
LargeFontおよびSmallFont文字セットブラウザの例。
互換性のある標準ファームウェア用のGPIO駆動ファクトリーメニューキーパッド自動化オプション。
インストール
Arduino Library Manager
このリポジトリがArduino Library Managerレジストリに登録されたら:
Arduino IDEを開きます。
Sketch > Include Library > Manage Libraries... を選択します(またはArduino IDE 2.xでライブラリマネージャーを開きます)。
AMT630A OSDを検索します。
目的のバージョンを選択し、Installをクリックします。
ZIPからインストール
リリースZIPをダウンロードし、Arduino IDEで Sketch > Include Library > Add .ZIP Library... を選択してインストールします。
ソースからインストール
リポジトリをArduinoスケッチブックのlibrariesディレクトリにクローンまたはコピーします。
Arduino IDEが既に開いている場合は再起動します。
基本的な配線
ライブラリはI2C経由でAMT630Aと通信します。begin()で使用されるデフォルトのESP32ピンは次のとおりです。
Signal Default ESP32 pin
SDA GPIO 21
SCL GPIO 22
常にESP32とモニター電子機器の間のグラウンドを接続してください。すべてのAMT630Aモニターが同じテストパッド、電圧レベル、電源入力、またはキーパッド配置を公開しているとは限りません。接続する前に、ご自身のボードを検証してください。
カスタムピンとI2Cクロックはbegin()に供給できます。
display.begin(21, 22, 100000);
最小テキスト例
#include <AMT630A_OSD.h>
AMT630A_OSD display;
void setup() {
Serial.begin(115200);
if (!display.begin()) return;
if (!display.setFontMode(AMT630A_OSD::LargeFont)) return;
if (!display.configureWindow(0, 160, 44)) return;
display.setDisplayOrigin(0, 40, 40);
display.writeString(0, 0, 0, "HELLO", AMT630A_OSD::White);
display.setVisible(0, true);
display.forceUpdate();
}
void loop() {
display.service();
}
重要な標準ファームウェア/C6所有権に関する注意
AMT630Aは、内部8051 MCUまたは外部I2Cのいずれが内部レジスタを制御するかを選択するためにSYSレジスタC6を使用します。テストされたモニターでは、標準ファームウェアは定期的に内部ビデオ/デコーダーレジスタにアクセスし、通常はMCUの所有権を期待します。通常の標準ファームウェア操作中に外部所有権を繰り返し取得すると、OSDとライブコンポジットビデオの両方を含む、ディスプレイパイプライン全体が最終的にフリーズすることが発見されました。ライブラリはOSDが制御される方法であるため、外部I2Cメカニズムを引き続き使用します。テストされた3ボタンモニターでは、長時間のテスト中に観察された競合/フリーズを防ぐために、持続的な外部OSDアクティビティの前に隠しファクトリーメニューに入ることが必要でした。EnterFactoryMode例は、既存のキーパッドスイッチ全体に接続された74HC4066を使用してその手順を自動化します。このファクトリーメニュー手順はファームウェア固有です。begin()によって自動的に呼び出されるわけではなく、他の例にも挿入されません。モニターに異なるファームウェアがある場合は、その動作を独立して検証してください。
ファクトリーメニュー自動化
テストされたモニターには、メニュー、+、-の3つの物理ボタンがあり、受動的な抵抗ラダーとして実装されています。74HC4066の3つのチャネルをこれらのボタン接点全体に配置できるため、ESP32はESP32/4066回路に電源が入っているときに物理ボタンを使用可能にしたまま、それらを電子的に押すことができます。テストされた74HC4066マッピング:
Button 4066 switch pins 4066 control Example ESP32 GPIO
+ 1, 2 13 5
Menu 3, 4 5 18
- 8, 9 6 19
Power VCC 14, GND 7 3.3 V / GND
デフォルトのライブラリシーケンスは次のとおりです。
Menu, Menu, Menu, -, Menu, +, -, -, +, +, Menu
テストされたファームウェアでは、明るさがアクティブな間にシーケンスを終了する必要があり、最後のMenuプレスでファクトリー画面が開きます。ハードウェアテストでは、100 msのプレス/150 msのギャップが最も短い再現可能なタイミングであることが判明しました。例ではマージンとして150 ms / 200 msを使用しています。
display.configureFactoryMenuControl(18, 5, 19); // Menu, Plus, Minus
display.setFactoryMenuTiming(150, 200);
display.enterFactoryMode();
カスタムシーケンスはFactoryMenuStepとsetFactoryMenuSequence()で供給できます。
setOSDCoexistence(true)は、視認性管理に、標準ファームウェアによって既に設定されているOSD有効/点滅ビットを置き換えるのではなく、保持するように指示します。これはファクトリーモード自体には入りません。例/EnterFactoryModeを参照してください。
フォントと文字セット
フォントモードはグローバルです。
display.setFontMode(AMT630A_OSD::LargeFont);
display.setFontMode(AMT630A_OSD::SmallFont);
検証済みのセルジオメトリ:
Mode Cell size
LargeFont 16 x 22 pixels
SmallFont 10 x 16 pixels
writeString()は、一般的なASCII文字をAMT630Aの組み込みROMにマッピングします。writeGlyph()はASCIIマッピングをバイパスし、生の10ビットグリフIDを書き込みます。バンドルされているLargeFontCharacterSetBrowserおよびSmallFontCharacterSetBrowserの例では、シリアルモニターからモニターのROMを探索できます。通常のASCIIによって使用される検証済みのSmallFont ROMマッピングは0x1C0付近から始まり、数字は0x1C1から、文字は0x1CBから始まります。
ウィンドウとIndex RAM
5つのハードウェアOSDウィンドウがありますが、すべてが512のIndex RAMセルを共有します。ウィンドウは視覚的に重なる場合があります。それらのバックグラウンドIndex RAM割り当ては、共有512セルプールに収まる必要があります。
display.configureWindow(0, 160, 66); // pixels; converted to cells
display.setDisplayOrigin(0, 30, 30);
検査ヘルパー:
display.getWindowWidth(0);
display.getWindowHeight(0);
display.getColumns(0);
display.getRows(0);
display.getWindowIndexStart(0);
display.getWindowIndexCells(0);
display.getIndexRAMUsed();
display.getIndexRAMFree();
releaseWindow()はウィンドウを解放し、ライブラリが残りのIndex RAM領域を再割り当てできるようにします。
テキストとセルの描画
display.clearWindow(0);
display.clearRegion(0, 2, 1, 4, 2);
display.fillRect(0, 0, 0, 8, 1, AMT630A_OSD::Blue);
display.setCell(0, 0, 0, glyph, AMT630A_OSD::White, AMT630A_OSD::Blue);
display.writeGlyph(0, 1, 0, 0x123, AMT630A_OSD::White, AMT630A_OSD::Transparent);
display.writeString(0, 0, 1, "READY", AMT630A_OSD::Green, AMT630A_OSD::Transparent);
display.writeStringCentered(0, 2, "CENTERED");
display.writeBar(0, 0, 3, 75, 100, 10, AMT630A_OSD::Green);
利用可能なテキスト色は、Transparent, White, Red, Green, Blue, Cyan, Yellow, Blackです。描画はライブラリのRAMコピーを変更し、影響を受けたセルをダーティとしてマークします。updateDisplay()はダーティセルを送信します。forceUpdate()は要求されたウィンドウ内のすべてのセルを送信します。
視認性とサービス
display.setVisible(0, true);
display.setOSDVisible(true);
display.updateDisplay();
通常の例では、loop()でdisplay.service()を呼び出します。これは、ライブラリ管理の視認性状態とハードウェアの状態を定期的に調整します。間隔は