chiark / gitweb /
silicon errata: B4 issue 4
[trains.git] / detpic / panic.asm
1 ;======================================================================
2 ; panic.asm
3 ;
4 ; This file implements panic_routine, which is called by the
5 ; `panic' macro in panic.inc.  See panic.inc for the functionality
6 ; of `panic'.
7
8         include common.inc
9
10 ;---------------------------------------------------------------------------
11 ; reserved access bank locations
12
13         udata_acs
14
15 ; used in panic routine for temporary storage:
16
17 flash_pattern           res     1
18 morse_counter           res     1
19 register_counter        res     1
20 bit_counter             res     1
21
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
25
26
27 ;****************************************************************************
28
29         code
30
31 ;****************************************************************************
32
33 panic_routine
34 ; switch off interrupts and power
35 ; reconfigure timer0 for writing diagnostic msg to the LED
36
37         clr_f    INTCON        ; disable all interrupts EVER
38         bc_f     PORTC,1       ; switch off booster
39
40 ; now we have time to copy the panic message address out of WREG
41 ; (turning off interrupts is urgent (we might get interrupted while
42 ;  panicing which would be bad because we might forget to panic).
43
44         mov_wf   panic_address
45
46
47 ; re-initialise timer0 config
48         bc_f     T0CON,6       ; p107 Timer0 -> 16bit mode
49         bc_f     T0CON,5       ; timer0 use internal clock
50         bc_f     T0CON,3       ; use prescaler
51         bc_f     T0CON,2       ; }
52         bs_f     T0CON,1       ; } prescale value 1:8 (13ms x 8)
53         bc_f     T0CON,0       ; }
54
55 ; get # bytes of morse msg, # registers in panic readout, message start addr.
56 ; back from condensed message start addr. stored in panic_address
57
58 panic_loop
59         mov_lw  4 ; size of each message's details
60         mul_wf  panic_address
61         mov_ff  PRODL,TBLPTRL           
62         mov_ff  PRODH,WREG
63         add_lw  (morse_messages_start)/256
64         mov_wf  TBLPTRH
65         clr_f   TBLPTRU
66
67         tblrd   *+              ; read 1st byte of error message
68                                 ; (gives # bytes morse, # bytes registers)
69         dw      0xffff ; silicon errata: B4 issue 4
70
71         mov_ff  TABLAT,panic_morse
72         mov_lw  00001111b
73         and_wff panic_morse     ; panic_morse now contains # bytes of morse msgs
74
75         mov_ff  TABLAT,panic_regs
76         mov_lw  01110000b
77         and_wff panic_regs
78         swap_f  panic_regs      ; panic_regs now contains # registers to read
79
80         call    led_black
81         call    waiting
82         call    waiting
83         call    waiting
84         call    waiting
85         call    waiting
86         call    waiting
87         call    waiting
88         call    waiting
89         call    morsemsg        ; transmit morse in red
90         call    led_black
91         call    waiting
92         call    waiting
93         call    waiting
94         call    waiting
95         call    registermsg     ; transmit contents of registers in 
96                                 ; red(=low) and blue(=high)
97         goto    panic_loop
98
99 ;****************************************************************************
100 ; PANIC SUBROUTINES
101
102 morsemsg
103 ; wrapper round morse_readout to flash the per-pic led red for a morse msg
104
105 morse_msg_start
106         clr_f           morse_counter           ; clear loop counter
107
108 morse_loop
109         mov_fw          panic_morse
110         cmp_fw_ifge     morse_counter           ; if loop counter >=panic_morse
111         return                                  ; return to panic
112
113         tblrd           *+
114         mov_ff          TABLAT,flash_pattern
115         call            morse_readout
116         inc_f           morse_counter
117         goto            morse_loop
118
119
120 ;--------------------------
121 morse_readout
122
123 ; Flashes the per-pic led and black in a specified pattern.
124 ;
125 ; The pattern is specified as the state for 8 identically-long time
126 ; periods each as long as a morse `dot', encoded into a byte with
127 ; most significant bit first.
128 ;                       On entry                On exit
129 ; W                     any                     undefined
130 ; flash_pattern         flash pattern           preserved
131 ; bit_counter           any                     undefined
132
133         mov_lw          9
134         mov_wf          bit_counter
135         rr_f            flash_pattern
136
137 morse_readout_loop
138         dec_f_ifz       bit_counter             ; done all the bits yet ?
139         return
140         ; No:
141
142         rl_f            flash_pattern           ; top bit goes into N, 
143                                                 ;ie Negative if 1
144         bra_n           morse_readout_if_led_1
145
146 morse_readout_if_led_0
147         call            led_black
148         bra             morse_readout_endif_led
149
150 morse_readout_if_led_1
151         call            led_red
152
153 morse_readout_endif_led
154         call            waiting
155         bra             morse_readout_loop
156
157 ;--------------------------
158 ;--------------------------
159 registermsg
160
161 register_msg_start
162         clr_f           register_counter        ; clear loop counter
163
164 register_loop
165         mov_fw          panic_regs
166         cmp_fw_ifge     register_counter        ; if loop counter >=panic_regs
167         return                                  ; return to panic
168
169         tblrd           *+
170
171         mov_fw          TABLAT          ; TABLAT has the 8-bit version
172         mov_wf          FSR0L           ; of the address.  So, 8 bits
173                                         ; go straight into FSR0L.
174
175         mov_lw          0x0f            ; For FSR0H, we see if the
176         mov_fw          FSR0H           ; address XX is >=0x60.
177                                         ; If it is then we meant 0xfXX;
178         mov_lw          0x5f            ; if not then we meant 0x0XX.
179         cmp_fw_ifle     FSR0L           ; (This is just like PIC does
180         clr_f           FSR0H           ; for insns using Access Bank)
181
182         mov_ff          INDF0,flash_pattern
183         call            register_readout
184
185         inc_f           register_counter        ;increment loop counter
186
187         call            waiting
188         call            waiting
189         goto            register_loop
190
191 ;--------------------------
192
193 register_readout
194
195 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
196 ; (black gap between each bit)
197 ;
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.
201 ;                       On entry                On exit
202 ; W                     any                     undefined
203 ; flash_pattern         flash pattern           preserved
204 ; bit_counter           any                     undefined
205
206         clr_f   bit_counter             ; clear loop counter
207         rr_f    flash_pattern
208
209
210 register_readout_loop
211         mov_lw          8
212         cmp_fw_ifge     bit_counter             ; if loop counter >=8 (register 
213                                                 ; length), return
214         return
215
216         mov_lw          4
217         cmp_fw_ifne     bit_counter     ; if loop counter !=4 (nybble length), 
218                                         ; skip insertion of extra black space
219         goto            not_nybble_boundary
220         call            waiting
221
222 not_nybble_boundary
223         rl_f            flash_pattern           ; top bit goes into N flag, 
224                                                 ; ie Negative if 1
225         bra_n           register_readout_if_led_1
226
227 register_readout_if_led_0
228         call            led_red
229         bra             register_readout_endif_led
230
231 register_readout_if_led_1
232         call            led_green
233
234 register_readout_endif_led
235         inc_f           bit_counter       ; increment loop counter
236         call            waiting
237         call            led_black
238         call            waiting
239         bra             register_readout_loop
240
241
242 ;****************************************************************************
243 ; GENERAL SUBROUTINES
244
245 ;----------------------------------------
246 waiting
247 ; waits for a fixed interval, depending on the configuration of TMR0
248
249         bc_f    INTCON,2        ; clear timer0 interrupt bit (p109)
250         clr_f   TMR0H           ; p107 set high byte of timer0 to 0 (buffered,
251                                 ; only actually set when write to tmr0l occurs)
252         clr_f   TMR0L           ; set timer0 low byte - timer now set to 0000h
253 waiting_loop
254         bt_f_if0 INTCON,TMR0IF          
255         bra     waiting_loop    ; wait for timer0 interrupt
256         return
257
258
259 ;****************************************************************************
260
261         include final.inc