]> cloudbase.mooo.com Git - avrcpm.git/blobdiff - avr/mmc.asm
Remove unsupported experimental ADC support
[avrcpm.git] / avr / mmc.asm
index 38fdfe0e4bc638550a887760f060ce0912b74940..de4964db817ee084a2275ad18975d75422d3f4d4 100644 (file)
 #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 "
@@ -117,9 +117,6 @@ mmcStat:
        .byte   1
 mmcCardType:
        .byte   1
-mmc_ocr:
-       .byte   4
-       
 
 
        .cseg
@@ -136,7 +133,7 @@ mul_yx_512:
        rol     yl
        rol     yh
        ret
-               
+
 ;------------------------------------------------
 spi_rcvr:
        out     SPDR,_255
@@ -145,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
 
@@ -162,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
@@ -192,7 +187,7 @@ mmc_wrl2:
        brne    mmc_wrl         ;tmp is 0 here
 
 mmc_wrbreak:
-       pop     temp2   
+       pop     temp2
        tst     temp            ;set flags
        ret
 
@@ -208,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:
@@ -217,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<n> is the command sequence of CMD55-CMD<n>      
-       
+; ACMD<n> is the command sequence of CMD55-CMD<n>
+
        push    yh
        push    yl
        push    xh
@@ -247,7 +246,7 @@ mmcCmd:
 
        cpi     temp,2
        brlo    mmc_cmddo               ; fall thru, if (retval <= 1)
-       
+
        tst     temp
        ret                             ; else return error
 
@@ -279,7 +278,7 @@ dmmccmd_nonl:
 
        ldi     temp,0xFF
        rjmp    mmc_cmdexit
-       
+
 ; Send command packet
 
 mmc_cmd_p:
@@ -295,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
@@ -315,22 +314,23 @@ 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:
-       ldi     temp,10
-       mov     _tmp1,temp
+       push    temp2
+       ldi     temp2,10
 mmc_cmdrl:
        rcall   spi_rcvr
        sbrs    temp,7
        rjmp    mmc_cmdexit
-       dec     _tmp1
+       dec     temp2
        brne    mmc_cmdrl
 
 ; Return with  response value
 
 mmc_cmdexit:
+       pop     temp2
 .if MMC_DEBUG
        printstring " CMDRes: "
        rcall   printhex
@@ -339,7 +339,33 @@ mmc_cmdexit:
 .endif
        tst     temp                    ;set flags
        ret
-       
+
+;------------------------------------------------
+; Send command and receive ocr response
+;      temp2:  Command, zl: expected cmd response
+;       yh..xl:        Argument
+;      return: yh..xl: ocr, z flag == 1, if return from mmcCmd was ok.
+
+mmcCmd_ocr:
+
+       rcall   mmcCmd
+
+       cp      temp,zl                 ;
+       brne    mmc_cocr_e
+
+; Get trailing return value of R7 response
+
+       ldi     temp2,4
+       ldiw    z,0x1a                  ;memory address of xl
+mmc_cocr1:
+       rcall   spi_rcvr
+       st      z+,temp
+       dec     temp2
+       brne    mmc_cocr1
+                                       ;z-flag =1
+mmc_cocr_e:
+       ret
+
 ;------------------------------------------------
 ; Check if 1 sec timeout
 ;      return Z-Flag set, if timeout
@@ -348,7 +374,7 @@ mmc_timeout_1s:
        lds     temp,delay_timer1
        tst     temp
        brne    mmc_ttex
-       dec     temp4
+       dec     zh
        breq    mmc_ttex
        ldi     temp,100
        sts     delay_timer1,temp
@@ -364,7 +390,7 @@ mmc_ttex:
 ; Initialize MMC/SD card
 
 mmcInit:
-.if MMC_DEBUG 
+.if MMC_DEBUG
        printnewline
        printstring     "mmcInit "
 .endif
@@ -387,37 +413,26 @@ mmci_lp:
        cpi     temp,1
        breq    mmci_1
        rjmp    mmci_lend
-mmci_1:        
-       ldi     temp4,10                ;Initialization timeout of 1000 ms.
+mmci_1:
+       ldi     zh,10                   ;Initialization timeout of 1000 ms.
        ldi     temp,100
        sts     delay_timer1,temp
        ldi     temp2,CMD8
        ldiw    y,0
        ldi     xh,0x01
        ldi     xl,0xAA
-       rcall   mmcCmd
-       cpi     temp,1                  ;SDv2?
-       brne    mmci_sdv1
+       ldi     zl,1
+       rcall   mmcCmd_ocr
+       brne    mmci_sdv1               ;SDv2?
 
-; Get trailing return value of R7 response
-
-       ldi     temp2,4
-       ldiw    z,mmc_ocr
-mmci_v2l1:
-       rcall   spi_rcvr
-       st      z+,temp
-       dec     temp2
-       brne    mmci_v2l1
-       sbiw    z,4
-       ldd     temp,z+2
-       cpi     temp,0x01
-       ldd     temp,z+3
-       cpc     temp,xl                 ;Reuse 0xAA value in xl
+       cpi     yl,0x01                 ;ocr[2]
+       brne    mmci_sdv1
+       cpi     yh,0xAA                 ;ocr[3]
        brne    mmci_sdv1
 
 ; 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
@@ -429,37 +444,30 @@ mmci_v2l2:
        rcall   mmc_timeout_1s
        brne    mmci_v2l2
        rjmp    mmci_sdv2end
-       
+
 ; Check CCS bit in the OCR
 mmci_ccc:
        ldi     temp2,CMD58
        ldi     yh,0
-       rcall   mmcCmd
+       ldi     zl,0
+       rcall   mmcCmd_ocr
+
        brne    mmci_sdv2end
 
-       ldi     temp2,4
-mmci_v2l3:
-       rcall   spi_rcvr
-       st      z+,temp
-       dec     temp2
-       brne    mmci_v2l3
-       sbiw    z,4
-       
        sbr     temp3,CT_SD2
-       ldd     temp,z+0
-       sbrc    temp,6
+       sbrc    xl,6
        sbr     temp3,CT_BLOCK
 
 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
@@ -476,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
@@ -503,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<<MMC_RDOP)
+       rjmp    mmc_rw_common
+
+mmcReadWord:
+
+.if (MMC_DEBUG > 1) || (MMC_DEBUG_RDW > 0)
+       printnewline
+       printstring "mmcRdWord "
+.endif
+       ldi     temp,(1<<MMC_RDOP) | (1<<MMC_RDWORD)
+       rjmp    mmc_rw_common
+
+mmcWriteSect:
+
+.if MMC_DEBUG > 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:
@@ -560,194 +599,118 @@ 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
+       sbrs    temp3,MMC_RDWORD
+        rjmp   mmc_rcv_readloop
 
+; discard x-1 bytes
 
-;--------------------------------------------------------------
-; Read word 
-; TODO: Read Word to ZL,ZH at given ZL/ZH Offset
-; Need for reading of single FAT16 Entrys without killing the
-; Entrys 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)
-
-       ldi             temp2,CMD17
-       rcall   mmcCmd
-       ldi             temp2,RES_ERROR
-       brne    mmc_rdexw
-       
-; 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_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
-       cp              zl,_0
-       cpc             zh,_0
+       breq    mmc_rcv_rlend
+       cp      zl,_0
+       cpc     zh,_0
        breq    mmc_rcvw_sto
 
        sbiw    zl,1
        spi_waitm
-       in              temp,SPDR
-       out             SPDR,_255
+       in      temp,SPDR
+       out     SPDR,_255
        rjmp    mmc_rcvw_rl
 
+; read next two bytes
+
 mmc_rcvw_sto:
        mov     zl,temp
        spi_waitm
-       in              temp,SPDR
-       out             SPDR,_255
+       in      temp,SPDR
+       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
+       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
+
+; read sector, store in buffer
+
+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
-       ret
-
-;--------------------------------------------------------------
-; Write sector 
-;      z:      Pointer to the data to be written
-;       yh..xl:        Sector number (LBA)
+       out     SPDR,_255
+       rjmp    mmc_rcv_readloop
 
-mmcWriteSect:
-.if MMC_DEBUG > 1
+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
@@ -755,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
-