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
26 cdu_inittimeout equ 750 ; ms
28 ptix2latbit equ 0x300 ; has to be a multiple of 0x100
29 ptix2latbit_section udata ptix2latbit
30 res maxpoints * 2 ; LAT* and bit
31 ; for unused point, 0x00 and 0x00
39 slave2ptinfo res maxpics
40 slave2ptinfo_anypoints equ 0
42 ;======================================================================
44 ; on slave, or master's own
46 ;----------------------------------------------------------------------
47 ; LOCAL POINTS - ACTUALLY DOING
50 ;----------------------------------------
52 ; On slave, called during i2c receive, ie High ISR
53 ; On master, called during serial receive, ie Low ISR
54 ; W fire point msg undefined
55 bt_f_if1 T3CON, TMR3ON
58 mov_wf pointmsg ; pointmsg = SS zz zz pp pp pp pp pp
60 intrh_fsr0_save ; point_set_pin uses FSR0, see below
64 clr_f TMR3L ; also copies TMR3H into actual timer register
73 ;----------------------------------------
77 ; OK, it's us, and we're done changing a point:
79 bt_f_if0 T3CON, TMR3ON
80 bra point_spurious_intr
89 call message_for_master
98 ; Toggles the pin. The effect is:
99 ; If we were idle, sets it H (to fire) unless pt0 in which case L
100 ; If we were firing, sets it L (to stop) unless pt0 in which case H
102 ; Called in various contexts, including both High and Low ISR.
104 ; pointmsg point to start or stop firing preserved
105 ; W,STATUS any undefined
107 ; all other any not interfered with
109 mov_lw ptix2latbit >> 8
110 mov_wf FSR0H ; FSR0H -> table
111 rl_fw pointmsg ; W = point addr, Z iff pt0
112 mov_wf FSR0L ; FSR0 -> &bit [Z still iff pt0]
113 mov_fw POSTDEC0 ; W = bit, FSR0 -> &LAT*
114 bra_z point_nonexistent
115 mov_ff INDF0, FSR0L ; W = bit, FSR0L -> LAT*
116 set_f FSR0H ; FSR0 -> LAT*, W = bit (still)
117 xor_wff INDF0 ; pin = !pin
124 ;----------------------------------------------------------------------
125 ; LOCAL POINTS - INITIALISATION
127 ;----------------------------------------
129 ; Initialises tables for points
130 ; Clears TRIS* bits for all points and sets each pin to `not triggering'
132 rcall point_timer_init
134 ; We do this in two stages.
135 ; Firstly, we scan the bitmap for this pic, setting
136 ; ptix2latbit to 0xff,0x00 for used points and 0x00,0x00
138 ; Secondly, we scan the bkptix2portnumbitnum, adjusting
139 ; ptix2latbit to have actually correct data.
140 ; Doing it like this avoids having to constantly recompute
141 ; individual TBLPTR*'s.
143 mov_lfsr ptix2latbit-1, 0 ; FSR0 -> this bit and LAT*
144 ; points just at last thing we've filled in
146 load_perpic_tblptr picno2ptmap, maxpoints/8
149 mov_wf t ; t = byte counter
151 points_init_byte_loop
152 mov_lw 8 ; W = bit counter
153 tblrd_postinc_fixup ; TABLAT = bitmap data being processed
156 clr_f PREINC0 ; FSR0 -> LAT*[current] := 0
159 set_f INDF0 ; FSR0 -still-> LAT*[current] := 0xff
161 clr_f PREINC0 ; FSR0 -> bit[current] := 0
164 bra points_init_bit_loop
166 bra points_init_byte_loop
169 ; We've scanned for points used on this board;
170 ; now find the actual pins.
172 mov_lw bkptix2portnumbitnum & 0xff
173 bt_f_if1 idloc1,idloc1_boarddet
177 mov_lw bkptix2portnumbitnum >> 8
178 mov_wf TBLPTRH ; TBLPTR* -> point port/bit data
180 set_f FSR2H ; FSR2 -> some SFR, will point to LAT/TRIS
181 mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7
182 mov_lfsr ptix2latbit-1, 0 ; FSR0 -> last bit (and previous LAT*)
185 mov_wf t ; t = loop counter
187 points_init_portbit_loop
188 tblrd_postinc_fixup ; TABLAT = portnum4 || bitnum4
190 bt_f_if0 PREINC0,7 ; zero?, FSR0 -> LAT*[this]
191 bra points_init_portbit_endif_used
193 points_init_portbit_if_used
195 bra_n point_initing_bad_point
197 ior_lw 0xf8 ; W -> bit value for bit
198 mov_wf FSR1L ; FSR1 -> bit value for bit
200 swap_fw TABLAT ; W = bitnum4 || portnum4
201 and_lw 0x0f ; W = portnum4
202 add_lw LATA & 0xff ; W = LAT*
203 mov_wf POSTINC0 ; LAT*[this] := LAT, FSR0 -> bit[this]
204 mov_wf FSR2L ; FSR2 -> LAT*
206 mov_fw INDF1 ; W = bit
207 mov_wf POSTDEC0 ; bit[this] = bit, FSR0 -> LAT*[this]
209 and_wff INDF2 ; LAT* &= ~bit, ie pin set to L (still Z)
210 pin_vh pall_pt0reverse ; but pt0 pin is backwards, set to H
211 ; (still Z, unless we've done this already)
213 add_wff FSR2L ; FSR2 -> TRIS*
214 com_fw INDF1 ; W = ~bit
215 and_wff INDF2 ; TRIS* &= ~bit, ie pin set to not Z
217 set_f FSR1L ; FSR1 -> bitnum2bit+7, again
218 points_init_portbit_endif_used
219 ; so now we move on to the next one
220 mov_fw POSTINC0 ; FSR0 -> bit[this]
223 bra points_init_portbit_loop
228 point_initing_bad_point
233 bt_f_if1 idloc1,idloc1_master
234 bra point_timer_init_if_master
236 mov_lw (1<<RD16)|(1<<T3ECCP1)| points_slave_t3scale; Fcy;!TMR3ON
238 mov_lw points_slave_t3inith
239 bra point_timer_init_endif_masterslave
240 point_timer_init_if_master
241 mov_lw (1<<RD16)|(1<<T3ECCP1)| points_master_t3scale; Fcy;!TMR3ON
243 mov_lw points_master_t3inith
244 point_timer_init_endif_masterslave
245 mov_wf TMR3H ; We just leave this here.
246 ; Since we never read TMR3L, it is never overwritten
253 ;======================================================================
256 ;----------------------------------------------------------------------
261 load_tblptr picno2ptmap
262 mov_lfsr slave2ptinfo-1, 0
265 points_master_init_board_loop
268 points_master_init_byte_loop
271 bs_f INDF0, slave2ptinfo_anypoints
273 bra points_master_init_byte_loop
275 bra points_master_init_board_loop
279 ;----------------------------------------------------------------------
281 ; FSR0 -> 1 0100 TTT O TTTTTTT
285 bra command_point_busy
287 tst_f_ifnz cducharging
288 bra command_point_cduempty
290 swap_fw POSTINC0 ; W = 0SSS 1010
291 and_lw 0x70 ; W = 0SSS 0000
293 mov_wf pointslave ; pointslave = 00SS S000
295 mov_fw INDF0 ; W = OssT tttt N = O
296 bra_n command_point_badmsg
297 ; OK: ; W = 0ssT tttt
298 and_lw 0x1f ; W = 000T tttt
299 bs_w 7 ; W = 100T tttt
300 mov_wf pointmsg ; pointmsg = 100T tttt
302 swap_fw INDF0 ; W = tttt 0ssT
303 and_lw 0x06 ; W = 0000 0ss0
304 ior_wff pointslave ; pointslave = 00SS Sss0
306 rr_fw pointslave ; W = 000S SSss
307 bra_nz command_point_ifslave
312 command_point_badmsg panic morse_PX
313 command_point_busy panic morse_PB
314 command_point_cduempty panic morse_PC
317 command_point_ifslave
318 mov_lfsr slave2ptinfo, 0
320 bt_f_if1 INDF0, slave2ptinfo_anypoints
327 rr_fw pointslave ; W = 000S SSss
328 bt_f_if1 STATUS, Z ; nothing ?
330 ; we need to write something:
338 points_getwritebyte @
341 bt_f_if0 STATUS, Z ; right slave ?
344 clr_f pointslave ; we're writing now, excellent
346 goto i2c_getwritebyte_yes
348 ;======================================================================
351 ;--------------------
360 mov_lw (cdu_inittimeout * 1000) / tickdiv_us + 1
366 mov_lw (cdu_timeout * 1000) / tickdiv_us + 1
370 ;--------------------
375 ;--------------------
377 pinlat_ifl p0_cdu_enable
380 tst_f_ifnz cducharging
381 dec_f_ifnz cducharging ; so, decrement only if it was nonzero
382 return ; return if we either didn't decrement,
383 ; or didn't reach zero
385 ; cducharging is already zero, from above
386 mov_lw b'00101000' ; CHARGED
390 ;--------------------
392 tst_f_ifnz cducharging
393 bra pointed_already_charging
396 bra pointed_butnot_firing
400 mov_lw b'00100000' ; POINTED
403 pointed_butnot_firing panic morse_PA
404 pointed_already_charging panic morse_PQ
406 ;======================================================================