timer0.src
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· SRC 代码 · 共 345 行
SRC
345 行
;-------------------------------------------------------------------------------
;
; THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
; ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
; PARTICULAR PURPOSE.
; Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
;
;-------------------------------------------------------------------------------
.list OFF
.include "kxshx.h"
.list ON
.aif SH_CPU eq h'40
.include "sh4.inc"
.aelse
.include "sh3.inc"
.aendi
.include "aspen.inc"
;
; since SHx assembler doesn't take C style defines, we can't automatically
; determine which version we are by include "bldver.h".
; If you are compiling this file for SHx, make sure you change the following
; line to:
CE_MAJOR_VER: .equ 3
;
; CE_MAJOR_VER: .equ 4
CLOCK_LEDS: .equ 0
; Note: this needs to match RESCHED_PERIOD in timer.h
RESCHED_PERIOD: .equ 1 ; Reschedule period in ms
SYSINTR_NOP: .equ 0
SYSINTR_RESCHED: .equ 1
SYSINTR_DEVICES: .equ 8
SYSINTR_TIMING: .equ SYSINTR_DEVICES+2
.aif CLOCK_LEDS eq h'2
LEDState .data.l 1
.data.l 1
.aendi
;
; ODO Platform LED addresses:
;
;HKEEP_FPGA_REGS_BASE: .equ h'A4000000 ; housekeeping FPGA reg base
;LED_ALPHA: .equ HKEEP_FPGA_REGS_BASE+h'00060000
;LED_DISCRETE: .equ HKEEP_FPGA_REGS_BASE+h'00040000
.import _CurMSec
.import _CurTicks
.import _wNumInterrupts
.import _dwSPC
.import _dwIsrTime1
.import _dwIsrTime2
.import _fIntrTime
.import _dwReschedIncrement
.import _OEMClockFreq
.import _dwIntrTimeCountdownRef
.import _dwIntrTimeCountdown
.import _dwPerfCountHigh
.aif CE_MAJOR_VER == h'0003
.import _DiffMSec
.import _ticksleft
.import _dwSleepMin
.import _dwPreempt
.aelse
.import _dwReschedTime
.aendi
;-------------------------------------------------------------------------------
; We make this a MACRO because it needs to be called from inside the
; ISR and we don't want to waste a function call to do it.
;
; Value is returned in R0
;-------------------------------------------------------------------------------
.macro PERFCOUNT_MACRO
mov #TMU_REGBASE, r2 ; (r2) = ptr to timer unit registers
mov.l @(TMU_TCOR0_OFFSET,r2), r0 ; (r0) = Timer 0 constant
mov.l @(TMU_TCNT0_OFFSET,r2), r2 ; (r2) = Timer 0 count
sub r2, r0 ; (r0) = Constant - count (ticks elapsed)
.endm
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
LEAF_ENTRY _Timer0ISR
.aif CLOCK_LEDS eq 1
mov #LED_ALPHA, r1 ; (r1) = LED address
mov.l @r1, r0
add #-1,r0
and #h'ff,r0 ; restrict change to lights only
mov.l r0, @r1 ; put it in lights
.aendi
.aif CLOCK_LEDS eq 2
mov.l #LEDState, r1
mov.l @r1, r0
mov.l @(4,r1),r3
cmp/EQ #1, r0
bf LED1
mov #0, r1
shll2 r3
shll2 r3
cmp/EQ r3,r1
bf LED2
mov #0, r0
mov #h'10000000, r3
bra LED2
LED1:
mov #0, r1
shlr2 r3
shlr2 r3
cmp/EQ r3,r1
bf LED2
mov #1, r0
mov #h'1, r3
LED2:
mov.l #LEDState, r1
mov.l r0, @r1
mov.l r3, @(4,r1)
mov #LED_ALPHA, r1 ; (r1) = LED address
mov.l r3, @r1 ; put it in lights
.aendi
;-------------------------------------------------------
; Check for IntrTime measurements (COMMON)
;
mov #_fIntrTime, r1 ; (r1) = ptr to fIntrTime gate
mov @r1, r6 ; (r6) = fIntrTime
tst r6, r6
bt skip_isrtime1
;-------------------------------------------------------
; Get ISR latency and saved program counter (INTRTIME)
;
PERFCOUNT_MACRO ; (r0) = PerfCountSinceTick()
mov #_dwIsrTime1, r1
mov r0, @r1 ; dwIsrTime1 = (r0)
stc spc, r0
mov #_dwSPC, r1
mov.l r0, @r1 ; Save Program Counter
mov #_wNumInterrupts, r0 ; (r0) = addr of interrupt counter
mov @r0, r1 ; (r1) = interrupt counter
add #1, r1 ; Increment counter
mov r1, @r0 ; Save interrupt counter
skip_isrtime1:
;-------------------------------------------------------
; Clear the timer interrupt (COMMON)
;
mov #TMU_REGBASE, r1 ; (r1) = ptr to timer unit registers
mov.w @(TMU_TCR0_OFFSET,r1), r0
tisr10: and #h'ff, r0 ; clear timer underflowed flag
mov.w r0, @(TMU_TCR0_OFFSET,r1) ; & and set new tcr0 value
mov #1, r3
mov.w @(TMU_TCR0_OFFSET,r1), r0
shll8 r3 ; (r3) = 0x100 (underflow bit)
tst r3, r0
bf tisr10 ; bit not clear, go clear it again!
;-------------------------------------------------------
; Blink the discrete LED's (COMMON)
;
; mov #LED_DISCRETE, r1 ; (r1) = LED address
; mov.l @r1, r0
; add #1,r0
; and #h'ff,r0 ; restrict change to lights only
; mov.l r0, @r1 ; put it in lights
;-------------------------------------------------------
.aif CE_MAJOR_VER == h'0003
; Update CurMSec and DiffMSec (COMMON)
;
mov #_CurMSec, r2 ; (r2) = ptr to counters
mov.l @r2, r3 ; (r3) = current millisecond count
mov #_DiffMSec, r0 ; (r0) = ptr to DiffMSec
mov.l @r0, r1 ; (r1) = millisecond delta
add #RESCHED_PERIOD, r3
add #RESCHED_PERIOD, r1
mov.l r3, @r2 ; update current millisecond counter
mov.l r1, @r0 ; update millisecond delta
.aelse
; Update CurMSec (COMMON)
;
mov #_CurMSec, r0 ; (r0) = ptr to counters
mov.l @r0, r1 ; (r1) = current millisecond count
add #RESCHED_PERIOD, r1
mov.l r1, @r0 ; update current millisecond counter
.aendi
;-------------------------------------------------------
; Update CurTicks (COMMON)
;
mov #_CurTicks, r0 ; (r0) = ptr to CurTicks
mov.l @r0, r2 ; (r2) = CurTicks lower DWORD
mov #_dwReschedIncrement, r3; (r3) = ptr to dwReschedIncrement
mov.l @r3, r3 ; (r3) = number of ticks per resched
clrt
addc.l r3, r2 ; increment tick count by resched period
bf/s nocarry ; skip next section if no carry
mov.l r2, @r0 ; update CurTicks lower DWORD
mov.l @(4,r0), r2 ; (r2) = CurTicks upper DWORD
mov #1, r3 ; (r3) = 1
add.l r3, r2 ; carry to upper DWORD
mov.l r2, @(4,r0) ; update CurTicks upper DWORD
nocarry:
tst r6, r6 ; (r6) = fIntrTime
bt normal
;-------------------------------------------------------
; Check the countdown (INTRTIME)
;
mov #_dwIntrTimeCountdown, r2
mov @r2, r0 ; (r0) = dwIntrTimeCountdown
add #-1, r0
tst r0, r0
bf/s normal
mov r0, @r2 ; dwIntrTimeCountdown--
mov #_dwIntrTimeCountdownRef, r0
mov @r0, r0 ; (r0) = dwIntrTimeCountdownRef
mov r0, @r2 ; Countdown = Reference
; Zero wNumInterrupts, which counts interrupts since SYSINTR_TIMING
mov #_wNumInterrupts, r0 ; (r0) = addr of interrupt counter
mov #0, r1 ; (r1) = 0
mov r1, @r0 ; Zero interrupt counter
;-------------------------------------------------------
; Get end-of-ISR time. (INTRTIME)
;
PERFCOUNT_MACRO ; (r0) = PerfCountSinceTick()
mov #_dwIsrTime2, r2
mov r0, @r2 ; dwIsrTime2 = (r0)
.aif CLOCK_LEDS eq 3
;-------------------------------------------------------
; Verification of INTRTIMEs with a Logic Analyzer (INTRTIME)
;
;Davli
; mov #h'A4060014, r2 ; (r1) = Debug LED address
; mov.l #h'12340001, r0 ;
; mov.l r0, @r2 ; Capture on Logic Analyzer
.aendi
mov #SYSINTR_TIMING, r0
rts
nop
;-------------------------------------------------------
; Normal processing (NORMAL)
.aif CE_MAJOR_VER == h'0003
; (cedar)
; (r1) = DiffMSec
;
normal:
mov #_ticksleft, r0
mov @r0, r0
cmp/EQ #0, r0
bf doresched
mov #_dwSleepMin, r0
mov @r0, r0
cmp/EQ #0,r0
bt part2
cmp/ge r0, r1
bt doresched
part2:
mov #_dwPreempt, r0
mov @r0, r0
cmp/EQ #0, r0
bt noresched
cmp/ge r0, r1
bt doresched
.aelse
; (dougfir or later)
; (r1) = CurMSec
;
normal:
mov #_dwReschedTime, r0 ; r0 = &dwReschedTime
mov @r0, r0 ; r0 == dwReschedTime
sub r1, r0 ; r0 == dwReschedTime - CurMSec
mov #0, r2 ; r2 == 0
cmp/ge r0, r2 ; (int) (dwReschedTime - CurMSec) <= 0?
bt doresched ; reschedule if true
.aendi
noresched:
rts
mov #SYSINTR_NOP, r0
doresched:
rts
mov #SYSINTR_RESCHED, r0 ; must set reschedule flag
.endf
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
LEAF_ENTRY _Timer2ISR
;-------------------------------------------------------
; Clear the timer interrupt
;
mov #(TMU_REGBASE + TMU_TCR2_OFFSET), r1 ; (r1) = ptr to timer unit registers
mov.w @r1, r0
tisr1: and #h'ff, r0 ; clear timer underflowed flag
mov.w r0, @r1 ; & and set new tcr0 value
mov #1, r3
mov.w @r1, r0
shll8 r3 ; (r3) = 0x100 (underflow bit)
tst r3, r0
bf tisr1 ; bit not clear, go clear it again!
;-------------------------------------------------------
; Update dwPerfCountHigh
;
mov #_dwPerfCountHigh, r2 ; (r2) = &dwPerfCountHigh
mov.l @r2, r3 ; (r3) = dwPerfCountHigh
add #1, r3
mov.l r3, @r2 ; dwPerfCountHigh++
rts
mov #SYSINTR_NOP, r0
.endf
.end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?