1        ;; pm.asm
2        ;;
3
4        list    p=16c84
5
6include "p16c84.inc"
7
8  cblock  0x0c
9
10        lo,hi,_upper,kz
11  endc
12
13ioport  equ     portb
14iobit   equ     0
15
16
17        org 0
18
19start:
20        clrf  lo
21        clrf  hi
22        clrf  _upper     ;Used as a known zero in
23                        ;the loop
24        call    cnt16bit
25
26
27        goto    start
28
29measure:
30;-----------------------------------------------
31;pulse width measurements with 3 Tcyc resolution
32;
33;The purpose of this routine is to accurately measure
34;the width of a pulse. The resolution is 3 instruction
35;cycles and the dynamic range is 19 bits or 3*2^19 cycles.
36;(That's 1,572,864 cycles which is approximately pi/10
37;seconds on a 20Mhz pic.)
38;
39;
40
41        btfsc   ioport,iobit
42         goto   $-1
43
44loop
45   btfsc ioport,iobit   ;If the pulse is over
46    goto high0          ;then adjust the count
47                        ;
48   movlw 1              ;Otherwise, intertwine the counter
49                        ;incrementing with the pulse checking
50   btfsc ioport,iobit   ;
51    goto high1          ;
52                        ;
53   addwf lo,f           ;Increment the lo byte
54                        ;
55   btfsc ioport,iobit   ;
56    goto high2          ;
57                        ;
58   rlf   _upper,w        ;Pick up the carry (if lo byte
59                        ;overflowed)
60   btfsc ioport,iobit   ;
61    goto high3          ;
62                        ;
63   addwf hi,f           ;Increment the high byte
64                        ;
65   btfsc ioport,iobit   ;
66    goto high4          ;
67                        ;
68   skpc                 ;If the high byte rolls over
69    btfsc ioport,iobit  ;or the pulse is over
70     goto high5_or_done ;then get out of the loop
71                        ;
72   clrwdt               ;Could be a nop or some inst.
73                        ;
74   btfsc ioport,iobit   ;
75    goto high6          ;
76                        ;
77   nop                  ;
78                        ;
79   btfss ioport,iobit   ;Note that we check the opp. level
80    goto loop           ;
81
82  ;fall through... Add 7 to the total count
83
84   incf  _upper,f
85
86high6:
87   incf  _upper,f
88
89high5_or_done:
90   skpnc            ;If c=1 then we have an
91    goto overflow   ;overflow
92
93   incf  _upper,f
94
95high4:
96   incf  _upper,f
97
98high3:
99   incf  _upper,f
100
101high2:
102   decf  lo,f       ;Get rid of the extra
103                    ;increment of the lo byte
104   incf  _upper,f
105
106high1:
107   incf  _upper,f
108
109high0:
110
111
112   rlf   _upper,f
113
114   rlf   lo,f
115   rlf   hi,f
116   rlf   _upper,f
117
118   rlf   lo,f
119   rlf   hi,f
120   rlf   _upper,f
121
122   rlf   lo,f
123   rlf   hi,f
124   rlf   _upper,f
125
126   swapf _upper,w
127   andlw 7
128   iorwf lo,f
129
130   movlw 7
131   andwf _upper,f
132
133   retlw 0
134
135overflow
136   ;If we get here, then there was an overflow.
137   ;it turns out that all three bytes of the
138   ;counter are zero. Decrementing all three
139   ;will set them to 0xff.
140
141   decf  _upper,f
142   decf  hi,f
143   decf  lo,f
144
145   retlw 0xff
146
147
148CONST		EQU	0
149CNT_PER_LOOP	EQU	7
150
151cnt16bit:
152        clrf    kz
153        clrf    lo
154        clrf    hi
155
156
157        movlw   CNT_PER_LOOP	;preset counts
158
159	btfsc   ioport,iobit
160	 goto	$-1
161
162loop1   btfsc   ioport,iobit
163         goto   quit1           ;1
164
165        addwf   lo,f            ;inc lo cnt
166        btfsc   ioport,iobit
167         goto   quit2           ;2
168
169        rlf     kz,w            ;get carry
170        btfsc   ioport,iobit
171         goto   quit3           ;3-2
172
173        addwf   hi,f            ;hi incremented depends on carry
174        btfsc   ioport,iobit
175         goto   quit4           ;4-2
176
177        skpc                    ;check if already finished
178        btfsc   ioport,iobit
179         goto   quit5           ;5-2
180
181        movlw   CNT_PER_LOOP	;add uncounted tests
182        btfsc   ioport,iobit
183         goto   quit6           ;6-2
184
185        btfss   ioport,iobit
186         goto   loop1
187                                ;7-2
188
189quit7   incf    kz,f            ;add uncounted tests
190quit6   incf    kz,f
191
192
193quit5   skpnc
194         goto   overflow1
195
196        movlw   -CNT_PER_LOOP + 4  ;
197	addwf	kz,w
198        addwf   lo,f
199        skpc
200         decf   hi,f
201	clrf	kz
202	return
203
204quit4   incf    kz,f
205        subwf   hi,f    ;counter-act the addwf
206
207quit3   incf    kz,f
208quit2
209   ;subtract the 7 added in above - the incf's
210   ;will keep track of how much needs to be added
211   ;back. ignore the C, since the loop didn't get
212   ;a chance to handle it.
213
214        movlw   -CNT_PER_LOOP + 1  ;+1 in lieu of incf kz,f
215        addwf   lo,f
216
217quit1   incf    kz,w
218
219        addlw	CONST   	;take into account
220                                ;initial latency
221        addwf   lo,f
222        skpnc
223         incf   hi,f
224
225        clrf    kz
226
227        return
228
229overflow1
230        movlw   0xff
231        movwf   lo
232        movwf   hi
233        clrf    kz
234        return
235
236
237  end
238