ラベル CAN IP の投稿を表示しています。 すべての投稿を表示
ラベル CAN IP の投稿を表示しています。 すべての投稿を表示

2016年7月3日日曜日

CNC4030 23 (チューブ式ポンプの製作 12)

前回 CAN通信が出来なかったのは、CANトランシーバICのハンダ付け不良が原因だった。
トランシーバはMaximのMAX3051EKAというICを使用しているのだが、これのRSピンをGNDに落とすのを忘れていた。Hi-speedモードにするためにはこのピンをGNDに接続する必要があるがハンダ付けを忘れてピンがフロート状態になってしまっていたためLow-speedモードか若しくはどっちつかずの不安定な状態で動作していたようだ。

ウラ面で8番ピンをGNDに接続する予定だったが、忘れてしまっていた。

このRSピン部を修正したら、CAN通信できるようになった。

ポンプ操作部の機能としては、ボリュームやスイッチで操作するマニュアルモードとCANbus経由で操作されるリモートモードを持つこととした。起動時の初期モードはマニュアルモードで、モード切り替えはCANbusから行う。リモートモードでは手動操作は無効となる。 CANbusからはこのモード切り替えの他に、PWMの周期、duty、回転方向が設定できる。少々判りづらいがRTLはこんな風になっている。

PWMモジュールは5年前に作った物だが、このモジュールではdutyは固定小数(1.7bit ... 整数部1、小数部7bit、最大値1.0)で設定できるようにしてある。そのため、上位側が回路(HDL)であれソフトウェアであれ、設定値のduty⇔パルス幅変換の計算をすることなく、duty値そのものを設定することが出来るので楽できる。PWM式のDAC等に応用する場合に扱いやすいだろうと考えてこのような仕様にした。

これはIP作成当時のシミュレーション波形


Zynq側で以下のようなプログラムを書いてCAN busから制御できるかを見た。

リモートモードに変更後、dutyを100msec毎に0%から100%まで上げた後、今度は逆に100%から0%まで下げ、最後にマニュアルモードに戻す。


動いている様子

マニュアルモードで動作中にリモートモードに設定されたことでCAN bus支配下になりプログラム通りに回転数が上昇・下降している。また、リモートモード中はボリュームやスイッチ操作を受付ないがマニュアルモードに復帰すると操作出来ている。

ということでコントローラも一応完成した。
今後はローラーを若干改良して実際に冷却液を流してみようと考えている。



2016年6月26日日曜日

CNC4030 22 (チューブ式ポンプの製作 11)

去年の9月頃、世界最小クラスかも知れないFPGAボードでCANを動かそうとしていた頃にある方からコメントの書込がされていたのを3日前まで気づかないでいた。せっかくコメントを書いて下さったのに大変申し訳無いことをしてしまった。 コメントの書込があった場合にはメールで知らせるように設定していた筈なのだが、コメント管理の設定に問題があったんだろうか? よく判らないのだがコメントの書込があるのに気づいて何か操作をしたらそこで新規コメントが書き込まれましたというメールが送信されてきた。

さて、コントローラだがzyboをCAN通信の相手にしてのデバッグを開始した。

が、通信できない。
以前CAN IP実装時に作ったボード(上の写真の青色ソケットのボード)に装着して動作させると通信できるので、今回作ったコントローラ基板の配線がどこかミスっているのかも知れない。
CANトランシーバICのパスコンの電源側の配線を忘れているのは見つけたが、他にもあるかな?


2015年10月4日日曜日

世界最小クラスかも知れないFPGAボード 11 (CAN IPを実装してみる 7)

CANバス経由でのリードバックを見てみた。
いきなり実機で動かすことはせず、RTLレベルとゲートレベルでシミュレーションをして動くことを確認してから実機で確認することにした。 シミュレーションではこれまでと同様にCANマスタとしてOpenCoresのCAN IPを使用した。
以下のようにCANバスからI2Cコントローラのreg_adrレジスタに0x55を、reg_wdatレジスタに0xAAを書き、次にreg_adrレジスタの値をリードバックしてみた。

以下がRTLシミュレーションの結果である。赤字のref_modelの部分がCANマスタの信号で、data_out[7:0]は受信した(即ち、自作CANIPが送信した)データである。 0x55 が受信できているので期待通りだ。

こちらはゲートレベルシミュレーションの結果で、こちらも期待位通りの結果だった。


I2C busの通信も起動できるかの確認
こちらも期待通りの結果だった。



実機での確認
シミュレーションと同じようにI2C コントローラに値を書いて、それが読めるかを見てみた。
zynq側のプログラム

