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