« 2017年3月 | トップページ

2017.04.20

RasPiカメラをFPGAにつないで、初めて信号が出た

今日もRasPiカメラをFPGAにつなぐための調査をしています。

Csk_csi

GPIO1と0を立ち上げた後、レジスタ設定を行い、最後に4msほど待ってからスタンバイを解除したら動きました。

レジスタ設定の中で0x6620~6623と、0x45xx番地や0x47xx番地のデータシートに載っていないレジスタについては、設定してもしなくても変化はないようです。

今の設定では1920×1080の30fpsにしたつもりなのですが、クロックは361MHz、

Clk

データレートも361MHzのDDRでした。

Data_1

また、データは団子になってやってきていて、

Data_2

1つの塊の周期は14us。最初はスキマがありますが、後はだいたい詰まっていて、13.48ms送った後、長い休みになります。

Data_4

繰り返しの周波数は32Hzでした。

まとめると、

  • クロック周波数361MHz
  • 1H=14us? ・・・2000~2527pixel ?
  • 1V=962H?

という結果でした。

設定したレジスタの値なども、何を参考にしたかさえよくわからなくなってきているので、次は高速差動信号のデコードに取り組もうと思います。

| | コメント (0)

2017.04.19

RasPiカメラ V2.1のI2C操作方法

昨日に引き続き、RasPiカメラV2の使い方を調べています。今日はI2Cの信号やGPIOの信号をどう操作するかを解明しました。

まずRasPiカメラからSDA、SCL、GPIO1、GPIO0の信号を引き出して、それをプローブにつなぎます。

Raspicam_1

そして、カメラを起動したときのこれらの4種類の信号の波形をオシロでキャプチャします。

Csi39

こんな感じの信号になりました。黄色と青はI2CのSCLとSDAで、赤と緑がGPIO0,1です。GPIOが立ち上がる前からI2Cは動作しているように見えます。

解析してみた結果は次の図です。

I2c_1

I2Cの信号は、カメラ以外のデバイスにもつながっているようで、57Hzくらいの頻度で常に出ています。カメラを操作しているI2C信号は、GPIOが立ち上がった後に出ているもののみなので、GPIOより前の信号は解析しないでも大丈夫です。

また、差動プローブを使って高速差動信号とのタイミングも見てみます。

Raspicam_2

I2c_2

GPIOを立ち上げて、I2Cで初期化した後で、D0に信号が来ているのがわかります。また、毎回のフレームの間にI2Cのアクセスが入っていますが、これはアナログゲインやライン中のピクセル数などを設定しているコマンドが入っています。

さて、GPIOのタイミング等を詳しくみてみましょう。オシロで見たところ、GPIO1が先に立ち上がって、300ns後にGPIO0が立ち上がっていました。

I2c_4

このカメラ(Sony IMX219)のデータシートに記載されている電源投入シーケンスを見てみます。データシートはネットを検索すれば見つかると思います。

I2c_3

電源を投入して、クロックを入れてから内部のXCLRが解除されるまでに200usの時間がかかり、I2Cのコマンド設定受け入れまでに5.3msかかるらしきことがわかります。

また、XCLRの解除後、スタンバイモードを解除するまでに少なくとも6ms必要であることもわかります。

したがって、GPIO0はXCLRで、GPIO1はクロック許可か電源コントロールではないかと考えられます。

sun

次に起動中に行われているI2Cのシーケンスを解析しました。

ざっくりと描くと次の図のようになっていました。

I2c_5_2


まず、GPIOを立ち上げた後、5ms待ってからIDCODEのチェックを行っています。

その後、ソフトウェアリセット、ソフトウェアスタンバイ状態の設定を行い、24ms待ってからレジスタ設定を行っています。

レジスタ設定が終わった後4ms待ってから、アナログゲインの設定などを行い、最後にストリーミング開始(スタンバイ解除)を行うというものでした。

レジスタ設定では、最初にこのようなシーケンスを実行しています。

I2c_6

ただ、このシーケンスは謎が多く、最初の6620,6621,6622,6623のレジスタはデータシートには存在しておらず、アクセスコマンドシーケンスは0Cと05が入れ替わっているなど、不可解な点が多くありました。

ネット上で検索すればSony IMX219のCドライバソースを見つけることができると思います。そういったものとほぼ一致していましたが、部分的に一致していない箇所があるので引き続き調査が必要そうです。

そして、PLLの設定を行ったあと、不明なレジスタをたくさん叩いて、最後にStreaming開始のコマンドを送っていました。

I2c_7

さて、これと同じのをFPGAで出せばよさそうですね。

希望が見えてきました。

| | コメント (0)

2017.04.18

RasPiカメラ V2.1のCSI信号の詳細

Raspberry Pi カメラ 2.1のMIPI D-PHY CSIインタフェースの動作を解析しています。

前回のブログで「クロックは30Hz」と書きましたが、それは間違いでした。

RaspberryPiをつないで、raspivid -w 1920 -h 1080 -t 100000 -o hoge と打つと、カメラが動き出します。そのときの各端子の様子を高速オシロで見てみました。

CSIのクロックはオシロでみるとこのような1.2Vくらいの振幅の波形をしていますが、

Csi_ck

LVCMOS12とかではありません。

電圧が低い部分に本当のクロックが隠れていました。

Csi_ck2

30HzでHLHL・・しているように見えますが、差動信号ですから両方が同時にHになるということはありませんよね。

同時にHになっているときはIDLE状態で、低い電圧のところに振幅100mVの真のクロックがいます。

Csi22

クロックの周波数は455MHz、振幅は200mVくらいのようです。

一方、データバス(D0,D1)を見てみると、同じようにHLHLと50kHzくらいでトグルしています。

Csi_d0

データもクロックと同様に電圧が高いところでは、差動の両方とも1.2Vくらいになるので、信号なしと考えるのが妥当です。同様に本当のデータは0V付近のところにあるようです。

差動プローブで測ってみると、本当の姿が見えてきます。Lになっていた部分が信号ありの状態で、Hになっていた部分が信号のない部分です。周期は18.86usでした。

Csi17

データ線の様子を拡大すると、

Csi23

455MHzくらいのDDRで動いているようです。約1nsで1bitを送っています。

元に戻って、1Hの中で信号のある期間を測ってみたら、9.03μ秒くらいでした。

Csi16

9.03usに455MHz×2のデータレートだと8217bit入るので、1つの画素を8bitとすると1000ピクセルくらい入る計算になります。そして、Dバスは2レーンあるので、横2000ピクセルくらいのデータ量になると考えられます。

なお、1V(垂直期間)は17430μ秒だったので、925本程度の水平ラインが入ることができます。2000×926ですから、1920×1080pの30fpsなのかもしれません。

RasPiカメラ 2.1のCSIのタイミングをまとめると次の図のようになりました。

Csi_timing

次はI2Cのシーケンスと、GPIOの操作方法を解析しようと思います。

| | コメント (0)

2017.04.15

Cosmo-Kの新基板が到着

火曜日に出図した基板が、もう届きました。

Cosmo-Kは、まだ一般のお客様向けには1枚も出荷していないのに、すでに2回目の改版です。

※ First User向けにはトータルで16台出ている。

今回、ホームページを見てご注文をくださったお客様がいらっしゃったので、少し改版して一般向けに販売できるように改良を続けています。

6層基板で金フラッシュ、0.1mm/0.1mmルール、国内製造です。

Cosmok_b

価格的には某P社の7営業日(実質10日)コース程度なので、同一の値段で納期が半分といった感じです。基板業界もだいぶん変わりましたね。

透明の袋に入って送られてくるので、中身がよくわかります。

Cosmok_b2

コネクタの下にあるViaが、レジストを越えてショートしないようにシルクをかけています。

Cosmok_b3Cosmok_b4


ちょっとシルクが薄いかもしれません。まぁ、大丈夫でしょうけど。

かなり品質が良く満足しています。

| | コメント (0)

2017.04.13

ラズベリーパイカメラをFPGAにつなぐ

ラズベリーパイカメラをFPGAにつなぐ方法を考えています。

ラズベリーパイのカメラは、SCCBでいろいろなレジスタを設定しないと、クロックやデータを送ってきません。しかし、SCCBのレジスタの一覧やアクセス方法は公開されていません。

ラズパイカメラは、15ピンのフレキケーブルでつなぎますが、これはMIPI D-PHYのCSI接続といいます。CSIでは、クロックやデータはカメラ側から出力されてきます。そのため、電源をつなげば画像が出てくる・・と最初は甘く思ったのですが、SCCBというプロトコルを使っていろいろと内蔵レジスタを設定してあげないと何も出てこないようです。

