📄 bbu_nand.s
字号:
ldr r0, [r3, #BBU_NDSR_offset] ; Read NDSR register
str r0, [r3, #BBU_NDSR_offset] ; Clear any sticky bits
;
; Return to caller
;
ldmfd sp!, {r0-r3, pc} ; Restore r0-r3, and return to caller
ENDFUNC
;
;*******************************************************************************
;
; ******************
; * *
; * BBU_NAND_erase * Erase data from the NAND flash
; * * (Erases a single page - 512 bytes)
; ******************
;
; INPUT:
;
; r0 = NAND page address to be erased (preserved)
; Address should be NAND address with the 8 LSBs missing (16-bit bus)
;
BBU_NAND_erase FUNCTION
stmfd sp!, {r0-r2, lr} ; Save r0-r2, and link register on the stack
ldr r2, =BBU_DFC_Physical_Base ; Base Address of NAND controller
;
; Set the controller into run mode
;
ldr r1, [r2, #BBU_NDCR_offset] ; Fetch the contents of the Control register
orr r1, r1, #BBU_NDCR_ND_RUN; Set the ND_RUN bit
str r1, [r2, #BBU_NDCR_offset] ; Write control register back
;
; Send the erase command to the controller
;
ldr r1, =0x5BD060 ; Erase command, 3 address cycles
str r1, [r2, #BBU_NDCB0_offset] ; Write to register
str r0, [r2, #BBU_NDCB0_offset] ; Write addrs cycle 1:4
mov r1, #0x0 ; Specify 1 page to be transfered
str r1, [r2, #BBU_NDCB0_offset] ; Write address cycle 5 and page count
;
; Wait for controller to indicate the command completed
;
40 ldr r0, [r2, #BBU_NDSR_offset] ; Read NDSR register
ands r0, r0, #BBU_NDSR_CS0_CMDD ; Test CS0_CMDD bit
beq %B40 ; Loop until data is ready
str r0, [r2, #BBU_NDSR_offset] ; Clear the sticky bit
ldmfd sp!, {r0-r2, pc} ; Restore r0-r2, and return to caller
ENDFUNC
;
;*******************************************************************************
;
; ***************
; * *
; * BBU_NAND_ID * Fetch the NAND device ID
; * *
; ***************
;
; OUTPUT:
;
; r0 = NAND ID
;
BBU_NAND_ID FUNCTION
stmfd sp!, {r1-r2, lr} ; Save r1-r2, and link register on the stack
ldr r2, =BBU_DFC_Physical_Base ; Base Address of NAND controller
;
; Set the controller into run mode
;
ldr r1, [r2, #BBU_NDCR_offset] ; Fetch the contents of the Control register
orr r1, r1, #BBU_NDCR_ND_RUN; Set the ND_RUN bit
str r1, [r2, #BBU_NDCR_offset] ; Write control register back
;
; Send the ID command to the controller
;
ldr r1, =0x610090 ; ID command, 1 address cycles
str r1, [r2, #BBU_NDCB0_offset] ; Write to register
str r0, [r2, #BBU_NDCB0_offset] ; Write addrs cycle 1:4
mov r1, #0x0 ; Specify 1 page to be transfered
str r1, [r2, #BBU_NDCB0_offset] ; Write address cycle 5 and page count
;
; Wait for controller to indicate the command completed
;
60 ldr r0, [r2, #BBU_NDSR_offset] ; Read NDSR register
ands r0, r0, #BBU_NDSR_RDDREQ; Test read request bit
beq %B60 ; Loop until data is ready
str r0, [r2, #BBU_NDSR_offset] ; Clear the sticky bit
;
; The read loop is to insure any "garbage" is removed from the buffer. The
; flash ID remains in the buffer so multiple reads "past the end" of the
; buffer should have no effect on the data in the buffer.
;
mov r1, #0x40 ; Init a loop counter
65 ldr r0, [r2, #BBU_NDDB_offset] ; Read the data buffer
subs r1, r1, #1 ; Decrment loop count
bne %B65 ; Loop until the counter is zero
bic r0, r0, #0xFF000000 ; Clear bits 31:24
bic r0, r0, #0x00FF0000 ; Clear bits 23:16
ldmfd sp!, {r1-r2, pc} ; Restore r1-r2, and return to caller
ENDFUNC
;
;*******************************************************************************
;
; *******************
; * *
; * BBU_NAND_unlock * Unlock the NAND flash
; * *
; *******************
;
; Parameters:
;
; None for now (may be expanded, so r0 and r1 are not used)
;
BBU_NAND_unlock FUNCTION
stmfd sp!, {r0-r5, lr} ; Save r2-r5, and link register on the stack
ldr r2, =BBU_DFC_Physical_Base ; Base Address of NAND controller
;
; Set the controller into run mode
;
ldr r3, [r2, #BBU_NDCR_offset] ; Fetch the contents of the Control register
orr r3, r3, #BBU_NDCR_ND_RUN; Set the ND_RUN bit
str r3, [r2, #BBU_NDCR_offset] ; Write control register back
;
; Send the unlock (start area) command to the controller
;
ldr r3, =0x630023 ; Unlock (start area) command, 4 address cycles
mov r5, #0 ; Clear a work register
str r3, [r2, #BBU_NDCB0_offset] ; Write to register
str r5, [r2, #BBU_NDCB0_offset] ; Write addrs cycle 1:4
str r5, [r2, #BBU_NDCB0_offset] ; Write address cycle 5 and page count
;
; Wait for controller to indicate the command completed
;
70 ldr r3, [r2, #BBU_NDSR_offset] ; Read NDSR register
ands r3, r3, #BBU_NDSR_RDDREQ ; Test the read request bit
beq %B70 ; Loop until data is ready
ldr r3, [r2, #BBU_NDSR_offset] ; Read NDSR register
str r3, [r2, #BBU_NDSR_offset] ; Clear the sticky bit(s)
;
; Do some dummy reads (intent is to make sure the buffer is empty)
;
mov r3, #0x40 ; Set up a loop count
72 ldr r1, [r2, #BBU_NDDB_offset] ; Dummy read
subs r3, r3, #1 ; Decrement loop count
bne %B72 ; Loop until counter is zero
;
; Short delay
;
mov r0, #0x20 ; Delay 0x20 clock ticks
bl BBU_tickWait ; Call wait routine
bl BBU_DFC_Init ; ***** DEBUG *****
;
; Set the controller into run mode
;
ldr r3, [r2, #BBU_NDCR_offset] ; Fetch the contents of the Control register
orr r3, r3, #BBU_NDCR_ND_RUN; Set the ND_RUN bit
str r3, [r2, #BBU_NDCR_offset] ; Write control register back
;
; Send the unlock (end area) command to the controller
;
ldr r3, =0x630024 ; Unlock (end area) command, 4 address cycles
mov r5, #0 ; Clear a work register
str r3, [r2, #BBU_NDCB0_offset] ; Write to register
str r5, [r2, #BBU_NDCB0_offset] ; Write addrs cycle 1:4
str r5, [r2, #BBU_NDCB0_offset] ; Write address cycle 5 and page count
;
; Wait for controller to indicate the command completed
;
75 ldr r3, [r2, #BBU_NDSR_offset] ; Read NDSR register
ands r3, r3, #BBU_NDSR_RDDREQ ; Test the read request bit
beq %B75 ; Loop until data is ready
ldr r3, [r2, #BBU_NDSR_offset] ; Read NDSR register
str r3, [r2, #BBU_NDSR_offset] ; Clear the sticky bit(s)
ldmfd sp!, {r0-r5, pc} ; Restore r2-r5, and return to caller
ENDFUNC
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -