📄 bbu_i2c.s
字号:
str r4, [r3, #bbu_I2C_ICR_offset] ; Set TB bit to start transfer
mov r2, #BBU_I2C_TimeOut ; Set up time out value
4 ldr r4, [r3, #bbu_I2C_ISR_offset] ; Get status register contents
subs r2, r2, #1 ; Decrement time out value
beq %F8 ; Return if there was a time out
ands r4, r4, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B4 ; No - still being transmitted
str r4, [r3, #bbu_I2C_ISR_offset] ; Write the ITE bit to clear it (sticky)
;
; Set up and then send 3rd byte (DATA) and STOP signal
;
str r1, [r3, #bbu_I2C_IDBR_offset] ; Place data byte into the IDBR
mov r4, #(bbu_ICR_TB | bbu_ICR_IUE | bbu_ICR_SCLE | bbu_ICR_STOP)
str r4, [r3, #bbu_I2C_ICR_offset] ; Set TB bit to start transfer
6 ldr r4, [r3, #bbu_I2C_ISR_offset] ; Get status register contents
ands r4, r4, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B6 ; No - still being transmitted
str r4, [r3, #bbu_I2C_ISR_offset] ; Write the ITE bit to clear it (sticky)
8 ldmfd sp!, {r3-r6, pc} ; Return to caller
ENDFUNC
;
;*********************************************************************************
;
; ***************
; * *
; * BBU_getPI2C * Subroutine
; * *
; ***************
;
; This subroutine is used to read data from the Power I2C bus
;
; PARAMETER PASSING:
;
; r0 = address in target device where data is to be read from
; r1 = data read from the register pointed to by r0
;
; RETURNED VALUE:
;
; r2 = non zero if no power I2C bus time out
; r2 = zero if there was a power I2C bus time out
;
;
BBU_getPI2C FUNCTION
stmfd sp!, {r3-r9, lr} ; Save used registers
;
; Make sure the clock to the I2C unit is enabled
;
; ldr r3, =xlli_CLKREGS_PHYSICAL_BASE ; Base address of clock unit
; ldr r2, [r3, #xlli_CKEN_offset] ; Get current setting of clock enable register
; orr r2, r2, #0x8000 ; Set bit 15 in the clock enable word (PWR I2C clock)
; str r2, [r3, #xlli_CKEN_offset] ; Write the register back
;
; Init the Power I2C controller for use
;
ldr r5, =bbu_PMRCREGS_PHYSICAL_BASE ; Load Power Manager controller base address
ldr r3, [r5, #bbu_PCFR_offset] ; Get present Config register data
orr r3, r3, #bbu_PI2C_EN ; Enable power manager I2C bus
str r3, [r5, #bbu_PCFR_offset] ; Write Config register data back
mov r2, #0 ; Set host controller slave address
str r2, [r5, #bbu_PI2SAR_offset] ; Set slave address register
str r2, [r5, #bbu_PI2CR_offset] ; Clear interrupts in ICR
mov r3, #(bbu_ICR_IUE | bbu_ICR_SCLE) ; Set IUE and SCLE bits
str r3, [r5, #bbu_PI2CR_offset] ; Enable the I2C in ICR
;
; Get the slave's address
;
ldr r6, =bbu_FFUART_PHYSICAL_BASE ; Fetch base address of the FFUART
ldrb r9, [r6, #bbu_UASPR_offset] ; Get contents of the scratch pad register
str r9, [r5, #bbu_PI2DBR_offset] ; Load Data Buffer Register
;
; Send 1st byte
;
orr r3, r3, #(bbu_ICR_TB | bbu_ICR_START)
str r3, [r5, #bbu_PI2CR_offset] ; Set TB and START bits (in addition to IUE & SCLE)
mov r2, #0x80000 ; Set up time out value
1 ldr r3, [r5, #bbu_PI2SR_offset] ; Get status register contents
subs r2, r2, #1 ; Decrement time out value
beq %F9 ; Return if timed out
ands r3, r3, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B1 ; No - still being transmitted
str r3, [r5, #bbu_PI2SR_offset] ; Write the ITE bit to clear it (sticky)
;
; Set up and then send 2nd byte (ADDRESS)
;
str r0, [r5, #bbu_PI2DBR_offset] ; Set register address in the IDBR
mov r3, #(bbu_ICR_TB | bbu_ICR_IUE | bbu_ICR_SCLE | bbu_ICR_STOP)
str r3, [r5, #bbu_PI2CR_offset] ; Set TB bit to start transfer
mov r2, #0x80000 ; Set up time out value
2 ldr r3, [r5, #bbu_PI2SR_offset] ; Get status register contents
subs r2, r2, #1 ; Decrement time out value
beq %F9 ; Return if timed out
ands r3, r3, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B2 ; No - still being transmitted
str r3, [r5, #bbu_PI2SR_offset] ; Write the ITE bit to clear it (sticky)
;
; Delay 50 uS (clock is 3.6864 MHz)
;
ldr r2, =xlli_OSTREGS_PHYSICAL_BASE ; Load OS timer base address
ldr r3, [r2, #xlli_OSCR0_offset] ; Fetch starting value of OSCR0
add r3, r3, #0xB8 ; 0xB8 is about 50usec
7 ldr r4, [r2, #xlli_OSCR0_offset] ; Fetch current OSCR0 value
cmp r4, r3 ; Is the timer past the time out value?
bmi %B7 ; Not yet
;
; Set up and then send 3rd byte - Slave read address
;
88 orr r9, r9, #1 ; Turn the address into a slave address
str r9, [r5, #bbu_PI2DBR_offset] ; Load Data Buffer Register
mov r3, #(bbu_ICR_TB | bbu_ICR_IUE | bbu_ICR_SCLE | bbu_ICR_START)
str r3, [r5, #bbu_PI2CR_offset] ; Set TB bit to start transfer
3 ldr r3, [r5, #bbu_PI2SR_offset] ; Get status register contents
ands r3, r3, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B3 ; No - still being transmitted
str r3, [r5, #bbu_PI2SR_offset] ; Write the ITE & IRF bits to clear them (sticky)
;
; Send STOP signal
;
mov r3, #(bbu_ICR_TB | bbu_ICR_IUE | bbu_ICR_SCLE | bbu_ICR_STOP | bbu_ICR_ACKNAK)
str r3, [r5, #bbu_PI2CR_offset] ; Set TB bit to start transfer
mov r2, #0x80000 ; Set up time out value
;
; Set up and then receive data byte (seems to hang in the following loop * 24-Oct-03)
;
5 ldr r3, [r5, #bbu_PI2SR_offset] ; Get status register contents
subs r2, r2, #1 ; Decrement time out counter
addeq r2, r2, #1 ; Increment back to 1 if timed out
beq %F9 ; and return to caller
ands r3, r3, #bbu_ISR_IRF ; Was the byte received yet?
beq %B5 ; no - keep looping
str r3, [r5, #bbu_PI2SR_offset] ; Write the IRF bit to clear it (sticky)
ldr r1, [r5, #bbu_PI2DBR_offset] ; Fetch data byte from the IDBR
9 ldmfd sp!, {r3-r9, pc} ; Return to caller
ENDFUNC
;
;*********************************************************************************
;
; ***************
; * *
; * BBU_putPI2C * Subroutine
; * *
; ***************
;
; This subroutine is used to write data to the PI2C bus
;
; PARAMETER PASSING:
;
; r0 = address in target device where data is to be sent
; r1 = data to be loaded into the register pointed to by r1
;
; RETURNED VALUE:
;
; r2 = non zero if no I2C bus time out
; r2 = zero if I2C bus time out
;
BBU_putPI2C FUNCTION
stmfd sp!, {r3-r9, lr} ; Save used registers
;
; Make sure the clock to the I2C unit is enabled
;
; ldr r3, =xlli_CLKREGS_PHYSICAL_BASE ; Base address of clock unit
; ldr r2, [r3, #xlli_CKEN_offset] ; Get current setting of clock enable register
; orr r2, r2, #0x8000 ; Set bit 15 in the clock enable word (PWR I2C clock)
; str r2, [r3, #xlli_CKEN_offset] ; Write the register back
;
; Init the Power I2C controller for use
;
ldr r5, =bbu_PMRCREGS_PHYSICAL_BASE ; Load Power Manager controller base address
ldr r3, [r5, #bbu_PCFR_offset] ; Get present Config register data
orr r3, r3, #0x40 ; Enable power manager I2C
str r3, [r5, #bbu_PCFR_offset] ; Write Config register data back
mov r2, #0 ; Set host controller slave address
str r2, [r5, #bbu_PI2SAR_offset] ; Set slave address register
str r2, [r5, #bbu_PI2CR_offset] ; Clear interrupts in ICR
mov r3, #(bbu_ICR_IUE | bbu_ICR_SCLE) ; Set IUE and SCLE bits
str r3, [r5, #bbu_PI2CR_offset] ; Enable the I2C in ICR
;
; Get the slave's address
;
ldr r8, =bbu_FFUART_PHYSICAL_BASE ; Fetch base address of FFUART
ldrb r9, [r8, #bbu_UASPR_offset] ; Get contents of the scratch pad register
str r9, [r5, #bbu_PI2DBR_offset] ; Load Data Buffer Register
;
; Send 1st byte
;
orr r3, r3, #(bbu_ICR_TB | bbu_ICR_START)
str r3, [r5, #bbu_PI2CR_offset] ; Set TB and START bits (in addition to IUE & SCLE)
mov r2, #0x8000 ; Set up loop counter
1 subs r2, r2, #1 ; decrement loop counter
beq %F9 ; exit if count is zero
ldr r3, [r5, #bbu_PI2SR_offset] ; Get status register contents
ands r3, r3, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B1 ; No - still being transmitted
str r3, [r5, #bbu_PI2SR_offset] ; Write the ITE bit to clear it (sticky)
;
; Set up and then send 2nd byte (ADDRESS)
;
str r0, [r5, #bbu_PI2DBR_offset] ; Set register address in the IDBR
mov r3, #(bbu_ICR_TB | bbu_ICR_IUE | bbu_ICR_SCLE)
str r3, [r5, #bbu_PI2CR_offset] ; Set TB bit to start transfer
mov r2, #0X80000 ; Set up time out value
2 ldr r3, [r5, #bbu_PI2SR_offset] ; Get status register contents
subs r2, r2, #1 ; Decrement time out value
beq %F9 ; Return if there was a time out
ands r3, r3, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B2 ; No - still being transmitted
str r3, [r5, #bbu_PI2SR_offset] ; Write the ITE bit to clear it (sticky)
;
; Set up and then send 3rd byte (DATA) and STOP signal
;
str r1, [r5, #bbu_PI2DBR_offset] ; Set data byte into the IDBR
mov r3, #(bbu_ICR_TB | bbu_ICR_IUE | bbu_ICR_SCLE | bbu_ICR_STOP)
str r3, [r5, #bbu_PI2CR_offset] ; Set TB bit to start transfer
3 ldr r3, [r5, #bbu_PI2SR_offset] ; Get status register contents
ands r3, r3, #bbu_ISR_ITE ; Was the byte sent yet?
beq %B3 ; No - still being transmitted
str r3, [r5, #bbu_PI2SR_offset] ; Write the ITE bit to clear it (sticky)
9 ldmfd sp!, {r3-r9, pc} ; Return to caller
ENDFUNC
;
;*********************************************************************************
;
; *****************
; * *
; * BBU_getI2C_16 * Subroutine
; * *
; *****************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -