最初は調子いいのに5秒くらい経ったところで絶対コケる
よく出るエラーメッセージはこんなの。
sd_read_block: Invalid CRC received 0xf605 result of computation 0x35ed
sd_card.cのsd_read_bytes()でコケてるらしい
症状
「16320バイトのデータを取ってきてね」
「(16320に満たない)バイト取ってきたよ」って報告してくる。
それをFatFsがエラーと判断して、
そのあとずっとデータが取得できない。

原因
FatFsのhw_config.cで設定してるクロック周波数が高すぎた。
L55あたりの宣言で、
クロック周波数(ボーレート)を12.5MHzに設定してたのがよくなかったっぽい。
// Hardware Configuration of SPI "objects"
// Note: multiple SD cards can be driven by one SPI if they use different slave
// selects.
static spi_t spis[] = { // One for each SPI.
{
.hw_inst = spi0, // SPI component
.miso_gpio = 4, // GPIO number (not Pico pin number)
.mosi_gpio = 7,
.sck_gpio = 6,
// SDカード初期化後のクロック周波数
.baud_rate = 12.5 * 1000 * 1000 // 速すぎ
}};
対処
クロック周波数を下げた。
// Hardware Configuration of SPI "objects"
// Note: multiple SD cards can be driven by one SPI if they use different slave
// selects.
static spi_t spis[] = { // One for each SPI.
{
.hw_inst = spi0, // SPI component
.miso_gpio = 4, // GPIO number (not Pico pin number)
.mosi_gpio = 7,
.sck_gpio = 6,
// SDカード初期化後のクロック周波数
.baud_rate = 11 * 1000 * 1000 // 下げた
}};
少しずつ下げていって安定したのが11MHzだった。
おすすめ(?)
前提として、SDカードは「低速で初期化 → そのあと高速で動作」がセオリーらしい。
安定動作してる現状の設定を置いておきます。
SDカードの性能によってはもっと上げられたり、もっと下げないと動かなかったりすると思うけどね。
hw_config.cで設定するクロック周波数
さっき載せたやつと同じ。11MHz。
// Hardware Configuration of SPI "objects"
// Note: multiple SD cards can be driven by one SPI if they use different slave
// selects.
static spi_t spis[] = { // One for each SPI.
{
.hw_inst = spi0, // SPI component
.miso_gpio = 4, // GPIO number (not Pico pin number)
.mosi_gpio = 7,
.sck_gpio = 6,
// SDカード初期化後のクロック周波数
.baud_rate = 11 * 1000 * 1000 // 下げた
}};
sd_spi.cで設定するクロック周波数
spiの初期化するときは400kHz
そのあとはhw_config.cで設定した11MHzで動く設定
/* 平常時のクロック周波数 */
void sd_spi_go_high_frequency(sd_card_t *pSD) {
// hw_config.cで設定したクロック周波数が設定される
uint actual = spi_set_baudrate(pSD->spi->hw_inst, pSD->spi->baud_rate);
TRACE_PRINTF("%s: Actual frequency: %lu\n", __FUNCTION__, (long)actual);
}
/* 初期化時のクロック周波数 */
void sd_spi_go_low_frequency(sd_card_t *pSD) {
uint actual = spi_set_baudrate(pSD->spi->hw_inst, 400 * 1000); // Actual frequency: 398089
TRACE_PRINTF("%s: Actual frequency: %lu\n", __FUNCTION__, (long)actual);
}
注意
「SDカード自体の性能」、「配線のごちゃつき」、「電源の安定性」とかで最適なクロック周波数は変わるから、この記事はクロック周波数を設定できるソースファイルがどこのなんて名前のファイルなのかの参考程度にして、各々いい塩梅の値を探してね。