2015/02/22

[電子工作]Nios Ⅱ/eをDE0でやっと動かした

,

 2年前とかに買ったDE0ですが、Timestampの不一致とやらでNiosを動作させることができず、ずっと放置していました。最近またNios動かせるようになりたいと思い、リベンジしてみました。

Quartus Ⅱ v14.0 Web EditionはCyclone Ⅲに対応していない

まずはこっから。本当に対応してませんでした。幾らなんでもサポート切るの早すぎじゃないですか…。DE0に乗っているCyclone Ⅲを使いたかったので、v13.0を利用しました。

Niosについて

Nios Ⅱ/eをDE0で利用する方法については、Sim's blogさんの以下の2つの記事を参考にしました。

NIOSを使ってみました(1) - Sim's blog http://blog.goo.ne.jp/sim00/e/8e1fc436d1e29a6decc20f8256adb914
NIOSを使ってみました(2) - Sim's blog http://blog.goo.ne.jp/sim00/e/35fbcf1fc1bfe67255e371c1ca2c770f

SimさんはQuartus Ⅱ v9.0で行っていますが、私はv13.0を利用したので、ところどころ違うところがありました。例えば、

  • sysid_0をsysidにrenameしませんでした(デフォルトでsysid_qsys_0という名前だった)。
  • module同士のconnection(配線)は手動で繋ぎました。(繋がないと、下に××モジュールをAvalon-MMに繋がないとダメだよなどととエラーが出てしまいます。)
  • addressは、最初はSimさんの例と同じように配置したのですが、結局[System]→[Assign Base Address]で配置しました。

 で、最終的にこのような構成になりました。IRQに関しては全く触っていません(なのでjtag_uart_0のIRQが未配線であるWarningが出てる)。
今回作ったNios周りの図
本来であれば、以下の公式チュートリアルをまず初めにやるべきなのかなあと思いましたまる

Nios II Hardware Development Tutorial
http://www.altera.com/literature/tt/tt_nios2_hardware_tutorial.pdf

Qsys内で間違えてNewしてしまったとき

最初projectを作成したあと、Nios部分を作りこむためにQsysを起動しますよね?ここで、最初からclk_0があるので、変なものを開いたかと思って[File]→[New]してしまうと、projectと関連のないデザインを作ってしまうことになります。
 これを放置したままでいると、main.vhdでは生成したnios componentを使おうとしているのに、関連性がないからQuartusはniosがどれだか分からないっていう状況になってしまいます。
 こういったときは、普通にNiosコア周りを[Generate]まで行い、その後Quartusの方でprojectに、Qsysが生成したNios関連のファイルをポイポイっと追加すると、QuartusはNiosがどれのことか理解してくれます。

.pofと.sof、どっち?

FPGAのAssemblerまでが正常に終了すると、<project root dir>/output_files以下に、生成物が保存されています。Xilinxだと.bitファイルなのですが、Alteraの場合、.pofと.sofという2つのファイルが出来ていました。どっちがどっちなんでしょう?
.pofか.sofか

新人エンジニアの赤面ブログ 『プログラミング?コンフィギュレーション?』 http://bit.ly/1L4Xu1X
Generating Secondary Programming Files http://bit.ly/1L4XSO8

上のリンク先などを参照するに、
.pof → Programmer Object File (EEPROMなど向け)
.sof → SRAM Object File (FPGAのSRAM向け)
のようです。なるほど、名前が違うんですね。

Deviceはどっち?

Programmerで、DE0に書き込もうとすると、JTAGスキャンした後に"Encounter devices with shared JTAG ID for device 1. Please select your device."と言われたりします。
どっち?
どうやらEP3C16とEP4CE15のJTAG IDが0x020F20DDで一緒らしいです[1][2]。DE0に載っているのはEP3C16なので、そっちを選びます。慣れないツールで英文見て、一瞬フリーズしてしまいました…。

その他エラーメッセージ諸々

QsysでのAvalonバス配線忘れのエラー

