前回で回路が完成しましたので、以前作成したZ8S180用のSPIでのSDCARDのアクセスソフトについてTNPZ84C015用に修正していきたいと思います。

まずはPIOAの入出力の設定ですが、D7~D5までが出力設定、D4-D0までが入力に設定します。

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

PIOAの初期化は次のようになります。

pioainit:
	ld	b,3
	ld	hl,PIO_init_data
pioainit01:
	ld	a,(HL)
	out	(PIOAC),a
	inc	hl
	djnz	pioainit01
	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

PIOAを通じて、SDCARDに対して、クロックを送り出すソフトが必要になりますが、ハードと直接制御するプログラムは次のようになります。

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

実際のタイミングは次のようになります。
デューティー約5μS(システムクロック20MHz時)となりました。

さらにクロックに同期して、DI端子に対してデータを出力し、かつDO端子からデータを読み書きするプログラムは次のようになります。

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

こちらも波形を見るとデューティー50%になっていませんが、読み書きはできるようです。(データとして0x40を出力し、返り値として0xffが帰っています)

SDCARDの初期化としては、80パルスのクロックを出した後に、cmd0(0x40,0x00,0x00,0x00,0x00,0x95)の48bitのデータを出力し、返り値として0x01が帰ってくれば第一段階の初期化は終わりです。

main:
	call	pioainit	

	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

	xor a
	out 	(PIOAD),a 		;CS="L" DI="L" CLK="L"
cmd0_out:
	ld 	hl,cmd0
	call 	cmd_out
	call 	r1_resp
	cp 	0x01
	jr 	nz,init_err
	ret

init_err:
	halt

cmd0: 				;;48bit(6byte) Fixed length
	.db 	0x40 		;;command index
	.db 	0x00 		;;argument
	.db 	0x00 		;;argument
	.db 	0x00 		;;argument
	.db 	0x00 		;;argument
	.db 	0x95 		;;CRC

返り値(0x01)のタイミングは次のようなります。

全体的なプログラムは次のようになります。

	;;   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_sdcard01.asm
        ;; $ asz80 -l -s -o tmpz84c015_spi_sdcard01.asm
        ;; $ aslink -i tmpz84c015_spi_sdcard01
        ;; $ monitor 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




        .area TEST(ABS)

        .org    0xa000	

main:
	call	pioainit	

	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

	xor a
	out 	(PIOAD),a 		;CS="L" DI="L" CLK="L"
cmd0_out:
	ld 	hl,cmd0
	call 	cmd_out
	call 	r1_resp
	cp 	0x01
	jr 	nz,init_err
	ret

init_err:
	halt

pioainit:
	ld	b,3
	ld	hl,PIO_init_data
pioainit01:
	ld	a,(HL)
	out	(PIOAC),a
	inc	hl
	djnz	pioainit01
	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

r1_resp:
	call 	resp
	cp 	0xff
	jr 	z,r1_resp
	ret

resp:
	ld 	d,0xff
	call 	spi_8bit
	ld a,e
	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

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


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

全体的なタイミングは次のようになります。

SPI, TMPZ84C015, Z80の関連記事
  • Z80(TMPZ84C015)に萌えたい。SPI対応モニタ
  • Z80(TMPZ84C015)に萌えたい。SDCARDソフトその2
  • Z80(TMPZ84C015)に萌えたい。SDCARDソフトその1
  • Z80に萌えたい  SPI対応モニタにアップ
  • Z80に萌えたい SD-CARD まとめ
  • Z80に萌えたい SD-CARDブロックライトその2
おすすめの記事
Z80
USB-シリアル変換モジュール(AE-UM232R 秋月電子)を使用して、Z80との 通信ができるようにします。 まず、シリアル通信用のクロ...