LPC4088 マイクロコントローラー用の SPI SD ドライバーに取り組んでいます。ただし、V2 カードまたは大容量カードを使用しているかどうかを検出するためにCMD8
(の後に) を送信すると、奇妙な応答が返されます。CMD0
正しい応答(0x01
最上位ビットの場合0x1AA
、下位12の場合)またはエラーを取得する代わりに0x00 00 00 02 1F
、私にはまったく意味がありません。
初期化に使用するコード:
bool initialize () {
//0. Initialize SPI
SPI::init();
//1. Set clock to 400kHz
SPI::set_clock(400000);
//2. Assert CS signal (=0)
assert_cs();
// 3. Delay at least 74 clocks
delay8(10);
// 4. Deassert CS signal
deassert_cs();
// 5. Delay at least 16 clocks
delay8(2);
uint8_t argument[4];
reset_argument(argument);
// 6. Send CMD0 (reset, go to idle)
if (!send_command(CMD::GO_IDLE_STATE, CMD_RESPONSE_SIZE::GO_IDLE_STATE, response, argument)) {
return false;
}
// 7. Send CMD8
bool version2;
reset_argument(argument);
pack_argument(argument, 0x1AA);
if (!send_command(CMD::SEND_IF_COND, CMD_RESPONSE_SIZE::SEND_IF_COND, response, argument)) {
return false;
}
if ((response[0] & 0xFE) == 0x04) {
//unknown command. This means we have version1
version2 = false;
} else if (response[0] & 0xFE) {
//other error, let's bail
return false;
} else {
//Response, we're version2
version2 = true;
if (response[4] != 0xAA) {
return false;
}
}
//....
}
send_command コード:
bool send_command(CMD::value cmd, uint8_t response_size, uint8_t *response, uint8_t *argument) {
assert_cs();
Crc7_SD crc;
crc += cmd | 0x40;
crc += argument[3] & 0xFF;
crc += argument[2] & 0xFF;
crc += argument[1] & 0xFF;
crc += argument[0] & 0xFF;
SPI::send(cmd | 0x40);
SPI::send(argument[3] & 0xFF);
SPI::send(argument[2] & 0xFF);
SPI::send(argument[1] & 0xFF);
SPI::send(argument[0] & 0xFF);
SPI::send((crc << 1) | 1);
volatile uint8_t data;
{
unsigned int timeout = SD_CMD_TIMEOUT;
do {
data = SPI::receive();
--timeout;
} while(timeout && (data & 0x80));
if (timeout == 0) {
deassert_cs();
return false;
}
}
for (int i = 0; i < response_size; i++) {
//First byte is already read above
if (response) {
response[i] = data;
}
data = SPI::receive();
}
deassert_cs();
return true;
}
SPI プロトコルにエラーがないことを確認するために、ロジック アナライザーで入力と出力を検証しました。結果: CMD0の後にCMD8が続きます。正しいコマンドを送信しているようですが、それでもこの奇妙な応答が返されます。
セットアップに関する追加情報:
マイコンはLPC4088
マイクロコントローラはこの OEM ボードに接続されています
SDカードモジュールはOEMボードのシリアル拡張コネクタに接続
ロジックアナライザーをSDカードモジュールに接続
マイクロコントローラーと OEM ボードの両方の 2 つの異なるバージョンを使用して、それらのいずれかにハードウェア エラーがあることを除外しました。残念ながら、2 つ目の SD コントローラーはありません。
SanDisk Ultra SDHC 4GB Class 6 SD カードと Transcend SDHC 4GB Class 4 SD カードを使用しましたが、どちらもまったく同じ結果が得られました。
最後になりましたが、私は組み込みソフトウェアの経験がほとんどないため、小さなばかげたエラーに過ぎない可能性があります。