chiark / gitweb /
less of an unsightly wiggle over bridge
[trains.git] / detpic / points.asm
1 ;======================================================================
2 ; POINTS
3
4   include common.inc
5
6 ;======================================================================
7 ; VARIABLES, HARDWARE, ETC
8 ;
9 ;               Timer 3         pointmsg        pointslave      cducharging
10 ;
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
18 ;
19 ;  notes:       firing          see             ie, slave*2     Counts down
20 ;                timeout         detect.asm                      in ticks
21 ;
22 ; cducharging only counts if the cdu is enabled
23 ;  (according to CDU Enable LAT bit)
24
25 cdu_timeout     equ     300 ; ms
26 cdu_inittimeout equ     750 ; ms
27
28 ptix2latbit equ 0x300 ; has to be a multiple of 0x100
29 ptix2latbit_section udata ptix2latbit
30   res maxpoints * 2     ; as produced by outpin_local_init
31
32   udata_acs
33 pointslave              res     1
34 pointmsg                res     1
35 cducharging             res     1
36
37   udata 0x340
38 slave2ptinfo            res     maxpics
39 slave2ptinfo_anypoints  equ     0
40
41 ;======================================================================
42 ; LOCAL POINTS
43 ; on slave, or master's own
44
45 ;----------------------------------------------------------------------
46 ; LOCAL POINTS - ACTUALLY DOING
47
48 near_local_do code
49 ;----------------------------------------
50 point_local_do @
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
55         bra     point_clash
56
57         mov_wf  pointmsg        ; pointmsg = SS zz zz pp  pp pp pp pp
58
59         intrlh_fsr0_save        ; point_set_pin uses FSR0, see below
60         call    point_set_pin
61         intrlh_fsr0_restore
62
63         clr_f   TMR3L           ; also copies TMR3H into actual timer register
64         bs_f    T3CON, TMR3ON
65         return
66
67 ;----------
68 point_clash
69         panic   morse_PB
70
71 points_section code
72 ;----------------------------------------
73 points_local_intrl @
74         bt_f_if0 PIR2, TMR3IF
75         return
76         ; OK, it's us, and we're done changing a point:
77
78         bt_f_if0 T3CON, TMR3ON
79         bra     point_spurious_intr
80
81         rcall   point_set_pin
82         intrh_mask
83         bc_f    T3CON, TMR3ON
84         bc_f    PIR2, TMR3IF
85         intrh_unmask
86
87         mov_lw  b'00100000'
88         call    message_for_master
89         intrl_handled_nostack
90
91 ;----------
92 point_spurious_intr
93         panic   morse_PI
94
95 ;----------
96 point_set_pin
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
100 ;
101 ; Called in various contexts, including both High and Low ISR.
102 ;
103 ;  pointmsg     point to start or stop firing   preserved
104 ;  W,STATUS     any                             undefined
105 ;  FSR0         any                             undefined
106 ;  all other    any                             not interfered with
107 ;
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
117         return
118
119 ;----------
120 point_nonexistent
121         panic   morse_PU
122
123 ;----------------------------------------------------------------------
124 ; LOCAL POINTS - INITIALISATION
125
126 ;----------------------------------------
127 points_local_init @
128 ; Initialises tables for points
129 ; Clears TRIS* bits for all points and sets each pin to `not triggering'
130
131         rcall   point_timer_init
132
133  outputs_local_init picno2ptmap, maxpoints, ptix2latbit, bkptix2portnumbitnum
134
135         return
136
137 ;----------
138 point_timer_init
139         bt_f_if1 idloc1,idloc1_master
140         bra     point_timer_init_if_master
141         ; slave:
142         mov_lw  (1<<RD16)|(1<<T3ECCP1)| points_slave_t3scale; Fcy;!TMR3ON
143         mov_wf  T3CON
144         mov_lw  points_slave_t3inith
145         bra     point_timer_init_endif_masterslave
146 point_timer_init_if_master
147         mov_lw  (1<<RD16)|(1<<T3ECCP1)| points_master_t3scale; Fcy;!TMR3ON
148         mov_wf  T3CON
149         mov_lw  points_master_t3inith
150 point_timer_init_endif_masterslave
151         mov_wf  TMR3H   ; We just leave this here.
152                         ; Since we never read TMR3L, it is never overwritten
153
154         bc_f    PIR2, TMR3IF
155         bs_f    PIE2, TMR3IE
156         bc_f    IPR2, TMR3IP
157         return
158
159 ;======================================================================
160 ; MASTER
161
162 ;----------------------------------------------------------------------
163 points_master_init @
164         clr_f   pointslave
165         clr_f   pointmsg
166
167         load_tblptr picno2ptmap
168         mov_lfsr slave2ptinfo-1, 0
169         mov_lw  maxpics
170         mov_wf  t
171 points_master_init_board_loop
172         clr_f   PREINC0
173         mov_lw  maxpoints/8
174 points_master_init_byte_loop
175         tblrd_postinc_fixup
176         tst_f_ifnz TABLAT
177         bs_f    INDF0, slave2ptinfo_anypoints
178         dec_w_ifnz
179         bra     points_master_init_byte_loop
180         dec_f_ifnz t
181         bra     points_master_init_board_loop
182
183         return
184
185 ;----------------------------------------------------------------------
186 command_point @
187                                         ; FSR0 -> 1 0100 TTT  O TTTTTTT
188                                         ; ie            1010 0SSS
189                                         ;               OssT tttt
190         tst_f_ifnz pointmsg
191         bra     command_point_busy
192
193         tst_f_ifnz cducharging
194         bra     command_point_cduempty
195
196         swap_fw POSTINC0                ; W =           0SSS 1010
197         and_lw  0x70                    ; W =           0SSS 0000
198         rr_w                            ; W =           00SS S000
199         mov_wf  pointslave              ; pointslave =  00SS S000
200
201         mov_fw  INDF0                   ; W =           OssT tttt  N = O
202         bra_n   command_point_badmsg
203         ; OK:                           ; W =           0ssT tttt
204         and_lw  0x1f                    ; W =           000T tttt
205         bs_w    7                       ; W =           100T tttt
206         mov_wf  pointmsg                ; pointmsg =    100T tttt
207
208         swap_fw INDF0                   ; W =           tttt 0ssT
209         and_lw  0x06                    ; W =           0000 0ss0
210         ior_wff pointslave              ; pointslave =  00SS Sss0
211
212         rr_fw   pointslave              ; W =           000S SSss
213         bra_nz  command_point_ifslave
214
215         mov_fw  pointmsg
216         goto    point_local_do
217
218 command_point_badmsg panic morse_PX
219 command_point_busy panic morse_PB
220 command_point_cduempty panic morse_PC
221
222 ;----------
223 command_point_ifslave
224         mov_lfsr slave2ptinfo, 0
225         add_wff FSR0L
226         bt_f_if1 INDF0, slave2ptinfo_anypoints
227         goto    i2c_needwrite
228         ; oops:
229         panic   morse_PS
230
231 ;----------
232 points_needwrite @
233         rr_fw   pointslave              ; W =           000S SSss
234         bt_f_if1 STATUS, Z ; nothing ?
235         return
236         ; we need to write something:
237         pop
238         goto    i2c_needwrite
239
240 ;----------
241 points_getwritebyte @
242         rr_fw   pointslave
243         xor_wfw cwslave
244         bt_f_if0 STATUS, Z ; right slave ?
245         return
246         ; yes:
247         clr_f   pointslave      ; we're writing now, excellent
248         mov_fw  pointmsg
249         goto    i2c_getwritebyte_yes
250
251 ;======================================================================
252 ; CDU
253
254 ;--------------------
255 cdu_init @
256         clr_f   pointslave
257         clr_f   pointmsg
258 ;...
259 ;-----
260 cdu_off @
261         mov_lw  (cdu_inittimeout * 1000) / tickdiv_us + 1
262         mov_wf  cducharging
263 cdu_panichook @
264         pin_l   p0_cdu_enable
265         return
266
267 ;-----
268 cdu_discharged
269         mov_lw  (cdu_timeout * 1000) / tickdiv_us + 1
270         mov_wf  cducharging
271         return
272
273 ;--------------------
274 cdu_on @
275         pin_h   p0_cdu_enable
276         return
277
278 ;--------------------
279 cdu_tickdiv @
280         pinlat_ifl p0_cdu_enable
281         return
282
283         tst_f_ifnz cducharging
284         dec_f_ifnz cducharging  ; so, decrement only if it was nonzero
285         return                  ; return if we either didn't decrement,
286                                 ;  or didn't reach zero
287
288         ; cducharging is already zero, from above
289         mov_lw  b'00101000' ; CHARGED
290         goto    serial_addbyte
291
292 near_gots code
293 ;--------------------
294 got_pointed @
295         tst_f_ifnz cducharging
296         return  ; presumably we just turned off
297
298         bt_f_if0 pointmsg, 7
299         bra     pointed_butnot_firing
300
301         clr_f   pointmsg
302         call    cdu_discharged
303         mov_lw  b'00100000' ; POINTED
304         goto    serial_addbyte
305
306 pointed_butnot_firing panic morse_PA
307
308 ;======================================================================
309   include final.inc