esp32 と OV2640 でDMA, I2S転送をやってみた

esp32-cameraライブラリを読み解く ~OV2640, SCCB, DMA, I2S 編~

記事公開日:2019年9月10日


スポンサーリンク

OV2640 起動後の各端子の電圧波形

では、先に述べたようにSCCBインターフェースで OV2640 を起動させて初期化設定すると、OV2640 の各端子から連続して垂直同期信号、水平同期信号、Pixel Clock信号、画素データなどが送信されるようになります。
ざっと概略図はこんな感じです。


OV2640のVSYNC(垂直同期)電圧が上がっている間が実際のフレームサイズになります。
そして、HREF(水平同期)電圧が上がっている間は水平走査線1列のデータです。
PCLK(Pixel Clock)はパラレル通信D0~D7の有効なデータを区切る役割をします。
そして、D0~D7のデータが実際の画素データです。

では、先ほど設定した100×72 pixel のフレームサイズで、実際にオシロスコープでVSYNCとHREF電圧を測定してみると、波形は以下のようになりました。


GNDやHIGHレベルが波打っていますが、これは恐らく、OV2640およびOLED SSD1331ディスプレイに流れる大電流によって、ブレッドボードの貧弱な電源ラインが変動したものと思われます。ブレッドボードとジャンパーワイヤー配線だとこうなるのも仕方ないかも知れません。誤作動する可能性高いのを承知しておいてください。
これについては今回は追求せず、次回の課題とします。

画像1枚分のデータは、VSYNC が HIGHレベルになっている間に送信されてきます。
今回、100×72 pixel なので、VSYNCがHIGHレベルの間のHREFのピーク数を数えると、72回 HIGH レベルになっていることが分かります。
昔のブラウン管で例えると、走査線の数が 72本あるということですね。

では、更にOV2640の HREF と D2端子の電圧波形を見てみると以下のようになりました。


これは、OV2640からテスト用のカラーバーを表示させたときのものです。
XVCLKの周波数が20MHzなので、100MHz級以上のオシロスコープでないと、まともな波形は見ることができませんね。
私の手持ちのオシロスコープは 2ch のため、D2端子しか見られませんでしたが、確かに画素データが出ているっぽいです。
これもかなり高周波で、速いところで約10MHzです。
こういうのを見ると、CPUの周波数はできるだけ速い方が有利だとういことが良く分かりますね。多量の画素を高速で信号変換して送信するわけですから・・・。

さて、VSYNC と HREF 信号は何となく意味は分かるのですが、PCLK信号が良く分からないと思いませんか?

私も最近まで PCLK 信号の働きが良く分からなかったので、久々にロジックアナライザー( ZEROPLUS LAP-C )を引っ張り出してきて測定してみました。
こんな感じにスパゲッティ状態接続でした。


みなさん、このロジックアナライザー LAP-Cは便利ですよ!
今回久々に使ってみて、ハッキリわかりました!
これについては、過去に以下の記事で扱いましたので参照してみてください。

ロジックアナライザー ZEROPLUS LAP-C を使ってみた ( SDカードの SPI クロック測定等 )

私は Amazon のマルツさん販売のものを買いました。

Amazon.co.jp

最大サンプルレート100MHzなので、この高周波でもギリギリ使用できます。
今回の様な謎が多いロジックのイメージセンサを使う場合にはロジアナがあると殆ど一発で謎を解決できることがありますヨ!!!

とにかく、測定した以下の波形を見てください。


これは、画質がCIFモードで、RGB565フォーマットの場合です。
そして、フレームサイズは前項で述べたように、100×72 pixel としています。
テストパターンのカラーバー(これについては後述します)を表示させた波形で、HREFがLOW→HIGHに遷移したところを見ているので、カラーバーの白色のパターンの波形を見ていることになります。

見て分かるとおり、最初の方で述べたXVCLK信号は20MHzになっていて、そして前項で述べたように PCLK信号はClock Dividerで2分周していますので、10MHzになっていることが分かります。
PCLK信号は所々長めのHIGHレベルになっていることが分かります。
この意味はこの先読み進めていくと段々理解できてきますよ。

では、もっと拡大してみると、こうなります。


これは、テスト用信号カラーバーを表示させたときの黄色の部分のロジックを見ています。
ロジアナ LAP-Cでは、パラレルのD7~D0信号をまとめて2進数表記してくれる便利な機能があって、なかなか良いです。

