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_i2cmours equ 2
24 panicst_i2cmenable equ 1
28 panic_vars_section udata 0x060 + maxpics ; not available via access bank
29 ; used in panic routine for temporary storage:
33 register_counter res 1
36 panic_address res 1 ; condensed form of message start addr.
37 panic_morse res 1 ; # bytes of morse msg in panic readout
38 panic_regs res 1 ; # registers in panic readout
53 panic_stack res stack_depth*3
55 ;****************************************************************************
59 ;****************************************************************************
63 ; switch off interrupts and power
64 ; reconfigure timer0 for writing diagnostic msg to the LED
66 mov_ff INTCON, psave_intcon
67 bc_f INTCON, GIEH ; disable all interrupts
72 mov_ff LATC, psave_latc
74 ; now we have time to save registers etc
75 ; (turning off interrupts is urgent (we might get interrupted while
76 ; panicing which would be bad because we might forget to panic).
81 mov_ff TABLAT, psave_tablat
82 mov_ff TBLPTRL, psave_tblptr
83 mov_ff TBLPTRH, psave_tblptr+1
84 mov_ff TBLPTRU, psave_tblptr+2
85 mov_ff FSR0L, psave_fsr0
86 mov_ff FSR0H, psave_fsr0+1
87 mov_ff FSR1L, psave_fsr1
88 mov_ff FSR1H, psave_fsr1+1
89 mov_ff PRODL, psave_prod
90 mov_ff PRODH, psave_prod+1
91 mov_ff STKPTR, psave_stkptr
93 mov_lfsr panic_stack + stack_depth*3 - 1, 0
103 clr_f STKPTR ; avoids stack overruns
108 ; re-initialise timer0 config, etc.
110 bra_z panic_setup_if_master
114 movlw (1<<TMR0ON) | morse_slave_t0scale
116 movlw morse_slave_t0inith
118 movlw morse_slave_t0initl
121 bra panic_setup_endif_masterslave
123 panic_setup_if_master
124 movlw (1<<TMR0ON) | morse_master_t0scale
126 movlw morse_master_t0inith
128 movlw morse_master_t0initl
131 pin_l p0_booster_userfault
135 call serial_write_char
137 panic_setup_endif_masterslave
139 ; get # bytes of morse msg, # registers in panic readout, message start addr.
140 ; back from condensed message start addr. stored in panic_address
143 mov_lw 4 ; size of each message's details
147 add_lw (morse_messages_start)/256
151 tblrd *+ ; read 1st byte of error message
152 ; (gives # bytes morse, # bytes registers)
153 dw 0xffff ; silicon errata: B4 issue 4
155 mov_ff TABLAT,panic_morse
157 and_wff panic_morse ; panic_morse now contains # bytes of morse msgs
159 mov_ff TABLAT,panic_regs
162 swap_f panic_regs ; panic_regs now contains # registers to read
166 rcall morsemsg ; transmit morse in red
170 rcall registermsg ; transmit contents of registers in
171 ; red(=low) and blue(=high)
175 ;****************************************************************************
179 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
182 clr_f morse_counter ; clear loop counter
186 cmp_fw_ifge morse_counter ; if loop counter >=panic_morse
187 return ; return to panic
190 mov_ff TABLAT,flash_pattern
196 ;--------------------------
199 ; Flashes the per-pic led and black in a specified pattern.
201 ; The pattern is specified as the state for 8 identically-long time
202 ; periods each as long as a morse `dot', encoded into a byte with
203 ; most significant bit first.
206 ; flash_pattern flash pattern preserved
207 ; bit_counter any undefined
214 dec_f_ifz bit_counter ; done all the bits yet ?
218 rl_f flash_pattern ; top bit goes into N,
220 bra_n morse_readout_if_led_1
222 morse_readout_if_led_0
224 bra morse_readout_endif_led
226 morse_readout_if_led_1
229 morse_readout_endif_led
231 bra morse_readout_loop
233 ;--------------------------
234 ;--------------------------
238 clr_f register_counter ; clear loop counter
242 cmp_fw_ifge register_counter ; if loop counter >=panic_regs
243 return ; return to panic
247 mov_fw TABLAT ; TABLAT has the 8-bit version
248 mov_wf FSR0L ; of the address. So, 8 bits
249 ; go straight into FSR0L.
251 mov_lw 0x0f ; For FSR0H, we see if the
252 mov_fw FSR0H ; address XX is >=0x60.
253 ; If it is then we meant 0xfXX;
254 mov_lw 0x5f ; if not then we meant 0x0XX.
255 cmp_fw_ifle FSR0L ; (This is just like PIC does
256 clr_f FSR0H ; for insns using Access Bank)
258 mov_ff INDF0,flash_pattern
259 rcall register_readout
261 inc_f register_counter ;increment loop counter
266 ;--------------------------
270 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
271 ; (black gap between each bit)
273 ; The pattern is specified as the state for 8 identically-long time
274 ; periods each as long as a morse `dot', encoded into a byte with
275 ; most significant bit first.
278 ; flash_pattern flash pattern preserved
279 ; bit_counter any undefined
281 clr_f bit_counter ; clear loop counter
285 register_readout_loop
287 cmp_fw_ifge bit_counter ; if loop counter >=8 (register
292 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
293 ; skip insertion of extra black space
294 bra not_nybble_boundary
298 rl_f flash_pattern ; top bit goes into N flag,
300 bra_n register_readout_if_led_1
302 register_readout_if_led_0
304 bra register_readout_endif_led
306 register_readout_if_led_1
309 register_readout_endif_led
310 inc_f bit_counter ; increment loop counter
314 bra register_readout_loop
317 ;****************************************************************************
318 ; GENERAL SUBROUTINES
320 ;----------------------------------------
321 waiting16 rcall waiting8
322 waiting8 rcall waiting4
323 waiting4 rcall waiting2
324 waiting2 rcall waiting
326 ; waits for a fixed interval, depending on the configuration of TMR0
328 bt_f_if1 idloc1,idloc1_master
329 pin_z p0_booster_userfault
331 bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
332 ; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
334 mov_wf TMR0H ; p107 set high byte of timer0 (buffered,
335 ; only actually set when write to tmr0l occurs)
337 mov_wf TMR0L ; set timer0 low byte - timer now set
338 waiting_loop ; wait for timer0 interrupt, or some other interrupt
339 bt_f_if1 INTCON,TMR0IF
342 bt_f_if1 idloc1, idloc1_master
346 bt_f_if0 SSPCON1, SSPEN
347 bra waiting_loop ; no readouts if i2c is disabled
348 ; slave, i2c enabled:
351 call pan_i2cs_interrupt
355 ;****************************************************************************
356 ; MEMORY READOUT - CRASH DUMP
358 ;----------------------------------------
359 ; MASTER'S PANIC SERIAL PORT HANDLING
361 ;--------------------
363 bt_f_if1 PIR1,RCIF ; host sent us something ?
366 bt_f_if0 SSPCON1, SSPEN
368 ; master, i2c enabled:
370 bt_f_if0 panicst, panicst_i2cmenable
374 rcall pan_i2cm_interrupt
384 bra_nz panicd_serialrx_err_loop
385 ; yay! host ack'd ferr/oerr
386 bc_f panicst, panicst_ferroerr
387 return ; return from panicd_serialrx
391 bs_f panicst, panicst_ferroerr
392 bc_f RCSTA, RCEN ; disable } to clear FERR/OERR
393 mov_fw RCREG ; read RCREG } (see PIC18FXX8 DS p182)
394 bs_f RCSTA, RCEN ; reenable }
395 panicd_serialrx_err_loop
396 bt_f_if0 PIR1, RCIF ; wait for a byte 0x10 to ack the overrun/error
397 bra panicd_serialrx_err_loop
401 pin_nz p0_booster_userfault
403 bra panicd_serialrx_err
405 bra panicd_serialrx_err
406 bt_f_if1 panicst, panicst_ferroerr
410 bra panicd_process_input_byte
412 ;----------------------------------------
413 ; CRASHREAD MASTER/SLAVE COMMON COMMAND BYTE HANDLING
418 panicd_process_input_byte
419 ; W instruction from host or master
422 ; we've received 0x00:
425 bs_f panicst, panicst_acked
430 bt_f_if0 panicst, panicst_acked ; well, ignore that !
431 bra write_only_tellmode
432 ; OK, we have an instruction:
435 bra write_if_setbytetowrite
437 bra panic_crashread_setpointer
438 bt_f_if0 idloc1,idloc1_master
439 bra write_ifnot0_ifnotmaster
440 ; the next few options are for master only:
443 bra write_if_master_slaveselect
445 bra write_if_master_masterread
447 bra write_if_master_slaveread
449 write_ifnot0_ifnotmaster
457 ; nope, well, we ignore it
461 panic_crashread_setpointer
462 ; W byte from master or host undefined
463 ; FSR1* crashread pointer updated
464 ; t, STATUS, PROD* any undefined
465 ; all others any preserved
477 ;======================================================================#
478 ; SPECIAL COMMANDS 0x08..0x0f
486 bt_f_if0 idloc1,idloc1_master
489 bc_f panicst, panicst_acked
490 goto serial_write_char
492 ;======================================================================
493 ; MASTER READOUT AND MASTER READOUT OF SLAVES
496 write_if_setbytetowrite
497 bt_f_if0 idloc1,idloc1_master
498 return ; for master only
501 mov_wf panic_valcount
502 bs_f panicst, panicst_writeslave
503 bs_f panicst, panicst_i2cmenable
507 write_if_master_slaveread
508 mov_wf panic_valcount
509 bc_f panicst, panicst_writeslave
513 write_if_master_slaveselect
516 bs_f panicst, panicst_i2cmours
517 bt_f_if1 panicst, panicst_writeslave
518 bra pan_i2cm_write_start
519 bra pan_i2cm_read_start
522 write_if_master_masterread
524 mov_wf panic_valcount
525 write_if_master_masterread_loop
527 call serial_write_char
528 dec_f_ifnz panic_valcount
529 bra write_if_master_masterread_loop
533 pan_i2cmu_read_got_byte
534 bt_f_if0 panicst, panicst_i2cmours
536 call serial_write_char
537 dec_f_ifnz panic_valcount
538 bra pan_i2cm_read_another
542 pan_i2cmu_write_next_byte
543 mov_fw panic_valcount
545 bt_f_if0 panicst, panicst_i2cmours
547 bt_f_if0 panicst, panicst_writeslave
549 bc_f panicst, panicst_writeslave
555 goto serial_write_char
558 pan_i2cmu_slave_no_ack
561 ;======================================================================
566 pan_i2csu_write_begin
571 mov_lw 0x80 ; M0000000
572 bt_f_if0 panicst, panicst_acked
580 pan_i2csu_read_another
581 bt_f_if1 panicst, panicst_acked
582 bra i2csu_read_panicd_ok
592 command_crashed_section code 0x2100
595 panic_crashread_commanded @
598 ;***************************************************************************