最初はレジスタ44と88に何かを書いてあげれば出てくると気楽に考えていたのですが、そうはいきませんでした。まず、SCCBはI2Cとは異なるプロトコルなので何が正しいのかさえよくわかりません。ACKも帰ってこないようです。

そこで、まずはカメラをラズベリーパイをつないでSCCBの信号をオシロでキャプチャするところから始めました。

Sccb

見てのとおり、SCCBはI2Cに似てはいますが、データの長さが32bitだったりするなど、かなりの相違があります。

アルバイトさんが、ラズベリーパイの出力する波形をオシロで解析して、どのレジスタにどんな値を書き込むかを調べてくれました。

Sccb3


それをVHDLにして

Cam_access

同じパターンの波形を送ってはみたのですが、クロックもデータも送られてきません。

ラズパイカメラには、CLKやGPIOという端子もありますが、正常に動作しているときには、CLK端子が0→1になったあとGPIOを0→1になっているようなので、これらの端子も何らかの制御に関わっているのだとは思います。

また、MIPI D-PHYではD0のPとNは双方向の信号です。低速な通信モードでは双方向で使うらしいのでが、ラズパイとつないだときには双方向として使われている感じではなさそうでした。

引き続き解析を行っていきます。

| | コメント (0)

2017.04.12

納期がnobis

レーダ信号処理機能を実装したのCosmo-Zを納品しにいったら、ダメだということになりました。仕様書を網羅した事前検証の計画を立てて、承認をもらって、それを実施して、結果をまとめたものを持っていかないと受け取ってくれません。

テストにめっちゃ時間がかかりそうなので、納期を1か月ほど延ばしてもらいました。

とにかく、この機構は大量の文書を要求します。昔、(電)で原発やってたころを思い出します。ああいう感じでやんなきゃならないのかな。

| | コメント (0)

2017.04.11

Cosmo-Kの新基板を出図

Cosmo-Kの基板を改版して出図しました。まだ一般のお客様向けには1枚も出荷していないのに、すでに2回目の改版です。

※ First User向けにはトータルで16台出ている。

今回、ホームページを見てご注文をくださったお客様がいらっしゃったので、問題のあった箇所を少し改版しています。

この基板、6層基板で金フラッシュ仕上げですが、14日の火曜日に出図して、15日の土曜日に到着するのですから、驚異的な速さだと思います。

Cosmok_gerber

+4万円くらいで実質2日で作ってもらうこともできますが、今回は4日コースで頼みました。

| | コメント (0)

2017.04.09

ハードウェアFFTの精度向上2

ハードウェアFFTを行うFPGAで、丸めの計算を単純な切り捨てから、四捨五入(0捨1入)に変更してみました。本当は最近接偶数丸めが良いのですが、0.5ちょうどになることはあまりないので、とりあえずは0捨1入で行います。

まず、従来の単純切捨てのFFTの場合です。

Fft_normal_1

周波数の全域にわたってFixed Patternなノイズが見えています。これを積算して1LSB以下の構造を見てみると、

Fft_normal_4368

このようなノイズの構造が見えてきます。

さて、いよいよ丸めを実装した場合です。下の図のようにFixed Patternなノイズが大幅に減りました。

Fft_round

ほとんどの場所でスペクトラムの値は0になっているのですが、それでも4か所ほど、Fixed Pattern Noiseが出てしまっています。

積算すると、1LSB以下の構造が見えてきて・・・

Fft_round_3004

やはり、ノイズが出やすい周波数があるようです。

単純切捨てに比べるとノイズは1万分の1くらいに減っているとは思いますが、それでもゼロにはなりませんでした。

ほとんどの周波数でFixed Pattern Noiseは1LSB以下に抑圧されましたが、積算すると見えてくるので、ゼロにはできなかったということです。

| | コメント (0)

2017.04.06

ハードウェアFFTの精度向上

FPGAを使ってハードウェアでFFTする回路を作ったのですが、ノイズに悩まされています。

そのノイズというのは、決まった周波数にいつもノイズがいるというものです。単一の正弦波(10kHz)をFFTすると下の図のような結果になります。

Integ1

1本立っているのが真のスペクトラムなのですが、全域にわたってフロアノイズが出ています。なお、16bitの演算精度なので、結果が1LSBなら-90dB、2LSBなら-84dB程度のところになります。

つまり、スペクトラムの全域にわたって±2LSB程度の誤差が出ているというわけです。その中でも特に1.2MHzと0.6MHzの値に特徴的な盛り上がりがあります。

このFFT結果を何度も積算して平均化してみると、ノイズの構造が見えてきます。

