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
26 panic_vars_section udata 0x060 + maxpics ; not available via access bank
27 ; used in panic routine for temporary storage:
31 register_counter res 1
34 panic_address res 1 ; condensed form of message start addr.
35 panic_morse res 1 ; # bytes of morse msg in panic readout
36 panic_regs res 1 ; # registers in panic readout
51 panic_stack res stack_depth*3
53 ;****************************************************************************
57 ;****************************************************************************
61 ; switch off interrupts and power
62 ; reconfigure timer0 for writing diagnostic msg to the LED
64 mov_ff INTCON, psave_intcon
65 bc_f INTCON, GIEH ; disable all interrupts
70 mov_ff LATC, psave_latc
72 ; now we have time to save registers etc
73 ; (turning off interrupts is urgent (we might get interrupted while
74 ; panicing which would be bad because we might forget to panic).
79 mov_ff TABLAT, psave_tablat
80 mov_ff TBLPTRL, psave_tblptr
81 mov_ff TBLPTRH, psave_tblptr+1
82 mov_ff TBLPTRU, psave_tblptr+2
83 mov_ff FSR0L, psave_fsr0
84 mov_ff FSR0H, psave_fsr0+1
85 mov_ff FSR1L, psave_fsr1
86 mov_ff FSR1H, psave_fsr1+1
87 mov_ff PRODL, psave_prod
88 mov_ff PRODH, psave_prod+1
89 mov_ff STKPTR, psave_stkptr
91 mov_lfsr panic_stack + stack_depth*3 - 1, 0
101 clr_f STKPTR ; avoids stack overruns
106 ; re-initialise timer0 config, etc.
108 bra_z panic_setup_if_master
112 movlw (1<<TMR0ON) | morse_slave_t0scale
114 movlw morse_slave_t0inith
116 movlw morse_slave_t0initl
119 bra panic_setup_endif_masterslave
121 panic_setup_if_master
122 movlw (1<<TMR0ON) | morse_master_t0scale
124 movlw morse_master_t0inith
126 movlw morse_master_t0initl
129 pin_l p0_booster_userfault
133 call serial_write_char
135 panic_setup_endif_masterslave
137 ; get # bytes of morse msg, # registers in panic readout, message start addr.
138 ; back from condensed message start addr. stored in panic_address
141 mov_lw 4 ; size of each message's details
145 add_lw (morse_messages_start)/256
149 tblrd *+ ; read 1st byte of error message
150 ; (gives # bytes morse, # bytes registers)
151 dw 0xffff ; silicon errata: B4 issue 4
153 mov_ff TABLAT,panic_morse
155 and_wff panic_morse ; panic_morse now contains # bytes of morse msgs
157 mov_ff TABLAT,panic_regs
160 swap_f panic_regs ; panic_regs now contains # registers to read
164 rcall morsemsg ; transmit morse in red
168 rcall registermsg ; transmit contents of registers in
169 ; red(=low) and blue(=high)
173 ;****************************************************************************
177 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
180 clr_f morse_counter ; clear loop counter
184 cmp_fw_ifge morse_counter ; if loop counter >=panic_morse
185 return ; return to panic
188 mov_ff TABLAT,flash_pattern
194 ;--------------------------
197 ; Flashes the per-pic led and black in a specified pattern.
199 ; The pattern is specified as the state for 8 identically-long time
200 ; periods each as long as a morse `dot', encoded into a byte with
201 ; most significant bit first.
204 ; flash_pattern flash pattern preserved
205 ; bit_counter any undefined
212 dec_f_ifz bit_counter ; done all the bits yet ?
216 rl_f flash_pattern ; top bit goes into N,
218 bra_n morse_readout_if_led_1
220 morse_readout_if_led_0
222 bra morse_readout_endif_led
224 morse_readout_if_led_1
227 morse_readout_endif_led
229 bra morse_readout_loop
231 ;--------------------------
232 ;--------------------------
236 clr_f register_counter ; clear loop counter
240 cmp_fw_ifge register_counter ; if loop counter >=panic_regs
241 return ; return to panic
245 mov_fw TABLAT ; TABLAT has the 8-bit version
246 mov_wf FSR0L ; of the address. So, 8 bits
247 ; go straight into FSR0L.
249 mov_lw 0x0f ; For FSR0H, we see if the
250 mov_fw FSR0H ; address XX is >=0x60.
251 ; If it is then we meant 0xfXX;
252 mov_lw 0x5f ; if not then we meant 0x0XX.
253 cmp_fw_ifle FSR0L ; (This is just like PIC does
254 clr_f FSR0H ; for insns using Access Bank)
256 mov_ff INDF0,flash_pattern
257 rcall register_readout
259 inc_f register_counter ;increment loop counter
264 ;--------------------------
268 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
269 ; (black gap between each bit)
271 ; The pattern is specified as the state for 8 identically-long time
272 ; periods each as long as a morse `dot', encoded into a byte with
273 ; most significant bit first.
276 ; flash_pattern flash pattern preserved
277 ; bit_counter any undefined
279 clr_f bit_counter ; clear loop counter
283 register_readout_loop
285 cmp_fw_ifge bit_counter ; if loop counter >=8 (register
290 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
291 ; skip insertion of extra black space
292 bra not_nybble_boundary
296 rl_f flash_pattern ; top bit goes into N flag,
298 bra_n register_readout_if_led_1
300 register_readout_if_led_0
302 bra register_readout_endif_led
304 register_readout_if_led_1
307 register_readout_endif_led
308 inc_f bit_counter ; increment loop counter
312 bra register_readout_loop
315 ;****************************************************************************
316 ; GENERAL SUBROUTINES
318 ;----------------------------------------
319 waiting16 rcall waiting8
320 waiting8 rcall waiting4
321 waiting4 rcall waiting2
322 waiting2 rcall waiting
324 ; waits for a fixed interval, depending on the configuration of TMR0
326 bt_f_if1 idloc1,idloc1_master
327 pin_z p0_booster_userfault
329 bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
330 ; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
332 mov_wf TMR0H ; p107 set high byte of timer0 (buffered,
333 ; only actually set when write to tmr0l occurs)
335 mov_wf TMR0L ; set timer0 low byte - timer now set
336 waiting_loop ; wait for timer0 interrupt, or some other interrupt
337 bt_f_if1 INTCON,TMR0IF
340 bt_f_if1 idloc1, idloc1_master
344 bt_f_if0 SSPCON1, SSPEN
345 bra waiting_loop ; no readouts if i2c is disabled
346 ; slave, i2c enabled:
349 call pan_i2cs_interrupt
353 ;****************************************************************************
354 ; MEMORY READOUT - CRASH DUMP
356 ;----------------------------------------
357 ; MASTER'S PANIC SERIAL PORT HANDLING
359 ;--------------------
361 bt_f_if1 PIR1,RCIF ; host sent us something ?
364 bt_f_if0 SSPCON1, SSPEN
366 ; master, i2c enabled:
369 rcall pan_i2cm_interrupt
376 bra_nz panicd_serialrx_err_loop
377 ; yay! host ack'd ferr/oerr
378 bc_f panicst, panicst_ferroerr
379 return ; return from panicd_serialrx
383 bs_f panicst, panicst_ferroerr
384 bc_f RCSTA, RCEN ; disable } to clear FERR/OERR
385 mov_fw RCREG ; read RCREG } (see PIC18FXX8 DS p182)
386 bs_f RCSTA, RCEN ; reenable }
387 panicd_serialrx_err_loop
388 bt_f_if0 PIR1, RCIF ; wait for a byte 0x01 to ack the overrun/error
389 bra panicd_serialrx_err_loop
393 pin_nz p0_booster_userfault
395 bra panicd_serialrx_err
397 bra panicd_serialrx_err
398 bt_f_if1 panicst, panicst_ferroerr
402 bra panicd_process_input_byte
404 ;----------------------------------------
405 ; CRASHREAD MASTER/SLAVE COMMON COMMAND BYTE HANDLING
410 panicd_process_input_byte
411 ; W instruction from host or master
414 ; we've received 0x00:
417 bs_f panicst, panicst_acked
422 bt_f_if0 panicst, panicst_acked ; well, ignore that !
424 ; OK, we have an instruction:
427 bra write_if_setbytetowrite
429 bra panic_crashread_setpointer
430 bt_f_if0 idloc1,idloc1_master
431 return ; all the remaining options are for master only
433 bra write_if_master_slaveselect
435 bra write_if_master_masterread
436 bra write_if_master_slaveread
440 panic_crashread_setpointer
441 ; W byte from master or host undefined
442 ; FSR1* crashread pointer updated
443 ; t, STATUS, PROD* any undefined
444 ; all others any preserved
455 ;======================================================================
456 ; MASTER READOUT AND MASTER READOUT OF SLAVES
459 write_if_setbytetowrite
460 bt_f_if0 idloc1,idloc1_master
461 return ; for master only
464 mov_wf panic_valcount
465 bs_f panicst, panicst_writeslave
469 write_if_master_slaveread
470 mov_wf panic_valcount
471 bc_f panicst, panicst_writeslave
475 write_if_master_slaveselect
478 bt_f_if1 panicst, panicst_writeslave
479 bra pan_i2cm_write_start
480 bra pan_i2cm_read_start
483 write_if_master_masterread
485 mov_wf panic_valcount
486 write_if_master_masterread_loop
488 call serial_write_char
489 dec_f_ifnz panic_valcount
490 bra write_if_master_masterread_loop
494 pan_i2cmu_read_got_byte
495 call serial_write_char
496 dec_f_ifnz panic_valcount
497 bra pan_i2cm_read_another
501 pan_i2cmu_write_next_byte
502 mov_fw panic_valcount
504 bt_f_if1 panicst, panicst_writeslave
506 bc_f panicst, panicst_writeslave
512 goto serial_write_char
514 ;======================================================================
519 pan_i2csu_write_begin
524 mov_lw 0x80 ; M0000000
525 bt_f_if0 panicst, panicst_acked
533 pan_i2csu_read_another
534 bt_f_if1 panicst, panicst_acked
535 bra i2csu_read_panicd_ok
545 near_serialrx_table code 0x2100
548 panic_crashread_commanded @
551 ;***************************************************************************