"**** must be connected to an Avalon-MM master"
多分スレーブのAvalon-MMポートが、どこのAvalon-MM Masterポートにも接続されていない。(そのまんま)
sysid_qsys_0のAvalon-MMがどこにも接続されていない。
例えば上の図だと、Connectionsを見ると、sysid_qsys_0のcontrol_slaveが、Avalon-MMバスのどこにも繋がっていません。なので、どっからも制御されないことになってしまいます。よって、control_slaveの白丸を2つクリックし、黒にすると接続したことになり、Warningが消えて上の図のようになります。
 まあ、CPUと周辺ペリフェラルは全てAvalonバスで繋ぐのがNiosらしいので、繋がってなかったらおかしいですよね。

Qsysでのアドレス衝突時のエラー

Error: System.nios2_qsys_0.data_master: onchip_memory2_0.s1 cannot be at 0x11000 (0x10000 or 0x18000 are acceptable)
Error: System.nios2_qsys_0.data_master: sysid_qsys_0.control_slave (0x11010..0x11017) overlaps onchip_memory2_0.s1 (0x11000..0x18fff)
"cannot be at <addr>"というエラーが出た時のQsysの画面
 これは、各ペリフェラルごとにアドレスを決めますが、それが衝突(重なって配置されてしまっている)していることを示すエラーです。これを解決するには、addressを手動修正でもいいですし、[System]→[Assign Base Address]を選ぶと、Qsysが全て自動で配置してくれるみたいです。

Qsysでのclk/resetの配線忘れエラー

Error: System.nios2_qsys_0: nios2_qsys_0.clk must be connected to a clock output
Error: System.nios2_qsys_0: nios2_qsys_0.reset_n must be connected to a reset source
 上のAvalon-MMバスと同様に、各モジュールにclkとresetを接続する必要があるようです。Qsysを立ち上げた時から存在していたclk_0は、clkとresetのバッファのようなもので、これらの出力を各ペリフェラルなどに接続すれば動きはするみたいです。

.bspのエラー

make[1]: *** [public.mk] Error 1
make: *** [../nios_software_test_2_bsp/-recurs-make-lib] Error 2

 Qsysでaddressなどを変更したあと、Nios IDEでBuildしようとしたら、このようなエラーが出てしまいました。どうやら、変更した部分がHardware Support Packageかなにかに反映されていないようです…?以下のサイトを参考にしたところ解決しました。

■第1部 第2章|組込みのこと http://ameblo.jp/umigasuki2/entry-11559007850.html

方法としては、
  • Nios IDEで、プロジェクトを選択した後、[Nios II]→[BSP Editor]
  • BSP Editorが起動したら、[File]→[Open]を選択し、Hardware Support Packageのプロジェクト(<project name>_bsp)のフォルダにある.bspファイルを選んで開く。
  • とりあえず右下の[Generate]を押す。
  • プロジェクトをリビルドする。
とやったところ、なんとかまた動作するようになりました。でもよく分からない…。この作業をする前後でpublic.mkに変更が加えられたか確認していないけれど、baseaddrか何かが変わったのかな。

BSP Editor起動直後。このままExitしてはだめ、[File]→[Open]で.bspファイルを開く。

BSP Editorで.bspを開いた時の画面。Linkerのaddressが変わるのかな?

SynopsysについてのCritical Warning

Critical Warning (332012): Synopsys Design Constraints File file not found: 'main.sdc'. A Synopsys Design Constraints File is required by the TimeQuest Timing Analyzer to get proper timing constraints. Without it, the Compiler will not properly optimize the design.

Critical Warning (332168): The following clock transfers have no clock uncertainty assignment. For more accurate results, apply clock uncertainty assignments or use the derive_clock_uncertainty command.

最小限のプロジェクトを作成した後、Implementationまで行おうとすると、こんなCritical Warningが出てきました。が、その割には動きます。なんでだ…

CygwinのWarning

0 [main] sh 7836 find_fast_cwd: WARNING: Couldn't compute FAST_CWD pointer.  Please report this problem to the public mailing list cygwin@cygwin.com

Nios IDEでprojectをbuildしている時に、Consoleに大量に流れていくエラーです。どうやら内部で回っているらしいcygwinの問題のようで、スルーしていてもbuild自体には問題なさそうです。

成功した場合どうなる?

-----------------------------------------------------------
Using cable "USB-Blaster [USB-0]", device 1, instance 0x00
Processor is already paused
Reading System ID at address 0x00001000: verified
Initializing CPU cache (if present)
OK

Downloading 00008000 ( 0%)
Downloaded 1KB in 0.0s      

Verifying 00008000 ( 0%)
Verified OK                      
Starting processor at address 0x00008020
-----------------------------------------------------------
 これは[Run As]→[Nios ⅡHardware]に成功した時のConsoleです。System IDがちゃんと認識されました。
 Eclipseでdebugすると、以下のようになります。どうでもいいんですけど、EclipseはRun時に流れるConsoleのメッセージがすぐ消えてしまって、なかなか追えないのがイライラします…。
EclipseでDebugしてるときのスクリーンショット

結論

思ってたよりはつまらずに出来ました。
 ただ、実は、Niosでやりたいことの一つが、TCP/IPを利用した通信で、どうもNiosで無償で利用できるコアにEthernet(RMIIとか)が無いようなんです。ジーザス。今はSPI通信経由でCC3300やENC28J60を利用しようかと考えていますが…ライブラリの移植にも手間が掛かりそうです。
 うーん…。
 


参考文献
[1] "Cyclone IV Device Handbook", Altera Corporation, Volume 1, December 2013, p.10-4, http://www.altera.com/literature/hb/cyclone-iv/cyiv-51010.pdf
[2] "Cyclone III Device Handbook", Altera Corporation, Volume 1,  June 2009, p.12-2, http://www.altera.com/literature/hb/cyc3/cyc3_ciii51012.pdf
[3] "Nios II プロセッサ: 世界で最も汎用性に優れたエンベデッド・プロセッサ", http://www.altera.co.jp/devices/processor/nios2/ni2-index.html, 2015/02/22閲覧
 XilinxのFPGA埋め込みコア"MicroBlaze"で利用できる無償IPコアよりは、数は多いと思うんですけれど、Ethernetはないんですよね…
Read more →

2015/02/02

[電子工作]紙を検知してソレノイドを動かす回路を作った

,
 なんて書けばいいんだろう、授業用に基板を作ったけど、具体的には「紙があるときだけ、ソレノイドを動かす回路」としか言えない。ま、とにかく作ったので書いておきます。


 概要


紙があるときだけ、ソレノイドを動かす回路です。ほんとそれだけです。以下にブロック図を示します。
今回の回路のブロック図
紙の検出には、秋月で販売されているフォトリフレクタ、LBR-127HDを使用しました。選定理由は特になく、たまたま最初に選んだのがこれで、試しに紙をかざしてみたらちゃんと動作したのでこれを使っています。

 で、フォトリフレクタは紙すれすれの場所に無いといけないので、場所の制約からメイン基板とは離れてしまいます。なので、センサーだけを載せるミニ基板を作りました。上のブロック図で"sub_sensor_pcb.sch/brd"となっているのがそうで、12mm × 35mm程度の大きさです。

 フォトリフレクタとメイン基板までは、1mの3芯銅線(オヤイデの人に選んでもらった極東電線製細物多芯ケーブル VVC 3芯 (7/0.18 × 3芯))で接続しています。ここのノイズ対策のために、メイン基板側で1 Logic ICのバッファーを入れています。また、フォトリフレクタのフォトトランジスタがON時に完全に0Vにはならず、C-E間飽和電圧Vce(sat) = 0.4Vだけ浮いてしまうので(これでもLVCMOS的にはLowですが)、それをLowレベルまで下げる役割も兼ねています。

 実際に信号に応じてソレノイドの制御信号を生成するのは、STM32 Nucleoボードで行っています。
 最初はLPC810で制御をしていたのですが、「立ち上がり/下がり割り込みから、一定時間遅れてピンを反転させる」というロジックを、自分の力ではどうしてもLPC810で実現できなかったので、書くのが簡単そうなmbed SDKが使え、なおかつ安い(\1,500)Nucleoを選んだ経緯があります。
 mbed SDKはInterruptInクラスで立ち上がり/立ち下がり時の割込みハンドラが扱えるので、これを利用してセンサーの出力変化時にFETの出力を変えています。

 ソレノイドの駆動にはFETを利用しています。ソレノイドは、0.1A~0.2A(実測)とそこそこの電流が流れるので、ON抵抗が低そうなInternational RectifierのHEXFET、IRLTS6342を利用しました。