Integ336

このように周期的なFixed Patternなノイズが見えてきます。

ノイズが生じる原因は、FFTの演算精度を16bitの固定小数点(つまり整数)で行っていて、バタフライ演算の後で生じる除算をした際にLSBを単純に切り捨ててしまっているから、その誤差が積み重なったのだと考えられます。

そこで、FPGAではなく、パソコンのソフトウェアを作ってFFT計算誤差を調べてみました。

最初は1024ポイントのFFTで、浮動小数点で計算します。入力データは正弦波なのですが、周波数が整数ではない場所に設定されていて、サイドローブが広がるようにしています。

Fftfloat


f=20あたりにピークがあって、あとは滑らかに減衰するだけです。

16bitの固定小数点で、誤差を単純に切り捨てた場合の結果を以下に示します。まさにFPGAでの計算のときのようなギザギザが生じてしまっています。このような形のギザギザは演算精度の問題であることがわかります。

Fftfp

そこで、最近接偶数丸めというのを使ってみました。

浮動小数点計算ほど滑らかではありませんが、特徴的なギザギザはなくなったようです。

Fft_nearest

FPGAのハードウェアでFFTを行う際にも、誤差は最近接丸めで処理すれば、もっと良い結果が出るかもしれないという知見が得られました。

| | コメント (0)

2017.04.05

Cosmo-Z 18bit版の性能評価

アルバイトさんが、Cosmo-Zの18bi版拡張ADCボードの特性を測ってくれました。

Cosmo-Zの18bit拡張ボードというのは、下の写真にあるようなボードで、±1Vpp入力で5MHzサンプリングのボードです。

Csz18_2

AD変換器にはAnalogDevicesのAD7960を使い、初段のプリアンプ(可変ゲインアンプ)にはAD8253を、2段目のプリアンプ(ADCドライブ用)にはTIのTHS4521を使っています。

ノーマルのCosmo-Zに比べると速度は遅いですが、ADCの性能やチャネル間のアイソレーションは抜群に良くなっています。また、入力にはx1 x10 x100 x1000の可変ゲインアンプが入っています。ゲイン1の設定の場合の分解能は7.6μVですが、ゲイン1000にすると1LSB=7.6nVとなります。

さて、性能を見てみましょう。まずはゲイン1の場合のノイズのヒストグラムです。

Hist_gain1

このADCは±4.096Vの範囲を18bitで変換するので、1LSB=4.096V*2/262144=31.25μVとなります。上のヒストグラムは半値全幅が7LSBなので約220μVに相当するのですが、可変ゲインアンプの後にゲインは4のプリアンプを乗せているので、入力に換算するとノイズの幅は55μVとなります。

sun

次はゲイン10の場合です。

Hist_gain10

ノイズによる広がりは22LSBになりました。入力換算ノイズは17μVとなります。

sun

ゲイン100の場合、広がりは96LSB程度になりましたが、プリアンプのゲインがトータルで400あるので入力に換算すると7.5μVとなります。

Hist_gain100

sun

最後はゲイン1000の場合。広がりは320LSBほどで、入力に換算したノイズは2.5μVとなります。

Hist_gain1000

sun

ゲインを10倍、100倍、1000倍と変えていっても、ノイズの増え方は10倍、100倍、1000倍とはならず、それよりゆっくり増加するのは、ノイズが初段の可変ゲインアンプだけで生じているからではなく2段目のプリアンプやADC自身で生じているためです。そのため、初段のアンプでゲインを稼ぐことは有意義といえます。

また、オーディオアナライザを使って綺麗な正弦波を作り、このボードに入力し、FFTを行ってスペクトラムを見てみるとひずみ率は-80dB程度でした。

Spec_18bit

周波数特性は約1MHzで3dBダウンとなりました。

Freq

この周波数特性を決めているのは、2段目のプリアンプで、現在は帰還抵抗が5kΩ//33pFという構成なので妥当な結果と言えます。

なお、コンデンサを減らすと周波数特性は良くなりますが、熱雑音によるノイズも増えるし、そもそも2.5MHz以上はエイリアシングだから無い方が良いので、難しいところです。

sun

この結果が妥当なものか検討してみます。

AD8253はゲインによってノイズの大きさが大きく変わります。

Ad8253_noise

