STM32F4Discovery-DCMIを介してカメラを接続します

カメラを携帯電話から
STM32F407VGT6マイクロコントローラー(
STM32F4Discoveryボード上で
実行 )に接続すると、このコントローラーにはこのケース用の特別なハードウェアインターフェイスがあるとは思いもしませんでした。 データシートを不注意に読んだのかもしれませんが、144フィートの
UFBGA176と
LQFPケースのチップのみに
DCMIインターフェースがあるといつも思っていました。 しかし、それほど前ではないが、音声付きの詳細を発見しました。100フィート
STM32F407にはDCMIも搭載されています。
MKでさまざまなモバイルハードウェア(特にLCDやカメラ)を研究し、共同発売することの大ファンなので、そのような発見をすり抜けることができなかったため、STM32周辺機器の研究でこのギャップを埋めることにしました。 実際、この資料は、アイデアの実装の説明に専念しています。
ちょっとした理論。
まず第一に、それが何であるかを想像する必要があります-むしろ、CMOSカメラとは何か、それは何と一緒に食べられるのか。
このタイプのカメラは、センサーからの情報をデジタル形式(RGB、YCbCr、および圧縮形式-JPEG)で表示します。 さまざまなカメラは機能の点で独自のニュアンスを持っています。私は、
Siemens C72電話(
PixelPlus PO2030Nセンサー)から
太古の時代から引き出された小さな解像度(VGA、640x480)のカメラの非常に特殊なケースを検討します。 このカメラは、操作が簡単で、多かれ少なかれ一般的なタイプに属しているため、研究に最適です。 むかしむかし、I 2
Cバスに2.8 Vのスタビライザーとプルアップ抵抗を付けて、接続のために小さなボードをエッチングしました。 ここにあります(ケーブルとカメラコネクタはカバーの下に隠れています)。

データ形式の分野でのニュアンスに加えて、カメラは同期リードの数の分野でも異なる場合があります。 ほとんどの(私の意見では)センサーには、特別なラインおよびフレーム同期の結論があります。 ただし、ピクセルストロボ出力しかないカメラがあり、特殊な送信コード(たとえば、
0x00または
0xFF )を使用して、新しいライン/フレームの開始を知らせます。 利用可能なカメラには外部同期出力があります。
ブロックの形でカメラのおおよその概略画像を推定できます。

ほとんどの場合、CMOSカメラは
I2Cインターフェイスを介して制御され
ます (ただし、
UARTによっても制御されるデバイスを見てきました)。 I2Cは、解像度、色域、出力データ形式などのさまざまなパラメーターを構成します。
EXTCLKの結論はカメラのクロッキングであり、外部から提供する必要があります。
DCLK-データがカメラデータバスに記録される前縁または後縁のストローブ信号(たとえば、マトリックスの1ピクセルのデータバイト、またはカメラが
RGB565モードで動作している場合は「ハーフピクセル」のデータバイト)。
HSYNCは、新しいラインの始まりを示す水平同期信号です
。VSYNCは、アクティブレベルが新しいフレームの始まりを示す同期信号です。 結論
D0..D7-データバス。 原則として、このようなカメラでは8ビットです。
同期信号について詳しく説明します。

グラフは、カメラがアクティブな
HSYNCフェーズでのみ
DCLK信号
アクティビティ用に設定されていることを示しています(つまり、このフェーズは私たちにとって重要であり、「ラインフィード」期間中のクロック信号には興味がありません)。 カメラが320x240の解像度に設定されている場合、
DCLKの 320パルスが各
HSYNCパルスの周期に適合し、240
HSYNCが
VSYNC周期に適合し
ます 。
ズームインすると、データバスで何が起こっているかがわかります。

