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

📄 bbu_i2c.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 3 页
字号:
        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 + -