コマンドのエラーがあるときは、Syntax ErrorとかMissing Operandといった答えを返しますが、あまり統一性はありません。オーバーレンジの時は、Over Rangeを返すはずですが、Missing Operandを返す時もあるようです。
デリミタはCR+LFで、EOIも返します。一般的な使い方として、電源立ち上げ時は自動的にフリーランモードになっていますので、そのままレンジ設定したり読みとれば良いわけですが、安心のためには一番はじめにMEASを出しておけば良いでしょう。
全く意味不明で、有害無益なファンクションとして、応答のあるコマンドを出した後、すぐにデータを読まないとSRQを発効するというものがあります。何を考えてんだかとおもいますが、PET2001のべーしっくの世界でもあるまいし、どう考えても何の使い道もありません。
Device(DCCT) %{ }% TimeOut 60; NameTable RangeName= "20mA","50mA","100mA","200mA","500mA","1A"; EfastTable RangeMode = "RANG1\r\n","RANG2\r\n","RANG3\r\n","RANG4\r\n","RANG5\r\n","RANG6\r\n"; EfastTable RangeRead ="RANG=1\r\n","RANG=2\r\n","RANG=3\r\n","RANG=4\r\n","RANG=5\r\n","RANG=6\r\n"; ParamTable{ set_auto_trig {rec=bo, command="MEAS\r\n"} read_auto_trig {rec=ai, command="MEAS?\r\n",conv="%lf\r\n",leng=511} set_single_trig {rec=bo, command="TRIG\r\n"} read_data {rec=ai, command="READ?\r\n",conv="%lf\r\n",leng=511} set_range {rec=mbbo,efast=RangeMode,name=RangeName} get_range {rec=mbbi,command="RANG?\r\n",efast=RangeRead} get_name {rec=si,command="*IDN?\r\n", conv="%[^\r\t\n]", leng=64} } %{ }%これでMakefile.Vxに
LIBOBJS += devDCCTGpib.oを付け加えてgmakeすれば一発で動くはずだったのです。しかしそうは問屋がおろさない。
本来、read?コマンドがでたとき、DCCT側の準備が出来ていない(データをregistorに用意していないとか、トリガーがかかっていない)場合は、GP-IBバス上のハンドシェイク信号でコマンドを拒否すれば良いのですが、実際には、read?が出てからデータをレジスタに用意するため、ハンドシェイクはOKを出しているのにデータがにゃあということになっています。これで読みとりが破綻する様です。とりあえずはread?コマンドと次のTA、LAを出すまでにwaitを入れてやれば問題は回避できます。
ウエイトを入れたところは、GP-IBアナライザで見ると、
M Timestamp Data Control mi s ms us ns A H 87654321 E A S R I NR ND D --------------------------------------------------------------------- 0 0 2 162 0 R 52 01010010 0 0 0 1 0 0 1 1 DAB 0 0 0 72 300 E 45 01000101 0 0 0 1 0 0 1 1 DAB 0 0 1 260 450 A 41 01000001 0 0 0 1 0 0 1 1 DAB 0 0 1 52 250 D 44 01000100 0 0 0 1 0 0 1 1 DAB 0 0 1 52 250 ? 3f 00111111 0 0 0 1 0 0 1 1 DAB 0 0 1 52 250 d 00001101 0 0 0 1 0 0 1 1 DAB 0 0 1 52 250 a 00001010 0 0 0 1 0 0 1 1 DAB 0 0 3 518 950 ? 3f 00111111 0 1 0 1 0 0 1 1 UNL 0 0 0 6 800 20 00100000 0 1 0 1 0 0 1 1 LA0 0 0 0 7 0 C 43 01000011 0 1 0 1 0 0 1 1 TA3と、READ?を出して、UNL、LA0、TA3を出すまでの間に約3.5ms入っています。繰り返しますが、GP-IBは3線ハンドシェイクをしており、かなりのろまなデバイスでもまた逆に高速なデバイスでも「ソフト的」に考慮する必要は本来ありません。また、「ソフト的」に対応してしまうのは大変悪い癖であり、例えば他のデバイスが同じバス上に来たときに、どういう動作をするか保証できる物ではありません。
とりあえずは「ソフト的」にwaitを入れて、動かすことにします。
コントロールの山本さんに相談の結果、gp-ib drive supportに手を入れていもらい、コマンドと次のUNL、LA、TAまでの間にwaitを入れることが出来るようにしてもらいました。これを使うため、gmakeでmakeを行うのではなく、まずgdcでコンパイルをします。ここで、gdcは
/cont/epics/R313/epicsTest/base313/bin/hppa8k/gdcを使う必要があります。また、Makefile.Vxの中でも、LIBOBJSだけでなく、SRCS.Cも付け加える必要があります。コンパイルした結果は、O.frc40とかO.frc64にdevDCCTGpib.cとして入っています。この中で、以下の部分を探します。
static struct devGpibParmBlock devSupParms = { &DCCTDebug, /* debugging flag pointer */ -1, /* device does not respond to writes */ TIME_WINDOW, /* # of clock ticks to skip after a device times out */ NULL, /* hwpvt list head */ gpibCmds, /* GPIB command array */ NUMPARAMS, /* number of supported parameters */ -1, /* magic SRQ param number (-1 if none) */ "devDCCTGpib", /* device support module type name */ DMA_TIME, /* # of clock ticks to wait for DMA completions */ NULL, /* SRQ handler function (NULL if none) */ NULL /* secondary conversion routine (NULL if none) */ ,(int) '\xff' /* End of String(eos) */ };この3行目、-1,/* device dose not respond to writes */の-1を-2とか-3にすると、-2だと1/60秒のwaitが、-3だと2/60秒のwaitが入ることになります。ここを変更して、gmakeでdevDCCTGpib.cをコンパイルすれば出来上がりです。この方法は、GP-IB規格にあっていない妙なGP-IBデバイスがうまく動かない場合にも応用出来るかもしれません。
/*** COMMAND LIST ***/ No. 0 BO set_auto_trig No. 1 AI read_auto_trig No. 2 BO set_single_trig No. 3 AI read_data No. 4 MBBO set_range No. 5 MBBI get_range No. 6 SI get_nameですから、あとはGP-IBアドレスを考えて、データベースを作れば良いことになります。capfastの図を参考までに載せます。
# Example vxWorks startup file #Following must be added for many board support packages cd "/users/tobiyama/epics_r313/iocBoot/iocfeedback" #ld < bin/enableA24_frc64.o ld < /cont/epics/R313/epicsTest/base313/src/libCompat/O.frc40/enableA24_frc40.o ld < bin/kekRouteSet_frc40.o #ld < bin/kekRouteSet_frc64.o ld < bin/iocCore ld < bin/seq ld < bin/feedbackLib enableSlaveA24() sysA24MallocInit(0x40000) dbLoadDatabase("dbd/feedbackApp.dbd") dbLoadDatabase("feedbackApp/Db/fb_ar_ktest.db","user=tobiyama") #dbLoadRecords("feedbackApp/Db/dbExample.db","user=tobiyama") iocInit #seq &snctest
GP-IBは、太古の昔に(IEEEで規定されたのが1975年、HPが構想を始めたのが1960年代後半だからもう神代の昔と言って良いかも知れない)、当時の非常に貧弱なコンピュータ環境で測定器をコントロールするためにHP社殿が開発された物です。今から思えば、エラーリカバリ機能はありませんし、TTLレベル動作のおかげでノイズにも強くなく、スピードも決して速いわけではありませんが、IEEE-488で規定されている仕様をちゃんと理解し、正しく使うなら、妙な動作などしないと確信しております。しかしながら、世の中には特定の計算機でなければ動かないとか、組み合わせによっては動かないなど、いやな言葉ですが“相性がある”デバイスがあるのも事実です。これは、それらを作った人たちが、GP-IBの動作を理解しておらず、「自分の環境でとりあえず動けばいい」という考えで、規格外の製品を作っているからではないでしょうか。もっと想像力を働かせて、正しく規格にあった製品を作って欲しいと思います。また、そのようなデバイスを発注する側としても、正しく規格にあったものを、手を抜かずに作らせることが必要だと思います。