File content as of revision 0:eea8d19a7f6b:
AREA asm_func, CODE, READONLY
; Export my asm function locaiton so that the C compiler can find it and link
EXPORT setup_counter
EXPORT measure_clock_cycles
;
ALIGN
;
setup_counter
;
; Setup base address for Timer/Counter
LDR r2, =0x40040000
; Setup data for control register, although don't start it yet
; TFC set HIGH prevents reset when CNR >= CMR so TCF can be detected
; TCF is cleared when timer is disabled after reading value
LDR r0, =0x06
STRB r0, [r2, #0x00] ; Setup control register
; Setup compare register
;STRH r0, [r2, #0x08]
; If prescalar is zero, set the register to all 0, CMPS also sets flags
CMPS r1, #0
BEQ set_pre_zero
; Generate prescale register and store, recycle r0 as its finished with
LDR r0, =0x03
LSLS r1, r1, r0 ; Shifts prescale value to the left 3 places
LDR r0, =0x04
ORRS r1, r1, r0 ; Sets prescalar enable flag appropiately
LDR r0, =0x78
ANDS r1, r1, r0 ; Ensure only the necessary bits are set, maybe redundant
B continue ; Skip setting register value to zero if above code is executed
set_pre_zero
LDR r1, =0x00000000
continue
STRB r1, [r2, #0x04] ; Setup prescale register appropriataly
; Setup base address for SysTick
LDR r2, =0xE000E010
; Setup SysTick and start
LDR r0, [r2, #0x00] ; Grab current SysTick control state
LDR r1, =0x05 ; Mask to set SysTick clock source as processor clock and start it running
ORRS r0, r0, r1
STR r0, [r2, #0x00]
; Return to previous code
BX LR
;
measure_clock_cycles
; r0 -> Channel Data, r1 -> SAMPLES
; Preserve state of all affected registers (ARM convention only requires this on r4 -> r11)
PUSH {r4-r6}
; Setup base address for Timer/Counter
LDR r2, =0x40040000
; Grab current control status register and prepare with sensor and enable
LDR r3, =0x03
ANDS r0, r0, r3 ; Trims sensor value to 2 bits in case value larger than 0x03 passed
LDR r3, =0x04
LSLS r0, r0, r3 ; Shift timer pin select to appropriate location
LDR r3, =0x80
ORRS r0, r0, r3 ; Set TCF flag
LDR r3, [r2, #0x00] ; Grab current control register state
ORRS r0, r0, r3 ; Combine with previous register state
STR r0, [r2, #0x00] ; Save control register
LDR r1, [r2, #0x08] ; Set compare register to number of samples
LDR r5, =0x80 ; Mask for TCF
BICS r0, r0, r4 ; Disable TCF flag
STR r0, [r2, #0x00] ; Set control register with TCF disabled
; Save current tick count of cpu
LDR r3, =0xE000E010 ; Base address of SysTick
LDR r4, [r3, #0x08]
; Start timer
STR r0, [r2, #0x00]
; Wait until TCF = 1 in Timer/Counter
loop
LDR r0, [r2, #0x00]
ANDS r0, r0, r5
BEQ loop ; Loops while TCF flag is zero
; Save current tick count of cpu
LDR r5, [r3, #0x08]
; Disable timer by toggling bit
LDR r3, =0x01
LDR r6, [r2, #0x00]
EORS r3, r3, r6
STR r3, [r2, #0x00]
; Compute time difference and place it into r0, r0 is the return value of the function
MOV r0, r4
SBCS r0, r0, r5 ; r0 = r4 - r5 (With sign)
BPL finish ; If result of subtraction creates a negative number, return value, otherwise recalculate
LDR r3, =0x00FFFFFF
SUBS r0, r3, r5 ; r0 = (2^24 - 1 - r5) + r4
ADDS r0, r0, r4
finish
;LDR r0, [r2, #0x00]
; Return registers to previous states
POP {r4-r6}
; Return to previous code
BX LR
;
ALIGN
END