📄 bbu_mmc.s
字号:
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 + -