さて、ではこれを読み解いていきますが、まず、OV2640 のPCLK信号はデフォルト設定でNegative Edgeモードに設定されています。
OV2640のデータシートを参照すると、PCLKがLOWレベルに切り替わった瞬間からパラレルのD7~D0のデータがActive(有効)になります。
要するにこんな感じです。


これは、カラーバーの黄色部分の途中のデータを抜粋して見ています。

PCLKの信号が立ち下がった時点のD7~D0のデータを有効にすると、この図の最初のところは、
11100000
となります。
D7 がbit7で、D0がbit0 となります。
ここで気付くと思いますが、左側のPCLKの信号がHIGHの時の
11111111
というデータが気になりますね。
最初の方で述べたように、RGB565の場合、2バイト分が1画素のデータになりますので、

11111111, 11100000

というデータが黄色ですね。
でも、一番左側の
11111111
というデータは、PCLKがHIGHなので無効ではないでしょうか?

実は、この前の前の画像を拡大してみると分かるのですが、HREFがHIGHレベルになった直後はPCLK信号の立ち下がりが3回しかありません。
ということは、有効なデータは3バイトということになります。
そして、それ以降の区間は4回の立ち下がりパターンで繰り返しています。
ということは、有効なバイトが1バイト分ズレていると考えられます。

すると、上図のように、途中のデータを抜粋してみた場合に限り、PCLK の立ち下がる1バイト前のデータと、立ち下がった時点の1バイトデータを合わせてRGB565データとすれば良いのではないかと思います。それならば辻褄(つじつま)が合います。
RGB565の黄色は、
赤11111、緑111111、青00000
となるので、それをつなげて2バイトデータすると
11111111 , 11100000
となるので、マッチしますね。

ズームした場合のフレームサイズをロジアナで確認

さて、では今度はズームした場合のフレームサイズはどうなっているのか、ロジックアナライザー LAP-C で見てみます。

まずは等倍で、フレームサイズが100×72 pixel の場合です。
下図の様になります。
下方の欄の波形は取り込んだ全体波形です。
HREFがHIGHになった画素1列分データ全体を見るのに良いです。


このように、PCLK がHIGHレベルになっている区間と、HREF がLOW になっている区間、つまり、画素データが無効の区間がやけに長いですね。

では、今度は2倍ズームで、フレームサイズが 200×148 pixel とすると、下図のようになります。


等倍と比べると、PCLK の HIGHレベルの区間と、HREF のLOWレベル区間が半分以下になっていますね。
間に画素1列分入っている感じです。

では、4倍ズームにしてみると、こんな感じになります。


どうでしょうか?
PCLK 信号のHIGHレベル持続が殆ど無く、ほとんど全てのデータが有効になっています。そして、HREFがLOWレベルの区間も更に短くなって、データが無駄なく1フレームに収まって、目いっぱい詰まっている感じですね。

ということは、CIFモード内の有効なサイズであれば、ズームしようがフレームサイズが変わろうが、1フレームのデータが転送される時間に影響が無いということです。
これは、OV2640 データシート独自和訳 を見ても書いてありますね。

以上から、ロジアナ LAP-Cのおかげで PCLK の役割とZOOMやOUTW等の意味が解明できました。
それにしても、ロジックアナライザーというものは本当に便利だなと思いました。
これを使わないと、OV2640の解明は一生できなかったと思います。
電子工作家ならば一家に一台ロジアナですね!!! ほんとに・・・。

では、これらの受信した HIGH-LOWレベルの画素データをどうやってESP32のメモリに保存したら良いのでしょうか?

メモリに保存しなければプログラミングでデータを抽出してディスプレイに表示できないわけですが、いちいちプログラムを組んで沢山あるGPIO端子のHIGH-LOWレベルを検出してメモリに書き込むのは、素人プログラミングでは計算が遅くなるし効率が悪いです。
フレームレートもメチャメチャ遅くなると思いますね。

実は、ESP32には嬉しい機能が予め備わっていました!
それはI2SインターフェースやDMAエンジンというものです。
次の項で説明します。


スポンサーリンク


「esp32-cameraライブラリを読み解く ~OV2640, SCCB, DMA, I2S 編~」への2件のフィードバック

  1. Hi aMiGO,
    Excellent job! I appreciate it very much.
    Although you don’t know much about DMA, you have come a long way.
    Congratulations

    Thanks
    Gustavo Murta (from Brazil)
    amigo (portuguese) = friend

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください