📄 juno_comm.asm
字号:
; ****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 + -