フォト
無料ブログはココログ

MyList

« FireTV Stick <地上波見なくなるよな> | トップページ | 「オレは聞いてない」 <有効な判断をしていないだけ> »

2018年9月11日 (火)

Bus pirate(2) <SDカードを読んでみる>

 Bus pirate(2018/9/3)で先割れスプーン的だと書いたけど、便利だったのでSPIモードでSDカードを読んでみた。 uSDカードアダプタはAmazonで買った安物。 3.3VのLDOとレベルシフタが載っている。

Buspirate36_sd

 昔SDカード/MMCカードで遊んでいたころはまだSDHC規格は無かったので知識が古い。

 調べてみると、MMCカード規格を作っていたMultiMediaCard AssociationはJDECと合併したらしい。 最近MMCカードは見かけないけど組み込み業界では eMMCとしてチップが基板に張り付けてある。

 MMCカードの規格はRenesas(旧日立)の「マルチメディアカードユーザーズマニュアル(j603002_mmc.pdf)」があるのだが、Renesasのサイトでは見つからないようだ。 ネット上では奇特な人が保存してくれているようだ。

 ここを参考にBus pirateでSDカードのデータを読んでみた。

 SDカードはSanDiskの2G microSDcard。
Sandisk_2g_sdc

【初期化】
 CMD1で初期化してみた。 初期化手順は、

  1. SPIモードにする
  2. CMD0:GO_IDLE_STATE:(要CRC)
  3. CMD1:SEND_OP_COND R1レスポンスが00hになるまで
  4. CMD2:ALL_SEND_CID
  5. CMD3:ET_RELATIVE_ADDR

これはMMCの初期化方法。 ユーザマニュアルに説明がある。 今回は、CMD2,CMD3は省略して先頭セクタを読んでみる。

 SPIモードにするには、CSをHにしてダミークロックを74クロック以上発行する。 74クロックはキリが悪いので80クロックとする。 

 BusPirateでは、"]"←CS=H、r:10←10byte(80clock)、

 コマンドレスポンスの先頭ビットは0なので0xFF以外のデータを読み出すまで待つ。ところが、BusPireteでは待つことができないのでとりあえず8byte読む。 0xFFでないデータがコマンドレスポンスだ。 (scriptを使うと待つことができる。)

【セクタ読み出し】
 読みだし手順は、

  1. CMD16:SEND_BKICKLEN
  2. CMD17:READ_SINGLE_BLK

 まずCMD16でブロックサイズを指定する。次にCMD17を送ると、コマンドレスポンスに続いてデータを読み出すことができる。 読み出す回数はコマンドレスポンス:5byte、データトークン(0xFE):1byte、ブロックデータ:512byte、CRC:2byteで520byteを指定している。

 6byte以内にデータトークン(0xFE)が読み出せないとすべてのデータが読めない。 そのときは読み取るデータを多くする。 (r:530とか)

HiZ>m 5 1 1 2 1 2 2  ←SPIモード
SPI (spd ckp ske smp csl hiz)=( 1 0 1 0 1 0 )
Ready
SPI>Wv         ←電源ON ピンステータス表示
Power supplies ON
Pinstates:
1.(BR)  2.(RD)  3.(OR)  4.(YW)  5.(GN)  6.(BL)  7.(PU)  8.(GR)  9.(WT)  0.(Blk)
GND     3.3V    5.0V    ADC     VPU     AUX     CLK     MOSI    CS      MISO
P       P       P       I       I       I       O       O       O       I
GND     3.29V   5.02V   0.00V   0.00V   H       L       H       H       L

SPI>]r:10                 ←SPImode
/CS DISABLED
READ: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

SPI>[0x40 0x00 0x00 0x00 0x00 0x95 r:8]   ←CMD0 GO_IDLE_STA
/CS ENABLED
WRITE: 0x40
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x95
READ: 0xFF 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF ←R1=0x01 "In Idle State"
/CS DISABLED

SPI>[0x41 0x00 0x00 0x00 0x00 0xff r:8]        ←CMD1 SEND_OP_COND 
/CS ENABLED
WRITE: 0x41
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0xFF
READ: 0xFF 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF ←R1=0x01 "In Idle State"
/CS DISABLED

SPI>[0x41 0x00 0x00 0x00 0x00 0xff r:8]    ←CMD1 SEND_OP_COND
/CS ENABLED
WRITE: 0x41
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0xFF
READ: 0xFF 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF ←R1=0x00 成功
/CS DISABLED
SPI>[0x50 0x00 0x00 0x02 0x00 0xff r:8]    ←CMD16 SET_BLOCK_LEN
/CS ENABLED
WRITE: 0x50
WRITE: 0x00
WRITE: 0x00
WRITE: 0x02
WRITE: 0x00
WRITE: 0xFF
READ: 0xFF 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF ←R1 Response=0x00 成功

SPI>[0x51 0x00 0x00 0x00 0x00 0xff r:520]   ←CMD17 READ_SINGLE_BLOCK
/CS ENABLED
WRITE: 0x51
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0xFF
READ: 0xFF 0xFF 0x00 0xFF 0xFF 0xFE 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                  (                        
                   )                       
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x03 0x3D 0x00 0x06 0x3F 0xFF 0xD7 0xF9 0x00 0x00 0x00
      0x07 0x89 0x3C 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x55 0xAA
0x5D 0xE1
/CS DISABLED

 ↑先頭から3byte目がR1レスポンス(0x00)。続いてデータトークン(0xFE)、SDカードの先頭セクタ。パーティションテーブル(下線部分)と末尾に55h、AAhがある。 最後の2byteはCRC(0x5D,0xE1)。

【SDHCカード】
 SanDisk SDHC 8GBも読んでみる。

Sandisk_8g_sdhc

 このカードはCMD1で初期化する方法は使えない。 初期化手順は、SD AssociationからDLできる [Physical Layer Simplified Specification]に解説がある。

  1. SPIモードにする
  2. CMD0: GO_IDLE_STATE:(要CRC)
  3. CMD8: SEND_IF_COND:(要CRC)
  4. ACMD41:SD_APP_OP_COND (CMD55+CMD41) R1レスポンスが00hになるまで 
  5. CMD58: READ_OCR

CMD8のパラメータは、0x00、0x00、電圧、チェックパターン(レスポンスで同じ値が返る)。 電圧は3.3vで使うので0x01、チェックパターンは0xAAを使う。 なぜって、ネット上にCRC(0x87)を計算した人がいるから。 ここは決め打ちでよさそう。

 CMD58は省略。データ読み出しはCMD16とCMD17上の例と同じ。

HiZ>m 5 1 1 2 1 2 2
SPI (spd ckp ske smp csl hiz)=( 1 0 1 0 1 0 )
Ready

SPI>Wv
Power supplies ON
Pinstates:
1.(BR) 2.(RD) 3.(OR) 4.(YW) 5.(GN) 6.(BL) 7.(PU) 8.(GR) 9.(WT) 0.(Blk)
GND 3.3V 5.0V ADC VPU AUX CLK MOSI CS MISO
P P P I I I O O O I
GND 3.29V 5.02V 0.00V 0.00V H L H H L

SPI>]r:10                ←SPImode
/CS DISABLED
READ: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

SPI>[0x40 0x00 0x00 0x00 0x00 0x95 r:8] ←CMD1 GO_IDLE_STATE
/CS DISABLED
READ: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
/CS ENABLED
WRITE: 0x40
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x95
READ: 0xFF 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

/CS DISABLED
SPI>[0x48 0x00 0x00 0x01 0xAA 0x87 r:8]  ←CMD8 SEND_IF_COND
/CS ENABLED
WRITE: 0x48
WRITE: 0x00
WRITE: 0x00
WRITE: 0x01
WRITE: 0xAA
WRITE: 0x86
WRITE: 0x87
READ: 0x01 0x00 0x00 0x01 0xAA 0xFF 0xFF 0xFF  ←R1:Idle R7:
/CS DISABLED

SPI>[0x77 0x00 0x00 0x00 0x01 0xff r:8]   ←CMD55 APP_CMD
/CS ENABLED
WRITE: 0x77
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x01
WRITE: 0xFF
READ: 0xFF 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
/CS DISABLED

SPI>[0x69 0x40 0x00 0x00 0x01 0xff r:8] ←CMD41 PP_SEND_OP_COND
/CS ENABLED
WRITE: 0x69
WRITE: 0x40
WRITE: 0x00
WRITE: 0x00
WRITE: 0x01
WRITE: 0xFF
READ: 0xFF 0x05 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
/CS DISABLED

SPI>[0x77 0x00 0x00 0x00 0x01 0xff r:8] ←CMD55 APP_CMD
/CS ENABLED
WRITE: 0x77
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x01
WRITE: 0xFF
READ: 0xFF 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
/CS DISABLED

SPI>[0x69 0x40 0x00 0x00 0x01 0xff r:8] ←CMD41 PP_SEND_OP_COND
/CS ENABLED
WRITE: 0x69
WRITE: 0x40
WRITE: 0x00
WRITE: 0x00
WRITE: 0x01
WRITE: 0xFF
READ: 0xFF 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
/CS DISABLED

SPI>[0x50 0x00 0x00 0x02 0x00 0xff r:8] ←CMD16 SET_BLOCK_LEN len=512byte
/CS ENABLED
WRITE: 0x50
WRITE: 0x00
WRITE: 0x00
WRITE: 0x02
WRITE: 0x00
WRITE: 0xFF
READ: 0xFF 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
/CS DISABLED

SPI>[0x51 0x00 0x00 0x00 0x00 0xff r:520] ←CMD17 READ_SINGLE_BLK
/CS ENABLED
WRITE: 0x51
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0x00
WRITE: 0xFF
READ: 0xFF 0xFF 0x00 0xFF 0xFF 0xFE 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
                  (                        
                   )                       
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x82 0x03 0x00 0x0B 0x50 0xCA 0xC6 0x00 0x20 0x00 0x00
      0x00 0xC0 0xEC 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      0x00 0x00 0x00 0x00 0x55 0xAA
0x68 0xC0
/CS DISABLED

 CMD8は PhysicalSpec Ver2.0から使えるらしい。 CMD8→ACMD41→CMD1の順に初期化するとどのカードでも使える。

 昔AVRでSD/MMCにアクセスするプログラムを作ったときは、初期化で苦労した記憶がある。 いまほど情報もなかったし、Arduinoも無かったから。

 今時は情報も多いし、Bus pirateのようなツールで試すと、F/Wレベルでの試行錯誤を減らせる。

###

 SDカードのライセンスにまつわるエトセトラは。Chanさんやねむさいんの、

が参考になる。



最近の投稿】【最近のCPUボード】【2017の投稿】【2016の投稿】【2015の投稿

 

« FireTV Stick <地上波見なくなるよな> | トップページ | 「オレは聞いてない」 <有効な判断をしていないだけ> »

CPUボード」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: Bus pirate(2) <SDカードを読んでみる>:

« FireTV Stick <地上波見なくなるよな> | トップページ | 「オレは聞いてない」 <有効な判断をしていないだけ> »