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