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
15 ; used in panic routine for temporary storage:
19 register_counter res 1
22 panic_address res 1 ; condensed form of message start addr.
23 panic_morse res 1 ; # bytes of morse msg in panic readout
24 panic_regs res 1 ; # registers in panic readout
29 ;****************************************************************************
33 ;****************************************************************************
36 ; switch off interrupts and power
37 ; reconfigure timer0 for writing diagnostic msg to the LED
39 clr_f INTCON ; disable all interrupts EVER
40 bc_f PORTC,1 ; switch off booster
42 ; now we have time to copy the panic message address out of WREG
43 ; (turning off interrupts is urgent (we might get interrupted while
44 ; panicing which would be bad because we might forget to panic).
47 clr_f STKPTR ; avoids stack overruns
49 ; re-initialise timer0 config
51 bra_z panic_setup_if_master
53 morse_t0setup sclock, (1<<TMR0ON), t0l_count, t0h_count
54 bra panic_setup_endif_masterslave
56 morse_t0setup mclock, (1<<TMR0ON), t0l_count, t0h_count
57 panic_setup_endif_masterslave
59 ; get # bytes of morse msg, # registers in panic readout, message start addr.
60 ; back from condensed message start addr. stored in panic_address
63 mov_lw 4 ; size of each message's details
67 add_lw (morse_messages_start)/256
71 tblrd *+ ; read 1st byte of error message
72 ; (gives # bytes morse, # bytes registers)
73 dw 0xffff ; silicon errata: B4 issue 4
75 mov_ff TABLAT,panic_morse
77 and_wff panic_morse ; panic_morse now contains # bytes of morse msgs
79 mov_ff TABLAT,panic_regs
82 swap_f panic_regs ; panic_regs now contains # registers to read
86 rcall morsemsg ; transmit morse in red
90 rcall registermsg ; transmit contents of registers in
91 ; red(=low) and blue(=high)
95 ;****************************************************************************
99 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
102 clr_f morse_counter ; clear loop counter
106 cmp_fw_ifge morse_counter ; if loop counter >=panic_morse
107 return ; return to panic
110 mov_ff TABLAT,flash_pattern
116 ;--------------------------
119 ; Flashes the per-pic led and black in a specified pattern.
121 ; The pattern is specified as the state for 8 identically-long time
122 ; periods each as long as a morse `dot', encoded into a byte with
123 ; most significant bit first.
126 ; flash_pattern flash pattern preserved
127 ; bit_counter any undefined
134 dec_f_ifz bit_counter ; done all the bits yet ?
138 rl_f flash_pattern ; top bit goes into N,
140 bra_n morse_readout_if_led_1
142 morse_readout_if_led_0
144 bra morse_readout_endif_led
146 morse_readout_if_led_1
149 morse_readout_endif_led
151 bra morse_readout_loop
153 ;--------------------------
154 ;--------------------------
158 clr_f register_counter ; clear loop counter
162 cmp_fw_ifge register_counter ; if loop counter >=panic_regs
163 return ; return to panic
167 mov_fw TABLAT ; TABLAT has the 8-bit version
168 mov_wf FSR0L ; of the address. So, 8 bits
169 ; go straight into FSR0L.
171 mov_lw 0x0f ; For FSR0H, we see if the
172 mov_fw FSR0H ; address XX is >=0x60.
173 ; If it is then we meant 0xfXX;
174 mov_lw 0x5f ; if not then we meant 0x0XX.
175 cmp_fw_ifle FSR0L ; (This is just like PIC does
176 clr_f FSR0H ; for insns using Access Bank)
178 mov_ff INDF0,flash_pattern
179 rcall register_readout
181 inc_f register_counter ;increment loop counter
186 ;--------------------------
190 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
191 ; (black gap between each bit)
193 ; The pattern is specified as the state for 8 identically-long time
194 ; periods each as long as a morse `dot', encoded into a byte with
195 ; most significant bit first.
198 ; flash_pattern flash pattern preserved
199 ; bit_counter any undefined
201 clr_f bit_counter ; clear loop counter
205 register_readout_loop
207 cmp_fw_ifge bit_counter ; if loop counter >=8 (register
212 cmp_fw_ifne bit_counter ; if loop counter !=4 (nybble length),
213 ; skip insertion of extra black space
214 bra not_nybble_boundary
218 rl_f flash_pattern ; top bit goes into N flag,
220 bra_n register_readout_if_led_1
222 register_readout_if_led_0
224 bra register_readout_endif_led
226 register_readout_if_led_1
229 register_readout_endif_led
230 inc_f bit_counter ; increment loop counter
234 bra register_readout_loop
237 ;****************************************************************************
238 ; GENERAL SUBROUTINES
240 ;----------------------------------------
241 waiting16 rcall waiting8
242 waiting8 rcall waiting4
243 waiting4 rcall waiting2
244 waiting2 rcall waiting
246 ; waits for a fixed interval, depending on the configuration of TMR0
248 bc_f INTCON,2 ; clear timer0 interrupt bit (p109)
249 ; Interrupt happens on overflow. So start at 65535-morse_t0cycles:
251 mov_wf TMR0H ; p107 set high byte of timer0 (buffered,
252 ; only actually set when write to tmr0l occurs)
254 mov_wf TMR0L ; set timer0 low byte - timer now set
256 bt_f_if0 INTCON,TMR0IF
257 bra waiting_loop ; wait for timer0 interrupt
261 ;****************************************************************************