前回のソフトでSDCARD初期化の第一段階、cmd0コマンドによるソフトウェアリセットが完了しました。
続いてSDCARDの第二段階の初期化を続けます。
まずは、cmd8( インターフェイスコンデション確認)を投げます。
SDHC及びVer2以上のSDカードには必衰です。
正常に認識すると、01000001AAの返答があります。
続いて、 cmd55( アプリケーション特化コマンド)を投げ、次のコマンドが アプリケーションコマンド であることを告げます。
続いて、cmd41( 初期化開始アプリケーションコマンド )で、SDCARD内部の初期化プロセスの実行を開始します。
cmd55、cmd41の組み合わせで、返り値が00になるまで繰り返し投げます。
戻り値00が帰ってきたら、SDCARDの初期化は終了です。
続いて、SDCARDの種類判別のために、cmd58を投げます。
cmd58コマンドのレスポンスの30bit目と31bit目に注目します。
30bit目 0:SDVer2 1:SDHC
31bit目 0:初期化未完了 1:初期化完了
したがって、31bit目が”1”の時(初期化が完了)に30bit目が”0”の時はSDver2、”1”の時はSDHCとなるはずです。
実際にコマンドを投げた時のターミナルの返答は次のようになりました。
手持ちの2GBのSD-CARD(TOSHIBA SD-S02G)の場合
CMD58:0080FF8000 31-28bitが”8”なので ”1000” 31bit=1 30bit=0です。
手持ちの4GBのSDHCの場合
CMD58:00C0FF8000 31-28bitが”C”なので ”1100” 31bit=1 30bit=1
となりました。
実際のコマンドを投げた状態のモニタは次のようになります。
lコマンドで読み込んだ後、cコマンドでa000をコールします。
プログラム中ではモニタのサブプログラムをコールしているので、モニタのバージョン(Ver0.71)に依存します。
>c a000 y:
CMD0:01
CMD8:01000001AA
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:01
CMD55:01
ACMD41:00
CMD58:0080FF8000
>
実際のプログラムは次のようになります。(ちょっと長いです)
;; TMPZ84C015 SPI (Parallel port) test (port A)
;;
;;
;; i/o address
;; PIOAD i/o 0x1C(r/w)
;; PIOAC i/o 0x1D(w)
;; PIOBD i/o 0x1E(r/w)
;; PIOBC i/o 0x1F(w)
;;
;;
;; assembler
;; program a000H
;; data a000H
;; assemblers ASxxxx and ASlink V5.10
;; tmpz84c015_spi_sdcard03.asm
;; $ asz80 -l -s -o tmpz84c015_spi_sdcard03.asm
;; $ aslink -i tmpz84c015_spi_sdcard03
;; $ monitor v.71 l command loedding ihx files at c(call) command a000
.z80
PIOAD .equ 0x1c ;PIO-A CH DATA REG
PIOAC .equ 0x1d ;PIO-A CH CONTL REG
;OUTPUT-PORT
S_DI .equ 7 ;0b10000000 D7
S_CS .equ 6 ;0b01000000 D6
S_CLK .equ 5 ;0b00100000 D5
;INPUT-PORT
DO .equ 0 ;0b00000001 D0
hex_a_disp .equ 0x0318 ;monitor v.71
putchar .equ 0x0364 ;monitor v.71
msgout .equ 0x0351 ;monitor v.71
.area TEST (ABS)
.org 0xa000
;; main program
main:
call pioainit
call init_spi
ret
pioainit:
ld b,3
ld hl,PIO_init_data
pioainit01:
ld a,(HL)
out (PIOAC),a
inc hl
djnz pioainit01
ret
init_spi:
push af
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out (PIOAD),a
ld b,80 ;80 clok output
call loopspii
pop af
xor a
out (PIOAD),a ;CS="L" DI="L" CLK="L"
call cmd0_out
cp 0x01
jp nz,init_err
call cmd8_out
cp 0x01
jp nz,init_err
call cmd55_out
cp 0x01
jp nz,init_err
call acmd41_out
call cmd58_out
ret
cmd0_out:
ld hl,cmd0
call cmd_out
call r1_resp
push af
ld hl,cmd0_msg
call msgout
pop af
push af
call hex_a_disp
ld a,0x0d
call putchar
pop af
ret
cmd0_msg:
.str "CMD0:"
.db 0x00
cmd8_out:
call dummy_data
ld hl,cmd8
call cmd_out
call r1_resp
cp 0x01
ret nz
ld b,4
ld hl,r7
cmd8_r:
call resp
ld (hl),a
inc hl
djnz cmd8_r
cmd8_r_d:
ld hl,cmd8_msg
call msgout
ld a,0x01
call hex_a_disp
ld hl,r7
ld b,4
cmd8_r_d_loop:
ld a,(hl)
call hex_a_disp
inc hl
djnz cmd8_r_d_loop
ld a,0x0d
call putchar
ld a,0x01
ret
cmd8_msg:
.str "CMD8:"
.db 0x00
call cmd58_out
cmd55_out:
call dummy_data
ld hl,cmd55
call cmd_out
call r1_resp
push af
ld hl,cmd55_msg
call msgout
pop af
push af
call hex_a_disp
ld a,0x0d
call putchar
pop af
ret
cmd55_msg:
.str "CMD55:"
.db 0x00
acmd41_out:
call dummy_data
ld hl,acmd41 ;sd-card Initialize
call cmd_out
;acmd41_loop:
call r1_resp
cp 0x00
push af
ld hl,acmd41_msg
call msgout
pop af
push af
call hex_a_disp
ld a,0x0d
call putchar
pop af
ret z
call cmd55_out
jr acmd41_out
init_err:
halt
cmd58_out:
call dummy_data
ld hl,cmd58
call cmd_out
call r1_resp
push af
ld b,4
ld hl,r7
cmd58_r:
call resp
ld (hl),a
inc hl
djnz cmd58_r
cmd58_r_d:
ld hl,cmd58_msg
call msgout
pop af
push af
call hex_a_disp
ld hl,r7
ld b,4
cmd58_r_d_loop:
ld a,(hl)
call hex_a_disp
inc hl
djnz cmd58_r_d_loop
ld a,0x0d
call putchar
pop af
ret
dummy_data:
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out (PIOAD),a
ld b,8 ;1clok output
call loopspii
xor a
out (PIOAD),a
ret
loopspii:
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
nop
nop
nop
nop
nop
djnz loopspii
ret
r1_resp:
call resp
cp 0xff
jr z,r1_resp
ret
resp:
ld d,0xff
call spi_8bit
ld a,e
ret
cmd_out: ;command out
push hl
push bc
ld b,0x06 ;command line word count
cmd_out1:
ld d,(hl) ;command line area
call spi_8bit
inc hl
djnz cmd_out1
pop bc
pop hl
ret
spi_8bit: ;outdata Dreg,inputdata Ereg
push bc
ld c,0x00
ld b,0x08
loopspi:
xor a
rlc d
rra
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
in a,(PIOAD)
rrca
rl e
djnz loopspi
xor a
out (PIOAD),a
pop bc
ret
PIO_init_data:
.db 0b11001111 ;PIOAC:set 0xcf: Mode3 (bit mode)
.db 0b00011111 ;PIOAC:set 0x1f: D4-D0=input D7-D5=output
.db 0b00000000 ;PIOAC:set 0x00: interrupt disables
acmd41_msg:
.str "ACMD41:"
.db 0x00
cmd58_msg:
.str "CMD58:"
.db 0x00
cmd0: ;;48bit(6byte) Fixed length
.db 0x40 ;;command index
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x95 ;;CRC
;cmd1:
; .db 0x41 ;;command init
; .db 0x00
; .db 0x00
; .db 0x00
; .db 0x00
; .db 0xf9 ;;CRC
cmd8:
.db 0x48
.db 0x00
.db 0x00
.db 0x01
.db 0xaa
.db 0x87
acmd41:
.db 0x69
.db 0x40
.db 0xff
.db 0x80
.db 0x00
.db 0xff
cmd58:
.db 0x7a
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
cmd55:
.db 0x77
.db 0x00
.db 0x00
.db 0x00
.db 0x00
.db 0xff
cmd16:
.db 0x50
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
cmd17:
.db 0x51
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
cmd24:
.db 0x58
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
r7:
.ds 4
.end