結果
3行目の「2: xxxxxxxx]の左端がリードバックして受信した値で、55になっているので成功だ。


http://bravo-fpga.blogspot.jp/2015/08/fpga-7.htmlに書いたとおり、I2CバスにはMCP3425ADT (16bit ΔΣ A/D)、 MCP4726A0T (12bit DAC)、 STTS751 (12bit 温度センサ)が接続されているが、今回はSTTS751のレジスタを読んでみることにした。


STTS751のレジスタマップは以下のようになっている。


Manufacturer ID、Revision、Product ID等固定値のレジスタと温度レジスタをリードしてみた。
zynq側のプログラム


結果

固定値の部分はデータシート通りの値が読めている。また、このプログラムを実行した時の室温は29℃だった。1℃の違いはあるが、温度も正しく読めていると考えて良いだろう。


ということで、リードバックは問題無さそうだ。


2015年9月6日日曜日

世界最小クラスかも知れないFPGAボード 10 (CAN IPを実装してみる 6)

LSEで合成した場合の結果が変な件だが、どうも解せないのでFPGAの設定をMachXO2に変えて合成し生成されたネットリストでゲートシミュレーションを実行してみた。結果は同じでCANが応答しない。

XO2用に合成した場合はモジュール階層がある程度維持されるようで、canモジュールも各サブモジュールの信号名も保持されたネットリストになっており、can_rxpp(受信モジュール)のステートマシンのステートカウンタの信号も残っていたのでその信号を見てみたところ、上図のようになっていた。 stateがステートカウンタ、prv_stateは直前のステート値を保持するレジスタである。
 このステートマシンはステート数16で4bitのステートカウンタの全ての値に意味がある。従って、state[1]が z になるのは変だ。 この z という状態はネットが浮いている、つまりどこにも接続されていないということなので、合成エンジンはstate[1]を不要と判断してその部分のレジスタを削除した可能性がある。

一方のprv_stateは一つ前のstateの値を保持するレジスタで、

prv_stateの値は以下の2箇所(794行目と821行目)で参照されている。

ST_ERROR値は4'd12とST_OVLDの値は4'd14なので、論理式の部分を解くと以下のようになり、確かにprv_state[1]は削除できることが解る。 ( prv_state != ST_ERROR && prv_state != ST_OVLDは、prv_state == ST_ERROR || prv_state == ST_OVLD の反転値なので両者でprv_state[1]は不要である。)

prv_stateの結果は間違っていないがstateの合成結果は明らかに間違っている。合成の最適化オプションの設定が関係しているかも知れない。上記合成は以下の最適化オプション設定で行った。

そこで、最適化オプションのResource SharingをFalseにして合成しなおしてみた。(尚、iCE40用のLSEの設定ではResoure SharingはデフォルトでTrueとなっている。)

生成されたネットリストでシミュレーションしてみると・・・

旨く行った!  state[1]も正常だ。
この結果を受けて、iCEcube2でもResource SharingをFalseにして合成してみた。

生成されたネットリストでシミュレーションしてみると・・・
こちらも旨く行った!   iCE40用の合成の場合は階層情報が維持されないようで、can_rxppモジュールのstateやprv_state等も上記の信号名しか参照できなかった。が、canはACKフレームを出しているので期待通りの動作をしている。

