前回のソフトで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
おすすめの記事