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

📄 juno_comm.asm

📁 OMAP1030 处理器的ARM 侧硬件测试代码 OMAP1030 是TI的双核处理器
💻 ASM
📖 第 1 页 / 共 2 页
字号:
  ; ****PERSEUS MOTHER MOD  START *****
        bne       $-(2*4) 
  ; ****PERSEUS MOTHER MOD  START *****

; Set Serial Clock HIGH, MOSI High & Assert #SS
        orr      r7, r7, #(SS_ACTIVE | MOSI_CLK_HI)
        strb     r7, [r8]
; Pause for 100 usecs _SS to first clock Pulse, Tssc 
    pausem   r3, Tssc, r2

; Read MISO and Store Into Buffer 
        mov    r4, #8

READ_BYTE
READ_BIT 
        and     r7, r7, #CLK_LOW
        strb  r7, [r8]
        ; Pause for the 2 usec Tslow time  
        pausem  r3, Tslow, r2

        orr   r7, r7, #CLK_HIGH
        strb  r7, [r8]

        ; Receive Bit 
        ldr   r7, [r8]
        ; Pause for the 2 usec to complete Tsck time  
        pausem  r3, Tslow, r2
        and   r6, r7, #MISO_BIT 
  
        sub   r4, r4, #0x1

        subs  r5, r4,#0x4       ;Determine Shift Amount, Negative indicates Shift
        rsblt r5, r5,#0         ;Right.  Otherwise Shift left or not at all (zero).
        orrlt r9, r9, r6, lsr r5
        orrge r9, r9, r6, lsl r5  

        teq   r4, #0 
    bne   READ_BIT

        ; Pause for the 100 usec for ATN to go inactive (Tsna)
        pausem   r3, Tsna, r2 

        ; Check for ATN still active, if it is grab another byte!
        ldr       r7, [r8]
        tst       r7, #ATN_ACTIVE 
    ;beq       SS_HI2
    ; ****PERSEUS MOTHER MOD  START *****
    bne       SS_HI2 
        ; ****PERSEUS MOTHER MOD  END *****

        pausem r3, 50, r2 ; Wait an additional 50 usecs for interbyte spacing
        strb   r9, [r0]  ; Store Byte 
        mov  r4, #8      ; Reset Bit Counter 
        mov  r9, #0      ; Reset Cumulative Value 
        add  r0, r0, #1  ; Increment Output Buffer pointer 
        add  r10, r10, #1 ; Increment Byte Count 
    b    READ_BYTE 

    ; SS High   
SS_HI2
        and       r7, r7, #SS_INACTIVE 
        strb      r7, [r8] 
        strb   r9, [r0]    ; Store Byte 
        ; Set Return Value 
        mov   r0,r10
    ; Restore SOE registers 
        ldmia      sp!, {r4,r5,r6,r7,r8,r9,r10,lr}

        add     r3, pc, #1      ; R3=PC+1 back to Thumb mode  16 bits mode
        bx      r3
        .state16

        ; Return 
        bx lr
          

;  void Pause(int clock_freq, int delay_time, void *virtual_page_ptr)
;  same as wait function
        
;  void Pause(int clock_freq, int delay_time, void *virtual_page_ptr)
;
; Where clock_freq is the current clock frequency of the processor in MHz. This
; would be OEMClockFreq/1,000,000 under Windows CE.  delay_time is in 
; microseconds.  The timer_ptr is a pointer to memory that 
; corresponds to the microprocessor's counter.  It can be a virtual or physical
; address, depending on whether or not the MMU (and WinCE) are running.  
 
; Parameters  r0 = clock_freq, r1 = delay_time (microseconds), r2 = timer_ptr 
; Locals  r3 = # of timer ticks occuring over the pause interval 
;         r4 = Timer TIM register pointer, r5 = Timer PRD register pointer 
;         r6 = Watchdog Control register pointer
;  The TIM counter calculation is based on Time Delay * Clock Freq.
        .state32 
_pause        
PAUSE
; Save Save on Entry Registers
        stmdb      sp!, {r4,r5,r6,r7,r8,r9}

        add r4, r2, #READ_TIM_OFFSET    ; Timer is only 16 bits
        add r5, r2, #LOAD_TIM_OFFSET    ; 
        add r6, r2, #CNTL_TIM_OFFSET 

; Since we cannot simply look up the value of the Watchdog Timer reload value 
; we use a known value ahead of time in the case of Windows CE 3.00 and later this 
; value is 463 which produces an interrupt every 1 ms (actually 1.000384 ms)  
; The following code is highly dependant on this interrupt interval!      
    mov  r0, r1, lsr #1
    ldrh r7, [r4]
    subs r8, r7, r0            ; r8 has the timer count after the specified interval (r0)  
                               ; if it is negative then it needs to wrap around the reload value 
    adr r9, tick_val
    ldr r9, [r9]
    addmi r8, r8, r9
                               ; r8 now has the Tick Val after the desired duration 
