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