なる研電子工作小品集>マルチメディアカード(MMC)

マルチメディアカード

マルチメディアカード達

ある日、あぷあぷ(店名)で、4MBのマルチメディアカードが20枚セットで\2000というのを見つけました。 その、必要最小限の使い方をここにまとめます。 詳しくはデータシートなどを見てください。 以下マルチメディアカードMMCと呼びます。

●SPIモード

MMCを読んだり書いたりするためには、MMCと通信する必要があります。MMCとの通信方法には、MMCモードSPIモードがあって、SPIモードのほうが簡単です。SPIモードではSPI通信と呼ばれている通信方法を使って通信します。クロック、データin、データoutの3本の信号線を使ったシリアル通信です。

■SPIモードのピン・アサイン

先ずは配線です。MMCはSDカードと大きさやピンなどに互換性がありますから、秋月電子などで売ってる(2005/03) SDカード用のコネクタを使用できます。データシートに入れろと書いてあるので、素直に4と5の間に3と4の間に0.1uFのコンデンサを入れます。MMCのDOホストのDIに、ホストのDOMMCのDIに繋ぎます。ホストってのはMMCを操るマイコンなどのことです。
マルチメディアカードのピンアサイン
ピン番略号操作権なかみ
1CSホストチップ選択信号 Lで選択
2DI(DataIn)ホストデータ信号
3GNDホスト電源 0V
4Vccホスト電源 2.7〜3.6V (Typ3.0V)
5CLKホストクロック信号
6GNDホスト電源 0V
7DO(DataOut)MMCデータ信号

■SPIプロトコル

簡単なので、ぐだぐだ書くよりも実際に通信している所を覗いた方が解りやすいでしょう。
1、ホスト→カード 0xAB (1010 1011)

2、カード→ホスト 0x78 (0111 1000)
3、ホスト→カード 0xAB (1010 1011) と カード→ホスト 0x78 (0111 1000) が同時、全二重。
要するに、CLKピンの立ち上がりで自分のDIを採取する、ということです。

●コマンドの送信

上でバイナリデータの送受信ができるのですが、意味のある構造を持たせてやらないと、「じDゃい1めうAしら」の様にMMCには理解してもらえません。「アドレス0x0019EAのデータを教えてくれ。」という様に理解してもらえるコマンドを送信すれば、「はい。そこのデータは0x674AF1AB… …FC17ですよ。」と答えてくれます。

例えば、CMD0というコマンドは以下のビット列になります。

STARTコマンド 6bit引数 32bitCRC 7bitSTOP
010000000000000000000000000000000000000010010101

コマンドはスタートビット(START(01))から送り始め、ストップビット(STOP(1))で終わります。コマンド6bitにはCMDxxのxxが入ります。このxxは十進数表記で、例えばCMD17なら010001となります。引数32bitはリードコマンドCMD17ならアドレスが入ったりします。CRC 7bitはMMCモードからSPIモードに切り替えるCMD0の時だけ必要です、SPIモードになってからは無視されます(有効にもできます)。

▼読み書きに必要なMMCのコマンド達
コマンド引数レスポンスはたらき
CMD0なし(0で埋める)R1カードをリセットする
CMD1なし(0で埋める)R1カードの初期化が完了したか否か聞く
CMD16ブロック長[Byte]R1CMD17、CMD24の転送ブロック長を設定する。リセット後のデフォルトは512Byte。上限2024Byteやライト時は無効で512Byte固定などカードによって制約あり。
CMD17アドレス[Byte]R1シングルブロックリード。引数で指定したアドレスからCMD16で設定した分だけカードから読む。
CMD24アドレス[Byte]R1シングルブロックライト。引数で指定したアドレスからCMD16で設定した分だけカードに書き込む。

●レスポンス

コマンドを送ったら、MMCは返事をしてくれます。これをレスポンスと呼びます。 レスポンスにはR1とR2の2種類あります。 R2は使わないのでR1レスポンスを見てみましょう。 R1レスポンスは8bitで、以下の構造を持っていて、全て0だと正常ということになります。 R1レスポンスを受けるには、クロックを出しながらレスポンスの頭 0 が出るのを待った後、残り7bit分受信します、例えば。

常に0引数が変アドレスが変消去中エラーCRCエラーコマンドが変意味不アイドル中
0*******

もう一つ必須なレスポンスがありました。データレスポンスです。?は気にしないでください。

0b???00101問題なし
0b???01011CRCエラー
0b???01101よくわからないエラー

●データの送受信

■受信

シングルブロックリードの手順は、コマンドを送信する→レスポンスを受信する→データを受信する、です。 データを受信する時のMMCからの信号には、頭にスタートブロックと呼ばれるヘッダが8bit、尾にCRCが16bit、付加されます。データをサンドイッチにしてデータトークンを構成してます。シングルブロックリード時のスタートブロックは0xFEです。2進では11111110でアイドル時のバスは1なので0がスタートビットと思ってよさそうです。それから、CRCを無視するにしてもMMCは送信するのでデータ受信後に16クロック以上出すことを忘れずに。

■送信

シングルブロックライトの手順は、コマンドを送信する→レスポンスを受信する→データを送信する→データレスポンスを受ける→(書き込み終了を待つ)、です。 受信と同様に送信するデータにも、頭にスタートブロック8bit、尾にCRC 16bit、を加えてデータトークンを構成して送信する必要があります。 シングルブロックライトのスタートブロック0xFEです。 尾のCRCはSPIモードでは無視してくれますがクロックだけ忘れずに。 データレスポンスはR1でよいのでしょうか?とは異なり、0b???00101なら成功です。 (書き込み終了を待つ)というのはMMCがデータを実際に書き込むために少々時間がかかるので、この間はコマンドを送信しないようにするということです。書き込み中はMMCのDOがLに保持されますから、これがHになるまで次のコマンドを送らないようにします。

●MMCの初期化

MMC起動後はMMCモードなのでSPIモードに移行させます。 この手順を以下に示します。

  1. CSをHにする。
  2. クロック(CLKのL→H)を74回以上送る。
  3. CSをLにする。
  4. CMD0を送信し、レスポンス0x01を受ける。
    CMD0はMMCモードで発行するので、CRCが必要です。CMD0のCRCは(1001010)です。
  5. CMD1を送信し、レスポンスを受ける。
  6. CMD1のレスポンスが0x01なら、CMD1のレスポンスが0x00になるまでCMD1を再送信し続ける。
これでMMCはSPIモードでコマンドを受け付ける状態になってます。

●実験

AVRによるMMCテスト回路 8bitマイコンのAVR ATtiny26LはMMCと同じ2.7Vから動作しSPIをハードウェアでサポートしてます。 コレで読み書きしてみようと思います。

まずは読みです。市販のSDカードリーダでASCIIなテキストファイルを書き込んだMMCを、自作のリーダに挿して内容をCOMポート経由でPCの画面にダンプします。
プログラム 読み出した結果

つづいて書きです。その前に警告をば。

【注意】FATをサポートしてないので書き込みを実行するとMMCのファイルシステムは破壊されます。既にMMCに記憶されているファイルはすべて壊れます。再度市販のSDカードリーダ等で使用するにはフォーマットを行う必要があります。
とにかく実験ということで、MMCの内容を「@」で埋め尽くすプログラム

●FAT

上の「●実験」で「読み出した結果」の 0040には「FAT12」という文字列が、 0042〜0047には第1FAT、0048〜004Dには第2FAT、004Eにはルートディレクトリエントリが、0x009Eにはファイルの断片が見えます。

MMCには書き込みブロック長が512Byteに固定されているものがあるので、FATをRAMが128Byteしかないマイコンで扱うのはちょっと難しいです。次回ということで。


●関連リンク

<<電子工作小品集へ戻る
Since 2005/03/20
LastUpdated 2008/06/29
Copyright 2008 Naru
アクセス  今日今日のアクセス  昨日昨日のアクセス