マイコン独立大作戦
SDカードインターフェースの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
WindowsパソコンにUSB接続して使う現行方式はそれなりに便利ではありますが、ときとしてWindows
のしがらみから開放されて、小さいながらも独立した一個のパソコンとして機能したいと思うこともあります。
独立大作戦の作戦その1はCRTインターフェースボードの製作です。
作戦その2はキーボードインターフェースです。
そして作戦その3は、SDカードインターフェースです。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第10回]
●セクタREADプログラム
いよいよセクタREADです。
SDカードは512バイトのセクタで構成されています。
READ/WRITEはセクタ単位で行ないます。
今回は前回のプログラムに追加変更を行なって、セクタアドレスを指定して1セクタ512バイトを読んで16進数で表示できるようにします。
下がそのように追加変更を行なったプログラムのアセンブルリストです。
2016/10/25 13:43 sdcdif2q.txt
END=81F6
;;; SD card PCI test program
;16.10.10 10.11 10.12 10.13 10.25
;
ORG $8100
;
CRLF=$101B
REENT=$1033
HXDP2=$104B
;
8100 3E90 START0:LD A,90
8102 D383 OUT (83),A
;card init
8104 2E0A LD L,0A
8106 16FF START01:LD D,FF
8108 CDA381 CALL SOUT
810B 2D DEC L
810C C20681 JP NZ,START01
;CMD0 out
810F 3E02 LD A,02
8111 D382 OUT (82),A;CS=L
8113 1640 LD D,40
8115 CDA381 CALL SOUT
8118 0604 LD B,04
811A C5 START02:PUSH BC
811B 1600 LD D,00
811D CDA381 CALL SOUT
8120 C1 POP BC
8121 05 DEC B
8122 C21A81 JP NZ,START02
8125 1695 LD D,95
8127 CDA381 CALL SOUT
812A CDBD81 START03:CALL SIN
812D 63 LD H,E
812E 7B LD A,E
812F F5 PUSH AF
8130 CD4B10 CALL HXDP2
8133 F1 POP AF
8134 FE01 CP 01
8136 C22A81 JP NZ,START03
;
;CMD1 out
8139 0E41 START07:LD C,41
813B 110000 LD DE,$0000
813E 210000 LD HL,$0000
8141 CDDA81 CALL COUT
8144 CDBD81 START09:CALL SIN
8147 63 LD H,E
8148 7B LD A,E
8149 F5 PUSH AF
814A CD4B10 CALL HXDP2
814D F1 POP AF
814E B7 OR A;00?
814F CA5A81 JP Z,RTEST
8152 FE01 CP 01
8154 C24481 JP NZ,START09
8157 C33981 JP START07
;read test
815A 0E51 RTEST:LD C,51;index=11(17d)
815C 110000 LD DE,$0000;adrs=00000000
815F 210000 LD HL,$0000
8162 CDDA81 CALL COUT
;test
8165 CDBD81 RTEST2:CALL SIN
8168 63 LD H,E
8169 7B LD A,E
816A F5 PUSH AF
816B CD4B10 CALL HXDP2
816E F1 POP AF
816F FEFE CP FE;token
8171 C26581 JP NZ,RTEST2
8174 CD1B10 CALL CRLF
;data block read
8177 0610 LD B,10;=16 16x32=512
8179 0E20 RTEST3:LD C,20;=32byte
817B C5 RTEST4:PUSH BC
817C CDBD81 CALL SIN
817F 63 LD H,E
8180 CD4B10 CALL HXDP2
8183 C1 POP BC
8184 0D DEC C
8185 C27B81 JP NZ,RTEST4
8188 CD1B10 CALL CRLF
818B 05 DEC B
818C C27981 JP NZ,RTEST3
818F CDBD81 CALL SIN;crc(2bytes) read
8192 63 LD H,E
8193 CD4B10 CALL HXDP2
8196 CDBD81 CALL SIN
8199 63 LD H,E
819A CD4B10 CALL HXDP2
819D CD1B10 END:CALL CRLF
81A0 C33310 JP REENT
;
; D:out data
81A3 0608 SOUT:LD B,08
81A5 7A SOUT2:LD A,D
81A6 2F CPL
81A7 D381 OUT (81),A;data out
81A9 3E01 LD A,01
81AB D383 OUT (83),A;pc0=1 out ~I_
81AD 7A LD A,D
81AE 17 RLA
81AF 57 LD D,A
81B0 3E00 LD A,00
81B2 D383 OUT (83),A;pc0=0 out _I~
81B4 05 DEC B
81B5 C2A581 JP NZ,SOUT2
81B8 3E01 LD A,01
81BA D383 OUT (83),A;pc0=1 out ~I_
81BC C9 RET
; E:in data
81BD 0608 SIN:LD B,08
81BF 3E01 SIN2:LD A,01
81C1 D383 OUT (83),A;pc0=1 out ~I_
81C3 00 NOP
81C4 00 NOP
81C5 00 NOP
81C6 3E00 LD A,00
81C8 D383 OUT (83),A;pc0=0 out _I~
81CA DB80 IN A,(80)
81CC 2F CPL
81CD 1F RRA
81CE 7B LD A,E
81CF 17 RLA
81D0 5F LD E,A;data in
81D1 05 DEC B
81D2 C2BF81 JP NZ,SIN2
81D5 3E01 LD A,01
81D7 D383 OUT (83),A;pc0=1 out ~I_
81D9 C9 RET
; CMD out
;C cmd
;D,E,H,L argument
81DA D5 COUT:PUSH DE
81DB 51 LD D,C
81DC CDA381 CALL SOUT;cmd out
81DF D1 POP DE
81E0 D5 PUSH DE
81E1 CDA381 CALL SOUT;D out
81E4 53 LD D,E
81E5 CDA381 CALL SOUT;E out
81E8 54 LD D,H
81E9 CDA381 CALL SOUT;H out
81EC 55 LD D,L
81ED CDA381 CALL SOUT;L out
81F0 16FF LD D,FF
81F2 CDA381 CALL SOUT;crc(dummy)+stop bit out
81F5 D1 POP DE
81F6 C9 RET
;
;END
COUT =81DA CRLF =101B END =819D
HXDP2 =104B REENT =1033 RTEST =815A
RTEST2 =8165 RTEST3 =8179 RTEST4 =817B
SIN =81BD SIN2 =81BF SOUT =81A3
SOUT2 =81A5 START0 =8100 START01 =8106
START02 =811A START03 =812A START07 =8139
START09 =8144
|
前回のプログラムではSDカードにアクセスするのにSINOUTサブルーチンを使いました。
SPIモードのルールに忠実なプログラムのサンプルというつもりで作りましたから、データ出力とデータ入力を同時に行なうようになっていました。
しかし実際の動作では出力(送信)と入力(受信)を同時に行なうことはまず無いのではと思います。
そこで今回は出力(送信)サブルーチンと入力(受信)サブルーチンに分けました。
またコマンド送信は6バイトの固定長なので、コマンド送信のためにコマンド送信サブルーチンを作りました。
上の全体のプログラムリストから、送信サブルーチンのみを取り出して下に示します。
;
; D:out data
81A3 0608 SOUT:LD B,08
81A5 7A SOUT2:LD A,D
81A6 2F CPL
81A7 D381 OUT (81),A;data out
81A9 3E01 LD A,01
81AB D383 OUT (83),A;pc0=1 out ~I_
81AD 7A LD A,D
81AE 17 RLA
81AF 57 LD D,A
81B0 3E00 LD A,00
81B2 D383 OUT (83),A;pc0=0 out _I~
81B4 05 DEC B
81B5 C2A581 JP NZ,SOUT2
81B8 3E01 LD A,01
81BA D383 OUT (83),A;pc0=1 out ~I_
81BC C9 RET
|
前回のSINOUTサブルーチンから入力(受信)部分を外しました。
下は受信サブルーチンです。
; E:in data 81BD 0608 SIN:LD B,08 81BF 3E01 SIN2:LD A,01 81C1 D383 OUT (83),A;pc0=1 out ~I_ 81C3 00 NOP 81C4 00 NOP 81C5 00 NOP 81C6 3E00 LD A,00 81C8 D383 OUT (83),A;pc0=0 out _I~ 81CA DB80 IN A,(80) 81CC 2F CPL 81CD 1F RRA 81CE 7B LD A,E 81CF 17 RLA 81D0 5F LD E,A;data in 81D1 05 DEC B 81D2 C2BF81 JP NZ,SIN2 81D5 3E01 LD A,01 81D7 D383 OUT (83),A;pc0=1 out ~I_ 81D9 C9 RET |
こちらは前回のSINOUTサブルーチンから送信部分を外したものです。
送信データがなくて大丈夫かと思われるかもしれませんが、大丈夫です。
送信データの終わりは必ずストップビット(1)で終りますから、データを何も送らないときは、実はそのままの状態(連続した1、つまりFF)を送っていることになります。
下は今回新たに作ったコマンド送信サブルーチンです。
; CMD out
;C cmd
;D,E,H,L argument
81DA D5 COUT:PUSH DE
81DB 51 LD D,C
81DC CDA381 CALL SOUT;cmd out
81DF D1 POP DE
81E0 D5 PUSH DE
81E1 CDA381 CALL SOUT;D out
81E4 53 LD D,E
81E5 CDA381 CALL SOUT;E out
81E8 54 LD D,H
81E9 CDA381 CALL SOUT;H out
81EC 55 LD D,L
81ED CDA381 CALL SOUT;L out
81F0 16FF LD D,FF
81F2 CDA381 CALL SOUT;crc(dummy)+stop bit out
81F5 D1 POP DE
81F6 C9 RET
|
Cレジスタにコマンド、D、E、H、Lレジスタにアーギュメント(引数)を入れてコールします。
CMD0以外はCRCはダミーで構いませんからFFを送ります。
メインプログラムのうち、最初のCMD0とCMD1を実行する部分は、前回のプログラムと同じですから、説明を省略します。
下は今回追加したセクタREADプログラムです。
;read test
815A 0E51 RTEST:LD C,51;index=11(17d)
815C 110000 LD DE,$0000;adrs=00000000
815F 210000 LD HL,$0000
8162 CDDA81 CALL COUT
;test
8165 CDBD81 RTEST2:CALL SIN
8168 63 LD H,E
8169 7B LD A,E
816A F5 PUSH AF
816B CD4B10 CALL HXDP2
816E F1 POP AF
816F FEFE CP FE;token
8171 C26581 JP NZ,RTEST2
8174 CD1B10 CALL CRLF
;data block read
8177 0610 LD B,10;=16 16x32=512
8179 0E20 RTEST3:LD C,20;=32byte
817B C5 RTEST4:PUSH BC
817C CDBD81 CALL SIN
817F 63 LD H,E
8180 CD4B10 CALL HXDP2
8183 C1 POP BC
8184 0D DEC C
8185 C27B81 JP NZ,RTEST4
8188 CD1B10 CALL CRLF
818B 05 DEC B
818C C27981 JP NZ,RTEST3
818F CDBD81 CALL SIN;crc(2bytes) read
8192 63 LD H,E
8193 CD4B10 CALL HXDP2
8196 CDBD81 CALL SIN
8199 63 LD H,E
819A CD4B10 CALL HXDP2
819D CD1B10 END:CALL CRLF
81A0 C33310 JP REENT
;
|
セクタREADコマンドはCMD17です。
17は10進数ですから16進数では11Hです。
01XXXXXXのXのところが11(010001)ですから、コマンド部分は01010001(51H)になります。
今回はテストとして最初のセクタ(セクタbO)を読み出しますから、引数部分は00 00 00 00になります。
セクタREADコマンドを送ったあとはトークン(FE)が送られてくるのを待ちます。
テストですから、トークンが送られてくるまで、受信データを16進数2桁で画面に表示します。
トークンを受信すると、そのあとはセクタデータが512バイト連続して送られてきますから、それを1バイトごとに16進数2桁で画面に表示します。
最後にCRC2桁が送られてきます。
CRCは処理としては不要ですがこれもテストですからそのまま16進数で表示します。
●プログラムの実行
セクタREADプログラムsdcdif2q.binをND80Z3.5で実行しました。
logfile nd80zlog\11031046.txt open ND80ZVに接続しました 0001 0000 - z 1000 00C3 - *** nd80z3 basic **** ndwr2h.bin loaded,from E23F to E535 >/ld sdcdif2q.bin,8100 loading SDCDIF2Q.BIN ...00f7(247)bytes loaded,from 8100 to 81F6 >jp 8100 FF01FF01FF00FF00FFFFFE 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000201511256B0000000000000000000002 0E000614D4B48B00000075573A00000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000055AA A3DB >/exit 0000 00C3 - リモート接続を終了しました logfile closed at Thu Nov 03 10:46:58 2016 |
SDカードのセクタbOが読めました。
これからいよいよセクタbOの内容を解読して、FAT16の構造にせまります。
SDカードインターフェースの製作[第10回]
2016.11.5upload
前へ
次へ
ホームページトップへ戻る