🛠️

SDカードのSPIモードの初期化に関する諸々

2022/07/13に公開

SDカードのSPIモードの実装を、自分で書いてみて試行錯誤した点のまとめです。多くは、正式な仕様によるものではなく、あくまで、実験に基づいた情報です。

SDカードのSPIモード

SDカードは一般的に4ビット幅のバス接続で使用されますが、マイコンなどのリソースの少ないホスト向けに、4線式のSPIでアクセスするモードとして提供されています。なお、SDUC(2TB以上)ではサポートされません。

SPIモードの初期化

SDカードの仕様書に書いてある通りに行えば問題ないはず、ですが、わりと嵌ります。特に、製品によって相性問題が生じやすいです。ここでは、電源ONからACMD41を実行するまでの諸々についてとりあげます。基本的な流れは以下の図のようになります。

ダミークロック

仕様では、74クロック以上と規定されています。8ビットのSPIで74クロックなんて半端な数は送れないので、80クロックで問題ありません。
ダミークロックを送るときは、CSとDI両方ともHレベルであることが必須条件です。なお、サンプリングタイミング(クロックが立ち上がる瞬間)以外でDIがLレベルになることには問題がない模様です。

CMD0が異常な値を返す場合

  • 電源ONからダミークロックまでの時間が短すぎる可能性。最低1ms待つように規定されています。
  • ダミークロックが正しく送れていない可能性。詳細は前項を参照。
  • DOのプルアップ忘れ。仕様上、DOは10kΩでプルアップする必要があります。
    プルアップしていない場合、エラーコード(0x3fなど)を返すカードが結構ありますが、2回繰り返すとうまくいく場合もあります。

CMD0が失敗するけど、2回目以降は成功する場合

  • DOのプルアップ忘れ。前項を参照。

CMD8が異常な値を返す場合

  • クロック(SCLK)の立ち上がり、立下り時間が許容範囲外の可能性。この場合、ほかのコマンドは実行できるのに、CMD8だけ失敗し、SDカードが特徴的なバイト列(例えば 00 00 00 02 1F)を返すという、不可解な現象が起きます。
    仕様上、クロックの立ち上がり、立下り時間は10ns以下と規定されていて、これは、クロックの周波数やDIとのタイミングには関係ありません。どんなにタイミング的に余裕があってもダメです。そして何故か、CMD8を実行するときだけ、この条件がシビアに影響するようです。
    実験では、100kHzのクロックにおいて、100nsでは1割、300nsでは3割、500nsでは9割のカードで、CMD8が失敗しました。電圧レベル変換回路を介して接続する場合や、マイコンのポートの出力ドライブ強度が低い場合は要注意です。
  • 稀に、コマンドの前に1バイト分のダミー読み出しが必要なカードがあります。この場合、先頭バイトの最上位ビットが立った、特徴的なバイト列(例えば C1 7F FF FF FF)を返します。
    コマンドを送る前に、Busy状態のチェックを兼ねて、1バイトの0xffを送るようにすれば、この問題を回避できます。(実際にBusyであるか否かに関係なく)

ACMD41が終わらない場合

  • 根気良く回しましょう。仕様上、最大で1秒と規定されています。実験では、最大250msかかるカードがありました。

まとめ

以上の実験を踏まえ、以下の点を考慮することで、サンプルとして使用したSDカード(SD/SDHC/SDXC)すべてにおいて、正常にSPIモードの初期化ができるようになりました。

  • DOに10kΩのプルアップをつけること。
  • 電源ONから最低1ms待つこと。
  • クロック(SCLK)の立ち上がり、立下り時間を10ns以下にすること。5V回路から抵抗で分圧して接続、はダメ。
  • ダミークロックを送るときはCSとDIをHレベルに保つこと。
  • CMD8、ACMD41などコマンドを送る前に、1バイトのダミー読み出し(0xffを送る)をすること。
  • ACMD41のループは最大1秒まで待つこと。

ところで・・・

SDUCがSPIモード非対応なのは仕様ですが、それ以外でもSPIモード非対応のカードが存在する、という噂を時々聞きます。そういう実物を見たことがないのですが、どなたか、実物を確認した方いますか?

参考

Discussion