マイコン独立大作戦
SDカードインターフェースの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
WindowsパソコンにUSB接続して使う現行方式はそれなりに便利ではありますが、ときとしてWindows
のしがらみから開放されて、小さいながらも独立した一個のパソコンとして機能したいと思うこともあります。
独立大作戦の作戦その1はCRTインターフェースボードの製作です。
作戦その2はキーボードインターフェースです。
そして作戦その3は、SDカードインターフェースです。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第28回]
●SDHCカード初期化+セクタREADプログラム
SDHCカード初期化+セクタREADプログラムは[第22回]でお見せしましたが、その後に初期化の手続き部分に手を加えました。
ですので手直し後のプログラムを下に再掲します。
基本的な部分は変わっていません。
2016/12/5 16:27 sdcdif5v.txt END=8334 ;;; SD card PCI test program ;16/10/10 10/11 10/12 10/13 10/25 10/26 10/27 10/28 10/29 10/31 ;12/4 12/5 ; ORG $8100 ; ADISP=$1015 DEDP=$1018 CRLF=$101B HDCMP=$1027 REENT=$1033 HXDP2=$104B HXDP4=$104E DMSB=$1A08 ; 8100 C30981 JP START0 8103 00 SCTN_H:DB 00 8104 00 SCTN_M:DB 00 8105 00 SCTN_L:DB 00 8106 00 SCTN_L0:DB 00 8107 00 WKCNTR:DB 00 8108 00 WKA:DB 00 8109 3E90 START0:LD A,90 810B D383 OUT (83),A ;card init 810D 2E0A LD L,0A 810F 16FF START01:LD D,FF 8111 CD8D82 CALL SOUT 8114 2D DEC L 8115 C20F81 JP NZ,START01 ;CMD0 out 8118 110D83 LD DE,CMD0T 811B CD1810 CALL DEDP 811E 3E02 LD A,02 8120 D382 OUT (82),A;CS=L 8122 0E40 LD C,40;cmd 8124 110000 LD DE,$0000 8127 210000 LD HL,$0000 812A 3E95 LD A,95;crc 812C CDC482 CALL COUT 812F CDA782 START03:CALL SIN 8132 63 LD H,E 8133 7B LD A,E 8134 F5 PUSH AF 8135 CD4B10 CALL HXDP2 8138 F1 POP AF 8139 FE01 CP 01 813B C22F81 JP NZ,START03 813E CD1B10 CALL CRLF ; ;CMD8 out 8141 111283 START04:LD DE,CMD8T 8144 CD1810 CALL DEDP 8147 0E48 LD C,48 8149 110000 LD DE,$0000 814C 21AA01 LD HL,$01AA 814F 3E87 LD A,87 8151 CDE682 CALL CMD8S 8154 CD1B10 CALL CRLF ; ;CMD58 8157 111783 LD DE,CMD58T 815A CD1810 CALL DEDP 815D 0E7A LD C,7A 815F 110000 LD DE,$0000 8162 210000 LD HL,$0000 8165 3EFF LD A,FF 8167 CDE682 CALL CMD8S ; 816A CD1B10 CMD55_0:CALL CRLF ; ;CMD55 816D 111D83 CMD55:LD DE,CMD55T 8170 CD1810 CALL DEDP 8173 0E77 LD C,77 8175 110000 LD DE,$0000 8178 210000 LD HL,$0000 817B 3EFF LD A,FF 817D CDC482 CALL COUT 8180 CDA782 CMD55_2:CALL SIN 8183 63 LD H,E 8184 7B LD A,E 8185 F5 PUSH AF 8186 CD4B10 CALL HXDP2 8189 F1 POP AF 818A FE01 CP 01 818C CA9381 JP Z,CMD55_3 818F B7 OR A 8190 C28081 JP NZ,CMD55_2 8193 CD1B10 CMD55_3:CALL CRLF ; ;ACMD41 8196 112383 LD DE,ACMD41T 8199 CD1810 CALL DEDP 819C 0E69 LD C,69 819E 11FF40 LD DE,$40FF 81A1 210080 LD HL,$8000 81A4 3EFF LD A,FF 81A6 CDC482 CALL COUT 81A9 CDA782 ACMD41_2:CALL SIN 81AC 63 LD H,E 81AD 7B LD A,E 81AE F5 PUSH AF 81AF CD4B10 CALL HXDP2 81B2 F1 POP AF 81B3 FEFF CP FF 81B5 CAA981 JP Z,ACMD41_2 81B8 B7 OR A 81B9 C26A81 JP NZ,CMD55_0 81BC CD1B10 CALL CRLF ; ;second CMD58 81BF 111783 LD DE,CMD58T 81C2 CD1810 CALL DEDP 81C5 0E7A LD C,7A 81C7 110000 LD DE,$0000 81CA 210000 LD HL,$0000 81CD 3EFF LD A,FF 81CF CDE682 CALL CMD8S 81D2 CD1B10 CALL CRLF ; ;CMD9 81D5 112A83 LD DE,CMD9T 81D8 CD1810 CALL DEDP 81DB 0E49 LD C,49 81DD 110000 LD DE,$0000 81E0 210000 LD HL,$0000 81E3 3EFF LD A,FF 81E5 CDC482 CALL COUT 81E8 CDA782 CMD9_2:CALL SIN 81EB 63 LD H,E 81EC 7B LD A,E 81ED F5 PUSH AF 81EE CD4B10 CALL HXDP2 81F1 F1 POP AF 81F2 B7 OR A 81F3 C2E881 JP NZ,CMD9_2 ; 81F6 CDA782 CMD9_3:CALL SIN 81F9 63 LD H,E 81FA 7B LD A,E 81FB F5 PUSH AF 81FC CD4B10 CALL HXDP2 81FF F1 POP AF 8200 FEFE CP FE 8202 C2F681 JP NZ,CMD9_3 8205 CD1B10 CALL CRLF 8208 0612 LD B,12;**** 820A C5 PUSH BC 820B CDA782 CMD9_4:CALL SIN 820E 63 LD H,E 820F 7B LD A,E 8210 CD4B10 CALL HXDP2 8213 C1 POP BC 8214 05 DEC B 8215 C5 PUSH BC 8216 C20B82 JP NZ,CMD9_4 8219 C1 POP BC 821A CD1B10 CALL CRLF ; ;read test 821D 112F83 RTEST0:LD DE,RTESTT 8220 CD1810 CALL DEDP 8223 210381 RTEST:LD HL,SCTN_H 8226 56 LD D,(HL) 8227 23 INC HL 8228 5E LD E,(HL) 8229 23 INC HL 822A 46 LD B,(HL) 822B 23 INC HL 822C 6E LD L,(HL) 822D 60 LD H,B 822E E5 PUSH HL 822F D5 PUSH DE 8230 0E51 LD C,51;index=11(17d) 8232 CDC482 CALL COUT ;test 8235 CDA782 RTEST2:CALL SIN 8238 63 LD H,E 8239 7B LD A,E 823A F5 PUSH AF 823B CD4B10 CALL HXDP2 823E F1 POP AF 823F FEFE CP FE;token 8241 C23582 JP NZ,RTEST2 8244 CD1B10 CALL CRLF ;data block read 8247 0610 LD B,10;=16 16x32=512 8249 210088 LD HL,$8800;*********** test 824C 0E20 RTEST3:LD C,20;=32byte 824E C5 RTEST4:PUSH BC 824F CDA782 CALL SIN ; PUSH HL ; LD H,E ; CALL HXDP2 ; POP HL 8252 73 LD (HL),E 8253 23 INC HL 8254 C1 POP BC 8255 0D DEC C 8256 C24E82 JP NZ,RTEST4 ; CALL CRLF 8259 05 DEC B 825A C24C82 JP NZ,RTEST3 825D 3E5B LD A,5B 825F CD1510 CALL ADISP 8262 E1 POP HL 8263 CD4E10 CALL HXDP4 8266 E1 POP HL 8267 CD4E10 CALL HXDP4 826A 3E5D LD A,5D 826C CD1510 CALL ADISP 826F CD1B10 CALL CRLF 8272 CDA782 CALL SIN;crc(2bytes) read 8275 210088 LD HL,$8800;*******test 8278 11FF89 LD DE,$89FF;******* 827B CD081A RTEST42:CALL DMSB 827E CD2710 CALL HDCMP 8281 CA7B82 JP Z,RTEST42 8284 DA7B82 JP C,RTEST42 8287 CD1B10 END:CALL CRLF 828A C33310 JP REENT ; ;*** SUBROUTINE *** ; ; D:out data 828D 0608 SOUT:LD B,08 828F 7A SOUT2:LD A,D 8290 2F CPL 8291 D381 OUT (81),A;data out 8293 3E01 LD A,01 8295 D383 OUT (83),A;pc0=1 out ~I_ 8297 7A LD A,D 8298 17 RLA 8299 57 LD D,A 829A 3E00 LD A,00 829C D383 OUT (83),A;pc0=0 out _I~ 829E 05 DEC B 829F C28F82 JP NZ,SOUT2 82A2 3E01 LD A,01 82A4 D383 OUT (83),A;pc0=1 out ~I_ 82A6 C9 RET ; E:in data 82A7 0608 SIN:LD B,08 82A9 3E01 SIN2:LD A,01 82AB D383 OUT (83),A;pc0=1 out ~I_ 82AD 00 NOP 82AE 00 NOP 82AF 00 NOP 82B0 3E00 LD A,00 82B2 D383 OUT (83),A;pc0=0 out _I~ 82B4 DB80 IN A,(80) 82B6 2F CPL 82B7 1F RRA 82B8 7B LD A,E 82B9 17 RLA 82BA 5F LD E,A;data in 82BB 05 DEC B 82BC C2A982 JP NZ,SIN2 82BF 3E01 LD A,01 82C1 D383 OUT (83),A;pc0=1 out ~I_ 82C3 C9 RET ; ; CMD out ;C cmd ;D,E,H,L argument ;A crc7+stopbit 82C4 D5 COUT:PUSH DE 82C5 320881 LD (WKA),A 82C8 51 LD D,C 82C9 CD8D82 CALL SOUT;cmd out 82CC D1 POP DE 82CD D5 PUSH DE 82CE CD8D82 CALL SOUT;D out 82D1 53 LD D,E 82D2 CD8D82 CALL SOUT;E out 82D5 54 LD D,H 82D6 CD8D82 CALL SOUT;H out 82D9 55 LD D,L 82DA CD8D82 CALL SOUT;L out 82DD 3A0881 LD A,(WKA) 82E0 57 LD D,A 82E1 CD8D82 CALL SOUT;crc7+stop bit out 82E4 D1 POP DE 82E5 C9 RET ; 82E6 CDC482 CMD8S:CALL COUT 82E9 CDA782 CMD8S2:CALL SIN 82EC 63 LD H,E 82ED 7B LD A,E 82EE F5 PUSH AF 82EF CD4B10 CALL HXDP2 82F2 F1 POP AF 82F3 FEFF CP FF 82F5 CAE982 JP Z,CMD8S2 82F8 F5 PUSH AF 82F9 0E04 LD C,04 82FB C5 PUSH BC 82FC CDA782 CMD8S3:CALL SIN 82FF 63 LD H,E 8300 7B LD A,E 8301 CD4B10 CALL HXDP2 8304 C1 POP BC 8305 0D DEC C 8306 C5 PUSH BC 8307 C2FC82 JP NZ,CMD8S3 830A C1 POP BC 830B F1 POP AF 830C C9 RET ; 830D 434D4430 CMD0T:"CMD0" 8311 0D DB 0D 8312 434D4438 CMD8T:"CMD8" 8316 0D DB 0D 8317 434D4435 CMD58T:"CMD5" 831B 38 "8" 831C 0D DB 0D 831D 434D4435 CMD55T:"CMD5" 8321 35 "5" 8322 0D DB 0D 8323 41434D44 ACMD41T:"ACMD" 8327 3431 "41" 8329 0D DB 0D 832A 434D4439 CMD9T:"CMD9" 832E 0D DB 0D 832F 52544553 RTESTT:"RTES" 8333 54 "T" 8334 0D DB 0D ; ;END ACMD41T =8323 ACMD41_2 =81A9 ADISP =1015 CMD0T =830D CMD55 =816D CMD55T =831D CMD55_0 =816A CMD55_2 =8180 CMD55_3 =8193 CMD58T =8317 CMD8S =82E6 CMD8S2 =82E9 CMD8S3 =82FC CMD8T =8312 CMD9T =832A CMD9_2 =81E8 CMD9_3 =81F6 CMD9_4 =820B COUT =82C4 CRLF =101B DEDP =1018 DMSB =1A08 END =8287 HDCMP =1027 HXDP2 =104B HXDP4 =104E REENT =1033 RTEST =8223 RTEST0 =821D RTEST2 =8235 RTEST3 =824C RTEST4 =824E RTEST42 =827B RTESTT =832F SCTN_H =8103 SCTN_L =8105 SCTN_L0 =8106 SCTN_M =8104 SIN =82A7 SIN2 =82A9 SOUT =828D SOUT2 =828F START0 =8109 START01 =810F START03 =812F START04 =8141 WKA =8108 WKCNTR =8107 |
シリアルデータOUT、データIN、コマンドOUTの各サブルーチンは2GBまでのSDカードプログラムと同じです(2GBまでのSDカードプログラムは[第12回]を参照してください)。
コマンドの送出とレスポンスの処理のパターンが同じ部分をサブルーチン化しました。
CMD8Sです。
初期化の最初のCMD0の送出のところまでは2GB以下のSDカードプログラムと同じですが、そのあとCMD1を送る代わりにCMD8を送ります。
初期化の簡単なフローチャートが[第23回]にありますから、そちらも参考にしてください。
●セクタREAD
上記プログラムは初期化のあとにセクタREADを行ないます。
基本的には2GBまでのプログラムと変わりません。
どちらもCMD17を使います。
コマンドは同じなのですが引数の単位が変わっています。
プログラムの先頭部分を比較してください。
[第12回]のSDカードプログラムではプログラム先頭のアドレス置数部が3バイトですが、今回のプログラムでは4バイトになっています。
スタンダードのSDカードのCMD17の引数で指定する読み出し開始アドレスの単位はバイトです。
過去からの色々があってこうなっているのだとは思いますが、無駄な設定だと思います。
バイト単位なので、それなら12345678なんて数も指定できるかというと、これはエラーになってしまいます。
単位はバイトなのですが、指定できるアドレスはセクタの先頭アドレスに限られます。
1セクタは512バイトなので、16進数に直すと200Hです。
つまり4バイト(32ビット)の下位9ビットは常に0ということになります。
さらにいいますと、セクタの先頭アドレスの上位3バイトはセクタb左に1ビットシフトした値に一致します。
ですからスタンダードのSDカードプログラムでは、先頭で3バイトのセクタb置数するようにして、CMD17を送出する段階でその3バイトの値を左に1ビットしたあと下位9ビットを0にして、それを引数にしているのです。
スタンダードのSDカードのセクタアドレス指定はそういうルールですから、指定できる最大アドレスはFFFFFE00になります。
10進数に直すと4294966784です。
約4GBです。
つまりスタンダードのSDカードのルール(Ver.1)では4GB以上のカードは扱えないことになります(実際は2GBまでのカードがスタンダードのSDカードのようです)。
そこでSDHCカードのためのルール(Ver.2)が作られたのでありましょう。
●Ver.2のCMD17
Ver.1とVer.2のCMD17は見かけ上は同じです。
しかし上で書いたように、引数の単位が違います。
Ver.1ではバイト単位(しかし実際にはセクタ単位のアドレス指定しかできない)ですが、Ver.2ではセクタnw定に変わりました。
うむ。
そうするべきでありましょう。
これですっきりしました。
CMD17の引数を指定するところでスタンダードのSDカード用プログラムではセクタb開始アドレスに換算するために、置数を左シフトして下位9ビットを0にしました。
その左シフトが不要になったので、SDHCカード用のプログラムでは、置数(セクタaj4バイトをそのままCMD17の引数として与えています。
そのようにルールを変更したおかげで、同じ32ビットの引数でありながら、扱えるカード容量は4GB×512≒2TB(テラバイト)と飛躍的に増大しました。
ただしSDHCカードは32GBまでです。
それを越えるサイズのカードはSDXCカードになります。
下は「Physical Layer Simplified Specification」からの引用です。
最新版(2016年12月現在)のV5.00です。
[出典]SD Card Association:Physical Layer Simplified Specification Version 5.00
それではSDXCカードでもSPIモードが使えるのか、ということなのですが。
どうやら使えるようではあります。
[出典]SD Card Association:Physical Layer Simplified Specification Version 5.00
下線部を読んで、一瞬「あれ?SDXCではSPIモードは使えないのか?」と思いましたが、落ち着いてよくよく読み直してみましたら、使えることは使えるようです。
「ただしVer.2以後に追加されたSDコマンドはSPIモードではサポートされませんよ」という但し書きのようです。
「使えるだろうけれど、パフォーマンスが悪いからSPIモードは使うべきではない」とのご託宣であります。
それはそうでしょうけれど、たっぷり年会費とロイヤリティを払わなければならないわけでありますから、たかが8ビットのシステムとしては、それはできない相談なのであります。
「身の丈に合った」という言葉がありますように、8ビットのCPUでクロックもせいぜい20MHzが精一杯なのですから、パフォーマンスなど、はなから計算外なのであります。
●セクタbO(MBR)
さてそれではいよいよSDHCカードの中身の解析にかかることにします。
もうすでに何回かお見せしていますが、下がSDHCカード(8GB)のセクタbOです。
カード先頭のセクタbOはMBR(Master Boot Record)です。
そのカードの最も基本的なファクタが書かれています。
[00000000] 8800 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8810 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8820 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8830 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8840 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8850 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8860 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8870 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8880 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8890 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 88A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 88B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 88C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 88D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 88E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 88F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8900 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8910 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8920 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8930 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8940 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8950 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8960 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8970 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8980 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 8990 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 89A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 89B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 82 ................ 89C0 03 00 0B 19 D1 C8 00 20-00 00 00 30 ED 00 00 00 ....ムネ. ...0.... 89D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 89E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 89F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............Uェ |
セクタbOの構成はスタンダードのSDカードと同じようです([第11回]参照)。
一番最後の2バイトは55AAです。
これはFATファイルの識別情報です。
ここに55AAがないと、このディスクは正しいFATファイルディスクとして認識されません。
その2バイトよりも前の64バイトが16バイトずつ4つのブロックに区切られていて、最大4個のパーティションブロックの情報が入れられます。
セクタREADプログラムは解析の便を考えて、読み込んだ1セクタ分のデータをND80Z3.5のアドレス8800〜89FFに置いています。
64バイトのパーティションブロック情報はアドレス89BE〜89FDにあります。
これを見ると、最初のブロックのみデータがありますが、そのあとの3ブロックにはデータがありません。
このSDHCカードはパーティションが1つだけであることがわかります。
パーティションブロックの16バイトの解析です。
16バイトの情報は先頭から下のように区切られています。
1バイト 00 ブート情報 80:ブート可 00:ブート不可
3バイト 820300 開始ヘッド、セクタ、シリンダ情報(古い表示方法です。現在は利用されません)
1バイト 0B FAT種別 0B:FAT32
3バイト 19D1C8 終了ヘッド、セクタ、シリンダ情報(古い表示方法です。現在は利用されません)
4バイト 00200000 パーティションの開始セクタ
4バイト 0030ED00 パーティションのセクタ数
最後にセクタ数があります。
格納されているデータ順はリトルエンディアンなので、通常の表現で示すと 00 ED 30 00 になります。
これを10進数に直すと15544320です。
1セクタは512バイトですから、512を掛ける代わりに2で割るとKBが求まります。
15544320/2≒7772160(KB)≒7.8(GB)
ということはSDHCカード(8GB)全部ををひとつのパーティションだけで使っている計算になります。
SDカードインターフェースの製作[第28回]
2016.12.8upload
前へ
次へ
ホームページトップへ戻る