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
113 movlw morse_slave_t0inith
115 movlw morse_slave_t0initl
118 bra panic_setup_endif_masterslave
120 panic_setup_if_master
121 movlw (1<<TMR0ON) | morse_master_t0scale
123 movlw morse_master_t0inith
125 movlw morse_master_t0initl
128 pin_l p0_booster_userfault
132 call serial_write_char
134 panic_setup_endif_masterslave
136 ; get # bytes of morse msg, # registers in panic readout, message start addr.
137 ; back from condensed message start addr. stored in panic_address
140 mov_lw 4 ; size of each message's details
144 add_lw (morse_messages_start)/256
148 tblrd *+ ; read 1st byte of error message
149 ; (gives # bytes morse, # bytes registers)
150 dw 0xffff ; silicon errata: B4 issue 4
152 mov_ff TABLAT,panic_morse
154 and_wff panic_morse ; panic_morse now contains # bytes of morse msgs
156 mov_ff TABLAT,panic_regs
159 swap_f panic_regs ; panic_regs now contains # registers to read
163 rcall morsemsg ; transmit morse in red
167 rcall registermsg ; transmit contents of registers in
168 ; red(=low) and blue(=high)
172 ;****************************************************************************
176 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
179 clr_f morse_counter ; clear loop counter
183 cmp_fw_ifge morse_counter ; if loop counter >=panic_morse
184 return ; return to panic
187 mov_ff TABLAT,flash_pattern
193 ;--------------------------
196 ; Flashes the per-pic led and black in a specified pattern.
198 ; The pattern is specified as the state for 8 identically-long time
199 ; periods each as long as a morse `dot', encoded into a byte with
200 ; most significant bit first.
203 ; flash_pattern flash pattern preserved
204 ; bit_counter any undefined
211 dec_f_ifz bit_counter ; done all the bits yet ?
215 rl_f flash_pattern ; top bit goes into N,
217 bra_n morse_readout_if_led_1
219 morse_readout_if_led_0
221 bra morse_readout_endif_led
223 morse_readout_if_led_1
226 morse_readout_endif_led
228 bra morse_readout_loop
230 ;--------------------------
231 ;--------------------------
235 clr_f register_counter ; clear loop counter
239 cmp_fw_ifge register_counter ; if loop counter >=panic_regs
240 return ; return to panic
244 mov_fw TABLAT ; TABLAT has the 8-bit version
245 mov_wf FSR0L ; of the address. So, 8 bits
246 ; go straight into FSR0L.
248 mov_lw 0x0f ; For FSR0H, we see if the
249 mov_fw FSR0H ; address XX is >=0x60.
250 ; If it is then we meant 0xfXX;
251 mov_lw 0x5f ; if not then we meant 0x0XX.
252 cmp_fw_ifle FSR0L ; (This is just like PIC does
253 clr_f FSR0H ; for insns using Access Bank)
255 mov_ff INDF0,flash_pattern
256 rcall register_readout
258 inc_f register_counter ;increment loop counter
263 ;--------------------------
267 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
268 ; (black gap between each bit)
270 ; The pattern is specified as the state for 8 identically-long time
271 ; periods each as long as a morse `dot', encoded into a byte with
272 ; most significant bit first.
275 ; flash_pattern flash pattern preserved
276 ; bit_counter any undefined
278 clr_f bit_counter ; clear loop counter
282 register_readout_loop
284 cmp_fw_ifge bit_counter ; if loop counter >=8 (register
289 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
290 ; skip insertion of extra black space
291 bra not_nybble_boundary
295 rl_f flash_pattern ; top bit goes into N flag,
297 bra_n register_readout_if_led_1
299 register_readout_if_led_0
301 bra register_readout_endif_led
303 register_readout_if_led_1
306 register_readout_endif_led
307 inc_f bit_counter ; increment loop counter
311 bra register_readout_loop
314 ;****************************************************************************
315 ; GENERAL SUBROUTINES
317 ;----------------------------------------
318 waiting16 rcall waiting8
319 waiting8 rcall waiting4
320 waiting4 rcall waiting2
321 waiting2 rcall waiting
323 ; waits for a fixed interval, depending on the configuration of TMR0
325 bt_f_if1 idloc1,idloc1_master
326 pin_z p0_booster_userfault
328 bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
329 ; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
331 mov_wf TMR0H ; p107 set high byte of timer0 (buffered,
332 ; only actually set when write to tmr0l occurs)
334 mov_wf TMR0L ; set timer0 low byte - timer now set
335 waiting_loop ; wait for timer0 interrupt, or some other interrupt
336 bt_f_if1 INTCON,TMR0IF
339 bt_f_if1 idloc1, idloc1_master
343 bt_f_if0 SSPCON1, SSPEN
344 bra waiting_loop ; no readouts if i2c is disabled
345 ; slave, i2c enabled:
348 call pan_i2cs_interrupt
352 ;----------------------------------------
353 ; MASTER'S PANIC SERIAL PORT HANDLING
355 ;--------------------
357 bt_f_if1 PIR1,RCIF ; host sent us something ?
360 bt_f_if0 SSPCON1, SSPEN
362 ; master, i2c enabled:
365 rcall pan_i2cm_interrupt
372 bra_nz panicd_serialrx_err_loop
373 ; yay! host ack'd ferr/oerr
374 bc_f panicst, panicst_ferroerr
375 return ; return from panicd_serialrx
379 bs_f panicst, panicst_ferroerr
380 bc_f RCSTA, RCEN ; disable } to clear FERR/OERR
381 mov_fw RCREG ; read RCREG } (see PIC18FXX8 DS p182)
382 bs_f RCSTA, RCEN ; reenable }
383 panicd_serialrx_err_loop
384 bt_f_if0 PIR1, RCIF ; wait for a byte 0x01 to ack the overrun/error
385 bra panicd_serialrx_err_loop
389 pin_nz p0_booster_userfault
391 bra panicd_serialrx_err
393 bra panicd_serialrx_err
394 bt_f_if1 panicst, panicst_ferroerr
399 ;****************************************************************************
404 panicd_process_input_byte
405 ; W instruction from host or master
408 ; we've received 0x00:
411 bs_f panicst, panicst_acked
416 bt_f_if0 panicst, panicst_acked ; well, ignore that !
418 ; OK, we have an instruction:
421 bra write_if_setbytetowrite
423 bra panic_crashread_setpointer
424 bt_f_if0 idloc1,idloc1_master
425 return ; all the remaining options are for master only
427 bra write_if_master_slaveselect
429 bra write_if_master_masterread
430 bra write_if_master_slaveread
434 panic_crashread_setpointer
435 ; W byte from master or host undefined
436 ; FSR1* crashread pointer updated
437 ; t, STATUS, PROD* any undefined
438 ; all others any preserved
449 ;======================================================================
450 ; MASTER READOUT AND MASTER READOUT OF SLAVES
453 write_if_setbytetowrite
454 bt_f_if0 idloc1,idloc1_master
455 return ; for master only
458 mov_wf panic_valcount
459 bs_f panicst, panicst_writeslave
463 write_if_master_slaveread
464 mov_wf panic_valcount
465 bc_f panicst, panicst_writeslave
469 write_if_master_slaveselect
471 bt_f_if1 panicst, panicst_writeslave
472 bra pan_i2cm_write_start
473 bra pan_i2cm_read_start
476 write_if_master_masterread
478 mov_wf panic_valcount
479 write_if_master_masterread_loop
481 call serial_write_char
482 dec_f_ifnz panic_valcount
483 bra write_if_master_masterread_loop
487 pan_i2cmu_read_got_byte
488 call serial_write_char
489 dec_fw_ifnz panic_valcount
490 bra pan_i2cm_read_another
494 pan_i2cmu_write_next_byte
495 mov_fw panic_valcount
497 bt_f_if1 panicst, panicst_writeslave
499 bc_f panicst, panicst_writeslave
505 goto serial_write_char
507 ;======================================================================
512 pan_i2csu_write_begin
517 mov_lw 0x80 ; M0000000
518 bt_f_if0 panicst, panicst_acked
526 pan_i2csu_read_another
527 bt_f_if1 panicst, panicst_acked
528 bra i2csu_read_panicd_ok
538 near_serialrx_table code 0x2100
541 panic_crashread_commanded @
542 bs_f panicst, panicst_acked ; since we were asked to
545 ;***************************************************************************