回路


センサー基板の回路図

メイン基板の回路図


センサー基板について


 フォトリフレクタの抵抗の値については、以下のように決めました。
赤外線LEDの順方向電圧Vf : 1.2V typ. (データシートのElectrical Specificationsより)
赤外線LEDに流すべき電流If : 20mA?(データシートのElectrical Specificationsの、Conditionsが大体そうだから)
よって、R1 = (Vcc - Vf) / If = (3.3 - 1.2) / 0.02 = 105(Ω)。
まあ、100ΩでもIf = 21mAとなり、絶対定格60mAの1/3なので、安全率3だし壊れはしないでしょう…ということで、100Ω。

 フォトトランジスタの抵抗R2は10kΩにしましたが、これは最初プルアップと思い込んで、いつもの様に10kΩにしていたら動いてしまったので、実験で決めた値になります。ちゃんと計算するなら、ON時に流す電流、データシートのグラフにある過渡応答特性などから総合的に判断すべきなんでしょう…。
その場合、R2 = (Vcc - Vce(sat)) / Ic = (3.3 - 0.4) / 0.002 = 1450(Ω)
あれ、結構低いですね、まあいいや…

 LED1は、電源がここまでは来ているよという確認の為に設けています。そうしないと、テスターでいちいち測ることになって面倒ですので。

 D1は、コネクタの逆挿入防止です。といってもXHコネクタは1方向しか入りませんが。ブレッドボード向けジャンパワイヤなどを利用した時のためと、安心のために一応入れています。ダイオードの選定理由は特に無し。面実装で小型で、Eagleのライブラリにあったから、かな。

 FUSE1は、万が一この基板がショートしたりして過大電流が流れた時に、それはどう考えても故障なので、せめて他の基板は動いてくれよと、この基板だけ切り離すためのポリスイッチです。電源電圧も低いですし、消費電流は100mAにも満たないでしょうから(これは計算できるはず)、1608サイズの小さなポリスイッチを利用しています。


メイン基板について


 最初はチャタリングが発生するかと思い、センサーからの入力に対してLPF(積分回路)を入れようかと思っていました。が、冷静に考えるとセンサーってスイッチではないですし、実際にオシロスコープで波形を見てみてもチャタリングなんてなかったので、結局R4 = 0Ω、C2 = NI(Not Inserted, 未実装)になっています。

 IC1は、波形整形のためのバッファーICです。この基板では、バッファーICはここにしか使用しないので、1ゲートロジックICであるTexas InstrumentsのSN74LVC1G07を使用しています。、後述の理由から、74LVC1G34(TI, NXP)を利用するか、74LVC1G08(2-input AND)か74LVC1G32(2-input OR)の2つの入力を接続してバッファーとして使うなどした方がいいようです。
 余談ですけど、1ゲートロジックは面実装ばかりですが、入力電圧範囲・電源電圧範囲が広いことが多く、基板を作る回路の時には便利ですね。あまり秋葉原とかには売っていませんけど。

 D1は、万が一コネクタに過大電圧(静電気とか?)が加えられた場合の保護回路です。本当に動くのかな、まだ試験したことないです。「ヤバい状況下で、保護回路が本当にちゃんと保護してくれるのか?」というのは気になる話ですので、今度試してみたいです。

 R3は、コネクタに何も繋がっていない場合、Logic ICの入力が不定にならないようにするための、プルアップ抵抗です。値は特に考えず10kΩ。

 メイン基板のJ3は、ここからNucleoに対してメイン電源を供給するために付けたコネクタです。でも、Nucleoを外部電源で動かすためには、Nucleo上のジャンパーの切り替えが必要だったので、まだ浸かってなかったりします。JP1は、この基板上で外部電源を利用するかどうか切り替えるジャンパーです。


 続いて、ソレノイド駆動回路に話を移します。

 FET(Q1、X1)は、ソレノイドのON/OFFを制御する素子です。モータードライバーなどのスイッチ素子は、わりかし過電流などで破壊されやすいので、交換を容易にするために手半田しやすい2SK4017用パターンも用意することにしました。初期では特性の良いQ1を実装しておき、もし壊れた場合は、以後X1にします。
 Q1を選定した理由は、Digikeyでよさそげなのを探していたところ出てきたことと、IRのFETは優秀そうだっていうイメージからです(この会社の主力製品ですよね)。

 R15はFET入力に対するダンピング抵抗です。そんな反射で困ったことはないけれど、半ばおまじないのように入れています、R16は、万が一Nucleo基板が挿入されていなかった場合に、FETの入力が不定とならないようにするための、プルダウン抵抗です。FETがそんな状況下でONされては困るので、プルダウンです。
 

パターン

センサー基板のパターン図
メイン基板のパターン図
  

 センサー基板は、ネジでちゃんと固定できるように、M3.2の穴を2つ開けてあります(1つだと回転しそう)。実際にはM3のネジを使いますけど、なんか余裕のない穴径は嵌まらなくなりそうで怖いので、+0.2mmして3.2にしています。
 で、ぶっちゃけるとこれらが基板の半分以上を占めています。やはり機構部品は大きいですね、電子部品のようにもっと小型化しないかなあとよく思ってしまいます。回路の部品は、なるべくセンサとコネクタの隙間に詰めるようにしました。
 もう一つ気をつけることとして、フォトリフレクタとXHコネクタは逆向きに実装することがあります。フォトリフレクタは紙方向に向きますが、その分コネクタから線を取り出すスペースは逆の面にしかありませんので。


 メイン基板は、なるべくバッファーICを、信号コネクタの直近に配置するようにしました。そうすれば、基板内はちゃんとした信号になるといいな(願望)。
 ソレノイドは、それなりに電流が流れるということで、配線を太くし、裏面のベタアースはしないようにしています(なんでだっけ)。ダイオードは、ソレノイドの直近に配置するようにしました。
 
 FETは、2つのデバイスのS、G、Dが全て共通なので、TO-251AAの2SK2417と、TSOP-6のIRLTS6342PbFをうまい具合に配置しないといけません。で、圧倒的にTO-251AAが大きいので、その間に何とか収まるように配置してみました。IRLTS6342PbFはDが4ピン分ありますので、それを2SK4017のDに繋がるポリゴン上に乗るよう、大まかに位置決めをしています。

 また、ソレノイドに流れる電流は、そのまま外部電源のGNDに帰って欲しいので、FETのSと外部電源につながるコネクタJ2のGNDをポリゴンで囲い、外のGNDとは小さく繋げています。

 そうそう、ここに書かれているArduinoのピン番号のシルク、基板を作ったら書かれていませんでした。SparkFun-Boards.lbrの なんですけど、番号とかは全てtPlace(21)に書かれてました。あれ、変だ… ガーバーデータを確かめないと、、


実際に制作してみて


 この基板も、当然のように最初動きませんでした。

 センサー基板からの出力はちゃんと出ているのをテスターで確認できたので、メイン基板の信号の流れを追っていくと、ロジックICの出力で信号が途絶えていました。
 このバッファIC、最初はLVCMOS出力かと思ってたのですが、よくよくデータシートを見たらOpen-Drainって書いてありました。そりゃ動きませんね、出力にVccへのプルアップ抵抗を付けてみたのですが、それでもまだ動きませんでした。えーなんでと思いつつデータシートを更に読むと、p.11のLayout Exampleで、NCピンをfloatにしてないのを見つけました。よく説明を読むと、GNDかVccに配線するよう書かれていました。で、その通りにジャンパを飛ばしてみたら案の定動きました。たとえ5ピンのロジックICだとしても、油断せずにデータシートはよく読めということですね…。

 それ以外にバグはなく、FETもちゃんと動いてくれました。

 今回の教訓

  • 例えロジックICでも、5ピンしかなくても、ちゃんとデータシートは読む。
  • NCピンの処遇はちゃんと確認する。
  • ICのOpen-Drain出力には気をつける。
Read more →