1 ;======================================================================
6 ;======================================================================
7 ; VARIABLES, HARDWARE, ETC
9 ; Timer 3 pointmsg pointslave cducharging
11 ; S Idle Off undefined undefined undefined
12 ; S Firing Counting up 100PPPPP undefined undefined
13 ; M Idle Off 00000000 0000 0000 0x00
14 ; M Firing Counting up 100PPPPP 0000 0000 0x00
15 ; M Telling Off 100PPPPP 00SS Sss0 0x00
16 ; M Told Off 100PPPPP 0000 0000 0x00
17 ; M Charging Off 00000000 0000 0000 >0
19 ; notes: firing see ie, slave*2 Counts down
20 ; timeout detect.asm in ticks
22 ; cducharging only counts if the cdu is enabled
23 ; (according to CDU Enable LAT bit)
25 cdu_timeout equ 200 ; ms
27 ptix2latbit equ 0x300 ; has to be a multiple of 0x100
28 ptix2latbit_section udata ptix2latbit
29 res maxpoints * 2 ; LAT* and bit
30 ; for unused point, 0x00 and 0x00
38 slave2ptinfo res maxpics
39 slave2ptinfo_anypoints equ 0
41 ;======================================================================
43 ; on slave, or master's own
45 ;----------------------------------------------------------------------
46 ; LOCAL POINTS - ACTUALLY DOING
49 ;----------------------------------------
51 ; On slave, called during i2c receive, ie High ISR
52 ; On master, called during serial receive, ie Low ISR
53 ; W fire point msg undefined
54 bt_f_if1 T3CON, TMR3ON
57 mov_wf pointmsg ; pointmsg = SS zz zz pp pp pp pp pp
59 intrh_fsr0_save ; point_set_pin uses FSR0, see below
63 clr_f TMR3L ; also copies TMR3H into actual timer register
72 ;----------------------------------------
76 ; OK, it's us, and we're done changing a point:
78 bt_f_if0 T3CON, TMR3ON
79 bra point_spurious_intr
88 call message_for_master
97 ; Toggles the pin. The effect is:
98 ; If we were idle, sets it H (to fire) unless pt0 in which case L
99 ; If we were firing, sets it L (to stop) unless pt0 in which case H
101 ; Called in various contexts, including both High and Low ISR.
103 ; pointmsg point to start or stop firing preserved
104 ; W,STATUS any undefined
106 ; all other any not interfered with
108 mov_lw ptix2latbit >> 8
109 mov_wf FSR0H ; FSR0H -> table
110 rl_fw pointmsg ; W = point addr, Z iff pt0
111 mov_wf FSR0L ; FSR0 -> &bit [Z still iff pt0]
112 mov_fw POSTDEC0 ; W = bit, FSR0 -> &LAT*
113 bra_z point_nonexistent
114 mov_ff INDF0, FSR0L ; W = bit, FSR0L -> LAT*
115 set_f FSR0H ; FSR0 -> LAT*, W = bit (still)
116 xor_wff INDF0 ; pin = !pin
123 ;----------------------------------------------------------------------
124 ; LOCAL POINTS - INITIALISATION
126 ;----------------------------------------
128 ; Initialises tables for points
129 ; Clears TRIS* bits for all points and sets each pin to `not triggering'
131 rcall point_timer_init
133 ; We do this in two stages.
134 ; Firstly, we scan the bitmap for this pic, setting
135 ; ptix2latbit to 0xff,0x00 for used points and 0x00,0x00
137 ; Secondly, we scan the bkptix2portnumbitnum, adjusting
138 ; ptix2latbit to have actually correct data.
139 ; Doing it like this avoids having to constantly recompute
140 ; individual TBLPTR*'s.
142 mov_lfsr ptix2latbit-1, 0 ; FSR0 -> this bit and LAT*
143 ; points just at last thing we've filled in
145 load_perpic_tblptr picno2ptmap, maxpoints/8
148 mov_wf t ; t = byte counter
150 points_init_byte_loop
151 mov_lw 8 ; W = bit counter
152 tblrd_postinc_fixup ; TABLAT = bitmap data being processed
155 clr_f PREINC0 ; FSR0 -> LAT*[current] := 0
158 set_f INDF0 ; FSR0 -still-> LAT*[current] := 0xff
160 clr_f PREINC0 ; FSR0 -> bit[current] := 0
163 bra points_init_bit_loop
165 bra points_init_byte_loop
168 ; We've scanned for points used on this board;
169 ; now find the actual pins.
171 mov_lw bkptix2portnumbitnum & 0xff
172 bt_f_if1 idloc1,idloc1_boarddet
176 mov_lw bkptix2portnumbitnum >> 8
177 mov_wf TBLPTRH ; TBLPTR* -> point port/bit data
179 set_f FSR2H ; FSR2 -> some SFR, will point to LAT/TRIS
180 mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7
181 mov_lfsr ptix2latbit-1, 0 ; FSR0 -> last bit (and previous LAT*)
184 mov_wf t ; t = loop counter
186 points_init_portbit_loop
187 tblrd_postinc_fixup ; TABLAT = portnum4 || bitnum4
189 bt_f_if0 PREINC0,7 ; zero?, FSR0 -> LAT*[this]
190 bra points_init_portbit_endif_used
192 points_init_portbit_if_used
194 bra_n point_initing_bad_point
196 ior_lw 0xf8 ; W -> bit value for bit
197 mov_wf FSR1L ; FSR1 -> bit value for bit
199 swap_fw TABLAT ; W = bitnum4 || portnum4
200 and_lw 0x0f ; W = portnum4
201 add_lw LATA & 0xff ; W = LAT*
202 mov_wf POSTINC0 ; LAT*[this] := LAT, FSR0 -> bit[this]
203 mov_wf FSR2L ; FSR2 -> LAT*
205 mov_fw INDF1 ; W = bit
206 mov_wf POSTDEC0 ; bit[this] = bit, FSR0 -> LAT*[this]
208 and_wff INDF2 ; LAT* &= ~bit, ie pin set to L (still Z)
209 pin_vh pall_pt0reverse ; but pt0 pin is backwards, set to H
210 ; (still Z, unless we've done this already)
212 add_wff FSR2L ; FSR2 -> TRIS*
213 com_fw INDF1 ; W = ~bit
214 and_wff INDF2 ; TRIS* &= ~bit, ie pin set to not Z
216 set_f FSR1L ; FSR1 -> bitnum2bit+7, again
217 points_init_portbit_endif_used
218 ; so now we move on to the next one
219 mov_fw POSTINC0 ; FSR0 -> bit[this]
222 bra points_init_portbit_loop
227 point_initing_bad_point
232 bt_f_if1 idloc1,idloc1_master
233 bra point_timer_init_if_master
235 mov_lw (1<<RD16)|(1<<T3ECCP1)| points_slave_t3scale; Fcy;!TMR3ON
237 mov_lw points_slave_t3inith
238 bra point_timer_init_endif_masterslave
239 point_timer_init_if_master
240 mov_lw (1<<RD16)|(1<<T3ECCP1)| points_master_t3scale; Fcy;!TMR3ON
242 mov_lw points_master_t3inith
243 point_timer_init_endif_masterslave
244 mov_wf TMR3H ; We just leave this here.
245 ; Since we never read TMR3L, it is never overwritten
252 ;======================================================================
255 ;----------------------------------------------------------------------
260 load_tblptr picno2ptmap
261 mov_lfsr slave2ptinfo-1, 0
264 points_master_init_board_loop
267 points_master_init_byte_loop
270 bs_f INDF0, slave2ptinfo_anypoints
272 bra points_master_init_byte_loop
274 bra points_master_init_board_loop
278 ;----------------------------------------------------------------------
280 ; FSR0 -> 1 0100 TTT O TTTTTTT
284 bra command_point_busy
286 tst_f_ifnz cducharging
287 bra command_point_cduempty
289 swap_fw POSTINC0 ; W = 0SSS 1010
290 and_lw 0x70 ; W = 0SSS 0000
292 mov_wf pointslave ; pointslave = 00SS S000
294 mov_fw INDF0 ; W = OssT tttt N = O
295 bra_n command_point_badmsg
296 ; OK: ; W = 0ssT tttt
297 and_lw 0x1f ; W = 000T tttt
298 bs_w 7 ; W = 100T tttt
299 mov_wf pointmsg ; pointmsg = 100T tttt
301 swap_fw INDF0 ; W = tttt 0ssT
302 and_lw 0x06 ; W = 0000 0ss0
303 ior_wff pointslave ; pointslave = 00SS Sss0
305 rr_fw pointslave ; W = 000S SSss
306 bra_nz command_point_ifslave
311 command_point_badmsg panic morse_PX
312 command_point_busy panic morse_PB
313 command_point_cduempty panic morse_PC
316 command_point_ifslave
317 mov_lfsr slave2ptinfo, 0
319 bt_f_if1 INDF0, slave2ptinfo_anypoints
326 rr_fw pointslave ; W = 000S SSss
327 bt_f_if1 STATUS, Z ; nothing ?
329 ; we need to write something:
340 bt_f_if0 STATUS, Z ; right slave ?
343 clr_f pointslave ; we're writing now, excellent
345 goto i2c_getwritebyte_yes
347 ;======================================================================
350 ;--------------------
362 mov_lw (cdu_timeout * 1000) / tickdiv_us + 1
366 ;--------------------
371 ;--------------------
373 pinlat_ifl p0_cdu_enable
376 tst_f_ifnz cducharging
377 dec_f_ifnz cducharging ; so, decrement only if it was nonzero
378 return ; return if we either didn't decrement,
379 ; or didn't reach zero
381 ; cducharging is already zero, from above
382 mov_lw b'00101000' ; CHARGED
386 ;--------------------
388 tst_f_ifnz cducharging
389 bra pointed_already_charging
392 bra pointed_butnot_firing
396 mov_lw b'00100000' ; POINTED
399 pointed_butnot_firing panic morse_PA
400 pointed_already_charging panic morse_PQ
402 ;======================================================================