\ ------------------------------------------------------------ \ PLUGAPOD & SD/FRAM INTERFACE SIGNALS: \ SCLK -> Clock \ MOSI -> SD/FR data in \ MISO <- SD/FR data Out \ PE7 -> SD Chip Select \ TA1 -> FRAM Chip Select \ TA2 <- SD write protect switch, 0 is unlock, 1 is lock \ TA3 <- SD card detect switch, 0 is present, 1 is no card \ \ SD 2GB Memory Range: 0x0000000 - 0x77A7FFFF \ Last valid 512byte block to read/write: 0x77A7FE00 \ Any attempt to read/write from 0x77A80000 & up will \ need to recycle the power in order to reset the SD card \ \ The SDRESET routine provided is tested on 2GB card or smaller \ \ FRAM Memory Range: 0x0000-0x7FFF \ ------------------------------------------------------------- SCRUB COLD HEX \ --- SD Variables --- VARIABLE R1 EEWORD ( response r1 VARIABLE R7 EEWORD ( response r7 VARIABLE BUFFINDEX EEWORD VARIABLE BUFF 200 ALLOT EEWORD 2VARIABLE SDSECPTR EEWORD \ ---- SD Chip Select ------ : SD-CSHI PE7 ON ; EEWORD : SD-CSLO PE7 OFF ; EEWORD \ ---- FR Chip Select ------ : FR-CSHI TA1 ON ; EEWORD : FR-CSLO TA1 OFF ; EEWORD \ --------- SPI -------------- : SPI-INIT ( -- ) 14 SPI0 MBAUD ( 20 Mhz 8 SPI0 BITS ( 8 bit SPI0 MSB-FIRST SPI0 LEADING-EDGE SPI0 ACTIVE-HIGH SPI0 MASTER SD-CSHI ( release SD CS FR-CSHI ( release FR CS ; EEWORD ( send a byte and return a byte : SPI-IO ( n -- n ) SPI0 TX-SPI SPI0 RX-SPI ; EEWORD : SDCMD ( addr32 cmd --- ) 40 + SPI-IO DROP DUP >< SPI-IO DROP SPI-IO DROP DUP >< SPI-IO DROP SPI-IO DROP 95 SPI-IO DROP ( CRC valid only for GO_IDLE_STATE ; EEWORD ( wait for response, r1 : GET-R1 FFF 0 DO FF SPI-IO DUP FF = NOT IF R1 ! LEAVE ELSE I FFE = IF FF R1 ! ( CR ." Timeout!" ( debug THEN THEN DROP LOOP ; EEWORD ( wait for response, r7 : GET-R7 FFF 0 DO FF SPI-IO DUP FF = NOT IF ( DUP . ) R1 ! FF SPI-IO DROP ( . ( debug FF SPI-IO 100 * ( . FF SPI-IO OR R7 ! ( . FF SPI-IO DROP ( . LEAVE ELSE I FFE = IF FF R1 ! CR ." Timeout!" THEN THEN DROP LOOP ; EEWORD : SEND-SDCMD SD-CSLO ( assert sd chip select SDCMD ( send command GET-R1 ( get response SD-CSHI ( deasser sd chip select FF SPI-IO DROP ( send 8 or more dummy clks to complete the operation ; EEWORD : SEND-CMD58 CR ." Checking VHS... " FFF 0 DO SD-CSLO 0.0 3A SDCMD GET-R7 ( send cmd58 SD-CSHI FF SPI-IO DROP R1 @ 1 = IF LEAVE ELSE I FFE = IF CR ." Timeout - R1 =" R1 @ . THEN THEN LOOP ; EEWORD : SEND-ACMD41 FFF 0 DO 0.0 37 SEND-SDCMD ( send cmd55 0.0 29 SEND-SDCMD ( send acmd41 R1 @ 0= IF ( ." Completed " ) LEAVE ELSE I FFE = IF 1 R1 ! ( ." Timeout. R1 =" R1 @ . THEN THEN LOOP ; EEWORD : SDRESET ( --- ) ( intialize sd card into spi mode by sending 80 clks A 0 DO FF SPI-IO DROP LOOP ( reset or go_idle_state mode CR ." Init CMD0... " 0.0 0 SEND-SDCMD ( send cmd0 & get response R1 @ 1 = IF ." completed!" ELSE ." failed. " ( ." R1=" R1 @ . ( debug THEN CR ." Sending CMD8 " 0.01AA 8 SEND-SDCMD ( send cmd8 R1 @ DUP 5 = IF DROP CR ." === SD Memory Card, Ver1.X === " ELSE 9 = IF CR ." === SD Memory Card, Ver2.00 or later === " ELSE CR ." Undetermine device " THEN THEN CR ." Sending CMD58 " SEND-CMD58 R7 @ FF80 = IF ." compatible voltage range, 2.7-3.6V " ELSE ." Non compatible voltage range " THEN CR ." Sending ACMD41... " SEND-ACMD41 R1 @ 0= IF ." Card is ready " ELSE CR ." Card is failed to reset." THEN ( turn off CRC checking to simplify communication 0.0 3B SEND-SDCMD ( send cmd59 ( CR ." CRC RESPONSE: " R1 @ . ( debug ( set block length to 512 bytes 0.0200 10 SEND-SDCMD ( send cmd16, Blocklen 512 ( CR ." CMD16 RESPONSE: " R1 @ . ( debug ; EEWORD ( Dump a block of 512-byte ) : SDDUMP ( addr32 --- ) SD-CSLO 2DUP 11 SDCMD GET-R1 ( send cmd17 R1 @ 0= IF BEGIN FF SPI-IO FE = UNTIL CR 8 SPACES 10 0 DO I 4 U.R LOOP ( 0-F index header CR 2DUP 8 D.R 201 1 DO FF SPI-IO 4 U.R I 10 MOD 0= I 200 = NOT AND IF ( display 16 bytes per line CR 2DUP SWAP I + SWAP 8 D.R THEN LOOP FF SPI-IO DROP ( ignore CRC FF SPI-IO DROP ( ignore CRC ELSE ." CMD17 REPORT " R1 @ . THEN 2DROP SD-CSHI ( release chip select FF SPI-IO DROP ( send some dummy clks ; EEWORD ( Fill a block of 512-byte with data ) : SDFILL ( addr32 data8 --- ) SD-CSLO 0 2SWAP 18 SDCMD GET-R1 ( send cmd24 R1 @ 0= IF FF SPI-IO DROP ( clear tx buffer FE SPI-IO DROP ( start block write DROP ( 0 ) 200 0 DO DUP SPI-IO DROP LOOP DROP ( fill block with variable FF SPI-IO DROP ( ignore CRC FF SPI-IO DROP ( ignore CRC FF SPI-IO R1 ! ( read data response token R1 @ 0F AND 5 = IF BEGIN FF SPI-IO 0= NOT UNTIL ( wait til not busy THEN ELSE ." Data Response Token: " R1 @ . THEN SD-CSHI ( release chip select FF SPI-IO DROP ( send some dummy clks ; EEWORD ( Copy a block of 512-byte of BUFF to SD memory ) ( assuming 512-byte of BUFF filled with data ) : SDCOPY ( addr32 --- ) SD-CSLO 18 SDCMD GET-R1 ( send cmd24 R1 @ 0= IF FF SPI-IO DROP ( clear tx buffer FE SPI-IO DROP ( start block write 100 0 DO BUFF I + @ DUP >< SPI-IO DROP SPI-IO DROP LOOP FF SPI-IO DROP ( ignore CRC FF SPI-IO DROP ( ignore CRC FF SPI-IO R1 ! ( read data response token R1 @ 0F AND 5 = IF BEGIN FF SPI-IO 0= NOT UNTIL ( wait til not busy THEN ELSE ." Data Response Token: " R1 @ . THEN SD-CSHI ( release chip select FF SPI-IO DROP ( send some dummy clks ; EEWORD ( copy a block 512-byte of program memory to SD memory ) : SDPCOPY ( paddr sdaddr32 --- ) SD-CSLO 18 SDCMD GET-R1 ( send cmd24 R1 @ 0= IF FF SPI-IO DROP ( clear tx buffer FE SPI-IO DROP ( start block write 100 0 DO DUP I + P@ DUP >< SPI-IO DROP SPI-IO DROP LOOP DROP FF SPI-IO DROP ( ignore CRC FF SPI-IO DROP ( ignore CRC FF SPI-IO R1 ! ( read data response token R1 @ 0F AND 5 = IF BEGIN FF SPI-IO 0= NOT UNTIL ( wait til not busy THEN ELSE ." Data Response Token: " R1 @ . THEN SD-CSHI ( release chip select FF SPI-IO DROP ( always send some dummy clks ; EEWORD \ ----------------------- END OF SD TEST ---------------- \ \ ---------- FRAM registers ------------------- 01 CONSTANT WRSR EEWORD ( write status register 02 CONSTANT WRITE EEWORD ( write memory data 03 CONSTANT READ EEWORD ( read memory data 04 CONSTANT WRDI EEWORD ( write disable 05 CONSTANT RDSR EEWORD ( read status register 06 CONSTANT WREN EEWORD ( set write enable latch \ ---------- FRAM Read/Write routines ------------ ( issue a read command ) : FRCMDREAD READ SPI-IO DROP ( Read instruction SPI-IO DROP ( High byte address SPI-IO DROP ( Low byte address ; EEWORD ( issue a write command ) : FRCMDWRITE WRITE SPI-IO DROP ( Write instruction SPI-IO DROP ( High byte address SPI-IO DROP ( Low byte address ; EEWORD ( enable FRam write latch ) : FRWREN FR-CSLO WREN SPI-IO DROP FR-CSHI ; EEWORD ( read a byte from the address ) : FRC@ ( n addr -- ) DUP >< FR-CSLO FRCMDREAD FF SPI-IO FR-CSHI ; EEWORD ( read a word from the address ) : FR@ ( addr -- ) DUP >< FR-CSLO FRCMDREAD FF SPI-IO 100 * FF SPI-IO + FR-CSHI ; EEWORD ( dump a block of memory ) : FRDUMP ( addr size --- ) FR-CSLO SWAP DUP DUP >< FRCMDREAD CR DUP 5 U.R SWAP DUP 0 DO FF SPI-IO 4 U.R I 1+ 10 MOD 0= IF CR ( display 16 bytes per line DUP I 1+ = NOT IF SWAP DUP I 1+ + 5 U.R SWAP THEN THEN LOOP 2DROP FR-CSHI ; EEWORD ( fill a block of memory with data ) : FRFILL ( addr size data --- ) FRWREN 0 2SWAP SWAP DUP >< FR-CSLO FRCMDWRITE SWAP DROP 0 DO DUP SPI-IO DROP LOOP DROP FR-CSHI ; EEWORD ( write a byte to the address ) : FRC! ( n addr -- ) FRWREN DUP >< FR-CSLO FRCMDWRITE SPI-IO DROP FR-CSHI ; EEWORD ( write a word to the address ) : FR! ( n addr -- ) FRWREN DUP >< FR-CSLO FRCMDWRITE DUP >< SPI-IO DROP SPI-IO DROP FR-CSHI ; EEWORD ( copy a block of program memory to FRam memory ) : FRPCOPY ( paddr fraddr size --- ) FRWREN SWAP DUP >< FR-CSLO FRCMDWRITE 0 DO DUP I + P@ DUP >< SPI-IO DROP SPI-IO DROP LOOP DROP FR-CSHI ; EEWORD \ ----------------------- END OF FRAM TEST ----------------- SPI-INIT ( init spi \ SDRESET ( init SD memory