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

📄 bbu_mmc.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 4 页
字号:
        ldr     r4,     [r2]            ; Fetch data
        ands    r4,     r4,     #0x80   ; is bit 7 set? (this is really bit 31 of the OCR)
        bne     %F20                    ; Yes - Continue the init process
        subs    r3,     r3,     #1      ; decrement loop count
        bne     %B14                    ; loop until zero
        mov     r0,     #0xFF           ; Indicate error
        b       %F40                    ; ...and take the exit path
;
;       CMD02 - Request card to send it's CID (Card ID) data
;
20      ldr     r0,     =0x00000000     ; Data to be sent
        mov     r1,     #0x02           ; Command to be sent (CMD02)
        bl      BBU_MMC_Cmd             ; Send out command
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F40                    ; Yes - return to caller
;
;       BBU has now read in the Card IDentification (CID) register information.
;       The data comes in from the controller in big endien format by 16-bit
;       words so it unfortunately gets a little scrambled (high and low bytes
;       are swapped. Also, the controller picks up the status byte that comes
;       back so the first byte of the CID register starts at offset 0, then
;       offset 3, 2, 5, 4,..... etc. (note: offset 1 (status byte - and typically
;       set to a value of 0x3F) is skipped).    
;
;       The ASCII data is big enden format by 16-bit word. BBU just uses a brute
;       force approach to re-arange 7 characters in the correct sequence.
;
        ldr     r3,     =bbu_MiscBuffer ; Address where data was sent
        cmp     r6,     #0x71           ; Is this a MMC card?
        addeq   r3,     r3,     #2      ; Not sure why I seem to need this but.....
        ldr     r1,     =BBU_ibuf       ; Address of BBU's input buffer
        ldrb    r0,     [r3, #0x3]      ; byte 0
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment      
        ldrb    r0,     [r3, #0x2]      ; byte 1
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment  
        ldrb    r0,     [r3, #0x5]      ; byte 2
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment  
        ldrb    r0,     [r3, #0x4]      ; byte 3
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment  
        ldrb    r0,     [r3, #0x7]      ; byte 4
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment  
        ldrb    r0,     [r3, #0x6]      ; byte 5
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment
        ldrb    r0,     [r3, #0x9]      ; byte 6
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment 
        mov     r0,     #0              ; Insert a null byte 
        strb    r0,     [r1],   #1      ; Stuff in BBU's buffer and increment
;
;       BBU is only set up to handle one MMC card at a time
;       so there is no need to cycle though the MMC init sequence to look for
;       additional cards. BBU sets this card's Relative Card Address (RCA) to
;       a value of 5 for further transactions. A inital value of of zero is used
;       for SD cards.
;
        cmp     r6,     #0x73           ; Is this card a MMC or a SD card?
        moveq   r0,     #0              ; SD card - use an address of zero
        movne   r0,     #5              ; MMC card - use address 5
        ldr     r1,     =BBU_RCA        ; Address of RCA
        str     r0,     [r1]            ; Save this data for future reference
        mov     r1,     #0x03           ; Command to be sent (CMD03) Set relative address
        ldr     r2,     =bbu_MiscBuffer ; Address where data is to be sent
        bl      BBU_MMC_Cmd             ; Send out command
;
;       Save the updated SD card RCA for future reference
;
        cmp     r6,     #0x73           ; Is this card a SD card?
        bne     %F24                    ; No - skip the following SD code
        ldr     r1,     =BBU_RCA        ; Address of RCA
        ldrb    r0,     [r2, #3]        ; Get low byte in bits 31:24
        strb    r0,     [r1, #2]        ; Store low byte in bits 23:16
        ldrb    r0,     [r2, #0]        ; Get high byte in bits 7:0
        strb    r0,     [r1, #3]        ; Store high byte in bits 31:24       
;
;       Now BBU will fetch the Card Specific Data (CSD) register from the card.
;
24      mov     r0,     #0x1            ; Set up for a short delay
        bl      BBU_msWait              ; Delay r0 milliseconds
        ldr     r0,     [r1]            ; Get the card's RCA
        mov     r1,     #0x09           ; Command to be sent (CMD09 = Send CSD)
        bl      BBU_MMC_Cmd             ; Send out command & fetch data
        mov     r5,     r1              ; Save controller base address in r5
;
;       Assemble the CSD data from what came back (into the right order) and
;       save it for possible future reference.
;
        ldr     r2,     =bbu_MiscBuffer ; Address where data was saved
        ldr     r3,     =BBU_MMC_CSD    ; Where assembled data will be stored
;
;       assemble 1st word
;
        ldrb    r0,     [r2, #0x11]     ; 1st byte
        ldrb    r1,     [r2, #0x0E]     ; 2nd byte
        mov     r1,     r1,     LSL #8  ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x0F]     ; 3rd byte
        mov     r1,     r1,     LSL #16 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x0C]     ; 4th byte
        mov     r1,     r1,     LSL #24 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        str     r0,     [r3],   #4      ; Save this data
;
;       Assemble 2nd word
;
        ldrb    r0,     [r2, #0x0D]     ; 5th byte
        ldrb    r1,     [r2, #0x0A]     ; 6th byte
        mov     r1,     r1,     LSL #8  ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x0B]     ; 7th byte
        mov     r1,     r1,     LSL #16 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x08]     ; 8th byte
        mov     r1,     r1,     LSL #24 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        str     r0,     [r3],   #4      ; Save this data
;
;       Assemble 3rd word
;
        ldrb    r0,     [r2, #0x09]     ; 9th byte
        ldrb    r1,     [r2, #0x06]     ; 10th byte
        mov     r1,     r1,     LSL #8  ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x07]     ; 11th byte
        mov     r1,     r1,     LSL #16 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x04]     ; 12th byte
        mov     r1,     r1,     LSL #24 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        str     r0,     [r3],   #4      ; Save this data
;
;       Assemble 4th word
;
        ldrb    r0,     [r2, #0x05]     ; 13th byte
        ldrb    r1,     [r2, #0x02]     ; 14th byte
        mov     r1,     r1,     LSL #8  ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x03]     ; 15th byte
        mov     r1,     r1,     LSL #16 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        ldrb    r1,     [r2, #0x00]     ; 16th byte
        mov     r1,     r1,     LSL #24 ; Shift
        orr     r0,     r0,     r1      ; OR into r0
        str     r0,     [r3],   #4      ; Save this data
;
;       At this point the MMC's Specific Data (CSD) register is saved
;       in the correct order (low order to high order bit) at four 32-bit
;       locations starting at offset BBU_MMC_CSD.
;
;       Calculate the number of bytes in this device. Start with the READ_BL_LEN.
;       READ_BL_LEN is stored in bits 83:80.
;
        ldr     r3,     =BBU_MMC_CSD    ; Address of CSD data
        mov     r1,     #1              ; Load 1 into r0
        ldrb    r2,     [r3, #0xA]      ; Fetch byte containing 4-bit READ_BL_LEN data
        and     r2,     r2,     #0xF    ; Isolate the READ_BL_LEN data
        mov     r1,     r1,     LSL r2                  ; r1 now contains the block length
        str     r1,     [r5, #BBU_MMC_BLKLEN_offset]    ; Save in the BLKLEN register
        mov     r4,     #1                              ; Set the number of blocks
        str     r4,     [r5, #BBU_MMC_NUMBLK_offset]    ; Save in the NUMBLK register
;
;       Now get the 12-bit C_SIZE data and calulate READ_BL_LEN * C_SIZE
;       C_SIZE is stored in bits 73:62.
;
        ldrb    r2,     [r3, #7]        ; Get the byte containing the 2 LSBs of C_SIZE
        and     r2,     r2,     #0xC0   ; Save bits 7:6
        mov     r2,     r2,     LSR #6  ; Move to bit locations 1:0
        ldrh    r4,     [r3, #8]        ; Get the upper 10 bits
        ldr     r0,     =0x3FF          ; load 10-bit mask
        and     r4,     r4,     r0      ; Save the 10 LSBs
        mov     r4,     r4,     LSL #2  ; Move 2 bits to the left
        orr     r2,     r2,     r4      ; r2 = value of C_SIZE -1
        add     r2,     r2,     #1      ; update r2 to actual size of C_SIZE
        mul     r1,     r1,     r2      ; r1 = READ_BL_LEN * C_SIZE
;
;       Last of all, get the C_SIZE_MULT and do the final multiplcation to get
;       the device size in bytes. C_SIZE_MULT is stored in bits 49:47.
;
        ldrb    r0,     [r3, #5]        ; Fetch this byte to get bit 47
        and     r0,     r0,     #0x80   ; Save bit #47
        mov     r0,     r0,     LSR #7  ; Move into bit zero location
        ldrb    r4,     [r3, #6]        ; Fetch this byte to get bits 49:48
        and     r4,     r4,     #3      ; Save bits 49:48
        mov     r4,     r4,     LSL #1  ; Move to the left by 1 bit
        orr     r0,     r0,     r4      ; r0 now contains the C_SIZE_MULT value
        add     r0,     r0,     #2      ; Add 2 to this value
        mov     r4,     #1              ; Set bit 1 in r0
        mov     r4,     r4,     LSL r0  ; F4 now contains the actual multiplier
        mul     r5,     r1,     r4      ; r5 now contains the total bytes in the device
;
;       Get the card's data transfer speed from the CSD register
;
        ldrb    r0,     [r3, #0xC]      ; Get bits 103:96
        and     r1,     r0,     #3      ; Save bits 1:0 in r1
;
;       The inital math is done in 10KHz increments but the multipliers
;       end up converting it to 1 KHz units.
;
        mov     r2,     #10             ; r2 = 100Khz (10 * 10 KHz)
        cmp     r1,     #1              ; Is the base value 1MHz?
        moveq   r2,     #100            ; Yes - change to 1 MHz
        cmp     r1,     #2              ; Is the base value 10 MHz?
        ldreq   r2,     =1000           ; Yes change to 10 MHz
        cmp     r1,     #3              ; Is the bease value 100 MHz?
        ldreq   r2,     =10000          ; Yes change to 100 MHz
        and     r1,     r0,     #0x78   ; Get the multipler bits
        mov     r1,     r1,     LSR #3  ; Right justify
        ldr     r4,     =BBU_MMC_MUL    ; Address of multiplier list
        ldrb    r0,     [r4, r1]        ; Get multipler
        mul     r0,     r0,     r2      ; R0 = frequency in KHz units
        ldr     r1,     =BBU_MMC_FREQ   ; Save max frequency here
        str     r0,     [r1]            ; Save for possible future reference
        mov     r4,     r0              ; Save a copy in r4
;
;       Figure out the Erase Group Size and save this information in case
;       there is a need to erase specific areas of the device. This data
;       is stored in bits 46:37 of the CSD for MMCs and in bits 45:39 for
;       SD cards with bit 46 also taken into consideration.
;
        ldrh    r0,     [r3, #0x4]      ; Get CSD bits 47:32
        cmp     r6,     #0x73           ; Is this card a SD card?
        bne     %F30                    ; No - Process MMC information
;
;       Calculate SD erase size
;
        mov     r0,     r0,     LSR #7  ; Right justify  bits 46:39
        ands    r1,     r0,     #0x80   ; Is bit 46 of the CSD set?
        movne   r0,     #1              ; Yes - set erase size to 1 sector
        bne     %F32                    ; ...and save this value
        and     r0,     r0,     #0x7F   ; Otherwise save these 7 bits
        add     r0,     r0,     #1      ; ...add 1 to it
        b       %F32                    ; ...and save this value instead
;
;       Calculate MMC erase size
;
30      mov     r0,     r0,     LSR #5  ; Right justify bits 41:37
        and     r1,     r0,     #0x3E0  ; Mask out the erase group size in r1
        mov     r1,     r1,     LSR #5  ; ...and right justify
        and     r0,     r0,     #0x1F   ; Mask out the multipier into r0
        add     r0,     r0,     #1      ; Add 1 to the multiplier
        add     r1,     r1,     #1      ; Add 1 to the erase group size
        mul     r0,     r0,     r1      ; r0 = erase group size

32      ldr     r1,     =BBU_MMC_EGS    ; Save Erase Group Size here
        strh    r0,     [r1]            ; Store this information
;
;       Place the card into the transfer state by issueing CMD7
;       Note: After call to BBU_MMC_Cmd, r1 = base address of MMC controller in use.
;
        ldr     r1,     =BBU_RCA        ; Address of SD card's RCA
        ldr     r0,     [r1]            ; Get the card's RCA
        mov     r1,     #0x07           ; Command to be sent (CMD07 = Select Card)
        ldr     r2,     =bbu_MiscBuffer ; Address where CMD data is to be sent
        bl      BBU_MMC_Cmd             ; Send out command & fetch data
        cmp     r0,     #0xFF           ; Error detected?
        beq     %F38                    ; Yes - exit with error code in r0
        mov     r0,     #0x1            ; Set up for a short delay
        bl      BBU_msWait              ; Delay r0 milliseconds 
;
;       Boost the clock rate for future transactions based on the max card

⌨️ 快捷键说明

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