ゲイン1の場合、AD8253の出すノイズは45nV/√Hzです。5MHzくらいまで見ているとすると、AD8253で225μVのノイズが発生していることになります。また2段目のTHS4521は4.6nV/√Hzなので23μV、帰還抵抗は5kΩなので熱雑音は20μV。二乗して全部足し合わせると、227μVとなります。

大ざっぱな計算ですが、最初のヒストグラムで示した220μVというのとほぼ一致しますので、ゲイン1のノイズの99%の発生原はAD8253であると推定されます。

ゲイン10の場合、AD8253の出すノイズは60μVに減りますが、これがゲインで10倍されるので600μVのノイズが2段目のTHS4521に加わることになります。THS4521の出すノイズと熱雑音は変わらないので、観測されるトータルで600μVとなります。ヒストグラムから読み取ったノイズの幅は22LSB=687μVなので、これも結果とよく一致します。

ゲイン100の場合、AD8253の出すノイズは55μVに減りますが、ゲインで100倍されるので5500μVのノイズが2段目のTHS4521に加わることになります。ヒストグラムの広がりは約100LSB=3.1mVなので、実際は計算値ほど悪くないという結果でした。

ゲイン1000の場合、AD8253の出すノイズは50μVに減りますが、ゲインで1000倍されるので5mVのノイズが2段目のTHS4521に加わることになります。ヒストグラムの広がりは約300LSB=10mVなので、実際は計算値ほど悪くないという結果でした。

ゲイン100以上で、ノイズが想定より少なくなるのはAD8253の周波数特性がG=100,G=1000の場合には早い段階で下がり始めるからでしょう。

Ad8253_freq_2

つまり、ノイズ発生源であるAD8253は、G=100以上で周波数特性が悪くなるため、高い周波数成分のノイズも減ったと考えられます。

| | コメント (0)

2017.04.04

HDMIを2つ入力するための回路

マルチビデオ入出力ボードCosmo-K DVIの開発を進めていて、重大な難点に当たりました。

DigilentのZYBOのIPを使ってHDMIを2入力作ろうとすると、何かのエラーが出ます。

2つのHDMI信号入力が同じI/Oバンクに割り当てられているので、もしかすると、クロックとかの制限で入らないのかもしれません。やば!!

そこで、アルバイトさんやインターンの学生さんに手伝ってもらって、下記のような構成が可能かどうか検証してみました。

Possible

1つのI/Oバンクに2種類のクロックが入ってきて、ISERDESとIDELAYを別々のクロックで動かすということです。

結果は「可能」でした。BUFGとかが結構苦しいそうですが入ります。

Digilentのhdmi_inのコアでは入らないので、自分でHDMI入力のコアを作ることになります。

また、Digilentのhdmi_inのコアで1入力のHDMI入力を試すと、ZYBOではうまく動くのですが、Cosmo-K DVIではなぜかうまくいきません。その原因は、ISERDESのデコードが、1つのデータ線だけなぜか1ビット遅れるというものだそうです。

やはり、コアは自分で作らないといけません。

| | コメント (0)

2017.04.01

固定小数点回路と浮動小数点回路

XILINXのFPGAである種の信号処理回路を作っているのですが、固定小数点回路と浮動小数点回路で結果が一致しました。

Fixed_vs_float

固定小数点では、16bit表現のとき、

符号.有効数字15桁

のようにして-1~1を表現する場合、結果を32768で割ることになります。

結果がパワーのような「二乗」で表現されている場合、16bitでは表現しきれないので32bit(二乗の和を積和する場合は48bit程度に拡張して)計算して、最終結果を32768*32768で割ることになります。

このような桁の換算が結構混乱しますが、演算自体は高速です。また、適当なビット([34:19]とか)をスライスして切り出せば、結果を目ですぐに見ることができ便利です。

一方、浮動小数点の場合は桁の換算は不要なのですが、XILINXのIPコアはIEEE754という形式で数を扱うので、これについて理解しておかなければなりません。詳しくはWikipediaを参照してください。

私は下記の形式にします。

Float

IEEE754で表現された数値は、16進表現をぱっと見て人間が理解できるものでもないので、デバッグはやりにくいです。

C言語のfloatと互換性があるのかどうかはよくわかりませんが、IEEE754の32bit形式で格納された値をfloat型に変換するには、

*(float *)(&val)

で、要するに無理やりキャストでうまくいくようでした。

固定小数点と、浮動小数点の両方で計算したある種の計算の結果が、先のグラフに示したとおりで、まったく同じになりました。

| | コメント (0)

« 2017年3月 | トップページ