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
27 panicst_restart_i2c equ 7
30 panic_vars_section udata 0x060 ; not available via access bank
32 ; used in panic routine for temporary storage:
36 register_counter res 1
39 panic_address res 1 ; condensed form of message start addr.
40 panic_morse res 1 ; # bytes of morse msg in panic readout
41 panic_regs res 1 ; # registers in panic readout
46 ;****************************************************************************
50 ;****************************************************************************
53 ; switch off interrupts and power
54 ; reconfigure timer0 for writing diagnostic msg to the LED
56 mov_ff INTCON, psave_intcon
57 bc_f INTCON, GIEH ; disable all interrupts
62 mov_ff LATC, psave_latc
66 ; now we have time to copy the panic message address out of WREG
67 ; (turning off interrupts is urgent (we might get interrupted while
68 ; panicing which would be bad because we might forget to panic).
71 clr_f STKPTR ; avoids stack overruns
74 mov_ff TABLAT, psave_tablat
75 mov_ff TBLPTRL, psave_tblptr
76 mov_ff TBLPTRH, psave_tblptr+1
77 mov_ff TBLPTRU, psave_tblptr+2
78 mov_ff FSR0L, psave_fsr0
79 mov_ff FSR0H, psave_fsr0+1
80 mov_ff FSR1L, psave_fsr1
81 mov_ff FSR1H, psave_fsr1+1
82 mov_ff PRODL, psave_prod
83 mov_ff PRODH, psave_prod+1
86 bs_f picno, picno_panicd
90 ;x bt_f_if1 SSPCON1, SSPEN
91 ;x bs_f panicst, panicst_restart_i2c
92 ;x bc_f SSPCON1, SSPEN
94 ; re-initialise timer0 config
96 bra_z panic_setup_if_master
98 morse_t0setup sclock, (1<<TMR0ON), t0l_count, t0h_count
99 bra panic_setup_endif_masterslave
100 panic_setup_if_master
101 morse_t0setup mclock, (1<<TMR0ON), t0l_count, t0h_count
102 panic_setup_endif_masterslave
104 ; get # bytes of morse msg, # registers in panic readout, message start addr.
105 ; back from condensed message start addr. stored in panic_address
108 mov_lw 4 ; size of each message's details
112 add_lw (morse_messages_start)/256
116 tblrd *+ ; read 1st byte of error message
117 ; (gives # bytes morse, # bytes registers)
118 dw 0xffff ; silicon errata: B4 issue 4
120 mov_ff TABLAT,panic_morse
122 and_wff panic_morse ; panic_morse now contains # bytes of morse msgs
124 mov_ff TABLAT,panic_regs
127 swap_f panic_regs ; panic_regs now contains # registers to read
131 rcall morsemsg ; transmit morse in red
135 rcall registermsg ; transmit contents of registers in
136 ; red(=low) and blue(=high)
140 ;****************************************************************************
144 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
147 clr_f morse_counter ; clear loop counter
151 cmp_fw_ifge morse_counter ; if loop counter >=panic_morse
152 return ; return to panic
155 mov_ff TABLAT,flash_pattern
161 ;--------------------------
164 ; Flashes the per-pic led and black in a specified pattern.
166 ; The pattern is specified as the state for 8 identically-long time
167 ; periods each as long as a morse `dot', encoded into a byte with
168 ; most significant bit first.
171 ; flash_pattern flash pattern preserved
172 ; bit_counter any undefined
179 dec_f_ifz bit_counter ; done all the bits yet ?
183 rl_f flash_pattern ; top bit goes into N,
185 bra_n morse_readout_if_led_1
187 morse_readout_if_led_0
189 bra morse_readout_endif_led
191 morse_readout_if_led_1
194 morse_readout_endif_led
196 bra morse_readout_loop
198 ;--------------------------
199 ;--------------------------
203 clr_f register_counter ; clear loop counter
207 cmp_fw_ifge register_counter ; if loop counter >=panic_regs
208 return ; return to panic
212 mov_fw TABLAT ; TABLAT has the 8-bit version
213 mov_wf FSR0L ; of the address. So, 8 bits
214 ; go straight into FSR0L.
216 mov_lw 0x0f ; For FSR0H, we see if the
217 mov_fw FSR0H ; address XX is >=0x60.
218 ; If it is then we meant 0xfXX;
219 mov_lw 0x5f ; if not then we meant 0x0XX.
220 cmp_fw_ifle FSR0L ; (This is just like PIC does
221 clr_f FSR0H ; for insns using Access Bank)
223 mov_ff INDF0,flash_pattern
224 rcall register_readout
226 inc_f register_counter ;increment loop counter
231 ;--------------------------
235 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
236 ; (black gap between each bit)
238 ; The pattern is specified as the state for 8 identically-long time
239 ; periods each as long as a morse `dot', encoded into a byte with
240 ; most significant bit first.
243 ; flash_pattern flash pattern preserved
244 ; bit_counter any undefined
246 clr_f bit_counter ; clear loop counter
250 register_readout_loop
252 cmp_fw_ifge bit_counter ; if loop counter >=8 (register
257 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
258 ; skip insertion of extra black space
259 bra not_nybble_boundary
263 rl_f flash_pattern ; top bit goes into N flag,
265 bra_n register_readout_if_led_1
267 register_readout_if_led_0
269 bra register_readout_endif_led
271 register_readout_if_led_1
274 register_readout_endif_led
275 inc_f bit_counter ; increment loop counter
279 bra register_readout_loop
282 ;****************************************************************************
283 ; GENERAL SUBROUTINES
285 ;----------------------------------------
286 waiting16 rcall waiting8
287 waiting8 rcall waiting4
288 waiting4 rcall waiting2
289 waiting2 rcall waiting
291 ; waits for a fixed interval, depending on the configuration of TMR0
293 bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
294 ; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
296 mov_wf TMR0H ; p107 set high byte of timer0 (buffered,
297 ; only actually set when write to tmr0l occurs)
299 mov_wf TMR0L ; set timer0 low byte - timer now set
300 waiting_loop ; wait for timer0 interrupt, or some other interrupt
301 bt_f_if1 INTCON,TMR0IF
304 bt_f_if0 SSPCON1, SSPEN
305 bra waiting_loop ; no readouts if i2c is disabled
307 bt_f_if1 idloc1, idloc1_master
308 bra waiting_loop ; no readouts on master yet
317 ;x bt_f_if0 panicst, panicst_restart_i2c
319 bc_f panicst, panicst_restart_i2c
322 bra_z waiting_done_if_master
329 waiting_done_if_master
332 ;****************************************************************************
337 panicd_process_input_byte
338 ; W instruction from host or master
341 ; we've received 0x00:
344 bs_f panicst, panicst_acked
349 bt_f_if0 panicst, panicst_acked ; well, ignore that !
351 ; OK, we have an instruction:
356 bra write_if_setpointer
357 bt_f_if0 idloc1,idloc1_master
358 return ; all the remaining options are for master only
360 ;nyi bra write_if_selectslave
362 ;nyi bra write_if_readout
378 i2csu_read_begin_panicd
379 mov_lw 0x80 ; M0000000
380 bt_f_if0 panicst, panicst_acked
388 i2csu_read_another_panicd
389 bt_f_if1 panicst, panicst_acked
390 bra i2csu_read_panicd_ok
395 ;***************************************************************************