SDカードへのアクセスの方法をまとめます。HDL に落とすための自分用のメモですが...
1)電源立ち上げ後、1ms 待つ
→ これは、SDカード読み出し部として、最初に1ms 待つ事にする。
2)SD_CS = "H" 、SD_DO = "H" にして、SD_CLK を74クロック送信する
→ 他のブロックの関係上、1バイト送信を使い、データ0xFF を10バイト送信する。
SD_CS に関しては、1バイト送信の送付の有無に関わらず、直接出力できるようにしておく。
3)CMD0送信
3−1)SD_CS = "L" にして、1バイト分の時間だけ待つ。この間はSD_CLK は出力しない。
3−2)SD_CS = "L" のままで、CMD0 を送信する。
→ CMD0 は、ソフトウエアリセットのコマンドで、"0x40" "0x00" "0x00" "0x00" "0x00" "0x95"
最後の1バイトは CRC-7 を計算済。この後、SPI モードに移行するため、CRC-7 は何でもよい。
また、MSB 先送り。
3−3)SD_CS = "L" のままで、SD_DI にデータが来るのを待つ。
→ 通常は、0xFF で、SDカードがレスポンスを返してくると、0xFF 以外の値が返ってくる。
CMD0 に対するレスポンスは、R1 。R1 は1バイト長。
CMD0 に対するレスポンスは、エラーがない通常の場合は、0x01 が返ってくる。
R1-bit7:0固定
R1-bit6:パラメータエラー
R1-bit5:アドレスエラー
R1-bit4:消去シーケンス中にエラー発生
R1-bit3:CRCエラー
R1-bit2:コマンドが違うよエラー
R1-bit1:消去中にリセットが実行された
R1-bit0:アイドル状態
3−4)SD_DI がずっと0xFF の場合は、タイムアウトを設けて、タイムアウトエラーなら、読み出しを中止する。
3−5)SD_DI が0x01 以外の場合もエラーとして、読み出しを中止する。
3−6)SD_CS = "L" のままで、1バイト分の時間だけ待つ。この間はSD_CLK は出力しない。
3−7)SD_CS = "H" にして、1バイト分の時間だけ待つ。この間はSD_CLK は出力しない。
3−8)SD_CS = "H" 、SD_DO = "H" にして、SD_CLK を1バイト分送信する。
→本来はクロックを送信しなくてもいいんですが、こうしないと駄目なSDカードがあるらしいです。
3−9)SD_CS = "H" にして、1バイト分の時間だけ待つ。この間はSD_CLK は出力しない。これでCMD0 が完了。
SD_CS やSD_CLK の送信方法は、他のコマンドも同様なので、以下は省略。また、タイムアウトやエラーの処理も同様。
4)CMD1送信
4−1)CMD1 を送信する。
→ CMD1 は、初期化のコマンドで、"0x41" "0x00" "0x00" "0x00" "0x00" "0x00"
4−2)SD_DI にデータが来るのを待つ(0xFF 以外の値)。
→ CMD1 に対するレスポンスは、R1。CMD1 に対するレスポンスは、最初、0x01。
SDカードの準備が完了すると、0x00 になる。
ブロックの動作としては、0x00、0x01 で正常終了。それ以外の値でエラーとする。
4−3)CMD1 が終了。
5)上記、4)CMD1送信で、0x01 が返ってきたときは、再度CMD1送信を繰り返す。0x00 になったら、次の6)に進む。
6)CMD16送信
6−1)CMD16 を送信する。
→ CMD16 は、アクセスのブロック長で、512バイトを指定する。"0x50" "0x00" "0x00" "0x02" "0x00" "0x00"
ブロック長は、SDに読み書きする時の単位で、512バイトがデフォルトの事が多いようです。
6−2)SD_DI にデータが来るのを待つ(0xFF 以外の値)。
→ CMD16 に対するレスポンスは、R1。CMD16 に対するレスポンスは、0x00が正常。それ以外はエラーとして処理。
6−3)CMD16 が完了。
これでやっとSDカードからデータを読み出せます。
他にもSDカードの情報を読み出して、アクセス周波数を変更したりなどをする必要があるんですが、あまり必要がなさそうなので、今回はパスです。
2011年10月04日
この記事へのコメント
コメントを書く

