現在、各種のメモリーカードがいろいろな機器にて使用されている。
よく聞くのがコンパクトフラッシュ、スマートメディア、メモリースティックあたりだろう。
最近になり、コンパクトフラッシュをより小型化し、多機能にしたマルチメディアカードなども発表されているが、これを使用している製品はまだそれほど多くない。コンパクトフラッシュメモリーは、スマートメディアに比べると容量が大きい傾向にあり、メモリーを効率よく使うためのコントローラーが内蔵されているために、そのコントローラーに対してコマンドを送る形式でアクセスを行う。
一方、スマートメディアはフラッシュメモリーをパッケージに収め、その端子を出しただけという構造であり、直接メモリICをアクセスする感じとなる。そのために、内部ICの特性をよく理解して使う必要がある。コンパクトフラッシュメモリーの端子は接点が表面には出ていないのに対し、スマートメディアでは手で触るような場所に端子が出ている。
また、コンパクトフラッシュの端子はPCカードの端子とほぼコンパチブルであり、ノートPC用のアダプタは単にピンの順番を入れ替えている程度である。
電源電圧も、3.3Vと5Vの両方に対応しているので、システムとしても設計しやすい。コンパクトフラッシュはメモリーモード、I/Oモード、IDEモードの3つのモードを持っており、各種拡張機器としての可能性を持っている。
メモリースティックに関しては詳細は調べていないが、音楽配信などをターゲットとして作られているため、著作権保護のための機能なども含まれ、非常に厳格な規格が定義されているようである。
今回は、コンパクトフラッシュメモリー(以下CF)を手軽に使うことに焦点をおき、その方法を簡単に説明する。
コンパクトフラッシュの詳細仕様に関しては、http://www.compactflash.org/を参照してほしい。
今回の設計においては主に日立と三菱の仕様書を参考にしたが、日立の仕様書は所々規格と異なることが書いてあり、三菱の仕様書だけでは具体的な使い方がわかりにくいという問題があるため、複数の仕様書を入手して調べることを奨める。
使用モード
前述の通り、CFにはメモリーモード、I/Oモード、IDEモードの3つのモードがある。
今回の目的は、外部メモリとしての使用なのでI/Oモードは除外する。
また、IDEモードとしてHDD互換で使用するためにはIDEコントローラーを使用するか、自前でIDEコントローラーと同等のものを作る必要があるので簡単とはいえなくなる。
そこで、メモリーモードで使用することとする。通電中の抜き挿し
また、通電中のCFの抜き挿しは電源端子をコントロールすることで可能とのことだが、今回の説明では省略する。使用上の注意点
通常、CFをPCに接続すると自動的にIDEのデバイスとして認識され、FDISK、Formatを行ってHDDとして使うこととなるが、今回の仕様はメモリーモードであるため、この作業を行うとメモリー内のデータが消えてしまうこととなる。
PCでアクセスする場合はそれなりのプログラムを作成する必要がある。一方、PCでは簡単に読み書きができないことにより、セキュリティに関しては有利となる。
メモリーモードで使用する場合の各端子の機能を表にした。
信号名 属性 端子番号 詳細 A10 - A0 I 8,10,11,12,14,15,
16,17,18,19,20アドレスピン。
A10が最上位で、A0が最下位。BVD1,BVD2 I/O 46,45 カード内部の電池電圧状態を示すが、電池を搭載していないため、常にHを出力。 /CD1,/CD2 O 26,25 カード挿入検出用。
カード内部でGNDに接続されているので、プルアップ抵抗が必要。/CE1,/CE2 I 7,32 カード選択信号。Lowアクティブ。
/CE1,/CE2,A0の組み合わせでワード/バイト/奇数アクセスを指定する。
/CE1,/CE2ともLowにするとワードアクセス、/CE1をLow、/CE2をHighにした場合、A0がLowのときに偶数アドレス、Highのときに奇数アドレスのアクセスとなる。
ただし、アトリビュート領域は偶数アドレスのみなのでA0をHighにしたときのデータは無効となる。/CSEL I 39 使用しない。 D15 - D0 I/O 31,30,29,28,27,
49,48,47,6,5,4,3,
2,23,22,21データピン。
D0が偶数バイトの最下位、D8が奇数バイトの最下位。GND - 1,50 グランド。 /INPACK O 43 使用しない。ホスト側にてオープンにしておく。 /IORD I 34 メモリーモードでは使用しない。 /IOWR I 35 メモリーモードでは使用しない。 /OE I 9 レジスタのデータ出力制御に使用する。 RDY/BSY O 37 電源投入時、リセット時などにはLowになるので、Highになったことを確認してからアクセスを行う。
プルアップ抵抗をつけておく。/REG I 44 タスクファイル領域をアクセスするときにはHigh、アトリビュート領域をアクセスするときにはLowにする。 RESET I 41 Highでカードをリセットする。 VCC - 13,38 電源入力。(3.3V/5V) /VS1,/VS2 O 33,40 カード電源電圧を設定する情報をホストに与える。
/VS1はGNDに接続され、/VS2は第2電源のために提供されている。/WAIT O 42 カードに対してアクセス要求をした後、データが出力されるまでの間、Lowになる。 *1
CFのアクセスタイムは規格上では300nsec。/WE I 36 アトリビュート領域、タスクファイル領域のレジスタのデータ入力時の制御に使用する。
レジスタに対する書き込みクロックとして使用される。
データRead/Write時にはCF内部バッファをインクリメントするクロックとしても使用される。WP O 24 ライトプロテクト。ライトプロテクト機能がないので常にLowを出力。 *1:日立の仕様書('99.5.28 Rev2.0)では常時HighとなっているがCFの規格ではそのような仕様にはなっていない。
8bitアクセスにおける接続例を以下に示す。
これだけの信号線を接続しておけば、メモリーモードで使えるようになる。
8ビットアクセスのため、/CE2はHighにして、/CE1のみでの制御となる。
アドレスバス、データバスはCPUのバスに接続し、/RD、/WRはCPUの制御信号に接続、/CD、/RDY、/RESETはCPUのポートに接続した。
/CE1、/REGはアドレスデコードにより、アトリビュート領域とタスクファイル領域をそれぞれメモリ空間にマッピングした。この図では/WAIT端子を使用していないが、本来であればCPUの/WAIT端子に接続する。今回は、CFへのアクセスがあった場合にFPGA内でWAITタイミングを生成し、CPUの/WAIT端子に信号を出力する方法をとった。
日立以外のCFを使うのであればこのような処理は不要と思える。
CFにはアトリビュート領域とタスクファイル領域が存在し、アトリビュート領域はCFの各種情報と設定用のレジスタが、タスクファイル領域には実際のデータアクセスに使用するレジスタがある。
アトリビュート領域
タスクファイル領域をアクセスするときには/REGはHighにする。
アトリビュート領域のアドレス0からはCIS(Card Information Structure)情報が格納されている。
この情報は、Tuple(タプル)によるリンクにより構成され、ある情報の最初にTuple-Linkにてデータのワード数を指定し、データの最後はFFHでターミネートするという構造の連続となっている。
CISはRead Onlyである。200HはConfigration Option Registerとなっており、CFカードをメモリーモード、I/Oモード、IDEモードのどのモードで使用するかの指定と、ハードリセット、割りこみの指定などを行う。
電源投入時にはメモリーモードとなっているので、特に設定する必要はない。202HはConfigration and Status Registerとなっており、カードの状態を知ることができる。
204HはPin Replacement registerとなっており、このレジスタのBit1を読みとることにより、RDY/BSY状態を知ることができる。
206HはSocket and Copy registerとなっており、ドライブ番号を指定する。
Configuration Option registerを設定する前にここを設定しておく必要がある。
通常、0に指定しておくことになるのでここは設定する必要はない。
タスクファイル領域
CFカードに対してデータのRead/Writeを行うときには、必ずタスクファイルレジスタを通して行う。
タスクファイル領域をアクセスするときには/REGはHighにする。レジスタ一覧
タスクファイルレジスタの一覧を以下に示す。
A10 A9-A4 A3 A2 A1 A0 Offset /OE=L /WE=L 0 × 0 0 0 0 0H Data Register Data Register 0 × 0 0 0 1 1H Error Register Feature Register 0 × 0 0 1 0 2H Sector Count Register Sector Count Register 0 × 0 0 1 1 3H Sector Number Registor Sector Number Registor 0 × 0 1 0 0 4H Cylinder Low Register Cylinder Low Register 0 × 0 1 0 1 5H Cylinder High Register Cylinder High Register 0 × 0 1 1 0 6H Drive Head Register Drive Head Register 0 × 0 1 1 1 7H Status Register Command Register 0 × 1 0 0 0 8H Dup. Even Data Register Dup. Even Data Register 0 × 1 0 0 1 9H Dup. Odd Data Register Dup. Odd Data Register 0 × 1 1 0 1 DH Dup. Error Registor Dup. Error Registor 0 × 1 1 1 0 EH Alt. Status Register Device Control Register 0 × 1 1 1 1 FH Drive Address Register Reserved 1 × × × × 0 8H Even Data Register Even Data Register 1 × × × × 1 9H Odd Data Register Odd Data Register データのRead/Writeを行うときにはそれぞれのコマンドに必要なレジスタを設定した後、Command Registerにコマンドを設定し、Status Registerを見ながらData RegisterのRead/Writeを行う。
コマンド一覧
Command Registerに設定できるコマンドセットと、それぞれのコマンドを実行する際に設定を必要とするレジスタの一覧を以下に示す。
Command Code FR SC SN CY DR HD LBA Check Power Mode E5H or 98H ○ Execute Drive Diagnostic 90H ○ Erace Sector C0H ○ ○ ○ ○ ○ ○ Format Track 50H ○ ○ ○ ○ ○ Identyfy Drive ECH ○ Idle E3H or 97H ○ ○ Idle Immediate E1H or 95H ○ Initialize Drive Parameters 91H ○ ○ ○ Read Buffer E4H ○ Read Multiple C4H ○ ○ ○ ○ ○ ○ Read Long Sector 22H or 23H ○ ○ ○ ○ ○ Read Sector 20 or 21H ○ ○ ○ ○ ○ ○ Read Verify Sector 40H or 41H ○ ○ ○ ○ ○ ○ Recalibrate 1XH ○ Request Sense 03H ○ Seek 7XH ○ ○ ○ ○ ○ Set Features EFH ○ ○ Set Multiple Mode C6H ○ ○ Set Sleep Mode E6H or99H ○ Stand By E2H or 96H ○ Stand By Immediate E0H or 94H ○ Transrate Sector 87H ○ ○ ○ ○ ○ ○ Wear Level F5H ○ ○ Write Buffer E8H ○ Write Long Sector 32H or 33H ○ ○ ○ ○ ○ Write Multiple C5H ○ ○ ○ ○ ○ ○ Write Multiple Without erase CDH ○ ○ ○ ○ ○ ○ Write Sector 30H or 31H ○ ○ ○ ○ ○ ○ Write Sector Without erase 38H ○ ○ ○ ○ ○ ○ Write Verify Sector 3CH ○ ○ ○ ○ ○ ○ FR : Feature Register
SC : Sector Count Register
SN : Sector Number Register
CY : Cylinder Register
DR : Drive Bit of Drive Head Register
HD : Head Number of Drive Head Register
LBA : Logical Block Address Mode Supported例えば、Read Sectorを実行する際にはSC、SN、CY、DR、HDをセットしてからCommand Registerに20Hをセットし、Read動作を行う。
コマンド概略
Check Power Mode
パワーモードをチェックするときに使用する。
SleepモードのときにはSector Count RegisterにOOHを、IdleモードのときにはFFHをセットする。Execute Drive Diagnostic
カードの自己診断を行う。診断結果はErrorレジスタに書き込まれる。
01H : 正常、02H : デバイス不良、03H : Sector Buffer Error、04H : ECC回路異常、05H : MPU異常Erace Sector
指定セクタの消去を行う。Format Track
Drive、Cylinder、Headにて指定されたすべてのセクタ(32セクタ)にFFを書き込む。
動作はWrite Sectorと同じで、データを書き込まないだけ。Identyfy Drive
シリンダ数、ヘッド数、トラックあたりのセクタ数、シリアルナンバー等、カードの属性情報を得る。
動作はRead Sectorと同じ。Idle
コマンド実行終了時、設定時間経過後に自動的にPower Downモードとなる。
設定時間はSector Count Registerに設定された値×5ms。Idle Immediate
Idle Modeに移行する。Initialize Drive Parameters
トラックあたりのセクタ数、シリンダあたりのヘッド数を変更する。Read Buffer
セクタバッファよりデータを読みだす。
データ転送方法はRead Sectorと同じ。Read Multiple
Multiple転送を行う。
実質的にMultiple転送はサポートされていない。Read Long Sector
通常のRead Sectorでは、1セクタ当たり512バイトの転送を行うのに対し、Read Long Sectorでは516バイトの転送を行う。ただし、この時にはカード側でのECCチェックは行われない。Read Sector
Head、Cylinder、Sector Numberで指定されたセクタよりSector Count数分のセクタのデータを読みだす。Read Verify Sector
セクタのベリファイを行う。
データの転送が発生しない点を除き、Read Sectoprと同等。Recalibrate
HDDとの整合性のために残されているコマンドで、実質的にNOP。Request Sense
コマンドが異常終了した際に、拡張エラーコードを知ることができる。Seek
HDDとの整合性のために残されているコマンドで、実質的にNOP。Set Features
カードに対して特定機能の設定を行う。
標準ATA規格には存在しないコマンド。Set Multiple Mode
Read/Write MultipleコマンドのEnableもしくはブロックを構成するセクタ数の設定を行う。
ブロック数は1に限定されている(Read/Write Multipleはサポートされていない)ので実質的には必要性のないコマンド。Set Sleep Mode
Sleep Modeに移行する。Stand By
Stand Byモードに移行する。Stand By Immediate
Stand Byモードに移行する。Transrate Sector
各セクタの書き換え回数を知ることができる。
標準ATA規格には存在しないコマンド。Wear Level
実質的にNOP。Write Buffer
セクタバッファを上書きする。
データ転送方法はWrite Sectorと同じ。Write Long Sector
Read Long Sectorと同様に516バイトでデータ転送を行うが、ECCの4バイトは破棄され、カード内部で生成したECCが書き込まれる。Write Multiple
Multiple転送を行う。
実質的にMultiple転送はサポートされていない。Write Multiple Without erase
Write動作に先立ってErase動作が行われないことを除いてWrite Multipleと同じ。Write Sector
Head、Cylinder、Sector Numberで指定されたセクタよりSector Count数分のセクタのデータを書き込む。Write Sector Without erase
Write動作に先立ってErase動作が行われないことを除いてWrite Multipleと同じ。Write Verify Sector
書き込みを行った後にベリファイを行う。
CFをRead/Writeするのに必要な操作をまとめてみた。
初期設定
装置の電源投入後、/CD1にてCFの検出を行う。LでCFあり。 CFが検出された場合、RESETをHにしてからCFの電源を入れ、しばらく待ってからRESETをLにする。(HでRESET) RDYがHになるのを待つ。 Socket and Copy Register(アトリビュートの206H)に00Hをセット Configuration Option Register(アトリビュートの200H)に00Hをセットし、メモリーモードにセットする。 Status Register(タスクファイルの07H)を読み込み、58Hになるまで待つ。 Drive Head Register(タスクファイルの06H)にA0Hをセットし、CHSモードにする。 Status Register(タスクファイルの07H)を読み込み、58Hになるまで待つ。 Sector Count Register(タスクファイルの02H)に1をセットする。 Status Register(タスクファイルの07H)を読み込み、58Hになるまで待つ。 Command Register(タスクファイルの07H)にIdentify Driveを得るためにECHをセットする。 Status Register(タスクファイルの07H)を読み込み、58Hになるまで待つ。 Data Register(8bitアクセスの場合はタスクファイルの00/01Hを交互)を512Byte読みこむ。 Word Addressの1、3、6よりシリンダ数、ヘッド数、セクタ数を得る。この値をもとにデータのアクセスを行う。 カードのCIS情報はアトリビュートの000Hから136Hに格納されているので、必要に応じて参照する。
書き込み
Cylinder Low/high Register(タスクファイルの04H、05H)にシリンダ番号をセットする Drive Head Register(タスクファイルの06H)の下位4ビットにヘッド番号をセットする。上位4ビットはAH固定。 Sector Number Register(タスクファイルの03H)にセクタ番号をセットする。 Sector Count Register(タスクファイルの02H)に1をセットする Command Register(タスクファイルの07H)にWrite Sectorを行うために30Hをセットする。 Status Register(タスクファイルの07H)を読み込み、58Hになるまで待つ。 Data Register(8bitアクセスの場合はタスクファイルの00/01Hを交互)に512Byte書きこむ。 Status Register(タスクファイルの07H)を読み込み、50Hになるまで待つ。
読み出し
Cylinder Low/high Register(タスクファイルの04H、05H)にシリンダ番号をセットする Drive Head Register(タスクファイルの06H)の下位4ビットにヘッド番号をセットする。上位4ビットはAH固定。 Sector Number Register(タスクファイルの03H)にセクタ番号をセットする。 Sector Count Register(タスクファイルの02H)に1をセットする Command Register(タスクファイルの07H)にRead Sectorを行うために20Hをセットする。 Status Register(タスクファイルの07H)を読み込み、58Hになるまで待つ。 Data Register(8bitアクセスの場合はタスクファイルの00/01Hを交互)に512Byte読みこむ。 Status Register(タスクファイルの07H)を読み込み、50Hになるまで待つ。
その他
参考文献レジスタをRead/Writeする場合には、必らずStatus Registerを監視し、RDY状態であることを確認してから行う。 Sector Count Registerに1以外の数値を入れて複数セクタを連続して読み出す方法もできるようだが、なぜかアクセス速度が遅くなってしまった。512Byte毎にSector Numberを設定して読み出すほうが速かった。 データのアクセスタイムは300nsecであるが、低速のCPUの場合、CPUの処理速度のほうがネックとなってくるので、処理の効率化も考慮する必要がある。
(株)日立製作所 HB289048C4データブック (ADJ-203-359B Rev.2.0)
三菱樹脂(株) PC Card ATAバスカード NOR型ATAバスコンパクトシリーズ(I) (SCF1-2.3)
CompactFlash Association CF+ and CompactFlash Specification Revision 1.4表紙へ