リーディングエッジ(この場合)では、1バイトがデータバスから削除されます。これは、表示のためにディスプレイに直接送信されるか、後続の処理のためにバッファに「入れられます」。
理論的には、 STM32マイクロコントローラーのDCMIインターフェースに関するすべてが多かれ少なかれ明確です。
DCMIインターフェイスは、最大14ビット幅のデータバスで動作し、ハードウェアとソフトウェアの両方の同期、およびデータ形式(YCbCr、RGB、JPEG)をサポートします。
さらに、
DCMIには
FIFOバッファーが含まれており、割り込み(データレジスタの入力を含む)を構成し、
DMAを介して作業を構成できます。
DCMI割り込みは、次の条件
が発生したときに
トリガーでき
ます 。ライン終了、フレーム終了、受信バッファーオーバーフロー、同期エラー検出(内部同期あり)。
戸惑うことに、カメラクロック用の特別な出力がないことで私は紹介されました。
SGS Microelectronicsの開発者がそれを拒否した理由はわかりませんが、たとえば、カスタムクロックソースがあると非常に便利です。
個人的には、PWMモードに含まれる汎用タイマーカウンターを使用して、4 MHzの蛇行を生成しました。 もちろん、このようなクロック速度では大きなFPSを取得することはできませんが、すぐに予約します-使用するディスプレイは
FSMCに接続されていないため、回路全体で最も長い機能はLCD出力機能です。したがって、より高い周波数では、画面への画像出力が失敗します。 したがって、アンロードする前にタイマーをオフにし、その後タイマーを再びオンにします。
DCMIハードウェアモジュールには、データレジスタに加えて、10個の制御/ステータスレジスタが含まれています。 制御レジスタ(
DCMI_CR )、ステータスレジスタ(
DCMI_SR )、割り込みステータスレジスタ(
DCMI_RIS )、割り込みイネーブルレジスタ(
DCMI_IER )、割り込みマスクレジスタ(
DCMI_MIS )、割り込みフラグリセットレジスタ(
DCMI_ICR )、内部同期コードレジスタ(
DCMI_ESCR ) 、内部同期コードのマスクをリセットするためのレジスタ(
DCMI_ESUR )、フレームの一部をキャプチャするときの開始値のレジスタ(
DCMI_CWSTRT )、およびCropWindowモードのフレームのフラグメントの値のレジスタ(
DCMI_CWSIZE )。 そして、もちろん、データレジスタは
DCMI_DRです。
この場合、フレームの一部のキャプチャと内部同期に関連するレジスタは、私たちには関係ありません。 また、今のところ中断を残すことにしたので、
DCMI_CR制御
レジスタと
DCMI_SRステータス
レジスタのみをより詳細に検討する価値があります。
制御レジスタにより、カメラとの相互作用のフォーマットを完全にカスタマイズできます:データバスサイズ、
HSYNCおよび
VSYNCラインのアクティブレベルなど。

順番に。
ENABLEビットは、もちろん、インターフェイスを含めることです。 フィールド
EDM (
拡張データモード )-データバスサイズ。 カメラのバスは8ビットなので、このフィールドは「00」に設定する必要があります。 フィールド
FCRC (
フレームキャプチャレート制御 )を使用すると、FPCをわずかに調整できます
。00-すべての着信フレームがキャプチャされ、
01-1秒おきに フレーム、 10-4秒ごとにキャプチャされます。
VSPOLおよび
HSPOLビットは、垂直および水平同期ラインのアクティブレベルです。 アクティブなレベルは無視され、アクティビティ期間中のデータはキャプチャされません。これを考慮する必要があります。
PCKPOL-ピクセルストローブのアクティブレベルのビット-バスからデータを読み取る信号のエッジ:フロントまたはバック。
ESS-同期方法の選択のビット:外部または内部。
JPEG-受信データの形式を選択します-圧縮されているかどうか。
CROP-フレームフラグメントのキャプチャを選択するビット(
トリミングウィンドウ )。 このビットが1に設定されている場合、インターフェイスは、
DCMI_CWSTRTおよび
DCMI_CWSIZEレジスタの値によって決定されるウィンドウのデータをキャプチャします。
だから、カスタマイズ可能。
私はSTの標準周辺機器ライブラリを使用することに慣れているため(「ペン」でレジスタをさらに掘り下げるまで、新しい周辺機器を使用する最初の反復では使用しませんが)、ライブラリを使用して設定を行います。
void DCMIInitialRoutine(void) { DCMI_InitTypeDef DCMI_CamType; DCMI_DeInit(); DCMI_CamType.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_CamType.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_CamType.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; DCMI_CamType.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; DCMI_Init(&DCMI_CamType); DCMI_CaptureCmd(ENABLE); DCMI_Cmd(ENABLE); return; }
実際、私のニーズのために、
DCMI_CRレジスタの1ビットに触れないようにすることができました-デフォルトでは、
CAPTUREおよび
ENABLEビットを除き、リセットされます。
インターフェイスが構成され、準備ができました。 カメラにクロック信号を適用すると、インターフェイスは処理が必要なデータの受信を開始します。
まず、タスクを可能な限り単純に設定します。ディスプレイに画像を表示して、データ処理が最小限になるようにします。
受信バッファからのデータのタイムリーな読み取りでは、ステータスレジスタ
DCMI_SRが役立ちます。

