11

Stack Overflow question Initialization of a microSD card using an SPI interfaceを見てきましたが、私の問題 (つまり、まだ試していないこと) に一致する回答はありませんでした。

マイクロコントローラーの SPI インターフェイス (具体的にはHC908 )を介して SD カードにアクセスしようとしている同様の問題があります。Physical Layer Simplified Specification v2.00 のフローチャートに従ってみましたが、Transcend 1 GB & 2 GB および AE&C 1 GB カードで正しく初期化されるようです。しかし、カメラで使用した古いカードの隠し場所から、他の 3 枚のランダムなカードで問題が発生しています。

私のコードはすべて HC908 アセンブラーです。SPI クロック ラインを調べたところ、初期化中に約 350 kHz で実行されました (100 ~ 400 kHz のウィンドウ内に収まる私の低い MCU クロック速度で HC908 が提供する唯一の速度乗数)。

初期化ルーチンを完了していない 3 つのカードの結果を次に示します (すべて、コードやタイミング パラメーターを変更せずに連続して実行されます)。

Canon 16Meg card (labeled as SD):
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (indicates idle)
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command set local flag to indicate v1 or MMC card
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
because illegal command branch to error routine
Send CMD13 [0x4D000000000D] (show status buffer) and Loop up to 8 times waiting for high bit on response to go low
R1= 0x05 (idle and illegal command)

不正コマンドフラグが立っていませんか?そのフラグをクリアするためにCMD8の後に何かをする必要がありますか?

SanDisk UltraII 256Meg
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command set local flag to indicate v1 or MMC card
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send 0xFF 4 times to read OCR
OCR = 0xFFFFFFFF
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Because illegal command, assume card is MMC
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command)
Repeat the CMD1 50 times (my arbitrary number to wait until idle clears)
Every R1 response is 0x05 (idle and illegal command)

なぜ OCR はすべて F なのですか? まったく適切ではないようです。また、ACMD41 と CMD1 が不正なコマンドに応答するのはなぜですか? 不正なコマンド応答があっても、カードが CMD55 の後に有効な ACMD を待機しているため、CMD1 が失敗していますか?

SanDisk ExtremeIII 2G:
Set card select high
Send 80 SPI clock cycles (done by writing 0xFF 10 times)
Set card select low
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Send CMD8 [0x40000001AA87] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? My loop shows the responses for each iteration and I got 0xFF 0xFF 0xC1 0x7F... is the card getting out of sync?)
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle and back in sync)
Send 0xFF 4 times to read OCR
OCR = 0x00FF80
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x5F (??? loop responses are 0xFF 0xFF 0xF0 0x5F... again out of sync?)
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x05 (idle and illegal command, but back in sync???)
Because illegal command, assume card is MMC
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x01 (idle)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?)
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x00 (out of idle)
Send CMD9 [0x4900000000AF] (get CSD) and Loop up to 8 times waiting for high bit on response to go low
R1 = 0x3F (??? loop responses are 0xFF 0xFF 0xC1 0x3F... again out of sync?)
Code craps out because Illegal command bit is high.

あのカードの何が悪いんだ?

同期している場合もあれば、そうでない場合もあります。(上記のパターン繰り返し可能です。) 私はこれを調査しましたが、MOSI/MISO 転送間で異常なクロック サイクルが発生することはありません。

4

3 に答える 3

23

わかりました...問題が見つかりました。この問題に遭遇した他の人にとっては、0xFF応答を得た後に余分なものを送信することを忘れないでください. これにより、カードは次のコマンドに備えて 8 クロック サイクル余分に使用できます。一部のカードは必要ないように見えますが (たとえば、私が使用しているトランセンド)、必要なカードもあります。

実際には、応答として0xFF取得するまで送信する「書き込みコマンド」ルーチンの最初に単純なループを配置しました。 . SDカードが(通常)SPIモードに関係している限り、入ってくるクロックサイクルがない場合、時間は静止します。0xFF0xFF

私が指摘し、まだ答えを見つけていないことの1つ(ただし、これまでのところ何も害はありません)、CSRの16バイトを読んだ後、さらに2バイトの非-0xFFが出てくるようです。 .. それはCRC16ですか?CSRにはCRCが組み込まれているので奇妙です...

于 2010-03-03T21:46:36.117 に答える
3

CRC を (CMD59 で) 有効にした場合、はい、データ ブロックに CRC16 が追加されます。

詳細については、「Physical Layer Simplified Specification Version 2.00」の「バス転送保護」および「データ読み取り」の章を参照してください。

于 2010-08-16T10:33:17.750 に答える
2

これは重要です。動作電圧を選択する必要があることがわかるまで、SD/MMC カードで非常に苦労しました。これを行うには、カードに供給している電圧に合わせてビットを設定して ACMD41 を送信します。注:選択できるビットは 1 つだけです。電圧を選択しないか、複数選択すると、アイドル状態でループし続け、一部の SD カードでは終了しません。

つまり、ACMD41 が応答 0x01 を送信し続ける場合は、電圧が選択されていません。電圧は、ACMD41 の 32 ビット パラメータ ビット 23...8 にあります。3.2V ... 3.3V の場合、これはビット 20 であるため、たとえば、次のことができます。

acmdSDAppOpCond[2] = (1 << (20 & 7));           /* 3.2V .. 3.3V */

これは 16 進値 0x10 なので、ACMD41 は次のようになります...

最も一般的な値の短い (そして不完全な) 表を次に示します。

Bit23: 3.5V..3.6V
Bit22: 3.4V..3.5V
Bit21: 3.3V..3.4V
Bit20: 3.2V..3.3V
Bit19: 3.1V..3.2V
Bit18: 3.0V..3.1V
Bit17: 2.9V..3.0V
Bit16: 2.8V..2.9V
Bit15: 2.7V..2.8V

どの時点でも CS をハイに切り替える必要はありません。常に低く保つことができます。

于 2014-04-24T10:19:16.927 に答える