Browse Source

Handle SPI w/ No Pullups

Updated SD driver to handle newer SD card adapters which omit the pullup resistors in the SD Card spec.
pull/48/head
Wayne Warthen 7 years ago
parent
commit
b85eda9649
  1. 62
      Source/HBIOS/sd.asm

62
Source/HBIOS/sd.asm

@ -79,6 +79,42 @@
; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA
; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD
;
;------------------------------------------------------------------------------
;
; *** HACK FOR MISSING PULLUP RESISTORS ***
;
; THERE IS A RECENT TREND FOR SD ADAPTER BOARDS (SUCH AS THOSE USED TO ATTACH AN
; SD CARD TO AN ARDUINO OR RASPBERRY PI) TO OMIT THE PULLUP RESISTORS THAT ARE SUPPOSED
; TO BE ON ALL LINES. DESPITE BEING A CLEAR VIOLATION OF THE SPEC, IT IS SOMETHING THAT
; WE WILL NOW NEED TO LIVE WITH. THE CLK, CS, AND MOSI SIGNALS ARE NOT AN ISSUE SINCE
; WE ARE DRIVING THOSE SIGNALS AS THE HOST. THE PROBLEM IS WITH THE MISO SIGNAL.
; FORTUNATELY, MOST OF THE TIME, THE SD CARD WILL BE DRIVING THE SIGNAL. HOWEVER,
; THERE ARE TWO SCEANRIOS WE NEED TO ACCOMMODATE IN THE CODE:
;
; 1. MISO WILL NOT BE DRIVEN BY THE SD CARD (FLOATING) PRIOR TO RESETING THE
; CARD WITH CMD0. NORMALLY, A COMMAND SEQUENCE INVOLVES WAITING FOR THE
; CARD TO BE "READY" BY READING BYTES FROM THE CARD AND LOOKING FOR $FF.
; WHEN MISO IS FLOATING THIS WILL NOT BE RELIABLE. SINCE THE SPEC INDICATES
; IT IS NOT NECESSARY TO WAIT FOR READY PRIOR TO CMD0, THE CODE HAS BEEN
; MODIFIED TO ISSUE CMD0 WITHOUT WAITING FOR READY.
;
; 2. MISO MAY NOT BE DRIVEN IMMEDIATELY AFTER SENDING A COMMAND (POSSIBLY
; JUST CMD0, BUT NOT SURE). NORMALLY, AFTER SENDING A COMMAND, YOU
; LOOK FOR "FILL" BYTES OF $FF THAT MAY OCCUR PRIOR TO THE RESULT. WHEN MISO
; IS FLOATING IT IS IMPOSSIBLE TO DETERMINE IF THE BYTE RECEIVED IS A FILL
; BYTE OR NOT. BASED ON WHAT I HAVE READ, THERE WILL ALWAYS BE AT LEAST
; ONE FILL BYTE PRIOR TO THE ACTUAL RESULT. ADDITIONALLY, THE SD CARD WILL
; START DRIVING MISO SOMETIME WITHING THAT FIRST FILL BYTE. SO, WE NOW
; JUST DISCARD THE FIRST BYTE RECEIVED AFTER A COMMAND IS SENT WITH THE
; ASSUMPTION THAT IT MUST BE A FILL BYTE AND IS NOT RELIABLE DUE TO FLOATING
; MISO.
;
; THESE CHANGES ARE CONSISTENT WITH THE POPULAR ARDUINO SDFAT LIBRARY, SO THEY ARE
; PROBABLY PRETTY SAFE. HOWEVER, I HAVE BRACKETED THE CHANGES WITH THE EQUATE BELOW.
; IF YOU WANT TO REVERT THESE HACKS, JUST SET THE EQUATE TO FALSE.
;
SD_NOPULLUP .EQU TRUE ; ASSUME NO PULLUP
;
#IF (SDMODE == SDMODE_JUHA) ; JUHA MINI-BOARD
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION
@ -1119,6 +1155,7 @@ SD_GOIDLE1:
LD A,$95 ; CRC FOR GO_IDLE_STATE COMMAND IS $95
LD (SD_CMDCRC),A ; SET CRC
CALL SD_EXECCMDND ; EXECUTE COMMAND W/ NO DATA RETURNED
RET NZ ; ABORT ON ERROR
LD A,(SD_RC) ; GET CARD RESULT
DEC A ; MAP EXPECTED $01 -> $00
@ -1171,10 +1208,23 @@ SD_EXECCMD:
CALL WRITESTR
POP AF
#ENDIF
;
CALL SD_SELECT
;
#IF (SD_NOPULLUP)
; DO NOT WAIT FOR READY PRIOR TO CMD0! THIS HACK IS REQUIRED BY
; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE
; COMMENTS AT TOP OF THIS FILE.
LD A,(SD_CMDBUF)
CP SD_CMD_GO_IDLE_STATE
JR Z,SD_EXECCMD0
#ENDIF
;
; WAIT FOR CARD TO BE READY
CALL SD_WAITRDY ; WAIT FOR CARD TO BE READY FOR A COMMAND
JP NZ,SD_ERRRDYTO ; HANDLE TIMEOUT ERROR
;
SD_EXECCMD0:
; SEND THE COMMAND
LD HL,SD_CMDBUF ; POINT TO COMMAND BUFFER
LD E,6 ; COMMANDS ARE 6 BYTES
@ -1184,6 +1234,13 @@ SD_EXECCMD1:
INC HL ; POINT TO NEXT BYTE
DEC E ; DEC LOOP COUNTER
JR NZ,SD_EXECCMD1 ; LOOP TILL DONE W/ ALL 6 BYTES
;
#IF (SD_NOPULLUP)
; THE FIRST FILL BYTE IS DISCARDED! THIS HACK IS REQUIRED BY
; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE
; COMMENTS AT TOP OF THIS FILE.
CALL SD_GET ; GET A BYTE AND DISCARD IT
#ENDIF
;
; GET RESULT
LD E,0 ; INIT TIMEOUT LOOP COUNTER
@ -1293,10 +1350,9 @@ SD_PUTDATA3:
XOR A
RET
;
; SELECT CARD AND WAIT FOR IT TO BE READY ($FF)
; WAIT FOR CARD TO BE READY ($FF). MUST ALREADY BE SELECTED.
;
SD_WAITRDY:
CALL SD_SELECT ; SELECT CARD
LD DE,$FFFF ; LOOP MAX (TIMEOUT)
SD_WAITRDY1:
CALL SD_GET

Loading…
Cancel
Save