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
21 panicst_ferroerr equ 4
22 panicst_writeslave equ 3
23 panicst_onlyourwrite equ 2
27 panic_vars_section udata 0x060 + maxpics ; not available via access bank
28 ; used in panic routine for temporary storage:
32 register_counter res 1
35 panic_address res 1 ; condensed form of message start addr.
36 panic_morse res 1 ; # bytes of morse msg in panic readout
37 panic_regs res 1 ; # registers in panic readout
52 panic_stack res stack_depth*3
54 ;****************************************************************************
58 ;****************************************************************************
62 ; switch off interrupts and power
63 ; reconfigure timer0 for writing diagnostic msg to the LED
65 mov_ff INTCON, psave_intcon
66 bc_f INTCON, GIEH ; disable all interrupts
71 mov_ff LATC, psave_latc
73 ; now we have time to save registers etc
74 ; (turning off interrupts is urgent (we might get interrupted while
75 ; panicing which would be bad because we might forget to panic).
80 mov_ff TABLAT, psave_tablat
81 mov_ff TBLPTRL, psave_tblptr
82 mov_ff TBLPTRH, psave_tblptr+1
83 mov_ff TBLPTRU, psave_tblptr+2
84 mov_ff FSR0L, psave_fsr0
85 mov_ff FSR0H, psave_fsr0+1
86 mov_ff FSR1L, psave_fsr1
87 mov_ff FSR1H, psave_fsr1+1
88 mov_ff PRODL, psave_prod
89 mov_ff PRODH, psave_prod+1
90 mov_ff STKPTR, psave_stkptr
92 mov_lfsr panic_stack + stack_depth*3 - 1, 0
102 clr_f STKPTR ; avoids stack overruns
107 ; re-initialise timer0 config, etc.
109 bra_z panic_setup_if_master
113 movlw (1<<TMR0ON) | morse_slave_t0scale
115 movlw morse_slave_t0inith
117 movlw morse_slave_t0initl
120 bra panic_setup_endif_masterslave
122 panic_setup_if_master
123 movlw (1<<TMR0ON) | morse_master_t0scale
125 movlw morse_master_t0inith
127 movlw morse_master_t0initl
130 pin_l p0_booster_userfault
134 call serial_write_char
136 panic_setup_endif_masterslave
138 ; get # bytes of morse msg, # registers in panic readout, message start addr.
139 ; back from condensed message start addr. stored in panic_address
142 mov_lw 4 ; size of each message's details
146 add_lw (morse_messages_start)/256
150 tblrd *+ ; read 1st byte of error message
151 ; (gives # bytes morse, # bytes registers)
152 dw 0xffff ; silicon errata: B4 issue 4
154 mov_ff TABLAT,panic_morse
156 and_wff panic_morse ; panic_morse now contains # bytes of morse msgs
158 mov_ff TABLAT,panic_regs
161 swap_f panic_regs ; panic_regs now contains # registers to read
165 rcall morsemsg ; transmit morse in red
169 rcall registermsg ; transmit contents of registers in
170 ; red(=low) and blue(=high)
174 ;****************************************************************************
178 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
181 clr_f morse_counter ; clear loop counter
185 cmp_fw_ifge morse_counter ; if loop counter >=panic_morse
186 return ; return to panic
189 mov_ff TABLAT,flash_pattern
195 ;--------------------------
198 ; Flashes the per-pic led and black in a specified pattern.
200 ; The pattern is specified as the state for 8 identically-long time
201 ; periods each as long as a morse `dot', encoded into a byte with
202 ; most significant bit first.
205 ; flash_pattern flash pattern preserved
206 ; bit_counter any undefined
213 dec_f_ifz bit_counter ; done all the bits yet ?
217 rl_f flash_pattern ; top bit goes into N,
219 bra_n morse_readout_if_led_1
221 morse_readout_if_led_0
223 bra morse_readout_endif_led
225 morse_readout_if_led_1
228 morse_readout_endif_led
230 bra morse_readout_loop
232 ;--------------------------
233 ;--------------------------
237 clr_f register_counter ; clear loop counter
241 cmp_fw_ifge register_counter ; if loop counter >=panic_regs
242 return ; return to panic
246 mov_fw TABLAT ; TABLAT has the 8-bit version
247 mov_wf FSR0L ; of the address. So, 8 bits
248 ; go straight into FSR0L.
250 mov_lw 0x0f ; For FSR0H, we see if the
251 mov_fw FSR0H ; address XX is >=0x60.
252 ; If it is then we meant 0xfXX;
253 mov_lw 0x5f ; if not then we meant 0x0XX.
254 cmp_fw_ifle FSR0L ; (This is just like PIC does
255 clr_f FSR0H ; for insns using Access Bank)
257 mov_ff INDF0,flash_pattern
258 rcall register_readout
260 inc_f register_counter ;increment loop counter
265 ;--------------------------
269 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
270 ; (black gap between each bit)
272 ; The pattern is specified as the state for 8 identically-long time
273 ; periods each as long as a morse `dot', encoded into a byte with
274 ; most significant bit first.
277 ; flash_pattern flash pattern preserved
278 ; bit_counter any undefined
280 clr_f bit_counter ; clear loop counter
284 register_readout_loop
286 cmp_fw_ifge bit_counter ; if loop counter >=8 (register
291 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
292 ; skip insertion of extra black space
293 bra not_nybble_boundary
297 rl_f flash_pattern ; top bit goes into N flag,
299 bra_n register_readout_if_led_1
301 register_readout_if_led_0
303 bra register_readout_endif_led
305 register_readout_if_led_1
308 register_readout_endif_led
309 inc_f bit_counter ; increment loop counter
313 bra register_readout_loop
316 ;****************************************************************************
317 ; GENERAL SUBROUTINES
319 ;----------------------------------------
320 waiting16 rcall waiting8
321 waiting8 rcall waiting4
322 waiting4 rcall waiting2
323 waiting2 rcall waiting
325 ; waits for a fixed interval, depending on the configuration of TMR0
327 bt_f_if1 idloc1,idloc1_master
328 pin_z p0_booster_userfault
330 bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
331 ; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
333 mov_wf TMR0H ; p107 set high byte of timer0 (buffered,
334 ; only actually set when write to tmr0l occurs)
336 mov_wf TMR0L ; set timer0 low byte - timer now set
337 waiting_loop ; wait for timer0 interrupt, or some other interrupt
338 bt_f_if1 INTCON,TMR0IF
341 bt_f_if1 idloc1, idloc1_master
345 bt_f_if0 SSPCON1, SSPEN
346 bra waiting_loop ; no readouts if i2c is disabled
347 ; slave, i2c enabled:
350 call pan_i2cs_interrupt
354 ;****************************************************************************
355 ; MEMORY READOUT - CRASH DUMP
357 ;----------------------------------------
358 ; MASTER'S PANIC SERIAL PORT HANDLING
360 ;--------------------
362 bt_f_if1 PIR1,RCIF ; host sent us something ?
365 bt_f_if0 SSPCON1, SSPEN
367 ; master, i2c enabled:
370 rcall pan_i2cm_interrupt
377 bra_nz panicd_serialrx_err_loop
378 ; yay! host ack'd ferr/oerr
379 bc_f panicst, panicst_ferroerr
380 return ; return from panicd_serialrx
384 bs_f panicst, panicst_ferroerr
385 bc_f RCSTA, RCEN ; disable } to clear FERR/OERR
386 mov_fw RCREG ; read RCREG } (see PIC18FXX8 DS p182)
387 bs_f RCSTA, RCEN ; reenable }
388 panicd_serialrx_err_loop
389 bt_f_if0 PIR1, RCIF ; wait for a byte 0x01 to ack the overrun/error
390 bra panicd_serialrx_err_loop
394 pin_nz p0_booster_userfault
396 bra panicd_serialrx_err
398 bra panicd_serialrx_err
399 bt_f_if1 panicst, panicst_ferroerr
403 bra panicd_process_input_byte
405 ;----------------------------------------
406 ; CRASHREAD MASTER/SLAVE COMMON COMMAND BYTE HANDLING
411 panicd_process_input_byte
412 ; W instruction from host or master
415 ; we've received 0x00:
418 bs_f panicst, panicst_acked
423 bt_f_if0 panicst, panicst_acked ; well, ignore that !
425 ; OK, we have an instruction:
428 bra write_if_setbytetowrite
430 bra panic_crashread_setpointer
431 bt_f_if0 idloc1,idloc1_master
432 return ; all the remaining options are for master only
434 bra write_if_master_slaveselect
436 bra write_if_master_masterread
437 bra write_if_master_slaveread
441 panic_crashread_setpointer
442 ; W byte from master or host undefined
443 ; FSR1* crashread pointer updated
444 ; t, STATUS, PROD* any undefined
445 ; all others any preserved
456 ;======================================================================
457 ; MASTER READOUT AND MASTER READOUT OF SLAVES
460 write_if_setbytetowrite
461 bt_f_if0 idloc1,idloc1_master
462 return ; for master only
465 mov_wf panic_valcount
466 bs_f panicst, panicst_writeslave
467 bs_f panicst, panicst_onlyourwrite
471 write_if_master_slaveread
472 mov_wf panic_valcount
473 bc_f panicst, panicst_writeslave
477 write_if_master_slaveselect
480 bt_f_if1 panicst, panicst_writeslave
481 bra pan_i2cm_write_start
482 bra pan_i2cm_read_start
485 write_if_master_masterread
487 mov_wf panic_valcount
488 write_if_master_masterread_loop
490 call serial_write_char
491 dec_f_ifnz panic_valcount
492 bra write_if_master_masterread_loop
496 pan_i2cmu_read_got_byte
497 call serial_write_char
498 dec_f_ifnz panic_valcount
499 bra pan_i2cm_read_another
503 pan_i2cmu_write_next_byte
504 mov_fw panic_valcount
506 bt_f_if0 panicst, panicst_onlyourwrite
508 bt_f_if0 panicst, panicst_writeslave
510 bc_f panicst, panicst_writeslave
516 goto serial_write_char
518 ;======================================================================
523 pan_i2csu_write_begin
528 mov_lw 0x80 ; M0000000
529 bt_f_if0 panicst, panicst_acked
537 pan_i2csu_read_another
538 bt_f_if1 panicst, panicst_acked
539 bra i2csu_read_panicd_ok
549 command_crashed_section code 0x2100
552 panic_crashread_commanded @
555 ;***************************************************************************