chiark / gitweb /
realtime: print all movpos positions on entering Run
[trains.git] / cebpic / morsepanic.asm
1 ; program writes SOS msg into flash then turns LED green
2 ; when serial interrupt received, turns off interrupts, turns off
3 ; power, transmits contents of SSPCON1 by flashing LED red, repeats
4 ; (next version will transmit SOS code first, then contents of 
5 ; SSPCON1)
6
7
8 ; to start, need to write into flash, starting at 30 0000h:
9 ; 10 10 10 00 | 1110 1110 | 1110 00 10 | 10 10
10
11         include common.inc
12         include morse-auto.inc
13         include ../iwjpictest/insn-aliases.inc
14         include ../iwjpictest/clockvaries.inc
15
16         extern  led_green
17         extern  led_red
18         extern  led_black
19
20 ;---------------------------------------------------------------------------
21 panic macro message
22         movlw   (message - morse_messages_start)/4
23         movwf   PANIC_ADDRESS
24         goto    panic_routine
25         endm
26
27 ;---------------------------------------------------------------------------
28 ; reserved access bank locations
29
30 WREG2           equ     00h     ; a 2nd working reg :-)
31 WREG3           equ     01h     ; a 3rd working reg :-)
32 WREG4           equ     02h     ; a 4th working reg :-)
33 BLANK           equ     03h     ; register full of zeros
34 TESTFLASH       equ     04h     ; test LED flash pattern
35
36 ; used in panic macro for temporary storage
37 PANIC_MORSE     equ     05h     ; stores # bytes of morse msg in panic readout
38 PANIC_REGS      equ     06h     ; stores # registers in panic readout
39 PANIC_ADDRESS   equ     07h     ; stores condensed form of message start addr.
40
41
42
43
44
45
46
47 ; constants
48
49 MORSE_MSG_LENGTH        equ     04h     ; lenght of morse messages in bytes
50
51
52
53 ;---------------------------------------------------------------------------
54 ; memory location definitions
55
56 ERROR_BUF_PAGE  equ     3       ; error codes on flash p3
57 F_ERROR_U       equ     00h     ; upper part of error memory locations
58 F_SOS_H         equ     40h     ; high (middle) part of SOS error memory loc.
59 F_SOS_L         equ     00h     ; lower part of SOS error memory loc.
60
61
62 ;---------------------------------------------------------------------------
63 ; error messages
64
65 err_SOS equ     0       ; msg 0 = SOS
66
67 ;****************************************************************************
68 ; VECTORS: special locations, where the PIC starts executing
69 ; after interrupts
70
71
72         org     0
73         goto    vector_reset
74
75
76 ; high priority interrupt
77 ;
78 ;        org     000008h
79 ;        goto    interrupt_high
80
81 ; low priority interrupt
82
83         org     000018h
84         goto    interrupt_low
85
86 ;****************************************************************************
87 ;ERROR MSGS
88
89 ;       org     4000h
90 ;       dw      1110111010101000b
91 ;       dw      1010000011100010b
92
93 ;---------------------------------------------------------------------------
94 ; Main - go to interrupt
95         goto    interrupt_low
96
97 ;****************************************************************************
98
99         code
100
101 ;****************************************************************************
102
103 vector_reset
104
105 ; serial set-up
106 ; enable interrupts so that this can be used as a trigger for the
107 ; panic routine
108
109 ; initial config - TXSTA register p181
110         bcf     TXSTA,6,0       ; p181, set 8-bit mode
111         bsf     TXSTA,5,0       ; transmit enable
112         bcf     TXSTA,4,0       ; asynchronous mode
113         bsc_txsta_brgh          ; set high or low baud rate
114
115 ; initial config - RCSTA register p182
116         bsf     RCSTA,7,0       ; serial port enable (p182)
117         bcf     RCSTA,6,0       ; 8-bit reception
118         bsf     RCSTA,4,0       ; enable continuous receive
119
120 ; set SPBRG to get correct baud rate
121         movlw_movwf_spbrg
122
123 ; interrupt set-up for serial receive
124         bcf     IPR1,5,0        ; set to low-priority interrupt
125
126 ;---------------------------------------------------------------------------
127 ; interrupt set-up
128
129 ; globally enable interrupts - p77
130         bsf     RCON,7,0        ; enable priority levels
131         bsf     INTCON,7,0      ; enable high-priority interrupts
132         bsf     INTCON,6,0      ; enable low-priority interrupts
133         bsf     PIE1,5,0        ; enable USART receive interrupt (p85)
134
135 ;---------------------------------------------------------------------------
136 ;---------------------------------------------------------------------------
137 ; Main - go to interrupt
138         goto    interrupt_low
139
140 ;****************************************************************************
141 ; INTERRUPT SUBROUTINES
142
143 interrupt_low
144         mov_lw          0x5a
145         mov_wf          TESTFLASH
146
147         panic   morse_TG
148
149 panic_routine
150 ; switch off interrupts and power
151 ; reconfigure timer0 for writing diagnostic msg to the LED
152
153         clrf    INTCON,0        ; disable all interrupts EVER
154         bcf     PORTC,1,0       ; switch off booster
155
156
157 ; re-initialise timer0 config
158         bcf     T0CON,6,0       ; p107 Timer0 -> 16bit mode
159         bcf     T0CON,5,0       ; timer0 use internal clock
160         bsc_morse_t0con_012     ; use prescaler? and configure it
161
162 ; get # bytes of morse msg, # registers in panic readout, message start addr.
163 ; back from condensed message start addr. stored in PANIC_ADDRESS
164
165 panic_loop
166         movlw   4
167         mulwf   PANIC_ADDRESS
168         movff   PRODL,TBLPTRL           
169         movff   PRODH,WREG
170         add_lw  (morse_messages_start)/256
171         movwf   TBLPTRH
172         clr_f   TBLPTRU
173
174         tblrd   *+              ; read 1st byte of error message
175                                 ; (gives # bytes morse, # bytes registers)
176
177         movff   TABLAT,PANIC_MORSE
178         movlw   00001111b
179         and_wff PANIC_MORSE     ; PANIC_MORSE now contains # bytes of morse msgs
180
181         movff   TABLAT,PANIC_REGS
182         movlw   01110000b
183         and_wff PANIC_REGS
184         swap_f  PANIC_REGS      ; PANIC_REGS now contains # registers to read
185
186         call    led_black
187         call    waiting
188         call    waiting
189         call    waiting
190         call    waiting
191         call    morsemsg        ; transmit SOS in red
192         call    led_black
193         call    waiting
194         call    waiting
195         call    waiting
196         call    waiting
197         call    registermsg     ; transmit contents of TESTFLASH in 
198                                 ; red(=low) and blue(=high)
199         goto    panic_loop
200
201 ;****************************************************************************
202 ; PANIC SUBROUTINES
203
204 morsemsg
205 ; wrapper round readout to flash the per-pic led red for a
206 ; (currently 4-byte) morse msg
207
208 morse_msg_start
209         clrf    WREG3,0         ; clear loop counter (WREG3)
210
211 morse_loop
212         mov_fw          PANIC_MORSE
213         cmp_fw_ifge     WREG3           ; if loop counter >=MORSE_MSG_LENGTH, 
214         return                          ; return to panic
215
216         tblrd           *+
217         mov_ff          TABLAT,WREG2
218         call            morse_readout
219         inc_f           WREG3
220         goto            morse_loop
221
222
223 ;--------------------------
224 morse_readout
225
226 ; Flashes the per-pic led red(0) in a specified pattern.
227 ;
228 ; The pattern is specified as the state for 8 identically-long time
229 ; periods each as long as a morse `dot', encoded into a byte with
230 ; most significant bit first.
231 ;               On entry                On exit
232 ; W             any                     undefined
233 ; WREG2         flash pattern           preserved
234 ; WREG4         any                     undefined
235
236         clr_f           WREG4           ; clear loop counter (WREG4)
237         rr_f            WREG2
238
239 morse_readout_loop
240         mov_lw          8
241         cmp_fw_ifge     WREG4           ; if loop counter >=8, return
242         return
243
244         rl_f            WREG2           ; top bit goes into N, ie Negative if 1
245         bra_n           morse_readout_if_led_1
246
247 morse_readout_if_led_0
248         call            led_black
249         bra             morse_readout_endif_led
250
251 morse_readout_if_led_1
252         call            led_red
253
254 morse_readout_endif_led
255         inc_f           WREG4           ; increment loop counter
256         call            waiting
257         bra             morse_readout_loop
258
259 ;--------------------------
260 ;--------------------------
261 registermsg
262
263 register_msg_start
264         clrf            WREG3,0         ; clear loop counter (WREG3)
265
266 register_loop
267         mov_fw          PANIC_REGS
268         cmp_fw_ifge     WREG3           ; if loop counter >=MORSE_MSG_LENGTH, 
269         return                          ; return to panic
270
271         tblrd           *+
272
273         mov_fw          TABLAT          ; TABLAT has the 8-bit version
274         mov_wf          FSR0L           ; of the address.  So, 8 bits
275                                         ; go straight into FSR0L.
276
277         mov_lw          0x0f            ; For FSR0H, we see if the
278         mov_fw          FSR0H           ; address XX is >=0x60.
279                                         ; If it is then we meant 0xfXX;
280         mov_lw          0x5f            ; if not then we meant 0x0XX.
281         cmp_fw_ifle     FSR0L           ; (This is just like PIC does
282         clr_f           FSR0H           ; for insns using Access Bank)
283
284         mov_ff          INDF0,WREG2
285         call            register_readout
286
287         inc_f           WREG3
288
289         call            waiting
290         call            waiting
291         goto            register_loop
292
293 ;--------------------------
294
295 register_readout
296
297 ; Flashes the per-pic led red(0) and green(1) in a specified pattern.
298 ; (black gap between each bit)
299 ;
300 ; The pattern is specified as the state for 8 identically-long time
301 ; periods each as long as a morse `dot', encoded into a byte with
302 ; most significant bit first.
303 ;               On entry                On exit
304 ; W             any                     undefined
305 ; WREG2         flash pattern           preserved
306 ; WREG4         any                     undefined
307
308         clrf    WREG4,0         ; clear loop counter (WREG4)
309         rrncf   WREG2,1
310
311
312 register_readout_loop
313         movlw           8
314         cpfslt          WREG4,0         ; if loop counter >=8 (register 
315                                         ; length), return
316         return
317
318         movlw           4
319         cmp_fw_ifne     WREG4           ; if loop counter !=4 (nybble length), 
320                                         ; skip insertion of extra black space
321         goto            not_nybble_boundary
322         call            waiting
323
324 not_nybble_boundary
325         rlncf           WREG2,1         ; top bit goes into N flag, 
326                                         ; ie Negative if 1
327         bn              register_readout_if_led_1
328
329 register_readout_if_led_0
330         call            led_red
331         bra             register_readout_endif_led
332
333 register_readout_if_led_1
334         call            led_green
335
336 register_readout_endif_led
337         incf            WREG4,1,0       ; increment loop counter
338         call            waiting
339         call            led_black
340         call            waiting
341         bra             register_readout_loop
342
343
344 ;****************************************************************************
345 ; GENERAL SUBROUTINES
346
347 ;----------------------------------------
348 waiting
349 ; waits for a fixed interval, depending on the configuration of TMR0
350
351         bcf     INTCON,2,0      ; clear timer0 interrupt bit (p109)
352         clrf    TMR0H,0         ; p107 set high byte of timer0 to 0 (buffered,
353                                 ; only actually set when write to tmr0l occurs)
354         clrf    TMR0L,0         ; set timer0 low byte - timer now set to 0000h
355 loop
356         btfss   INTCON,2,0      ; check whether timer0 interrupt has been set -
357                                 ; skip next instruction if so
358         bra     loop
359         return
360
361
362 ;****************************************************************************
363
364         org 0x2000
365         dw      0xffff
366
367         org 0x6000
368         dw      0xffff
369
370         end