2016.12.8
前へ
次へ
ホームページトップへ戻る

マイコン独立大作戦
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

前へ
次へ
ホームページトップへ戻る