マイコン独立大作戦
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
前へ
次へ
ホームページトップへ戻る