FPGAでFDDコントローラを作る (1) ヘッド操作

 前回の仮想FDDを作るでFDDをエミュレートする機能はできました。ここまでくると実際のFDDも動かしたくなってきました。そこで今回は、レベル3/S1から少し離れてFDDを直接制御するモノを作ってみようかと思います。
 まあ、直接制御するモノ自体はすでに作られている方もおられますし、データを取り出す装置としてすでにKryoFluxというものが販売されているので、今更こんなものをという感じもありますが…。

まずは周辺回路から

 というわけで、最初はPC/AT用3.5インチFDDを制御する回路を設計していきます。

 使用するFDDはTEACのFD-235HG。これのデータシートが入手できたので見てみると、入出力ピンの内容はネットにあがっている情報と同じPC/AT用ですが、2ピンだけちょっと異なるようです。これは3モードFDDなので記録容量を切り替えるMODE SELECTという信号を入れるみたいです。あれ、写真だと3ピンが抜けていますね。まぁ使用しないので問題ないです。


TEAC FD-235HGの背面

 FDDの各信号はすべてオープンコレクタなので、FDDから出力される信号にはプルアップ抵抗で+3.3Vと接続します。一方、FDDに入力する信号はドライブ内部で+5Vでプルアップされています。このFDDは1KΩでプルアップされているようですが、これだとFPGAと直接つなぐには電圧と電流が少し高いのが心配です。なのでロジックIC 74LS05を介して接続することにします。ちなみに74LS05は+5V駆動ですが+3.3V出力から+5V入力への接続は問題ないはず。

その他、押しボタンスイッチと状態表示用LCDも接続します。


FDDコントローラ回路図1(クリックで拡大)

FPGAの内部構成を考える

 前回の仮想FDDの構成を参考に、流用できるところは流用します。構成内容としては…

Neos II マイコンシステム
JTAG(USB)を介してPCとSDRAM内データの送受信をする機能、PCからの指示を受けてFDCにコマンドを送信しFDDを動作させる橋渡し役としての機能をソフトウェア(制御プログラム)で実装します。仮想FDDのプログラムを流用して使用します。
FDC, UNIT_SELモジュール
マイコン側からI/Oを通じてコマンドを受信しFDDを操作する機能、FDDからのデータをパラレルデータにする機能を実装します。仮想FDDのものを流用します。
MOTOR CONTROLモジュール
FDDへのモータ制御およびFDDの準備ができているかなどの信号を生成します。
DATA SEPARATERモジュール
FDDからのデータをクロック成分とデータ成分に分割します。
SDRAM READ/WRITEモジュール
FDCで生成したパラレルデータをSDRAMに書き込みます。

FDDコントローラ ブロック図

とりあえずはこんな感じでしょうか。まあ、この構成は作っていく過程で変わる可能性もあります。

 では、まずはモータとヘッドを制御するものを実装していくために必要な信号とどのように使うかを整理していきたいと思います。

モータを制御する

 FDからデータを取り出すにはまずモータを回さないことには始まりません。モータを回すにはMOTOR ON 1信号とドライブセレクト(DRIVE SEL 1)信号をONにします。ドライブセレクトとモータON/OFFの指示はマイコン側からUNIT_SEL I/Oに書き込むことで行います。
 モータOFF指示が書き込まれた時はすぐに信号をOFFにはせず、約5秒ほどONを持続させるようにします。これはFDDを連続して操作する際に、モータOFF/ONで発生する待ち時間を減らす&モータへの負担を減らすためです。
 モータOFFの時は、ドライブセレクト信号は常にOFFになるようにマスクします。

準備完了かどうか

 モータは回り始めてから回転が安定するまではタイムラグがあります。FDDには安定したらREADY信号を出力するものがありますが、PC/AT用のFDDにはこの信号がありません。なので、ここではモータONになった後、約0.5秒ほど待つようにします。
 回転が始まるとデータの開始地点を表すINDEX信号が一定周期(約200ms)でONになります。約0.5秒ほど待ったのち、この信号が2回ほどONになれば準備完了(内部のREADY信号をON)とします。

ヘッドを動かす

 あるトラックのデータにアクセスするにはその位置までヘッドを動かす必要があります。ヘッドを動かすためにSTEP信号とDIRC信号を使います。
 ヘッドの移動方向はDIRC信号をONにしたとき円周の内側、OFFで外側になります。STEP信号に1マイクロ秒ほどのパルスを入れるとヘッドが動きます。STEP信号を連続して入れる時、そのパルス周期は最低3ミリ秒間隔をおくようにします。
 ヘッドの操作指示はマイコン側からFDC I/Oに書き込むことで行います。

ヘッドの位置を知るには?

 TRACK00信号はヘッドがトラック0(一番外側)にあるときにONになります。一方、トラック0以外にヘッドがどこにあるかを知る信号はありません。ヘッドの位置(トラック番号)はSTEPパルスを入れた回数から計算したものをFDCユニットで管理します。
 FDCユニットが管理するトラック番号と実際のヘッド位置が合わないこともあります。こういう時はヘッドをトラック0まで戻してリトライする操作をソフトウェア側で行うことが必要になります。

DISK CHANGE信号の扱い

 PC/AT用のFDDにはDISK CHANGE信号があります。これは、電源ON時やディスクを抜いた時にONになります。この信号は、ディスクを新たに入れただけでは変化しません。STEPパルスを入れた時に初めて更新されます。
 ということで、ディスクを入れ替えた時はヘッドをトラック0に戻して初期状態にすればいいですね。
 実装としては、この信号がONの時は内部のREADY信号はONにならないようにマスクします。

ここまでの機能を実装する

 モータとヘッドの制御が分かったところで、ここまでの機能を実際に作っていきます。まずは、周辺回路をブレッドボード上に実装します。


ブレッドボード上に実装

 次にFPGA内を実装します。とはいいながら実はすでに前回の仮想FDDでだいたいは実装してあったのでこれらを流用して完成。PC上でシミュレーションして各信号が想定通り変化することを確認します。

 一方で、NeosIIマイコンで動作させる制御プログラムも作ります。こちらはテスト用に以下の機能を実装します。  各機能をボタンに割り当てたら、こちらもシミュレーションで想定通り動くことを確認します。

実機でテスト

 では、いよいよ実機でテストを行います。FDDをブレッドボードに接続してFPGAをコンフィグレーションします。FDD用フラットケーブルはPC用のものをそのまま使用しています。FDD用の電源は別途外付けHDD用のもの(+12Vと+5Vが出ている)を使用しました。


FDDを接続して起動した状態

 まずは、リストアを実行。お、FDDのアクセスランプがついてモータ音もします。ヘッドが動いたかどうかはよくわかりませんが問題ないようです。


リストアでトラック0に移動

 次は、ステップインを実行。ヘッドが動いている音がします。FDCのトラック番号もカウントアップされていますね。


ステップインでヘッドを移動

 ここでまたリストアを実行。ウィーンと音がしてヘッドが無事トラック0まで移動したようです。

これでモータとヘッドの一連の制御がうまくいきました。ということで、次回はFDDからデータを読みだしてPCへ送るような機能を実装していきたいと思います。(つづく)

参考文献

  1. TEAC FD-235HG-C304 MICRO FLOPPY DISK DRIVE SPECIFICATION
  2. FUJITSU MB8877A Datasheet

次→ FDDコントローラを作る (2)

 

FPGAで8ビットパソコンを拡張する

 

TOP PAGE