上述の通り、can_rxppモジュールのステートマシンはステート数が16あるステートマシンだ。
ステート間の遷移パターンは49パターンある。
上図のcovered_fsm、... はCoveredというコードカバレッジツール用のもので、このステートマシンの(記述されている)ステート遷移がシミュレーションで全てカバーされているか(検証されているか)を見るための記述である。 このcan_ip開発時に検証した。(CAN IPのDEBUG 8

上記のような複雑なステートマシンの場合は、Resource Sharingは旨く作用しない場合があるのかも知れない。  ということで、Synplifyで旨く行って、LSEで旨く行かないことの原因らしきものは判った。

次は、実機でFPGAが反応しない(ACK応答しない)件だ。
Resource SharingをFalseにして合成したビットマップファイルをFPGAにダウンロードして実機で動作させてみたところ、Synplifyの場合と同じでACKフレームが出ない。反応していないように見えた。  そこで、can_ipの内部信号をFPGAの未使用ピンに出して、その状態をロジアナで観測してみた。

引き出したのはステートマシンがIDLEステートにいることを示す信号と、ERRORステートにいることを示す信号、そして、can_phyモジュールで生成されるcanのRXD信号をサンプリングするためのイネーブル信号(b2r_spen)だ。

その結果、ステートマシンは動いてはいるようだが途中でエラーステートに遷移していることが判った。 さらに細かく見ていくと、b2r_spenの間隔が異常に短い箇所があることが判った。

b2r_spenはcan_phyモジュールで生成されていて、信号受信が無い(RXD信号が変化しない)場合は、自走してビットレートに応じた周期のパルスになる。今の場合は1Mbpsなので1us周期のパルスとなる。また、RXD信号に0➔1または1➔0の遷移がある場合は、そのエッジで周期が微調整される。その様子は以前CAN IPのDEBUG 7に書いた。
俯瞰して見てみると、この現象には周期性があるようだ。

なので、ノイズでの誤動作とかメタステーブルとかが原因では無さそうだ。
念の為オシロスコープでも見てみた。

そこで、ロジアナで採取したCANのRXD信号をテストベンチに取り込んで、シミュレーションで再現するかを見てみることにした。その為には・・・
まず、GTKWaveで観測している波形をTIMファイルにエクスポートする。

TIMファイルは以下のような形式のテキストファイルで全ての信号の情報を含んでいるので、そこからRXDの部分を抽出する。


そして、時刻情報と信号の値をテキストエディタなどを使ってテストベクタに変換する。

このベクタでRTLシミュレーションを実施したところ、現象が再現された。

色々原因を探った結果、Zynq側のビットレートが1Mbpsに対して9%程度低い可能性が見えてきた。
以下の波形はRXD信号に変化が無くてcan_phyが自走してb2r_spenを生成している部分だが、パルス間隔は1us (=1Mbps)となっていて正しい。


これに対して、RXDを見てみると、以下の波形は9シンボル分の間隔を見ているが、その値は9.83usとなっている。 9.83÷9 ≒ 1.09なので9%程度ビットレートがズレている。
CANの規格では送受信間のクロックのズレは最大1.58%となっているので9%は大きすぎる。


Zynq側に何か問題がありそうだ。
ZynqのCANモジュールのリファレンスクロックは24MHzだが、IO_PLLのから供給していて実際は23.809525MHzが供給されている。

ただ、誤差は0.8%程度なのでこれが原因とは考えにくい。とすると、CANモジュール内部のクロック関係の設定が怪しい。クロック関連の設定要素としてはBRPR(プリスケーラ)レジスタとBTRレジスタがある。それぞれの設定とビットレートとの関係はZynq-7000 AP SoC Technical Reference Manualに書いてある。現在のプログラムの設定値もここを参考にして決定した。

が、よく見ると、最下段のfreqBIT_RATEの式は間違っているようだ。Sync Segmentの分が含まれていない。正しくは、
freqBIT_RATE = freqCAN_REF_CLK / ((can.BRPR[BRP] + 1) * (3 + can.BTR[TS1] + can.BTR[TS2]))
でなければならない筈だ。現在の設定値はBRPR[BRP]が1,BTR[TS1]が8、BTR[TS2]が2なので、間違っている方の式でビットレートを求めると、24/((1+1)×(2+8+2)) = 1と1Mbpsになるが、正しくは、24/((1+1)×(3+8+2)) ≒ 0.923の筈で、これは1/0.923 = 1.083なので8%程度の誤差となる。
原因はここのようだ。
そこで、プログラムのTS1の値を7に変更することにした。


修正したプログラムを走らせてみたところ、旨くいった!!  やたっ!

以下のプログラムではPWMのDutyを0%から100%まで5%刻みでCANバス経由で設定しているが、そのとおりにPWMの出力は変化している。




ということで、遂に世界最小クラスかもしれないFPGAボードでCANを動かすことが出来た。!!
やったー \(^_^)/

iCE40LMのパッケージへのハンダ付けの挑戦をするためにデジタル温調ハンダゴテを購入したのが2月だから、ここまで来るのに8ヶ月位かかったが、なんとかCANの動作まで漕ぎ着けた。  また、今回は2Gsのオシロよりも100Msの自作ロジアナの方が役に立った。このロジアナは作ってよかったと実感している。自作したものが十分使えて役に立ったという点も非常にうれしい。

次はCANバス経由でのリードバックを確認しよう。

ERROR: Failed to spawn fakeroot worker to run ...

なにかと忙しくてなかなか趣味の時間を確保できない。 ...orz  家の開発機のOSはLinux Mintなのだが、最近バージョンを22に更新したところ、myCNC用のpetalinuxをビルドできなくなってしまった。ビルドの途中で ERROR: Failed to spawn ...