ファイルを使え! SDカードとFATファイルシステム
テストプログラムが数十KB程度ならシリアルポートで転送しても1秒かからないので問題にならないが、
SNESのプログラムだと数MBにもなるので転送じゃ時間がかかってしょうがない。
Altera DE1ボードにはSDカードスロットが付いていることもあり、
SDカードからSDRAMにプログラムを読み込んで実行することにしました。
またFAT16を実装して、PCでSDカードにファイルを置いたものをそのまま読めるようにしました。
さらにSDHCカードが容易に入手できるので、SDHCカードサポートとFAT32も実装しました。
_ ▼ SDカード (SPIモード)
DE1ボードのマスタークロックは50MHzなので、
1/2でSDカードへのアクセスクロックは25MHzとしました。
DE1の配線の都合もありSPIモードのみの動作で、とりあえずreadのみ実装。
SDSCcard_ctrl_SPImode.sflp とSDカード情報読み取りサンプル。
%i "SDSCcard_ctrl_SPImode.h"
%i "seg7_ctrl.h"
circuit SDCARD_test
{
input SW<10>;
output HEX0<7>, HEX1<7>;
output SD_CSn; // SD Card CSn
output SD_CLK; // SD Card Clock
output SD_CMD; // SD Card Command & Dout
input SD_DAT; // SD Card Data
SDSCcard_ctrl_SPImode sdcard;
seg7_ctrl seg70, seg71;
stage_name sdget { task do(); }
SD_CSn = sdcard.CSn;
SD_CLK = sdcard.CLK;
SD_CMD = sdcard.CMD;
sdcard.DAT = SD_DAT;
HEX1 = seg71.con(sdcard.rdata<7:4>).oSEG;
HEX0 = seg70.con(sdcard.rdata<3:0>).oSEG;
generate sdget.do();
stage sdget {
if(sdcard.ack){
// CSD
// sdcard.read(0x000000||0b0||SW<6:0>);
// MBR(第一パーティションエントリ)
sdcard.read(0x000001||SW<7:0>);
finish;
}
}
}
_ ▼ SDカード (SDバスモード) 2016/07/09
基本的にデータはSDカードからSDRAMへロードします。
SDカードのアクセスについては、従来はSPIモードでアクセスしており、
数十KBのデータであれば一瞬でロードできていました。
しかしSNESのデータについては4MBほどあるものもあり、
ロードに数秒かかっている状況でした。
そこで、DE2-115ボードのSDカードコネクタではデータバスが4本ともFPGAと接続されていることもあり、
SDカードのSDバスモード(4bit bus mode)を利用することによって、
ロード時間短縮できないかと思い立ち、実装したものです。
結果としては、4MBのデータロードに7秒かかっていたものを、3秒に短縮することができました。
今回の実装ではいわゆる通常のSDカード(SDSC)のみサポートし、
SDHC、SDXCは未サポートです。
SDSCの仕様ではデフォルトスピードで12.5MB/sまでいけるようですが、
今回の実装ではシングルブロックモードのみの使用のため、
コマンドの度にビジー時間が長く1.3MB/s程度しか出ません。
マルチブロックリードを活用することでもっと速度は上げられますが、
FATファイルシステムとの兼ね合いもあり、今回はこれで我慢します。
トップモジュール
inout wire [3:0] SD_DAT, // SD Card Data
inout wire SD_CMD, // SD Card Command Signal
output wire SD_CLK, // SD Card Clock
input wire SD_WP_N, // SD Card Write Protect
wire sd_cmd_out, sd_cmd_en;
assign SD_CMD = sd_cmd_en ? sd_cmd_out : 1'bz;
接続部とテスト
//--------------------- SD_Card Interface ------------------
SDSCcard_ctrl_SDmode sdcard;
output SD_CLK; // SD Card Clock
output SD_CMD_en; // SD Card CMD Enable
output SD_CMD; // SD Card Command
input SD_RES; // SD Card Response
input SD_DAT<4>; // SD Card Data
SD_CLK = sdcard.CLK;
SD_CMD_en = sdcard.CMD_en;
SD_CMD = sdcard.CMD;
sdcard.RES = SD_RES;
sdcard.DAT = SD_DAT;
stage sdget {
if(sdcard.ack){
// MBR(第一パーティションエントリ)
// 0x1FE -> 0x55
// 0x1FF -> 0xAA
sdcard.read(0x000001FF);
finish;
}
}
SDSCcard_ctrl_SDmode.sflp
なお、Terasic DE0 FPGAボードについてもSDバスモードが使用できます。
これについては、DE0の古い回路図にはDAT1とDAT2が接続されていないように書かれているため、
使用できるかどうか噂レベルでしか聞いていなかったのですが、
DE0の新しい回路図ではちゃんとデータバスが4本とも接続されているように書かれており、
実際に基板を見ても接続されているようでした。
_ ▼ FAT16
SDカードをFAT16でフォーマットしたものをそのままFPGAで読めるようにとりあえずreadのみ実装。
6502のアセンブラで実装するという手もあったんですが、
SFLで記述した方が楽そうだったのではたしてソフトマクロでの実装となりました。
32MB〜2GBまでのFAT16にフォーマットされたSDカードをサポート。
FAT16.sflp とファイルをSDRAMに読み込むサンプル。
%i "sdram_ctrl.h"
%i "SDSCcard_ctrl_SPImode.h"
%i "FAT16.h"
circuit FAT16_test
{
output SD_CSn; // SD Card CSn
output SD_CLK; // SD Card Clock
output SD_CMD; // SD Card Command & Dout
input SD_DAT; // SD Card Data
sdram_ctrl sdram;
reg_ws reset;
SDSCcard_ctrl_SPImode sdcard;
FAT16 fat;
stage_name card2ram { task do(); }
if(reset){
generate card2ram.do();
reset := 0b0;
}
SD_CSn = sdcard.CSn;
SD_CLK = sdcard.CLK;
SD_CMD = sdcard.CMD;
sdcard.DAT = SD_DAT;
instruct fat.sread sdcard.read(fat.sadrs);
fat.sack = sdcard.ack;
fat.sdata = sdcard.rdata;
stage card2ram {
reg_wr c2rdata<8>, tA<22>;
first_state st1;
state st1 if(fat.ack){
fat.fopen(0x00); // 1つめのファイルを指定
tA := 0;
goto st2;
}
state st2 if(fat.ack){
fat.read();
goto st3;
}
state st3 if(fat.ack){
c2rdata := fat.fdata;
fat.read();
goto st4;
}
state st4 if(fat.ack & sdram.ack){
sdram.write(tA, fat.fdata||c2rdata);
tA++;
if(fat.eof) finish;
else goto st2;
}
}
}
今後何かSDカードを使ってログを取るようなことが必要になったらwriteも実装しようかな。
_ ▼ SDHCカード (SPIモード) 2024/02/03
もはや2GB以下のSDカードは中古での入手しかなくなり、SDHCカードが容易に購入できるようになったので、
扱っているプロジェクトでもSDHCカードを使用できるようにコントローラを実装。
SDHCcard_ctrl_SPImode.sflp
_ ▼ SDHCカード (SDモード) 2024/02/18
SDHCカードもSDバスモードを実装。
SPIモードに比べて読み込み速度は1.6倍になった。
SDHCcard_ctrl_SDmode.sflp
_ ▼ FAT32 2024/02/03
SDHCをフォーマットするとFAT32となるので、FAT16に続きFAT32も実装。
4GB〜32GBまでのFAT32にフォーマットされたSDHCカードをサポート。
これで容易にSDHCカード経由でファイルをやり取りできるようになった。
ファイルサイズ4MBでのSDカードでのリードが10secだったのに対し、
SDHCカードのSPIモードでのリードは5sec、SDモードでのリードは3secと、
読み込み時間を半分以下にできた。
FAT32.sflp
_ ▼ 参考
・SD Simplified Specifications
・MMC/SDCの使いかた
・AVR工作室 MMCの実験
・SDカード
・SDカードのSPIモードの初期化に関する諸々
・FATファイルシステムのしくみと操作法
・FAT FS フォーマットの実装についての覚え書き
・FAT32ファイルシステム読解
・PIC16F1シリーズを使ってSDカードを制御する2 書き込み・読み込み
・PIC16F18346でSDHCカードを使ってみた (MCC不使用)
・RX マイコン SDHI を使った SD モードドライバー
・SDカードを使ってみよう
・PICを使ってSDカードを操作
・SDカードから1セクタ読み取るまでの手順解説−WentWayUp
・SH7144でSDカードコントローラを試作
Copyright(C) pgate1 All Rights Reserved.
|