Browse Source

parts/z80/sdc: add sdcSetBlkSize and sdcReadBlk

pull/10/head
Virgil Dupras 5 years ago
parent
commit
54d0286486
4 changed files with 105 additions and 46 deletions
  1. +83
    -1
      parts/z80/sdc.asm
  2. +3
    -0
      recipes/rc2014/sdcard/glue.asm
  3. +2
    -0
      recipes/rc2014/sdcard/jumptable.inc
  4. +17
    -45
      recipes/rc2014/sdcard/sdinit.asm

+ 83
- 1
parts/z80/sdc.asm View File

@@ -20,6 +20,18 @@
; SDC_PORT_CSLOW: Port number to make CS low
; SDC_PORT_SPI: Port number to send/receive SPI data

; *** Consts ***
.equ SDC_BLKSIZE 512

; *** Variables ***
; Index of the sector currently contained in SDC_BUF
.equ SDC_SECTOR SDC_RAMSTART
; Whenever we read a sector, we read a whole block at once and we store it
; in memory. That's where it goes.
.equ SDC_BUF SDC_SECTOR+1
.equ SDC_RAMEND SDC_BUF+SDC_BLKSIZE

; *** Code ***
; Wake the SD card up. After power up, a SD card has to receive at least 74
; dummy clocks with CS and DI high. We send 80.
sdcWakeUp:
@@ -199,7 +211,6 @@ sdcInitialize:
or a ; cp 0
jr nz, .error
; Success! out of idle mode!
; At this point, you are ready to read and write data.
jr .success

.error:
@@ -213,3 +224,74 @@ sdcInitialize:
pop de
pop hl
ret

; Send a command to set block size to SDC_BLKSIZE to the SD card.
; Returns zero in A if a success, non-zero otherwise
sdcSetBlkSize:
push hl
push de

ld a, 0b01010000 ; CMD16
ld hl, 0
ld de, SDC_BLKSIZE
call sdcCmdR1
; Since we're out of idle mode, we expect a 0 response
; We need no further processing: A is already the correct value.
pop de
pop hl
ret

; Read block index specified in A and place the contents in (SDC_BUF).
; Doesn't check CRC.
; Returns 0 in A if success, non-zero if error.
; Returns SDC_BUF in HL
sdcReadBlk:
push bc

out (SDC_PORT_CSLOW), a
ld hl, 0 ; read single block at addr A
ld d, 0
ld e, a
ld a, 0b01010001 ; CMD17
call sdcCmd
or a ; cp 0
jr nz, .error

; Command sent, no error, now let's wait for our data response.
ld b, 20
.loop1:
call sdcWaitResp
; 0xfe is the expected data token for CMD17
cp 0xfe
jr z, .loop1end
cp 0xff
jr nz, .error
djnz .loop1
jr .error ; timeout. error out
.loop1end:
; We received our data token!
; Data packets follow immediately, we have 512 of them to read
ld bc, SDC_BLKSIZE
ld hl, SDC_BUF
.loop2:
call sdcWaitResp
ld (hl), a
cpi ; a trick to inc HL and dec BC at the same time.
; P/V indicates whether BC reached 0
jp pe, .loop2 ; BC is not zero, loop
; Read our 2 CRC bytes
call sdcWaitResp
call sdcWaitResp
; success!
xor a
jr .end
.error:
; try to preserve error code
or a ; cp 0
jr nz, .end ; already non-zero
inc a ; zero, adjust
.end:
out (SDC_PORT_CSHIGH), a
ld hl, SDC_BUF
pop bc
ret

+ 3
- 0
recipes/rc2014/sdcard/glue.asm View File

@@ -17,6 +17,8 @@ jr init
jp sdcCmd
jp sdcCmdR1
jp sdcCmdR7
jp sdcReadBlk
jp sdcSetBlkSize

; interrupt hook
.fill 0x38-$
@@ -57,6 +59,7 @@ SHELL_RAMSTART .equ BLOCKDEV_RAMEND
SHELL_EXTRA_CMD_COUNT .equ 0
#include "shell.asm"

.equ SDC_RAMSTART SHELL_RAMEND
.equ SDC_PORT_CSHIGH 6
.equ SDC_PORT_CSLOW 5
.equ SDC_PORT_SPI 4


+ 2
- 0
recipes/rc2014/sdcard/jumptable.inc View File

@@ -6,4 +6,6 @@ JUMP_SDCWAITRESP .equ 0x0e
JUMP_SDCCMD .equ 0x11
JUMP_SDCCMDR1 .equ 0x14
JUMP_SDCCMDR7 .equ 0x17
JUMP_SDCREAD .equ 0x1a
JUMP_SDCSETBLKSIZE .equ 0x1d


+ 17
- 45
recipes/rc2014/sdcard/sdinit.asm View File

@@ -5,51 +5,30 @@
or a
jp nz, .error

; Alright, normally we should configure block size and all, but this is
; too exciting and we'll play it dirty: we'll read just enough bytes
; to fetch our "Hello World!" and print it and we'll leave the SD card
; hanging. Yeah, I know, not very polite.
ld hl, sOk
call JUMP_PRINTSTR

call JUMP_SDCSETBLKSIZE
or a
jp nz, .error

out (5), a
ld hl, sCmd
ld hl, sOk
call JUMP_PRINTSTR
ld a, 0b01010001 ; CMD17
ld hl, 0 ; read single block at addr 0
ld de, 0
call JUMP_SDCCMD
cp 0
jr nz, .error

ld hl, sCmd
call JUMP_PRINTSTR
; Command sent, no error, now let's wait for our data response.
ld b, 20
.loop1:
call JUMP_SDCWAITRESP
; 0xfe is the expected data token for CMD17
cp 0xfe
jr z, .loop1end
cp 0xff
jr nz, .error
djnz .loop1
jr .error
; read sector 0
xor a
call JUMP_SDCREAD
or a
jp nz, .error

.loop1end:
ld hl, sGettingData
push hl
ld hl, sOk
call JUMP_PRINTSTR
; Data packets follow immediately
ld b, 12 ; size of "Hello World!"
ld hl, sDest ; sDest has null chars, we'll be alright
; printing it.
.loop2:
call JUMP_SDCWAITRESP
ld (hl), a
inc hl
djnz .loop2
out (6), a
ld hl, sDest
pop hl
; SDC buffer address is in HL
; YOLO! print it!
call JUMP_PRINTSTR

ret
.error:
call JUMP_PRINTHEX
@@ -57,14 +36,7 @@
call JUMP_PRINTSTR
ret

sCmd:
.db "CMD", 0xa, 0xd, 0
sGettingData:
.db "Data", 0xa, 0xd, 0
sOk:
.db "Ok", 0xa, 0xd, 0
sErr:
.db "Err", 0xa, 0xd, 0

sDest:
.fill 0x10

Loading…
Cancel
Save