LPS2
    ldrh r9, [r4]              ; See if we have counted through specified time
    cmp r9, r8                              
    bgt LPS2

; Restore Registers 
        ldmia      sp!, {r4,r5,r6,r7,r8,r9}
; Return 
    mov pc, lr


;; Routine slightly modified from the Tony Viscardi original (C) 
;
;  void wait(int clock_freq, int delay_time, void *virtual_page_ptr)
;
; NOTE: Code will start and stop Timer 
; Where clock_freq is the current clock frequency of the processor in MHz. This
; would be OEMClockFreq/1,000,000 under Windows CE.  delay_time is in 
; milliseconds.  The timer_ptr is a pointer to memory that 
; corresponds to the microprocessor's counter.  It can be a virtual or physical
; address, depending on whether or not the MMU (and WinCE) are running.  
 
; Parameters  r0 = clock_freq (doesn't matter for WD Timer), 
;             r1 = delay_time (milliseconds), r2 = timer_ptr 
; Locals  r3 = # of WD timer ticks occuring over the wait interval less than 141  
;         r4 = Timer LOAD_TIM register pointer, r5 = Timer READ_TIM register pointer 
;                 r6 = Max Count 0xFFFF constant 
;         r7 = temp storage,  r8 = Value of TIM counter register

        .state16
$wait 

; Save Save on Entry Registers
    push   {r4,r5,r6,r7,lr}

    add r4, r2, #READ_TIM_OFFSET    ; Timer is only 16 bits
    add r2, r2, #CNTL_TIM_OFFSET 

    mov r7, #WD_TIMER_FREE
    strh r7, [r2]

    mov r6, #0                 ;
    mvn r6 ,r6
    mov r3, #16
    lsr r6, r3
    strh r6, [r4]              ; store 0xFFFF (max ticks) 

FIRST
    cmp r1, #MAX_NO_PRESCALE   ; Is the time greater than 141 ms (Max Time of WD Timer?)
    blt LESS_141               ; If not wait until it is 
    ldrh r7, [r2]
    mov  r3, #WD_TIMER_ENABLE
    orr  r7, r3
    strh r7,[r2]               
EVAL 
    cmp r1, #MAX_NO_PRESCALE   ; Is the time greater than 141 ms (Max Time of WD Timer?)
    blt LESS_141               ; If not wait until it is 

LWD1
    ldrh r7, [r4]               ; See if we have counted through zero, thus
    add  r7, r7, #0             ; indicating that 141 ms have elapsed
    bne  LWD1
    mov  r3, #MAX_NO_PRESCALE
    sub  r1, r1, r3
    blt  terminate
    ldrh r7, [r2]
    mov  r3, #WD_TIMER_ENABLE
    orr  r7, r3
    strh r7,[r2]               
    b EVAL

LESS_141
                               ; Timer should be disabled at this point 
    adr r0, quot_ptr
    ldr r0, [r0]
    mov r7, #250
    mov r5, #4
    lsl r7, r5                  ; r7 = 1000
    mul r1, r7
    mul r1, r7                  ; r1 now has the number of nanoseconds elapsed (Max is within 32 bits = 141*1000*1000)
    mov r5, #78
    add r2, r7, r5
    add r2, r2, r2    
                               ; r2 has the # of nanoseconds in one WD Timer Tick (2156)
    
    bl  U$DIV                  ; r0 will point to a Quotient/Remainder pair representing the number of WD Timer Ticks for the specified interval 
    ldr r0, [r0]               ; Get the Quotient only 
    sub r3, r6, r0             ; r3 has the timer count after the specified interval (r0)  

    ldrh r7, [r2]
    mov r5,#WD_TIMER_FREE
    orr r7, r5
    mov r5, #WD_TIMER_ENABLE
    orr  r7, r5
    strh r7,[r2]               
    
LWD2
    ldrh r7, [r4]              ; See if we have counted through specified time
    cmp r7, r3                              
    bgt LWD2


terminate
    mov r7, #0
    strh r7,[r2]              ; // Set the TCR (just to be sure the timer is halted).

; Restore Registers 
    pop  {r4,r5,r6,r7,pc}

                .align 4
tick_val        .word   WD_TICK_VAL
resp_ptr        .word   INIT_RESP
quot_ptr        .word   quot_remainder


⌨️ 快捷键说明

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