X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/825ecc9d1df4b7b39bbbcbc6461d0407dd7d9d22..a8cde371bfde7e3b77ecad8b3935cfe972125ea7:/avr/mmc.asm diff --git a/avr/mmc.asm b/avr/mmc.asm index 887d54a..de4964d 100644 --- a/avr/mmc.asm +++ b/avr/mmc.asm @@ -39,12 +39,12 @@ #define CMD55 (55) /* APP_CMD */ #define CMD58 (58) /* READ_OCR */ -/* Disk Status Bits (DSTATUS) */ +/* Disk Status Bits (masks) (DSTATUS) */ #define MMCST_NOINIT 0x01 /* Drive not initialized */ #define MMCST_NODISK 0x02 /* No medium in the drive */ #define MMCST_PROTECT 0x04 /* Write protected */ -/* Card type flags (CardType) */ +/* Card type flags (masks) (CardType) */ #define CT_MMC 0x01 /* MMC ver 3 */ #define CT_SD1 0x02 /* SD ver 1 */ #define CT_SD2 0x04 /* SD ver 2 */ @@ -65,7 +65,7 @@ #define SPI_MODE SPI_MODE_0 ;------------------------------------------------ -; +; .macro spi_clkslow .if MMC_DEBUG > 1 printstring "SPI_CLK_SLOW " @@ -76,7 +76,7 @@ .endm ;------------------------------------------------ -; +; .macro spi_clkfast .if MMC_DEBUG > 1 printstring "SPI_CLK_FAST " @@ -92,7 +92,7 @@ .endm ;------------------------------------------------ -; +; .macro spi_disable .if MMC_DEBUG > 1 printstring "SPI_DISABLE " @@ -133,7 +133,7 @@ mul_yx_512: rol yl rol yh ret - + ;------------------------------------------------ spi_rcvr: out SPDR,_255 @@ -142,11 +142,9 @@ spi_rcvr_l: rjmp spi_rcvr_l in temp,SPDR .if MMC_DEBUG > 2 - push temp printstring "<" rcall printhex printstring " " - pop temp .endif ret @@ -159,14 +157,14 @@ spi_xmit: .endif out SPDR,temp ;fall thru -spi_wait: +spi_wait: sbism8 SPSR,SPIF rjmp spi_wait ret - + ;------------------------------------------------ -; Wait for card ready -; return 1:OK, 0:Timeout +; Wait for card ready +; return 1:OK, 0:Timeout mmcWaitReady: push temp2 @@ -189,7 +187,7 @@ mmc_wrl2: brne mmc_wrl ;tmp is 0 here mmc_wrbreak: - pop temp2 + pop temp2 tst temp ;set flags ret @@ -205,7 +203,7 @@ mmcDeselect: ret ;------------------------------------------------ -; Select the card and wait for ready +; Select the card and wait for ready ; return 255:Successful, 0:Timeout mmcSelect: @@ -214,19 +212,23 @@ mmcSelect: breq mmcDeselect ;return via Deselect sbr temp,255 ret - + ;------------------------------------------------ -; Send a command packet to MMC +; Send a command packet to MMC ; temp2: Command ; yh..xl: Argument +; return: +; temp: 0 = ok, no error +; z-flag 1 = ok, no error +; mmcCmd: sbrs temp2,7 rjmp mmc_cmddo -; ACMD is the command sequence of CMD55-CMD - +; ACMD is the command sequence of CMD55-CMD + push yh push yl push xh @@ -244,7 +246,7 @@ mmcCmd: cpi temp,2 brlo mmc_cmddo ; fall thru, if (retval <= 1) - + tst temp ret ; else return error @@ -276,7 +278,7 @@ dmmccmd_nonl: ldi temp,0xFF rjmp mmc_cmdexit - + ; Send command packet mmc_cmd_p: @@ -292,11 +294,11 @@ mmc_cmd_p: rcall spi_wait out SPDR,xl rcall spi_wait - + ldi temp,0x95 ;CRC for CMD0(0) cpi temp2,CMD0 breq mmc_cmdxcrc - ldi temp,0x87 ;CRC for CMD8(0x1AA) + ldi temp,0x87 ;CRC for CMD8(0x1AA) cpi temp2,CMD8 breq mmc_cmdxcrc ldi temp,0x01 ;Dummy CRC + Stop @@ -312,7 +314,7 @@ mmc_cmdxcrc: cpi temp2,CMD12 ; Skip a stuff byte when stop reading brne mmc_cmdres rcall spi_rcvr - + ; Wait for a valid response in timeout of 10 attempts mmc_cmdres: @@ -337,7 +339,7 @@ mmc_cmdexit: .endif tst temp ;set flags ret - + ;------------------------------------------------ ; Send command and receive ocr response ; temp2: Command, zl: expected cmd response @@ -388,7 +390,7 @@ mmc_ttex: ; Initialize MMC/SD card mmcInit: -.if MMC_DEBUG +.if MMC_DEBUG printnewline printstring "mmcInit " .endif @@ -411,7 +413,7 @@ mmci_lp: cpi temp,1 breq mmci_1 rjmp mmci_lend -mmci_1: +mmci_1: ldi zh,10 ;Initialization timeout of 1000 ms. ldi temp,100 sts delay_timer1,temp @@ -430,7 +432,7 @@ mmci_1: ; The card can work at vdd range of 2.7-3.6V. ; Wait for leaving idle state (ACMD41 with HCS bit). - + ldi temp2,ACMD41 ldi yh,0x40 ldi yl,0 @@ -442,7 +444,7 @@ mmci_v2l2: rcall mmc_timeout_1s brne mmci_v2l2 rjmp mmci_sdv2end - + ; Check CCS bit in the OCR mmci_ccc: ldi temp2,CMD58 @@ -458,14 +460,14 @@ mmci_ccc: mmci_sdv2end: rjmp mmci_lend - + ; SDv1 or MMCv3 mmci_sdv1: ldi temp2,ACMD41 ldiw y,0 movw x,y - rcall mmcCmd + rcall mmcCmd cpi temp,2 brsh mmci_mmcv3 sbr temp3,CT_SD1 ;SDv1 @@ -482,19 +484,19 @@ mmci_v1_l: rcall mmc_timeout_1s brne mmci_v1_l rjmp mmci_lend ;Timeout - + ; Set R/W block length to 512 mmci_v1_2: - ldi temp2,CMD16 + ldi temp2,CMD16 ldiw x,512 rcall mmcCmd breq mmci_lend ldi temp3,0 - + mmci_lend: sts mmcCardType,temp3 rcall mmcDeselect - + ; Initialization succeded? lds temp,mmcStat @@ -509,47 +511,78 @@ mmci_lex: printstring " CT: " push temp lds temp,mmcCardType - rcall printhex + lcall printhex pop temp printstring " InitRes: " - rcall printhex + lcall printhex printstring " " .endif spi_disable ret - - + +;-------------------------------------------------------------- + + .equ MMC_RDOP = 0 ;Read Operation + .equ MMC_RDWORD = 1 ;Read Word (FAT entry) + ;-------------------------------------------------------------- -; Read sector -; z: Pointer to the data buffer to store read data -; yh..xl: Start sector number (LBA) mmcReadSect: + .if MMC_DEBUG > 1 printnewline printstring "mmcRdSect " .endif - ldiw z,hostbuf ;for now + ldi temp,(1< 1) || (MMC_DEBUG_RDW > 0) + printnewline + printstring "mmcRdWord " +.endif + ldi temp,(1< 1 + printnewline + printstring "mmcWrSect " +.endif + ldi temp,0 + +mmc_rw_common: + push temp3 + mov temp3,temp + lds temp,mmcStat + ldi temp2,RES_NOTRDY + sbrc temp,log2(MMCST_NOINIT) + rjmp mmc_rwexit_2 - lds _tmp0,mmcStat - ldi temp,RES_NOTRDY - sbrc _tmp0,MMCST_NOINIT - ret - spi_clkfast lds temp,mmcCardType sbrs temp,log2(CT_BLOCK) rcall mul_yx_512 ;Convert to byte address (*512) - ldi temp2,CMD17 + sbrc temp3,MMC_RDOP + ldi temp2,CMD17 + sbrs temp3,MMC_RDOP + ldi temp2,CMD24 rcall mmcCmd - ldi temp2,RES_ERROR - brne mmc_rdex - + breq mmc_rw_1 + rjmp mmc_rwexit_error + +mmc_rw_1: + ldiw y,512 + sbrs temp3,MMC_RDOP + rjmp mmc_wroper + +;------------------------------------------------------------------------------- ; Receive a data packet from MMC - ldiw y,512 ;Number of bytes to tranfer ldi temp,200 ;Wait for data packet in timeout of 200ms. sts delay_timer1,temp mmc_rcv_wl: @@ -566,109 +599,34 @@ mmc_rcv_wl: mmc_rcv_start: .if MMC_DEBUG > 1 - cpi temp,0xFE ;If not valid data token, + cpi temp,0xFE ;If not valid data token, breq mmc_rcv_dbg1 printstring "Token: " - rcall printhex + lcall printhex printstring " " mmc_rcv_dbg1: .endif - cpi temp,0xFE ;If not valid data token, - brne mmc_rdex - + cpi temp,0xFE ;If not valid data token, + breq mmc_rw_2 + rjmp mmc_rwexit_error +mmc_rw_2: + rcall spi_rcvr ;Shift in first byte. .if MMC_DEBUG > 3 printnewline - rcall printhex + lcall printhex printstring " " .endif out SPDR,_255 ;Start shift in next byte. -mmc_rcv_rl: - sbiw yl,1 - breq mmc_rcv_rle - st z+,temp - spi_waitm - in temp,SPDR -.if MMC_DEBUG > 3 - rcall printhex - printstring " " -.endif - out SPDR,_255 - rjmp mmc_rcv_rl - -mmc_rcv_rle: - st z+,temp ;Store last byte in buffer -.if MMC_DEBUG > 3 - printnewline -.endif - rcall spi_wait ;while SPI module shifts in crc part1. - rcall spi_rcvr ;Read second crc. - - ldi temp2,RES_OK ;Return success -mmc_rdex: - rcall mmcDeselect - spi_disable - mov temp,temp2 -.if MMC_DEBUG > 1 - printstring "RdSectRes: " - rcall printhex - printstring " " -.endif - ret - - -;-------------------------------------------------------------- -; Read word -; Read Word to ZL,ZH at given ZL/ZH Offset -; Needed for reading a single FAT16 entry without killing the -; entries in hostbuffer... -; -; in zh,zl: Pointer to word within the sector to read -; in yh..xl: Start sector number (LBA) -; out zh,zl: Word thats been read -mmcReadWord: -.if MMC_DEBUG > 1 - printnewline - printstring "mmcRdWord " -.endif - lds _tmp0,mmcStat - ldi temp,RES_NOTRDY - sbrc _tmp0,MMCST_NOINIT - ret - - spi_clkfast - lds temp,mmcCardType - sbrs temp,log2(CT_BLOCK) - rcall mul_yx_512 ;Convert to byte address (*512) + sbrs temp3,MMC_RDWORD + rjmp mmc_rcv_readloop - ldi temp2,CMD17 - rcall mmcCmd - ldi temp2,RES_ERROR - brne mmc_rdexw - -; Receive a data packet from MMC +; discard x-1 bytes - ldiw y,512 ;Number of bytes to tranfer - ldi temp,200 ;Wait for data packet in timeout of 200ms. - sts delay_timer1,temp -mmc_rcvw_wl: - rcall spi_rcvr - cp temp,_255 - brne mmc_rcvw_start - lds temp2,delay_timer1 - cpi temp2,0 - brne mmc_rcvw_wl -mmc_rcvw_start: - cpi temp,0xFE ;If not valid data token, - ldi temp2,RES_ERROR - brne mmc_rdexw - - rcall spi_rcvr ;Shift in first byte. - out SPDR,_255 ;Start shift in next byte. mmc_rcvw_rl: sbiw yl,1 - breq mmc_rcvw_rle + breq mmc_rcv_rlend cp zl,_0 cpc zh,_0 breq mmc_rcvw_sto @@ -679,6 +637,8 @@ mmc_rcvw_rl: out SPDR,_255 rjmp mmc_rcvw_rl +; read next two bytes + mmc_rcvw_sto: mov zl,temp spi_waitm @@ -686,74 +646,71 @@ mmc_rcvw_sto: out SPDR,_255 mov zh,temp +.if MMC_DEBUG_RDW > 0 + movw temp,z + lcall printhexw + printstring " " +.endif + +; discard the rest + mmc_rcvw_rl2: sbiw yl,1 - breq mmc_rcvw_rle + breq mmc_rcv_rlend spi_waitm in temp,SPDR out SPDR,_255 rjmp mmc_rcvw_rl2 -mmc_rcvw_rle: - rcall spi_wait ; while SPI module shifts in crc part1. - rcall spi_rcvr ;Read second crc. - - ldi temp2,RES_OK ;Return success -mmc_rdexw: - rcall mmcDeselect - spi_disable - mov temp,temp2 -.if MMC_DEBUG > 1 - printstring "RdWordRes: " - rcall printhex - printstring " " -.endif - ret -;-------------------------------------------------------------- -; Write sector -; z: Pointer to the data to be written -; yh..xl: Sector number (LBA) +; read sector, store in buffer -mmcWriteSect: -.if MMC_DEBUG > 1 +mmc_rcv_readloop: + sbiw yl,1 + breq mmc_rcv_rle + st z+,temp + spi_waitm + in temp,SPDR +.if MMC_DEBUG > 3 + lcall printhex + printstring " " +.endif + out SPDR,_255 + rjmp mmc_rcv_readloop + +mmc_rcv_rle: + st z+,temp ;Store last byte in buffer +mmc_rcv_rlend: +.if MMC_DEBUG > 3 printnewline - printstring "mmcWrSect " .endif - ldiw z,hostbuf ;for now - - lds _tmp0,mmcStat - ldi temp,RES_NOTRDY - sbrc _tmp0,MMCST_NOINIT - ret - - spi_clkfast - lds temp,mmcCardType - sbrs temp,log2(CT_BLOCK) - rcall mul_yx_512 ;Convert to byte address (*512) + rcall spi_wait ;while SPI module shifts in crc part1. + rcall spi_rcvr ;Read second crc. - ldi temp2,CMD24 - rcall mmcCmd - brne mmc_wrexer - + ldi temp2,RES_OK ;Return success + rjmp mmc_rwexit + + +;------------------------------------------------------------------------------- ; Send a data packet to MMC +mmc_wroper: + .if MMC_DEBUG > 2 ; printnewline printstring "mmcXMIT " .endif rcall mmcWaitReady - breq mmc_wrexer + breq mmc_rwexit_error ldi temp,0xFE ;Data token out SPDR,temp - ldiw y,512 mmc_x_loop: ld temp,z+ spi_waitm out SPDR,temp sbiw yl,1 brne mmc_x_loop - + rcall spi_wait ldi temp,0xFF ;dummy crc rcall spi_xmit @@ -761,27 +718,43 @@ mmc_x_loop: rcall spi_rcvr .if MMC_DEBUG > 2 printstring "XMITRes: " - rcall printhex + lcall printhex printstring " " .endif andi temp,0x1F ;If not accepted, return with error cpi temp,0x05 ldi temp2,RES_OK ;Return success - breq mmc_wrex + breq mmc_rwexit -mmc_wrexer: - ldi temp,RES_ERROR -mmc_wrex: +mmc_rwexit_error: + ldi temp2,RES_ERROR +mmc_rwexit: rcall mmcDeselect spi_disable +mmc_rwexit_2: mov temp,temp2 + .if MMC_DEBUG > 1 - printstring "WrSectRes: " - rcall printhex + sbrc temp3,MMC_RDOP + rjmp mmc_dbg_rder + + printstring "WrSectRes: " + rjmp mmc_dbg_rwerex + +mmc_dbg_rder: + sbrc temp3,MMC_RDWORD + rjmp mmc_dbg_rdwder + printstring "RdSectRes: " + rjmp mmc_dbg_rwerex + +mmc_dbg_rdwder: + printstring "RdWordRes: " +mmc_dbg_rwerex: + lcall printhex printstring " " .endif + pop temp3 ret ;-------------------------------------------------------------- ; vim:set ts=8 noet nowrap -