chiark / gitweb /
mascan compilation wip
[trains.git] / detpic / panic.asm
1 ;======================================================================
2 ; panic.asm
3 ;
4 ; This file implements panic_routine, which is called by the
5 ; `panic' macro in panic.inc.  See panic.inc for the functionality
6 ; of `panic'.
7
8         include common.inc
9
10 ;---------------------------------------------------------------------------
11 ; reserved access bank locations
12
13  udata_acs
14
15 psave_intcon    res     1
16 psave_bsr       res     1
17
18 panicst                         res     1
19 panicst_restart_i2c             equ     7
20 panicst_acked                   equ     5
21
22 panic_vars_section udata 0x060 ; not available via access bank
23 ; used in panic routine for temporary storage:
24
25 flash_pattern           res     1
26 morse_counter           res     1
27 register_counter        res     1
28 bit_counter             res     1
29
30 panic_address   res     1       ; condensed form of message start addr.
31 panic_morse     res     1       ; # bytes of morse msg in panic readout
32 panic_regs      res     1       ; # registers in panic readout
33
34 t0l_count       res     1
35 t0h_count       res     1
36
37 psave_latc      res     1
38 psave_t         res     1
39 psave_tablat    res     1
40 psave_tblptr    res     3
41 psave_fsr0      res     2
42 psave_fsr1      res     2
43 psave_prod      res     2
44 psave_stkptr    res     1
45
46 stack_depth     equ     31
47 panic_stack     res     stack_depth*3
48
49 ;****************************************************************************
50
51         code
52
53 ;****************************************************************************
54
55
56 panic_routine
57 ; switch off interrupts and power
58 ; reconfigure timer0 for writing diagnostic msg to the LED
59
60         mov_ff  INTCON, psave_intcon
61         bc_f    INTCON, GIEH   ; disable all interrupts
62
63         mov_ff  BSR, psave_bsr
64         banksel flash_pattern
65
66         mov_ff  LATC, psave_latc
67
68 ; now we have time to save registers etc
69 ; (turning off interrupts is urgent (we might get interrupted while
70 ;  panicing which would be bad because we might forget to panic).
71
72         mov_wf   panic_address
73
74         mov_ff  t, psave_t
75         mov_ff  TABLAT, psave_tablat
76         mov_ff  TBLPTRL, psave_tblptr
77         mov_ff  TBLPTRH, psave_tblptr+1
78         mov_ff  TBLPTRU, psave_tblptr+2
79         mov_ff  FSR0L, psave_fsr0
80         mov_ff  FSR0H, psave_fsr0+1
81         mov_ff  FSR1L, psave_fsr1
82         mov_ff  FSR1H, psave_fsr1+1
83         mov_ff  PRODL, psave_prod
84         mov_ff  PRODH, psave_prod+1
85         mov_ff  STKPTR, psave_stkptr
86
87         mov_lfsr panic_stack + stack_depth*3 - 1, 0
88         mov_lw  stack_depth
89         mov_wf  STKPTR
90 stacksave_loop
91         mov_ff  TOSU, POSTDEC0
92         mov_ff  TOSH, POSTDEC0
93         mov_ff  TOSL, POSTDEC0
94         dec_f_ifnz STKPTR
95         bra     stacksave_loop
96
97         clr_f    STKPTR         ; avoids stack overruns
98         clr_f   panicst
99         bs_f    picno, picno_panicd
100
101         call    panic_kill_hook
102
103 ; re-initialise timer0 config
104         call    read_pic_no
105         bra_z   panic_setup_if_master
106 panic_setup_if_slave
107         morse_t0setup sclock, (1<<TMR0ON), t0l_count, t0h_count
108         bra     panic_setup_endif_masterslave
109 panic_setup_if_master
110         morse_t0setup mclock, (1<<TMR0ON), t0l_count, t0h_count
111 panic_setup_endif_masterslave
112
113 ; get # bytes of morse msg, # registers in panic readout, message start addr.
114 ; back from condensed message start addr. stored in panic_address
115
116 panic_loop
117         mov_lw  4 ; size of each message's details
118         mul_wf  panic_address
119         mov_ff  PRODL,TBLPTRL           
120         mov_ff  PRODH,WREG
121         add_lw  (morse_messages_start)/256
122         mov_wf  TBLPTRH
123         clr_f   TBLPTRU
124
125         tblrd   *+              ; read 1st byte of error message
126                                 ; (gives # bytes morse, # bytes registers)
127         dw      0xffff ; silicon errata: B4 issue 4
128
129         mov_ff  TABLAT,panic_morse
130         mov_lw  00001111b
131         and_wff panic_morse     ; panic_morse now contains # bytes of morse msgs
132
133         mov_ff  TABLAT,panic_regs
134         mov_lw  01110000b
135         and_wff panic_regs
136         swap_f  panic_regs      ; panic_regs now contains # registers to read
137
138         call    led_black
139         rcall   waiting16
140         rcall   morsemsg        ; transmit morse in red
141         call    led_black
142         rcall   waiting8
143         rcall   waiting4
144         rcall   registermsg     ; transmit contents of registers in 
145                                 ; red(=low) and blue(=high)
146         rcall   waiting16
147         bra     panic_loop
148
149 ;****************************************************************************
150 ; PANIC SUBROUTINES
151
152 morsemsg
153 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
154
155 morse_msg_start
156         clr_f           morse_counter           ; clear loop counter
157
158 morse_loop
159         mov_fw          panic_morse
160         cmp_fw_ifge     morse_counter           ; if loop counter >=panic_morse
161         return                                  ; return to panic
162
163         tblrd           *+
164         mov_ff          TABLAT,flash_pattern
165         rcall           morse_readout
166         inc_f           morse_counter
167         bra             morse_loop
168
169
170 ;--------------------------
171 morse_readout
172
173 ; Flashes the per-pic led and black in a specified pattern.
174 ;
175 ; The pattern is specified as the state for 8 identically-long time
176 ; periods each as long as a morse `dot', encoded into a byte with
177 ; most significant bit first.
178 ;                       On entry                On exit
179 ; W                     any                     undefined
180 ; flash_pattern         flash pattern           preserved
181 ; bit_counter           any                     undefined
182
183         mov_lw          9
184         mov_wf          bit_counter
185         rr_f            flash_pattern
186
187 morse_readout_loop
188         dec_f_ifz       bit_counter             ; done all the bits yet ?
189         return
190         ; No:
191
192         rl_f            flash_pattern           ; top bit goes into N, 
193                                                 ;ie Negative if 1
194         bra_n           morse_readout_if_led_1
195
196 morse_readout_if_led_0
197         call            led_black
198         bra             morse_readout_endif_led
199
200 morse_readout_if_led_1
201         call            led_red
202
203 morse_readout_endif_led
204         rcall           waiting
205         bra             morse_readout_loop
206
207 ;--------------------------
208 ;--------------------------
209 registermsg
210
211 register_msg_start
212         clr_f           register_counter        ; clear loop counter
213
214 register_loop
215         mov_fw          panic_regs
216         cmp_fw_ifge     register_counter        ; if loop counter >=panic_regs
217         return                                  ; return to panic
218
219         tblrd           *+
220
221         mov_fw          TABLAT          ; TABLAT has the 8-bit version
222         mov_wf          FSR0L           ; of the address.  So, 8 bits
223                                         ; go straight into FSR0L.
224
225         mov_lw          0x0f            ; For FSR0H, we see if the
226         mov_fw          FSR0H           ; address XX is >=0x60.
227                                         ; If it is then we meant 0xfXX;
228         mov_lw          0x5f            ; if not then we meant 0x0XX.
229         cmp_fw_ifle     FSR0L           ; (This is just like PIC does
230         clr_f           FSR0H           ; for insns using Access Bank)
231
232         mov_ff          INDF0,flash_pattern
233         rcall           register_readout
234
235         inc_f           register_counter        ;increment loop counter
236
237         rcall           waiting8
238         bra             register_loop
239
240 ;--------------------------
241
242 register_readout
243
244 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
245 ; (black gap between each bit)
246 ;
247 ; The pattern is specified as the state for 8 identically-long time
248 ; periods each as long as a morse `dot', encoded into a byte with
249 ; most significant bit first.
250 ;                       On entry                On exit
251 ; W                     any                     undefined
252 ; flash_pattern         flash pattern           preserved
253 ; bit_counter           any                     undefined
254
255         clr_f   bit_counter             ; clear loop counter
256         rr_f    flash_pattern
257
258
259 register_readout_loop
260         mov_lw          8
261         cmp_fw_ifge     bit_counter             ; if loop counter >=8 (register 
262                                                 ; length), return
263         return
264
265         mov_lw          4
266         cmp_fw_ifne     bit_counter     ; if loop counter !=4 (nybble length), 
267                                         ; skip insertion of extra black space
268         bra             not_nybble_boundary
269         rcall           waiting4
270
271 not_nybble_boundary
272         rl_f            flash_pattern           ; top bit goes into N flag, 
273                                                 ; ie Negative if 1
274         bra_n           register_readout_if_led_1
275
276 register_readout_if_led_0
277         call            led_red
278         bra             register_readout_endif_led
279
280 register_readout_if_led_1
281         call            led_green
282
283 register_readout_endif_led
284         inc_f           bit_counter       ; increment loop counter
285         rcall           waiting
286         call            led_black
287         rcall           waiting
288         bra             register_readout_loop
289
290
291 ;****************************************************************************
292 ; GENERAL SUBROUTINES
293
294 ;----------------------------------------
295 waiting16       rcall   waiting8
296 waiting8        rcall   waiting4
297 waiting4        rcall   waiting2
298 waiting2        rcall   waiting
299 waiting
300 ; waits for a fixed interval, depending on the configuration of TMR0
301
302         bc_f    INTCON,2        ; clear timer0 interrupt bit (p109)
303 ; Interrupt happens on overflow.  So start at 65535-morse_t0cycles:
304         mov_fw  t0h_count
305         mov_wf  TMR0H           ; p107 set high byte of timer0 (buffered,
306                                 ; only actually set when write to tmr0l occurs)
307         mov_fw  t0l_count
308         mov_wf  TMR0L           ; set timer0 low byte - timer now set
309 waiting_loop    ; wait for timer0 interrupt, or some other interrupt
310         bt_f_if1 INTCON,TMR0IF
311         bra     waiting_done
312
313         bt_f_if0 SSPCON1, SSPEN
314         bra     waiting_loop    ; no readouts if i2c is disabled
315
316         bt_f_if1 idloc1, idloc1_master
317         bra     waiting_loop    ; no readouts on master yet
318
319         bt_f_if1 PIR1, SSPIF
320         call    i2cs_interrupt
321
322         bra     waiting_loop
323
324 ;----------
325 waiting_done
326 ;x      bt_f_if0 panicst, panicst_restart_i2c
327         return
328         bc_f    panicst, panicst_restart_i2c
329         mov_lw  picno
330         and_lw  0x7f
331         bra_z   waiting_done_if_master
332  call i2cs_init
333 lgl
334  call led_green
335  bra lgl
336         goto    i2cs_init
337
338 waiting_done_if_master
339         return
340
341 ;****************************************************************************
342 ; MEMORY READOUT
343
344 ;----------
345 i2csu_write_panicd
346 panicd_process_input_byte
347 ;               W       instruction from host or master
348         tst_w_ifnz
349         bra     write_ifnot_00
350         ; we've received 0x00:
351
352         mov_lfsr 0,1
353         bs_f    panicst, panicst_acked
354         return
355
356 ;----------
357 write_ifnot_00
358         bt_f_if0 panicst, panicst_acked ; well, ignore that !
359         return
360         ; OK, we have an instruction:
361
362         bt_w_if1 7 ; huh?
363         return
364         bt_w_if1 6
365         bra     panic_crashread_setpointer
366         bt_f_if0 idloc1,idloc1_master
367         return ; all the remaining options are for master only
368 ;nyi    bt_w_if1 5
369 ;nyi    bra     write_if_selectslave
370 ;nyi    bt_w_if1 4
371 ;nyi    bra     write_if_readout
372         return ; huh ?
373
374 ;----------
375 panic_crashread_setpointer
376 ;  W                    byte from master or host        undefined
377 ;  FSR1*                crashread pointer               updated
378 ;  t, STATUS, PROD*     any                             undefined
379 ;  all others           any                             preserved
380         mov_wf  t
381         mov_lw  1<<6
382         mul_wf  FSR1L
383         mov_ff  PRODH, FSR1H
384         mov_fw  t
385         and_lw  0x3f
386         ior_wfw PRODL
387         mov_wf  FSR1L
388         return
389
390 ;----------
391 panic_crashread_commanded
392         bs_f    panicst, panicst_acked ; since we were asked to
393         panic   morse_E
394
395 ;----------
396 got_aargh
397         panic   morse_T
398
399 ;----------
400 i2csu_read_begin_panicd
401         mov_lw  0x80 ; M0000000
402         bt_f_if0 panicst, panicst_acked
403         goto    i2cs_read_data
404 ;...
405 i2csu_read_panicd_ok
406         mov_fw  POSTINC1
407         goto    i2cs_read_data
408
409 ;----------
410 i2csu_read_another_panicd
411         bt_f_if1 panicst, panicst_acked
412         bra     i2csu_read_panicd_ok
413         ; not ok
414         mov_lw  0x0b ; AARGH
415         goto    i2cs_read_data
416
417 ;***************************************************************************
418         include final.inc