2009/03/15

DWM付録ARM基板(2008/5)(5) SDカードアクセス

DWM添付ARM基板ですが、USBマスストレージデバイスとして見せるためのファームが添付されていますが、手持ちのカードの一部しかアクセスできない状態でした。

やはり添付ファームだと、ソース量が多かったり、関連ライブラリが色々絡んで来ざるを得なくなって見通しが悪くなってしまいますから、自分でSPI経由のSDアクセスを作りこむことにしました。別に、必ずしもUSBマスストレージデバイスとして見えなくてもかまわないわけなので。

中々カードがコマンドに応答しないなど悪戦苦闘しましたが、結果的に、2GBのSDカードは自前のロジックでもきちんと読めることが判りました。
  • SPI経由で読み出したデータ
readblk: resp 0
0000: fa b8 00 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0
. . . . . . . . . . . . . . . .
0010: fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00
. . . | . . . . . . . . . ! . .
0020: 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75
. . . . 8 . u . . . . . . . . u
0030: f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b
. . . . . . . . . | . . . t . .
0040: 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00
L . . . . . | . . . . . . . . .

  • Linuxから、ddで読み出したデータ
000000 fa b8 00 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0
000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00
000020 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75
000030 f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b
000040 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00

当然ながら両者一致しています。

当初は、I/Oポートの扱いを間違えたりといった初歩的なミスでつまずいていましたが、SDカードのSPIアクセスとしては
  • 送信データはクロックの立ち上がりエッジで、カードから読み取られる。
  • 最初にCS/DI=Hにした状態でクロックを74回以上送信。
  • 初期化はCMD0によるリセットと、CMD1/ACMD41によるカード初期化。
    CMD0を送ってレスポンスがIdle State(0x1)になったら、すかさずACMD1を送信します。
  • ACMD1は、CMD55 + CMD41の組み合わせ
    レスポンスが0x1から0x0に変わるまで、何回か送信をリトライする必要があります(かなり時間が掛かるようです)。
  • CMD17の引数はバイトオフセットかつブロックサイズ(512)の倍数にするのが良いようです。コマンド引数はビッグエンディアン([31:24]、[23-16]、[15-8]、[7-0]の順)で指定します。
などを実施すれば、それほど難しくなくアクセスできるようです。

自前で作りこんだおかげで、読めなかったSDカードがどういう振る舞いをしているかもわかってきました。
  • 読めるカード(2GBノーブランド、1GBノーブランド)
    PCショップで500円程度で売られていた安物ですが、CMD0、ACMD41にきちんと応答してくれます。
  • 読めないカード(512MB、128MB、いずれもパナソニック製)
    これらのカードは、CMD0に対して63(初回目)、5(2回目以降)を返却してきます。63は良くわからないのですが、5は"Illegal Command"なので、
  1. ソフトが何かを間違えていて、カードによっては厳しくチェックされてエラーになっている
  2. そもそもカード側が何かに対応していない
などの可能性がありそうです。

参考URL:
MMCの使いかた
マルチメディアカード

MMCドライバ
AVR試用記-sdcard
ゴミ SD カード活用
SDカードが認識しない。。。
などなどを参考にさせていただきました。

0 件のコメント: