⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bbu_mmc.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 4 页
字号:
        ALIGN   4
        ENDFUNC
;
;       ******************
;       **              **
;       ** LITERAL POOL **     LOCAL DATA STORAGE
;       **              **
;       ******************
;
        LTORG
;
;*********************************************************************************
;
;       ****************
;       *              * 
;       * BBU_MMC_Read *        READ A SINGLE SECTOR OF DATA FROM A MMC/SD CARD
;       *              *
;       ****************
;
;       This subroutine will read a block of data from a MMC that has already been
;       initalized with the BBU IMMC command and save the data (usually 512 bytes)
;       in the user specified buffer.
;
; PARAMETER PASSING:
;
;       INPUT - r0 = Sector # to be read from the device
;               r1 = Address where data is to be written to
;
;       OUTPUT - r0 = 0xFF for BBU detected error. Otherwise...
;                r0 = the sector length of the device (in bytes)
;                r1 = destroyed
;
BBU_MMC_Read    FUNCTION

        stmfd   sp!,    {r2-r5, lr}     ; Save used registers
        mov     r4,     r0              ; Save off read block number
        mov     r5,     r1              ; Save off buffer address into r5
        mov     r3,     #0x200          ; Set sector length to 512 bytes for now
;
;       Prepare to read a single sector from the selected device
;
        mul     r0,     r4,     r3      ; Generate the starting address for the read
        mov     r1,     #17             ; Command to be sent (CMD17 = READ SINGLE SECTOR)
        ldr     r2,     =bbu_MiscBuffer ; Address where CMD data is to be sent
        bl      BBU_MMC_Cmd             ; Send out command
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F38                    ; Yes - exit with error code in r0
;
;       Monitor MMC_I_REG for requests to read data from the MMC
;       Note: Bit is set when there are 32 bytes ready to read.
;
        mov     r4,     #0x10000                        ; Set up time out counter
32      subs    r4,     r4,     #1                      ; Decrement loop counter
        moveq   r0,     #0xFF                           ; Set error code if timed out
        beq     %F38                                    ; ..and exit if timed out
        ldr     r2,     [r1, #BBU_MMC_I_REG_offset]     ; Fetch interrupt register status
        ands    r2,     r2,     #BBU_MMC_RD_REQ         ; read request?
        beq     %B32                    ; No - keep looping
;
;       Move 32 bytes of data into the memory address provided by caller then
;       wait for another read request by the controller.
;
        mov     r4,     #0x20                           ; Move 32 bytes
34      ldrb    r2,     [r1, #BBU_MMC_RXFIFO_offset]    ; Fetch a byte
        strb    r2,     [r5],   #1                      ; Save in memory
        subs    r4,     r4,     #1      ; decrement byte transfer count
        bne     %B34                    ; Loop until done
        subs    r3,     r3,     #0x20   ; Decrement total byte transfer count from block size
        bne     %B32                    ; Fetch data until block is transfered
;
;       Stop the MMC clock
;
        mov     r4,     #BBU_stop_clk                   ; Set the stop clock bit
        str     r4,     [r1, #BBU_MMC_STRPCL_offset]    ; Stop the clock

        ldr     r0,     [r1, #BBU_MMC_BLKLEN_offset]    ; Get block length of this MMC
38      ldmfd   sp!,    {r2-r5, pc}                     ; Restore registers and return
        ENDFUNC
;
;*********************************************************************************
;
;       *****************
;       *               * 
;       * BBU_MMC_Erase *        ERASE A SINGLE BLOCK OF DATA IN THE MMC
;       *               *
;       *****************
;
;       This subroutine will erase a block of data from a MMC that has already been
;       initalized with the BBU IMMC command and mounted with the MMC_MOUNT command.
;
; PARAMETER PASSING:
;
;       INPUT - r0 = Sector number of the first sector in the block to be erased
;
;       OUTPUT - r0 = 0xFF for BBU detected error. Otherwise...
;                r0 = Size of the erase group (in sectors)
;                r1 = Size of sector (in bytes)
;
BBU_MMC_Erase   FUNCTION

        stmfd   sp!,    {r2-r6, lr}     ; Save used registers
        mov     r4,     #0x200          ; BBU assumes all sectors are 512 bytes
        mul     r0,     r0,     r4      ; Calculate starting address
        mov     r4,     r0              ; Save off starting address
        ldr     r5,     =BBU_RCA        ; Location of Relative Card Address
        ldr     r6,     [r5]            ; Fetch the RCA & save for later reference
;
;       Prepare to erase a single block from the selected card by sending the
;       erase group start and stop address. MMC and SD cards use different
;       commands to set up the erase length. Under BBU MMC cards use an RCA of
;       5 so any other value is assumed to be a SD card (although this is not
;       always guaranteed).
;
        cmp     r6,     #5              ; MMC or SD card?
        moveq   r1,     #35             ; MMC - (CMD35 = ERASE_GROUP_START)
        movne   r1,     #32             ; SD Card - (CMD32 = ERASE_GROUP_START)
        ldr     r2,     =bbu_MiscBuffer ; Address where CMD reply is to be sent
        bl      BBU_MMC_Cmd             ; Send out command & fetch data
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F48                    ; Yes - exit with error code in r0
        mov     r0,     #0x1            ; Set up for a short delay
        bl      BBU_msWait              ; Delay r0 milliseconds
;
;       Set the ERASE_GROUP_END data (Note: BLKLEN in MMC terms is the same as
;       sector size in disk tems)
;
        ldr     r2,     =BBU_MMC_EGS    ; Erase Group Size saved here here
        ldrh    r0,     [r2]                            ; Get this information
        ldr     r1,     =BBU_MMC1_PHYSICAL_BASE         ; Load base address for MMC1 controller
        ldr     r2,     [r1, #BBU_MMC_BLKLEN_offset]    ; Get block length of this MMC
        sub     r2,     r2,     #1                      ; Decrement by 1 byte
        mul     r0,     r0,     r2      ; Generate an ending address within the erase block
        add     r0,     r0,     r4      ; Add 1 block to base address
        cmp     r6,     #5              ; MMC or SD card?
        moveq   r1,     #36             ; MMC - (CMD36 = ERASE_GROUP_END)
        movne   r1,     #33             ; SD Card - (CMD33 = ERASE_GROUP_END)
        ldr     r2,     =bbu_MiscBuffer ; Address where CMD reply is to be sent
        bl      BBU_MMC_Cmd             ; Send out command & fetch data
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F48                    ; Yes - exit with error code in r0
        mov     r0,     #0x1            ; Set up for a short delay
        bl      BBU_msWait              ; Delay r0 milliseconds
;
;       Send the erase command
;
        mov     r0,     #0              ; Stuffer bits
        mov     r1,     #38             ; Command to be sent (CMD038 = ERASE)
        ldr     r2,     =bbu_MiscBuffer ; Address where CMD reply is to be sent
        bl      BBU_MMC_Cmd             ; Send out command & fetch data
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F48                    ; Yes - exit with error code in r0

        mov     r0,     #1              ; Set up a delay time
        bl      BBU_msWait              ; Delay for r0 millisecoonds
        mov     r4,     #BBU_stop_clk                   ; Set the stop clock bit
        str     r4,     [r1, #BBU_MMC_STRPCL_offset]    ; Stop the clock
;
;       Fecth the size of the erase group from the Card Specific Data (CSD) word
;       Erase Group Size in bits 46:42 (+1)
;       Erase Group Multipler in bits 41:37 (+1)
;
        ldr     r2,     =BBU_MMC_EGS    ; Erase Group Size saved here here
        ldrh    r0,     [r1]            ; Fetch this data
        ldr     r1,     [r1, #BBU_MMC_BLKLEN_offset]    ; Get block length of this MMC
48      ldmfd   sp!,    {r2-r6, pc}                     ; Restore registers and return
        ENDFUNC
;
;*********************************************************************************
;
;       *****************
;       *               * 
;       * BBU_MMC_Write *        WRITE A SINGLE BLOCK OF DATA TO THE MMC
;       *               *
;       *****************
;
;       This subroutine will write a block of data to a MMC that has already been
;       initalized with the BBU IMMC command. (Under development)
;
; PARAMETER PASSING:
;
;       INPUT - r0 = Source address of data to be written to MMC/SD device
;               r1 = Sector number in the MMC/SD device to be written to
;
;       OUTPUT - r0 = 0xFF for BBU detected error. Otherwise...
;                r0 = the sector length of the device (in bytes)
;
BBU_MMC_Write   FUNCTION

        stmfd   sp!,    {r1-r5, lr}     ; Save used registers
        mov     r4,     r1              ; Save off sector number to be written
        mov     r5,     r0              ; Save source address in r5
;
;       Get MMC controller base address
;
        ldr     r1,     =BBU_MMC1_PHYSICAL_BASE ; Load base address for MMC1 controller
        ldr     r3,     =BBU_MMC_lastInit       ; Address where # of last MMC port initialized is
        ldrb    r2,     [r3]                    ; Fetch MMC # last initialized
        cmp     r2,     #2                      ; Was MMC2 the last MMC initialized?
        ldreq   r1,     =BBU_MMC2_PHYSICAL_BASE ; YES - Load base address for MMC2 controller
;
;       Prepare to write a single sector to the selected card by sending the
;       block length.
;
        ldr     r0,     [r1, #BBU_MMC_BLKLEN_offset]    ; Get block length of this MMC
        mov     r1,     #16             ; Command to be sent (CMD016 = SET BLOCKLEN)
        ldr     r2,     =bbu_MiscBuffer ; Address where CMD reply is to be sent
        bl      BBU_MMC_Cmd             ; Send out command & fetch data
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F58                    ; Yes - exit with error code in r0
        mov     r0,     #0x1            ; Set up for a short delay
        bl      BBU_msWait              ; Delay r0 milliseconds
;
;       Set up to write a block to the MMC
;
        ldr     r0,     [r1, #BBU_MMC_BLKLEN_offset]    ; Get block length of this MMC
        mul     r0,     r0,     r4                      ; Calculate the starting address
        mov     r1,     #24             ; Command to be sent (CMD024 = WRITE BLOCK)
        ldr     r2,     =bbu_MiscBuffer ; Address where CMD reply is to be sent
        bl      BBU_MMC_Cmd             ; Send out command & fetch data
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F58                    ; Yes - exit with error code in r0
;
;       Monitor MMC_I_REG for requests to write data to the MMC
;       Note: Bit is set when there are 32 bytes ready to write (apparently).
;
        ldr     r3,     [r1, #BBU_MMC_BLKLEN_offset]    ; Get block length of this MMC
52      ldr     r2,     [r1, #BBU_MMC_I_REG_offset]     ; Fetch interrupt register status
        ands    r4,     r2,     #BBU_MMC_WR_REQ         ; Write request?
        beq     %B52                    ; No - keep looping
;
;       Move 32 bytes of data from the memory address provided by caller then
;       wait for another write request by the controller.
;
        mov     r4,     #0x8            ; Move 32 bytes (8 doublewords)
54      ldr     r2,     [r5],   #4                       ; Fetch data from memory
        str     r2,     [r1, #BBU_MMC_TXFIFO_offset]    ; Store in transmit buffer
        subs    r4,     r4,     #1      ; decrement doubleword transfer count
        bne     %B54                    ; Loop until done
        subs    r3,     r3,     #0x20   ; Decrement total byte transfer count from block size
        bne     %B52                    ; Write data until block is transfered

        mov     r0,     #0x1            ; Set up for a short delay
        bl      BBU_msWait              ; Delay r0 milliseconds

        mov     r0,     #1              ; Set up a delay time
        bl      BBU_msWait              ; Delay for r0 millisecoonds
        mov     r4,     #BBU_stop_clk                   ; Set the stop clock bit
        str     r4,     [r1, #BBU_MMC_STRPCL_offset]    ; Stop the clock

        ldr     r0,     [r1, #BBU_MMC_BLKLEN_offset]    ; Get block length of this MMC
58      ldmfd   sp!,    {r1-r5, pc}                     ; Restore registers and return
        ENDFUNC


BBU_MMC_CMDAT_value     DCD     0       ; Optional bits to be ORed into command 

        END                                                                                                               

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -