1 ;======================================================================
4 ; This file implements panic_routine, which is called by the
5 ; `panic' macro in panic.inc. See panic.inc for the functionality
10 ;---------------------------------------------------------------------------
11 ; reserved access bank locations
19 panicst_restart_i2c equ 7
22 panic_vars_section udata 0x060 + maxpics ; not available via access bank
23 ; used in panic routine for temporary storage:
27 register_counter res 1
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
47 panic_stack res stack_depth*3
49 ;****************************************************************************
53 ;****************************************************************************
57 ; switch off interrupts and power
58 ; reconfigure timer0 for writing diagnostic msg to the LED
60 mov_ff INTCON, psave_intcon
61 bc_f INTCON, GIEH ; disable all interrupts
66 mov_ff LATC, psave_latc
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).
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
87 mov_lfsr panic_stack + stack_depth*3 - 1, 0
97 clr_f STKPTR ; avoids stack overruns
102 ; re-initialise timer0 config
104 bra_z panic_setup_if_master
106 morse_t0setup sclock, (1<<TMR0ON), t0l_count, t0h_count
107 bra panic_setup_endif_masterslave
108 panic_setup_if_master
109 morse_t0setup mclock, (1<<TMR0ON), t0l_count, t0h_count
110 panic_setup_endif_masterslave
112 ; get # bytes of morse msg, # registers in panic readout, message start addr.
113 ; back from condensed message start addr. stored in panic_address
116 mov_lw 4 ; size of each message's details
120 add_lw (morse_messages_start)/256
124 tblrd *+ ; read 1st byte of error message
125 ; (gives # bytes morse, # bytes registers)
126 dw 0xffff ; silicon errata: B4 issue 4
128 mov_ff TABLAT,panic_morse
130 and_wff panic_morse ; panic_morse now contains # bytes of morse msgs
132 mov_ff TABLAT,panic_regs
135 swap_f panic_regs ; panic_regs now contains # registers to read
139 rcall morsemsg ; transmit morse in red
143 rcall registermsg ; transmit contents of registers in
144 ; red(=low) and blue(=high)
148 ;****************************************************************************
152 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
155 clr_f morse_counter ; clear loop counter
159 cmp_fw_ifge morse_counter ; if loop counter >=panic_morse
160 return ; return to panic
163 mov_ff TABLAT,flash_pattern
169 ;--------------------------
172 ; Flashes the per-pic led and black in a specified pattern.
174 ; The pattern is specified as the state for 8 identically-long time
175 ; periods each as long as a morse `dot', encoded into a byte with
176 ; most significant bit first.
179 ; flash_pattern flash pattern preserved
180 ; bit_counter any undefined
187 dec_f_ifz bit_counter ; done all the bits yet ?
191 rl_f flash_pattern ; top bit goes into N,
193 bra_n morse_readout_if_led_1
195 morse_readout_if_led_0
197 bra morse_readout_endif_led
199 morse_readout_if_led_1
202 morse_readout_endif_led
204 bra morse_readout_loop
206 ;--------------------------
207 ;--------------------------
211 clr_f register_counter ; clear loop counter
215 cmp_fw_ifge register_counter ; if loop counter >=panic_regs
216 return ; return to panic
220 mov_fw TABLAT ; TABLAT has the 8-bit version
221 mov_wf FSR0L ; of the address. So, 8 bits
222 ; go straight into FSR0L.
224 mov_lw 0x0f ; For FSR0H, we see if the
225 mov_fw FSR0H ; address XX is >=0x60.
226 ; If it is then we meant 0xfXX;
227 mov_lw 0x5f ; if not then we meant 0x0XX.
228 cmp_fw_ifle FSR0L ; (This is just like PIC does
229 clr_f FSR0H ; for insns using Access Bank)
231 mov_ff INDF0,flash_pattern
232 rcall register_readout
234 inc_f register_counter ;increment loop counter
239 ;--------------------------
243 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
244 ; (black gap between each bit)
246 ; The pattern is specified as the state for 8 identically-long time
247 ; periods each as long as a morse `dot', encoded into a byte with
248 ; most significant bit first.
251 ; flash_pattern flash pattern preserved
252 ; bit_counter any undefined
254 clr_f bit_counter ; clear loop counter
258 register_readout_loop
260 cmp_fw_ifge bit_counter ; if loop counter >=8 (register
265 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
266 ; skip insertion of extra black space
267 bra not_nybble_boundary
271 rl_f flash_pattern ; top bit goes into N flag,
273 bra_n register_readout_if_led_1
275 register_readout_if_led_0
277 bra register_readout_endif_led
279 register_readout_if_led_1
282 register_readout_endif_led
283 inc_f bit_counter ; increment loop counter
287 bra register_readout_loop
290 ;****************************************************************************
291 ; GENERAL SUBROUTINES
293 ;----------------------------------------
294 waiting16 rcall waiting8
295 waiting8 rcall waiting4
296 waiting4 rcall waiting2
297 waiting2 rcall waiting
299 ; waits for a fixed interval, depending on the configuration of TMR0
301 bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
302 ; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
304 mov_wf TMR0H ; p107 set high byte of timer0 (buffered,
305 ; only actually set when write to tmr0l occurs)
307 mov_wf TMR0L ; set timer0 low byte - timer now set
308 waiting_loop ; wait for timer0 interrupt, or some other interrupt
309 bt_f_if1 INTCON,TMR0IF
312 bt_f_if0 SSPCON1, SSPEN
313 bra waiting_loop ; no readouts if i2c is disabled
315 bt_f_if1 idloc1, idloc1_master
316 bra waiting_loop ; no readouts on master yet
325 ;x bt_f_if0 panicst, panicst_restart_i2c
327 bc_f panicst, panicst_restart_i2c
330 bra_z waiting_done_if_master
337 waiting_done_if_master
340 ;****************************************************************************
345 panicd_process_input_byte
346 ; W instruction from host or master
349 ; we've received 0x00:
352 bs_f panicst, panicst_acked
357 bt_f_if0 panicst, panicst_acked ; well, ignore that !
359 ; OK, we have an instruction:
364 bra panic_crashread_setpointer
365 bt_f_if0 idloc1,idloc1_master
366 return ; all the remaining options are for master only
368 ;nyi bra write_if_selectslave
370 ;nyi bra write_if_readout
374 panic_crashread_setpointer
375 ; W byte from master or host undefined
376 ; FSR1* crashread pointer updated
377 ; t, STATUS, PROD* any undefined
378 ; all others any preserved
390 panic_crashread_commanded
391 bs_f panicst, panicst_acked ; since we were asked to
395 pan_i2cmu_read_got_byte
396 pan_i2cmu_write_next_byte
402 pan_i2csu_write_begin
407 mov_lw 0x80 ; M0000000
408 bt_f_if0 panicst, panicst_acked
416 pan_i2csu_read_another
417 bt_f_if1 panicst, panicst_acked
418 bra i2csu_read_panicd_ok
428 ;***************************************************************************