By Nikolai Golovchenko
; Pulse width capture test
;
; Board: SX Demo/Proto Board
;
; Three routines are tested - 8 bit, 16 bit, and 24 bit. The resolution
; is 4 cycles in every case. Testing is done manually in step mode.
;
; A routine is selected by three buttons at RB3, RB2, RB1:
;
; RB3=0 - 8-bit
; RB2=0 - 16-bit
; RB1=0 - 24-bit
;
; A pulse is generated manually by pressing a button at RB0.
;
; The pulse measurement code is based on Scott Dattalo's idea.
;
; May 10, 2001
; by Nikolai Golovchenko
DEVICE SX28L, OSCHS2, TURBO, STACKX, OPTIONX
RESET start
ORG $08 ;global bank
pulse0 DS 1 ;LSB of the counter
pulse1 DS 1
pulse2 DS 1 ;MSB
ORG $10 ;bank0
ORG $30 ;bank1
ORG $50 ;bank2
ORG $70 ;bank3
ORG $90 ;bank4
ORG $B0 ;bank5
ORG $E0 ;bank6
ORG $F0 ;bank7
RA_DIR EQU %00000000
RB_DIR EQU %00001111
;RB.0 .. RB.3 - button inputs
RC_DIR EQU %00000000
;input port pins
but_8 EQU RB.3
but_16 EQU RB.2
but_24 EQU RB.1
pulse EQU RB.0
OPTION_INIT EQU $7F ;OPTION load value
;x--- ---- 0 = register 01h addresses w
;-x-- ---- 1 = RTCC roll-over interrupt is disabled
;--x- ---- 1 = RTCC increments upon transition on RTCC pin
;---x ---- 1 = RTCC increments on high-to-low transitions
;---- x--- 1 = Prescaler is assigned to WDT, and divide rate on
; RTCC is 1:1
;---- -xxx 111 = Prescaler divider 1:128 (WDT)
;****************************************************************************
; Start of program
;****************************************************************************
ORG $000 ;page 0
start
;init ports
clr RA
clr RB
clr RC
mov w, #RA_DIR
mov !RA, w
mov w, #RB_DIR
mov !RB, w
mov w, #RC_DIR
mov !RC, w
;load option and make w addressable
mov w, #OPTION_INIT
mov !OPTION, w
;****************************************************************************
; Main loop:
; 1) wait a transition in pulse from 0 to 1
; 1) select the test routine
; 2) measure the pulse width
; 3) goto 1
;****************************************************************************
loop
;wait the low to high transition
snb pulse
jmp $-1
sb pulse
jmp $-1
;select and run the test routine
call select
;repeat
jmp loop
;selection routine
select
sb but_8
jmp mpulse8 ;call pulse8 and return
sb but_16
jmp mpulse16 ;call pulse16 and return
sb but_24
jmp mpulse24 ;call pulse24 and return
retp ;if nothing selected just return
;****************************************************************************
; 8 bit pulse width measurement at 4 cycle resolution
;
; Return values at check points A and B (see below) will be:
; Check point: A B A B A B A B ...
; Counter value: 1 2 3 4 5 6 7 8 ...
;
; Size: 11 instruction words
;****************************************************************************
mpulse8
mov w, #1 ;init counter
mov pulse0, w
mov w, #2 ;init increment size
mpulse8_loop
sb pulse ;check input the first time (A)
jmp mpulse8a ; if low, exit
add pulse0, w ;increment counter by two
nop ;wait a cycle to sample at an equal interval
;instead of nop we can restart the watchdog:
; clrwdt
;or check the counter overflow:
; sc
snb pulse ;check input the second time (B)
jmp mpulse8_loop
;here the pulse end was detected after the second input check - correct the
;counter
clrb pulse0.0
mpulse8a
;here the pulse end was detected after the first input check - leave the counter
;unchanged; if we fall here from the second input check, don't change counter
;either.
retp ;return
;****************************************************************************
; 16 bit pulse width measurement at 4 cycle resolution
;
; Return values at check points A, B, and C (see below) will be:
; Check point: A B C A B C A B C A ...
; Counter value: 0 1 2 3 4 5 6 7 8 9 ...
;
; Size: 23 instruction words
;****************************************************************************
mpulse16
clr pulse0 ;clear LSB of the counter
clr pulse1 ;clear MSB of the counter
mov w, #3 ;init increment size
mpulse16loop
sb pulse ;check input the first time (A)
jmp mpulse16a ; if low, exit
add pulse0, w ;increment counter by three
nop ;wait a cycle to sample at an equal interval
;instead of nop we can restart the watchdog:
; clrwdt
;or check the counter overflow:
; sb pulse1.7 - counter value is limited to 0..32770
;or: sb pulse1.6 - counter value is limited to 0..16387
;or: sb pulse1.5 - counter value is limited to 0..8197
;or: sb pulse1.4 - counter value is limited to 0..4099
;
sb pulse ;check input the second time (B)
jmp mpulse16b
snc ;propagate carry to the higher byte
inc pulse1 ;
snb pulse ;check input the third time (C)
jmp mpulse16loop
;here we construct the correction value in w according to the check point -
;A (w = 0), B (w = 2), or C (w = 1). Then counter is then corrected -
;pulse = pulse - w.
;point C entry
xor w, #$03 ;3^3^2^3 = 1
clc ;clear carry to avoid following carry propagation
;point B entry
mpulse16b
xor w, #$02 ;3^2^3 = 2
snc ;propagate carry if we didn't finish the addition
inc pulse1 ;
;point A entry
mpulse16a
xor w, #$03 ;3^3 = 0
;correct counter
sub pulse0, w
sc
dec pulse1
;return
retp
;****************************************************************************
; 24 bit pulse width measurement at 4 cycle resolution
;
; Return values at check points A, B, C and D (see below) will be:
; Check point: A B C D A B C D A B C D A ...
; Counter value: 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
;
; Size: 39 instruction words
;****************************************************************************
mpulse24
clr pulse0 ;clear LSB of the counter
clr pulse1 ;clear middle byte of the counter
clr pulse2 ;clear MSB of the counter
mov w, #1 ;init increment size
mpulse24loop
sb pulse ;check input the first time (A)
jmp mpulse24a ; if low, exit
add pulse0, w ;increment counter by one
nop ;wait a cycle to sample at an equal interval
;instead of nop we can restart the watchdog:
; clrwdt
;or check the counter overflow:
; sb pulse2.6 - counter value is limited to 0..2^24
;or: sb pulse2.5 - counter value is limited to 0..2^23
;or: sb pulse2.4 - counter value is limited to 0..2^22
;etc...
;
sb pulse ;check input the second time (B)
jmp mpulse24b
snc ;propagate carry to the higher byte
add pulse1, w ;
sb pulse ;check input the third time (C)
jmp mpulse24c
snc ;propagate carry to the higher byte
add pulse2, w ;
snb pulse ;check input the fourth time (D)
jmp mpulse24loop
;here we construct the correction value in w according to the check point -
;A (w = 3), B (w = 0), C (w = 1), or D (w = 2). Then counter is then corrected -
;pulse = (pulse << 2) + w.
;
;for simplicity, the two lower bits can be shifted into pulse, but the bits
;should be reversed:
;A (w = 3), B (w = 0), C (w = 2), or D (w = 1)
;point D entry
xor w, #$03 ;1^3^2^3^2 = 1
clc ;clear carry to avoid following carry propagation
;point C entry
mpulse24c
xor w, #$02 ;1^2^3^2 = 2
snc ;propagate carry if we didn't finish the addition
inc pulse2 ;
clc ;clear carry to avoid following carry propagation
;point B entry
mpulse24b
xor w, #$03 ;1^3^2 = 0
snc ;propagate carry if we didn't finish the addition
incsz pulse1 ;
dec pulse2 ;
inc pulse2 ;
;point A entry
mpulse24a
xor w, #$02 ;1^2 = 3
;correct counter
rr WREG
rl pulse0
rl pulse1
rl pulse2
rr WREG
rl pulse0
rl pulse1
rl pulse2
;return
retp
;****************************************************************************
ORG $200 ;page 1
ORG $400 ;page 2
ORG $600 ;page 3