中でも、プリンタポートは外付け部品も少なく、電圧の変換が不要なので手軽にインタフェースできます。なんと言っても、高価なインタフェースチップが不要で、簡単なロジック回路やマイコンがあれば、誰でも自由にインタフェースを自作できます。自作の装置では、プリンタポートの信号線の本来の役割を無視して、独自の規格のパラレルIOポートとして使えば、プロトコルも自分で勝手に決めることができます。その反面、遅い、NT系OSで手軽に使えない、信頼性が低いなどの欠点もあります。そこでプリンタポートをIEEE規格に準拠させようと思っても、ニブルモードやバイトモードなどのレガシー(旧式)の解説はいくつか見つかりますが、ECPモードやEPPモードなどの高度なものを作ろうとしても資料が無く、実現するのはUSBやRS232Cより難しいでしょう。プリンタポートを使って、高速で高機能なインタフェースを手軽に作りたいけど、資料が無くてわからない。そんな労力を低減するのが本企画の目的です。この企画では、モルフィー企画様のVirtex300Eボードを使って、IEEE1284に対応した装置を開発することを目的とします。開発に使っている装置を右の写真に載せます。写真のようにVirtex300Eボードを、SRAMと高速ADコンバータのついた万能基板に載せます。今回開発するIPの概要を、右の図に示します。本IPは、IEEE1284機能を実現するコアの部分と、VirtexEのブロックRAMなどを使用する周辺部分から構成されています。コアの部分は、使いまわしが効くようにソースを分けてあります。IPのダウンロード使用にあたっては、次の点に注意してください。このIPは未完成であり、十分に検証されていません。現バージョンの商用利用はお断りいたします。商用利用については別途ご相談承ります。機能の拡充にともない、予告無く更新します。ナヒテック」が所有します。現在、実現されている機能は次のとおりです。オートネゴーシエーション機能ニブルモード互換モードバイトモードECPモード(読みこみのみ。)現在、次の機能がまだ実現されていません。EPPモードECPモードの書きこみECPモードの周辺機器側FIFORLE付きECPモード拡張リンク上記の項目に同意いただければ、次のリンクをクリックしてダウンロードしてください。●IEEE1284コアのダウンロード(IEEE1284main-ver01.vhd)IPの使い方IEEE1284コアの解説IEEE1284main.vhdの入出力ピンを説明します。IEEE1284のデータバスをリバース(周辺装置→PC方向)にする。デバッグ用これらの信号線をどのように使えばよいか、少し詳しく解説します。�@クロック等クロックとリセット信号です。�Aユーザ側信号ユーザロジックから、IEEE1284へデータを送受信するのに必要な信号です。■データを受信(PC→周辺装置)する場合PCからデータを受信すると、Data_OUT[7:0]にそのデータを載せ、DataReceivedに1クロック長の信号を出します。周辺装置がビジー状態の時にはBusy信号をHighにします。Busy信号はIEEE1284のハンドシェイク等には無関係です。それを受信したPCがどのように処理するかを任されています。PCへ送信したいデータが用意できたときには、DataAvailをHighにします。この信号がLowになると、IEEE1284のハンドシェイクにWaitをかけます。PCから送信要求がされると、DataReqに1クロック長の信号が出ますので、Data_IN[7:0]に送信したデータを載せ、DataWrに1クロック長の信号を入れてください。DataReqからDataWrまでは即答する必要はありませんが、あまり長いとPCがタイムアウトするので、数ミリ秒以内には返すようにしましょう。�BIEEE1284側信号IEEE1284の対応するピンに接続します。入力信号には必ず1段以上のD-FFを入れてください。�CIEEE1284の状態を示す信号ネゴーシエーションの結果、現在どのモードであるかを示します。ODBuf_ENは、データバスを双方向にするための、出力イネーブル信号です。次の写真は、ECPモードでデバイスIDを読み出した時の波形です。CH1がnAck信号で、CH2がnSelect信号です。CH1のnAck信号はデータのストローブに使われる信号で、その立下りエッジで、PCはデータを読み込みます。CH2のnSelect信号は周辺装置が送りたいデータがあることを示す信号で、Lowレベルのとき、送信したいデータがあることを示します。この信号が立ちあがると、送信完了を意味します。この写真を見ると、最初の20μ秒はnACKが詰まっていて、後は閑散としています。その理由はFIFOです。FIFOフィル時の波形ECPモードで読みこむ最初の20μ秒を拡大した波形を次の写真に載せます。ECPモードでは、PCのIOチップは、FIFOを使います。周辺装置からFIFOへの読みこみはハードウェアが自動で行います。そのため、約1μ秒に1回データを読み込んでおり、この状態ではとても高速です。FIFOフル時の波形FIFOがフルになると、PC側のECPのハードウェアは自動読みこみを一時停止します。この状態で、ソフトウェアがFIFOからデータを取り出してやると、FIFOに1バイトの空きができるので、自動的にIEEE1284へデータを要求します。ソフトウェアは、FIFOのステータスを見ることと、FIFOからデータを取り出すことで、2回inp命令を実行します。私のPCでは1回のアクセスに約1.5μ秒を要します。これは、Windowsのデバイスドライバを作ったわけではなく、単純なinp命令を使っているため実際の読みこみ動作よりかなり遅いです。デバイスドライバを組めば、もっと速くなるでしょう。最初の写真から判断すると、私の使っているマザーボードでは、FIFOへの高速読みこみは21回行われています。FIFOの深さが16バイトです。PC側のハードウェアが、16バイトをFIFOに読みこむ時間は約16μ秒ですが、この間にもソフトウェアはFIFOから読み出しを行っています。ソフトウェアがFIFOから5バイト読み出す時間は、およそ3.1×5=15μですから、16バイト読みこんだ後には、FIFOのおよそ5バイト分の余裕が空いているはずです。したがって、FIFOがフルになるまでには、あと5バイト読みこめます。それゆえ、21バイト分が高速に読み出されたのでしょう。ECPモードでは、FIFOが満杯か否かで読み出し速度に差が生じるようです。各モードがデータを如何に速く読み出せるかを競います。0.047MByte/s私の実験環境(Celeron366MHz自作PC)では、Windows98上でinp、outp命令を使うことによるIOポートへのアクセスには1回あたり1.6μ秒要することがわかっています。ニブルモードとバイトモードの場合、12回のIOアクセスでは19μ秒要しますが、その他にもWindowsのメッセージ処理などが2〜3μ秒加わっているため、上記の結果になったものと思われます。1回のアクセスに12回というのはいささか多い気がしますが、これはハンドシェイクを厳密に行う上の問題で、プログラミングで頑張れば回数は、もっと減らせるはずです。82バイトの読みこみに要する時間オシロスコープを用いて、デバイスIDを読み出すのに必要な時間を計測しました。47kByte/s思ったほどECPモードが速くないのは、FIFOが16バイトしかないため、すぐに埋まってしまうからです。FIFOからの読み出しにデバイスドライバを作成したわけではなく、inp命令を使用しているため、Windows98のVxDの処理などに要する時間と考えられます。デバイスドライバを作成すれば、もっと速くなるはずです。ソフトウェアIEEE1284の実験を行うため、次の図のようなソフトウェアを開発しています。デバイスIDについてデバイスIDを設定すると、Windowsの起動時にPnPで認識させることができます。Windowsの起動時にネゴーシエーションを行って、ニブルモードでID要求するようです。デバイスIDは、可変長のASCII文字列です。最初の2バイトは、文字列の長さを示します。その後、キーと値を「:」(コロン)で組み合わせ、「;」(セミコロン)で区切ります。FPGA;次に、各キー名と意味を簡単に説明します。DDKで規定されています。その中から、パラレルポートにつなぐ周辺装置として、意味がありそうなものをいくつか紹介します。通信関係を意味するらしい。テープデバイス※IEEE1284.4とは、複数のデバイスをパラレルポートにつなぐ技術です。USBでは127台までつなげることができますが、そのIEEE1284ポート版です。上記のデバイス以外にも、たくさんのデバイスクラスがWindowsで規定されています。IEEE1284ポート越しに、認識されるかは不明です。マイナーなデバイスほど結果は不明です。デバイスドライバを作って、INFファイルを記述すればPnPインストールができるかと思います。これだけは知っておきたい、IEEE1284のモードIEEE1284には、互換モード、バイトモード、ニブルモード、ECPモード、EPPモードの5つのモードがあります。その機能はいろいろと差があります。中でもEPPとECPは高度なモードで、書きこみ(PC→周辺装置)と読みこみ(周辺装置→PC)の両方ができます。ECPとEPPはハンドシェイクをハードウェアで行い、高速です。ステータス用の4本の信号線を使って、1バイトを2回に分けて読み込む。FIFO、ランレングス圧縮、内部モードこれだけは知っておきたい、IEEE1284の信号IEEE1284の信号はとても気まぐれです。モードによって信号の機能も名前も変わるからです。名前や機能は変わっても、信号の持つ機能の本質はあまり変わりません。ハンドシェイクに使われる信号プリンタポートを単純なIOとして使った場合、PCが送ったデータを周辺装置が正しく受け取ったかどうかなどをハンドシェイクして確認することは滅多にありませんでした。いわゆる送りっぱなしの状態でした。IEEE1284では、どのモードであれ、ハンドシェイクを行うことになっています。PC→周辺装置へのハンドシェイクはnStrobeかnAutoLFをストローブ信号として使います。(モードによっては、名前がHostClkやHostBusyだったりしますが、機能と目的は一緒です)周辺装置→PCへデータを送る際のハンドシェイクは、ほとんどの場合、nAckを使います。ハンドシェイクの信号は基本的には負論理ですが、例外もあります。周辺装置から送りたいデータがあることを示す信号nDataAvailは、周辺装置からPCへ送りたいデータが存在することを示す信号です。ECPモードではこの信号はnPeriphReqという名前ですが、機能は一緒です。Lowの時に、周辺装置からPCへ送りたいデータが存在します。周辺装置がバイトモード、ニブルモード、ECP、EPPモードの時に1284ActiveがLowレベルになると、互換モードへ戻ります。ネゴーシエーション中にLowレベルになると、ネゴーシエーションを強制終了し、互換モードへ戻るでしょう。このように、1284Activeは、IEEE1284のモードを終了させる機能を持ちます。XFlagSelect信号は、IEEE1284のモードではXFlagとなります。これは、周辺装置が、要求されたモードに対応しているか否かを示す信号です。その他の信号Busy信号の意味は、周辺装置からPCへ、ビジー状態であることを伝えるフラグです。nInit信号の意味は、PCが周辺装置に初期化を要求する信号です。BusyとnInitは、多くのモードでは、IEEE1284の機能に影響を与えません。ユーザが任意に使用しても問題はなさそうです。ECPではnInitをデータバスの方向切り替えに利用していますので、注意が必要です。Busy信号を本来のビジーフラグと時分割で各種制御線として使うこともあります(ニブルとECP)。波形的な注意点プリンタポートから出る信号は、とてもいいかげんな信号です。昔は、オープンコレクタにプルアップ抵抗が基本でした。このため、波形品質はとても低いのが実情です。昔のように、プリンタポートの信号をマイコンのIOポートで受ける場合には、応答速度がそれほど速くないから問題にはなりませんでしたが、数十MHzで動くようなハードウェアロジックで受けると、波形の汚さを痛感します。STBなどの信号は、出力がオープンコレクタなので、立下りは鋭い波形ですが、立ちあがりはプルアップ抵抗のお世話になっているので、緩慢な立ちあがりになります。そのため、信号がスレッショルド近傍で何回もHとLを往復し、チャタリングのような波形になることもあります。それでも数MHzという遅いクロックで、パラレルポートのインタフェースをしていた頃は問題になりませんでした。本VHDLソースでは、このような現象に対して耐性を持たせております。0.5μ秒以内であれば、信号がばたついても大丈夫です。