読み取りに使用できるビット数は非常に少ないため、3ビットのみです。
HSYNCおよび
VSYNCビットは、対応するラインのステータスを通知します。アクティブフェーズまたはラインフィード。 最も興味深いのは
FNEビットです。 バッファをデータで埋めるように指示します。 または記入しません。
一定のサイクルで
DCMI_SRの
FNEビットの状態を確認すると、32ビットの
受信バッファーにデータが到着したことがわかります。 私の場合、データは次のように配置されます。
FNEビットが設定
されると、受信バッファーの
DCMI_SRステータス
レジスタには4つのバイト、2つの隣接ピクセルのデータが含まれます:
Byte0と
Byte1-ピクセル
nの 16ビット、
Byte2と
Byte3-ピクセル
n + 1の 16ビット。 それらを組み合わせて表示用に送信するだけです。 メインループは次のようになります。
while (1) { while ((DCMI_GetFlagStatus(DCMI_FLAG_FNE)) == RESET);
つまり、
DCMI_SRステータス
レジスタで
FNEビットが
設定されるのを
待ち 、その後16ビットのデータを2
パスでディスプレイにアップロードします。
この時点で、論理的な結論に達したいと思いますが、そうでした。
ディスプレイでMKを点滅させて再起動した後、私は見ました...いいえ、私は自分の身近な物理学を見ましたが、黒と青の色合いで見ました。 赤と緑の色は完全に欠けていました。
デバッガーで簡単に逆アセンブルした後、次のことが発見されました。インターフェイスデータレジスタには、1ピクセルのデータが16ビットのみ含まれ、下位8ビットは
Byte0 (上図を参照)、最古は
Byte2にあります。 スペース
Byte1および
Byte3は空でした。 今まで、私は現実の記録間の矛盾がどこから来たのか理解しておらず、STMに目を向けることがあります。
その結果、
DCMIインターフェースを使用してカメラから画像を取得することができましたが、多少の困難はありました。 図では、カメラの
STM32F3Discoveryデモボードの画像が表示されたディスプレイの写真を示しています。

ロジックアナライザーを接続した場合の
EXTCLK 、
PIXCK 、
HSYNC 、および
VSYNCの出力に表示されるものを
次に示します。

すべてが期待どおりに見えます。240個の
HSYNCパルスが1つの
VSYNCの持続時間に収まり、320
PIXCK -1つの
HSYNCに 収まります。
HSYNCのアクティブフェーズで
は、カメラは設定されたとおりに
PIXCK信号を出力しません。
一般的に言って、インターフェースは私をいくらか失望させました。 カメラをクロックするための「通常の」足の欠如、興味深い組み込みチップの欠如(ハードウェアJPEGエンコーダーについてはどうでしょうか?)、さらに半分の
FIFOでタンバリンと踊る...
PIXCK 、
HSYNC 、および
VSYNC割り込みでカメラを使用して作業を整理しましたが、ハードウェア
DCMIを使用してカメラを操作していましたが、これほどバントはありませんでした。
それでも、近い将来、フレームをキャプチャして
JPEGで圧縮し、SDカードに画像を書き込もうとします。
PS。 念のため、「
Code :: Blocks 」のプロジェクトへのリンクを提供します-それは突然誰かに役立つでしょう。
www.dropbox.com/sh/nfjdwqsdzlr7djm/9v2mQM8uYV