|
今日調べてまとめたものを掲載。実際の端子操作を念頭になるべく分かりやすく書いたつもりですが、誤解・勘違い・誤りがあろうかと思います。誤字脱字、遺漏脱肛など、みつけたら、やさしく教えてね。
────────────────────────────────────
■一般注意事項(今回の仕様の一部を含む)
●SDカードシリーズ、SD・SDHC・SDXCなどの規格のうち、2GB以下のSDのみ対応。なお、この条件を満たすSDへの対応を保証するものではない。
●基本的にアイドル時は、/CS、CLK、DINともH。なお、SD側のDOもアイドル時はH。
つじかわさんが「動作不安定のため」、/CSだけ74HC14で反転させ、CLK、DINは2回反転させて「整形」したとされている。当初のプログラムにおいて、プログラム側で/CSを負論理で書いていたなら他の信号と同様に2回反転させて「整形」すれば済むはずである。 ところで、MSX起動時、汎用ポートの8ピンはL、7・6ピンはHである。MSXにSDを装着したまま起動したとすると、SDに通電した時点で/CS=L、つまり選択状態となる。つじかわさんはこれを嫌って、当初から8ピンだけは74HC14で反転するつもりだったのではないか? /CSは、起動時からHの7又は6ピンに割り当てればいいようなものであるが、頻繁に書き換えるCLKとDINをビットが隣りどうしのセットで扱いたかったのかも知れない。CLKの立下りでDIがSDに読み込まれるので、7・6ピンを同時に変化させたのだろう。 この結果、余禄として、本来同時に変化すべきトリガAとトリガBに、実はタイムラグが生じる予想外の"発見"に至ったのではないか。 なお、書籍「フラ研」には「CLK」にバッファを入れたら、すんなり正常動作した旨の記述がある(109頁)。つじかわさんが動作不安定に悩まされたのも、CLKが原因だったかもしれない。 ●随所にダミークロックが8クロック挿入されるが、この間、/CSはH・Lどっちでもいいとされる(「フラ研」95頁。ホンマかいな?)。今回はダミークロックの間は一般に/CS=Lで統一する。
●CLKはホスト側で発生する。DIN(DATA IN)やDO(DATA OUT)の端子名はSD側から見た名称であるが、以下で「出力する」と言った場合は、一般にホスト側からの出力を意味する。DOのみカード側の出力となる。混乱しないように>自分。
●ホスト側からDINに出力するときは、CLKの立下りでSDに取り込まれる。SDが取り込んだタイミングを見計らってCLK=Hにする。
●ホスト側に読み込むときは、CLKの立上がりでSDはDOに出力するのでタイミングを見て読み込み後、CLK=Lにする。
──────────────────────────────────── ■初期化シーケンス(初期化中は400kHz以下のクロック。)
1 /CS=H
2 CLKから80クロック出力
CLK=Hの初期状態から、L・Hを80回送信し、CLK=Lとする。 資料によっては「74クロック」と記載しているものもあるが、SanDiskやALTERAの資料等では「80クロック」となっている。ダミーデータを10バイト送信すると考えれば「80クロック」に根拠があると思われる。 浅草ギ研さんは「クロックを10バイト送る」と表現されている。8bit×10バイト=80クロックだが、CLKの動きだからクロックで表現するほうが分かりやすい。 3 /CS=L
/CS=Lの状態でSDがCMD0を認識すると「SPIモード」に移行する。SPIモード以外に、SDカード本来の「ネイティブモード」があるのは知っているよね。SandDiskがSPI対応を提案して取り入れられたそうです。SandDisk、エライ! 4 CMD0発行
SDに対するリセット開始の命令である。 データ並びは、40H,00H,00H,00H,00H,95H。 一般に、コマンドは先頭1バイトがコマンド本体、続く4バイトが引数、最後の1バイトがCRCとなる。 先頭2ビットは「01」で始まり残る6ビットが実質的なコマンドを示す。CMD0の場合、2進数で書くと「01000000B」なので、これを16進数にすると「40H」となる。 引数は持つものと持たないものがある。CMD0は引数を持たないので全部「00H」で埋める。CRCのビット0はエンドビットとして「0」に決まっているので、実質7ビットがCRCである。SDでは、ホストとカード間の通信におけるエラー検出にCRCが使われるが、SPIモードではCMD0のみ意味を持ち、他のコマンドでは基本的に無視される。CRCの計算は面倒なのでかなり助かる。CMD0のCRCだけはチェックされるので、エンドビットの「0」を含めて「95H」となる。 DINに値をセットしながら、H・Lを繰返しCLKの立下がりでコマンドを送出する。 コマンド送出後、CLKの立上がりでDOをポーリングし続ける。SDが「BUSY」状態の間はDOはHのままである。これがL(つまり「0」)になると「コマンド・レスポンス」の始まりである。
浅草ギ研さんはレスポンス待ちについて、「1バイトずつポーリングする。値がFFHのときはBUSY、FEHになるとBUSY終了」旨の書き方をされているが、ちょっと誤解を招きそうな気がする。BUSYの期間は不定である。「ポーリング結果をレジスタのビット0に入れ、左にシフトしながら次のポーリング結果を待つ」と書くのがより動作を理解しやすいだろう。「0」がきたときは、結果的にレジスタの値は「FEH」になるけどね。 5 コマンド・レスポンスの受信
DOから「0」を先頭に8ビット(=1バイト)のコマンド・レスポンスを受信する。「00000001B」(初期化プロセス実行中)であればOK。違っていたら何らかのエラーが起きている。 エラーがあった場合、今回のプログラムの仕様ではBASICに渡すバッファの先頭にエラー・レスポンスを残すしてRETするので、作業を中止してエラーの原因究明に当たろう。 他のコマンドでは、コマンド・レスポンスは「00H」であるが、CMD0だけ「01H」の点に注意が必要である。 ちなみに、コマンド・レスポンスには、1バイトの「R1」のほか「R1b」「R2」「R3」があるが。SPIモードでは「R1」のみ気にしておけばいい。 6 CMD1のための間奏曲(インターメッツォ)
ポーリング終了直後のCLKはHとなっているのでLにする。 CLKのH・Lを8回繰り返す。 CLK=Hにする。 /CS=Hにする。 この、CMD0とCMD1との間の操作は書籍によっては書いていない。ダミークロック送出と/CS=Hのタイミングが逆になってる例もあった。浅草ギ研さんもずいぶん悩んだらしい。この動作全体をしなくても動くこともあるらしい。 一応、安全のための「おまじない」として入れておく。 7 CMD1発行
SDの初期化作業が終わったかどうかの問い合わせ。 データ並びは、41H,00H,00H,00H,00H,F9H。ただしCRCはどうでもいいよ。
発行手順はCMD0と同様。SDが初期化作業中であれば、DOはHのまま。再びCMD1を発行し続けてポーリングする。 大容量化によってBUSY期間は長くなるらしく、100ms以上のタイムアウト期間を見込むべきらしい。 コマンド送出後、CLKの立ち上がりでDOをポーリングし続ける。ポーリングについてはCMD0と同じ。 8 コマンド・レスポンスの受信
DOから「0」を先頭に8ビット(=1バイト)のコマンド・レスポンスを受信する。「00000000B」ならOK。違っていたら何らかのエラーが起きている。 9 次のCMDのための間奏曲(インターメッツォ)
ここは 6 と同じ。 くたびれたところへ、ちょうどガメラが来た(・∀・)わ〜い♪ 怪獣見よっとw |
全体表示



お〜、ナニカしらの信念に基づくSDカードアクセス仕様が出来上がってきたみたいですね。所々にまじないが仕掛けてあり、Goodです。
足りない場合は、御札をはるなどるれば効果倍増かもしれません。仕様であれ、プログラムであれ、完全なものは形が美しいかもしれません。
美しさがどこかにあるのなら、成功は目前のような気がします。そう、亀甲型など安定感がありよさそうです(汗;)。
[ dotallcafe ]
2014/12/13(土) 午前 1:00
どもども〜(・∀・)
錯綜した情報をだいぶ整理できたように思います。
神は細部に宿って軒下貸して母屋盗られると言いますからね、確か。
ガメラは緊迫感がありますが、カメだけに亀甲縛りの緊縛感が似合うかもw(ღˇ▿ˇ)ぁん♥
[ KIKI ]
2014/12/13(土) 午後 11:49