Update SD version and start working on DMA

This commit is contained in:
Byron Lathi
2024-07-21 18:58:35 -07:00
parent abb1668f14
commit 90c5c0dc94
5 changed files with 146 additions and 14 deletions

View File

@@ -9,6 +9,7 @@ INCLUDE=include/sdram_controller_define.vh
TB_NAME=sim_top
COPY_FILES=addr_map.mem init_hex.mem
SD_IMAGE=sd_image.bin
FLAGS=-DSIM -DRTL_SIM -DVERILATOR -DSDIO_AXI
@@ -17,9 +18,12 @@ all: waves
waves: $(TB_NAME)
./$(TB_NAME) -fst
$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES)
$(TB_NAME): $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) $(COPY_FILES) $(SD_IMAGE)
iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INCLUDE) $(SUPER6502_FPGA_SOURCES) $(SIM_SOURCES) -I ../../
$(SD_IMAGE):
dd if=/dev/urandom bs=1 count=65536 of=$(SD_IMAGE)
# I feel like this should also realize that the outside files are newer...
.PHONY: $(COPY_FILES)
$(COPY_FILES): ../../$@

View File

@@ -180,7 +180,8 @@ IOBUF dat_buf (
);
mdl_sdio #(
.LGMEMSZ(16)
.LGMEMSZ(16),
.MEMFILE("sd_image.bin")
) u_sd_card_emu (
.sd_clk(o_sd_clk),
.sd_cmd(w_sd_cmd),

View File

@@ -1,6 +1,7 @@
MEMORY
{
RAM: start = $0000, size = $200;
SDRAM: start = $200, size = $de00;
ROM: start = $F000, size = $1000, file = %O;
}

View File

@@ -16,7 +16,7 @@ SD_CMD = SD_CONTROLLER
SD_ARG = SD_CONTROLLER + $4
SD_DATA = SD_ARG
SD_FIFO_0 = SD_CONTROLLER + $8
SD_FIFO_2 = SD_CONTROLLER + $C
SD_FIFO_1 = SD_CONTROLLER + $C
SD_PHY = SD_CONTROLLER + $10
@@ -25,12 +25,12 @@ SD_PHY_CLKCTRL = SD_PHY + $1
SD_PHY_SAMP_VOLT = SD_PHY + $2
SD_PHY_BLKSIZ = SD_PHY + $3
SD_DMA_BASE = SD_CONTROLLER + $28
SD_DMA_STAT_CTRL = SD_CONTROLLER + $2C
SD_DMA_BASE = SD_CONTROLLER + $14
SD_DMA_BASE2 = SD_CONTROLLER + $18
SD_DMA_LEN = SD_CONTROLLER + $1C
SDIOCLK_100KHZ = $FC
SDIOCLK_25MHZ = $03
SPEED_512B = $09
.zeropage
@@ -102,9 +102,94 @@ _init:
lda sreg+1
bpl @acmd41
; cmd 11
; cmd 2
; cmd 3
; send_r2(2, 0x00);
stz sreg+1
stz sreg
ldx #$00
lda #$00
jsr pusheax
lda #2
jsr send_r2
lda SD_FIFO_0
lda SD_FIFO_0
lda SD_FIFO_0
lda SD_FIFO_0
; send_r1(3, 0x00);
stz sreg+1
stz sreg
ldx #$00
lda #$00
jsr pusheax
lda #3
jsr send_r1
lda #$30
sta SD_PHY_CLKCTRL
stz SD_PHY_SAMP_VOLT
lda #SPEED_512B
sta SD_PHY_BLKSIZ
lda #SDIOCLK_25MHZ
sta SD_PHY_CLKDIV
@wait_clk2: lda SD_PHY_CLKDIV
cmp #SDIOCLK_25MHZ
bne @wait_clk2
; The upper 16 bits are the RCA, but they are already in sreg
; The lower 16 are don't cares, so we can leave them.
jsr pusheax
lda #7
jsr send_r1b
; Now we need to DMA the first sector into memory, say at $1000
; The example code reads multiple, but we can probably just read 1 (cmd17)
; write to address $1000
; dma length is 1
stz SD_DMA_BASE+$3
stz SD_DMA_BASE+$2
lda #$10
sta SD_DMA_BASE+$1
stz SD_DMA_BASE
stz SD_DMA_LEN + $3
stz SD_DMA_LEN + $2
stz SD_DMA_LEN + $1
lda #$01
sta SD_DMA_LEN
; address 0
stz sreg+1
stz sreg
ldx #$00
lda #$00
jsr pusheax
lda #18
jsr send_dma
; Try reading again just to make sure it works.
stz SD_DMA_BASE+$3
stz SD_DMA_BASE+$2
lda #$12
sta SD_DMA_BASE+$1
stz SD_DMA_BASE
stz SD_DMA_LEN + $3
stz SD_DMA_LEN + $2
stz SD_DMA_LEN + $1
lda #$01
sta SD_DMA_LEN
; address 0
stz sreg+1
stz sreg
ldx #$00
lda #$02
jsr pusheax
lda #18
jsr send_dma
@end:
@@ -142,8 +227,23 @@ send_goidle:
; Arg on stack as 32 bits
; returns the response in eax
; (How can we signal a failure then?)
send_r1:
pha ; push command to stack
send_r1: stz tmp1
inc tmp1
bra send
send_r1b: stz tmp1
inc tmp1
inc tmp1
inc tmp1
bra send
send_dma: pha
lda #$20
sta tmp1
pla
bra send
send: pha ; push command to stack
jsr popeax
PHA
stx SD_ARG+$1
@@ -153,7 +253,8 @@ send_r1:
sta SD_ARG+$3
pla
sta SD_ARG ; lsb has to be the last written.
lda #$81 ; This also clears error flag (only for acmd41?)
lda #$80 ; This also clears error flag (only for acmd41?)
ora tmp1
sta SD_CMD+$1
pla
ora #$40
@@ -168,4 +269,29 @@ send_r1:
ldx SD_DATA + $1
lda SD_DATA
rts
; Command in A
; Arg on stack as 32 bits
; returns the response in eax
; (How can we signal a failure then?)
send_r2:
pha ; push command to stack
jsr popeax
PHA
stx SD_ARG+$1
lda sreg
sta SD_ARG+$2
lda sreg+1
sta SD_ARG+$3
pla
sta SD_ARG ; lsb has to be the last written.
lda #$82 ; This also clears error flag (only for acmd41?)
sta SD_CMD+$1
pla
ora #$40
sta SD_CMD
jsr wait_busy
rts