chiark / gitweb /
less of an unsightly wiggle over bridge
[trains.git] / detpic / common.inc
1 ;======================================================================
2 ; common.inc
3 ; common macros & equs etc.
4 ; generally include this at the top of each file.
5
6 ;----------------------------------------------------------------------
7 ; COMMON INCLUDES and BOILERPLATE
8         include         p18f458.inc
9         radix           dec 
10         include         panic.inc
11         include         morse+auto.inc
12         include         ../iwjpictest/insn-aliases.inc
13         include         ../iwjpictest/clockvaries.inc
14         include         variables+vars.inc
15         include         pindata.inc
16         include         program+clocks.inc
17         include         i2clib.incm
18
19 tickdiv equ 16
20 tickdiv_us equ tick_us * tickdiv
21
22 ;----------------------------------------------------------------------
23 ; Common conventions for function register notation:
24
25 ;                       Master                          Slave
26 ; Registers etc.
27 ;   W                   Trashed                         Trashed
28 ;   STATUS              Trashed                         Trashed
29 ;   BSR                 Not used                        Not used
30 ;   t,u,v               Low ISR                         Low ISR
31 ;   TBLPTR*,TABLAT      Low ISR                         Low ISR
32 ;   PROD*               Low ISR                         Low ISR
33 ;   FSR0                Low ISR                         Low ISR
34 ;   PCLATU              Always set to 0                 Not used
35 ;   PCLATH              Low ISR                         Not used
36 ;   t_dolocal           Low ISR                         High ISR
37 ;   FSR1                Low ISR                         High ISR (detect[1])
38 ;   FSR2                High ISR (nmra[1])              High ISR (detect[1])
39 ;   PORTB               Special read handling[2]        Used normally
40 ;
41 ;   Main loop           detection scan                  detection scan
42 ;   High ISR            NMRA output                     I2C service
43 ;   Low ISRs            everything else                 everything else
44 ;
45 ; Trashed       May be trashed by any routine anywhere.  Saved
46 ;               during every ISR entry/exit.
47 ;
48 ; Low ISR       May be used/trashed by any routine run in low-priority
49 ;               interrupt, or any routine run during initialisation.
50 ;               May therefore not be used in background loop with
51 ;               interrupts enabled.  May not be used by high-priority
52 ;               ISR (unless explicitly saved, eg intrlh_fsr0_{save,restore}).
53 ;
54 ; High ISR      May be used/trashed by any routine run in high-priority
55 ;               interrupt, or any routine run during initialisation.
56 ;               May therefore not be used elsewhere with interrupts
57 ;               enabled.
58 ;
59 ;               Only the routines specially noted as intended to
60 ;               be called from the High ISR are safe.
61 ;
62 ; ... (subsystem)
63 ;               Register is reserved for use by this subsystem, which
64 ;               is allowed to expect the value to be preserved.
65 ;               Anything else which uses it must save and restore (and
66 ;               may also need to disable interrupts, depending on its
67 ;               relative status).
68 ;
69 ; Not High      May be used by any routine not running in high-priority
70 ;               interrupt.  Not saved by high-priority interrupt
71 ;               entry/exit, so any high-priority interrupt routine which
72 ;               uses this register must save and restore it.
73 ;
74 ; A routine which is allowed to trash a register may document that it
75 ; saves that register for the benefit of its callers.
76 ;
77 ;  [1]  FSR1 and FSR2 on slave pics are reserved exclusively for the
78 ;       I2C response and detection code (detect.asm), after
79 ;       detect_slave_init.  Likewise FSR2 is reserved exclusively
80 ;       for the NMRA output ISR after nmra_init.
81 ;
82 ;  [2]  On the master PIC we the interrupt-on-change feature of PORTB.
83 ;       This means that routines mustn't casually read PORTB.  Instead,
84 ;       they should call portb_read from serout.asm.
85 ;
86 ; General-purpose hardware allocation:
87 ;
88 ;                       Master                  Slave
89 ;  Timer 0              nmra                    Disabled
90 ;  Timer 2              tick, int. low          -
91 ;  Timer 1              -                       -
92 ;  CCP1                 -                       -
93 ;  Timer 3              point fire timer        point fire timer
94 ;  ECCP                 -                       -
95 ;
96 ;   (...) indicates that this is a projected use, NYI
97
98 ;----------------------------------------------------------------------
99 ; Conventional routine names:
100 ;
101 ; <periph>_local_do     Process a master-to-slave command to activate
102 ;                       a local peripheral, in High ISR.  Also called
103 ;                       on master in Low ISR to activate its own
104 ;                       local peripherals.  NB strange calling convention!
105 ;
106 ; <periph>_local_init   Initialises RAM tables for local peripheral
107 ;                       and arranges for pins to be set in appropriate
108 ;                       quiescent state.  Configures pic built-in
109 ;                       peripherals.
110 ;
111 ; <periph>_local_intrl  Low ISR service routine for peripheral (see below).
112 ;                               
113 ; command_<periph>      Called when an appropriate message has been
114 ;                       received from the host.
115 ;
116 ; <something>_intrl     Low ISR service routine.
117 ;                       Checks for any relevant interrupt.
118 ;                       If not, just returns
119 ;                       If found, services it and then does either
120 ;                        intrl_handled or intrl_handled_nostack
121 ;                        neither of which return; the latter is
122 ;                        faster but implies a promise
123 ;
124 ;----------------------------------------------------------------------
125 ; MACROS
126
127 @ macro
128   endm
129
130 ;----------------------------------------
131 ; For adding a byte to the debug buffer.
132 ; Not for use in High ISR.  In all cases:
133 ;
134 ;  STATUS       any             trashed
135 ;  all others   any             preserved
136
137   ifdef DEBUG
138 ;----------
139 Dv macro  ; sorry, but assembler's dw directive isn't case-sensitive
140 ;
141 ;  W            message byte    preserved
142 ;
143         call    debugbyte
144         endm
145
146 ;----------
147 Dl macro debug_literal_value
148 ;
149 ;  W            any             literal value as specified
150 ;
151         mov_lw  debug_literal_value
152         Dv
153         endm
154
155 ;----------
156 Df macro debug_register_file_address
157 ;
158 ;  W            any             value from specified memory location
159 ;
160         mov_fw  debug_register_file_address
161         Dv
162         endm
163
164 ;----------
165 DI macro
166 ;
167 ;  STATUS       any             trashed
168 ;
169         inc_f   debug_intrdiag
170         endm
171   else
172 Dv macro
173    endm
174 Dl macro debug_literal_value
175    endm
176 Df macro debug_register_file_address
177    endm
178 DI macro
179    endm
180   endif
181
182 ;----------------------------------------
183 ; For entering and leaving Low ISR, saving and restoring STATUS and W
184 ; See above under <something>_intrl, and {master,slave}_interrupt_low
185
186 enter_interrupt_low macro
187         mov_ff  STATUS, isr_low_save_status
188         mov_wf  isr_low_save_w
189         mov_ff  STKPTR, isr_low_save_stkptr
190         endm
191
192 intrlh_fsr0_save macro ; Low ISR on master, High ISR on slave
193         mov_ff  FSR0L, isr_lh_save_fsr0
194         mov_ff  FSR0H, isr_lh_save_fsr0+1
195         endm
196
197 intrlh_fsr0_restore macro
198         mov_ff  isr_lh_save_fsr0,   FSR0L
199         mov_ff  isr_lh_save_fsr0+1, FSR0H
200         endm
201
202 intrl_handled_core macro ; for internal use only
203         mov_fw  isr_low_save_w
204         mov_ff  isr_low_save_status, STATUS
205         retfie
206         endm
207
208 intrl_handled_nostack macro
209         pop     ; undo the `call' from the original ISR
210         intrl_handled_core
211         endm
212
213 intrl_handled macro
214         goto    intrl_handled_routine
215         endm
216
217 ;----------------------------------------
218 ; For disabling all interrupts, to make a critical section:
219 ; (for use from main program and Low ISR only)
220 ;
221 ;  GIEH                 modified appropriately
222 ;  everything else      preserved
223
224 intrh_mask macro
225         bc_f    INTCON,GIEH
226         endm
227
228 intrh_unmask macro
229         bs_f    INTCON,GIEH
230         endm
231
232 ;----------------------------------------
233 ; For the fix specified in the silicon errata:
234 ; silicon revision B4 issue 4
235 ;
236 ;                       Before          After
237 ;  TABLAT               any             data from flash
238 ;  TBLPTR*              correct         incremented/decremented
239 ;  everything else      any             preserved
240
241 tblrd_postinc_fixup macro
242         tblrd   *+
243         dw      0xffff
244         endm
245
246 tblrd_postdec_fixup macro
247         tblrd   *-
248         dw      0xffff
249         endm
250
251 ;----------------------------------------
252 ; For setting up TBLPTR
253
254 load_tblptr macro value
255 ;
256 ;                       Before          After
257 ;  TBLPTR*              any             set
258 ;  W, STATUS            any             undefined
259 ;
260         mov_lw  value & 0xff
261         mov_wf  TBLPTRL
262
263         mov_lw  value >> 8
264         mov_wf  TBLPTRH
265
266   if value > 0xffff
267         mov_lw  value >> 16
268         mov_wf  TBLPTRU
269   else
270         clr_f   TBLPTRU
271   endif
272         endm
273
274 load_perpic_tblptr macro flash_map_base, perpic_entry_size
275 ;
276 ;                       Before          After
277 ;  TBLPTR*              any             set
278 ;  W, STATUS, PROD*     any             undefined
279 ;  everything else      any             preserved
280 ;
281         mov_lw  perpic_entry_size
282         mul_wf  picno
283
284         mov_lw  flash_map_base & 0xff
285         add_wfw PRODL
286         mov_wf  TBLPTRL
287
288         mov_lw  flash_map_base >> 8
289         addc_wfw PRODH
290         mov_wf  TBLPTRH
291
292         clr_f   TBLPTRU         ; TBLPTR* -> our point data
293         endm
294
295 ;----------------------------------------
296 ; invocation macro for outpins_local_init_part{1,2}, see misc.asm
297 outputs_local_init macro picno2thingmap, maxthings, thingix2latbit, bkthingix2portnumbitnum
298
299         load_perpic_tblptr picno2thingmap, maxthings/8
300         mov_lfsr thingix2latbit-1, 0
301         mov_lw  maxthings/8
302
303         call    outpins_local_init_part1
304
305         mov_lw  bkthingix2portnumbitnum >> 8
306         mov_wf  TBLPTRH         ; TBLPTR* -> point port/bit data
307         mov_lw  bkthingix2portnumbitnum & 0xff
308         mov_wf  TBLPTRL
309
310         mov_lfsr thingix2latbit-1, 0 ; FSR0 -> last bit (and previous LAT*)
311         mov_lw  maxthings
312
313         call    outpins_local_init_part2
314
315         endm
316
317 ;----------------------------------------------------------------------
318 ; PINSPECS stuff
319 ;
320 ; A PINSPEC is a constant 0x<bit><port> where <port> is a b c d e
321 ; and <port> is 0 1 2 3 4 5 6 7.  Generally p<picno>_<subsystem>_<pin>
322 ; are equ'd for this.
323
324   radix hex
325 p0_cdu_enable           equ     5b
326 p0_rs232_fcin           equ     4b
327 p0_booster_shutdown     equ     2b
328 p0_booster_overload     equ     1b
329 p0_booster_userfault_   equ     0b
330 p0_spare2               equ     6d
331 p0_spare1               equ     5d
332 p0_rs232_fcout          equ     5c
333 pall_perpicled          equ     2d
334 pall_pt0reverse         equ     7b
335 p0_spare0               equ     0a
336 p0_booster_dirn         equ     0c
337 p0_booster_pwm          equ     1c
338   radix dec
339
340 ;                       
341 ;  LAT*                 may be subject to read-modify-write, see below
342 ;  TRIS*                may be subject to read-modify-write, see below
343 ;  PORT*                may be read, see below
344 ;  everything else      untouched
345 ;
346 ;                       LAT*<bit>       TRIS*<bit>      PORT*   W
347 ;  pin_z                -               set             -       -
348 ;  pin_h                set             cleared         -       -
349 ;  pin_l                cleared         cleared         -       -
350 ;  pin_nz               -               cleared         -       -
351 ;  pin_vh               set             -               -       -
352 ;  pin_vl               cleared         -               -       -
353 ;  pin_vhl              toggled         -               -       -
354 ;  pin_ifh              -               -               read    -
355 ;  pin_ifl              -               -               read    -
356 ;  pinlat_ifh           read            -               -       -
357 ;  pinlat_ifl           read            -               -       -
358 ;  pin_inw_ifh          -               -               -       read
359 ;  pin_inw_ifl          -               -               -       read
360
361 pin_z   macro   pinspec
362         bs_f    TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4
363         endm
364
365 pin_nz  macro   pinspec
366         bc_f    TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4
367         endm
368
369 pin_znz macro   pinspec
370         btg_f   TRISA + (TRISB-TRISA)*((pinspec-0xa) & 15), pinspec >> 4
371         endm
372
373 pin_vh  macro   pinspec
374         bs_f    LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
375         endm
376
377 pin_vl  macro   pinspec
378         bc_f    LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
379         endm
380
381 pin_vhl macro   pinspec
382         btg_f   LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
383         endm
384
385 pin_h   macro   pinspec
386         pin_vh  pinspec
387         pin_nz  pinspec
388         endm
389
390 pin_l   macro   pinspec
391         pin_vl  pinspec
392         pin_nz  pinspec
393         endm
394
395 pin_ifh macro   pinspec
396         bt_f_if1 PORTA + (PORTB-PORTA)*((pinspec-0xa) & 15), pinspec >> 4
397         endm
398
399 pin_ifl macro   pinspec
400         bt_f_if0 PORTA + (PORTB-PORTA)*((pinspec-0xa) & 15), pinspec >> 4
401         endm
402
403 pinlat_ifh macro        pinspec
404         bt_f_if1 LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
405         endm
406
407 pinlat_ifl macro        pinspec
408         bt_f_if0 LATA + (LATB-LATA)*((pinspec-0xa) & 15), pinspec >> 4
409         endm
410
411 pin_inw_ifh macro       pinspec
412         bt_w_if1 pinspec >> 4
413         endm
414
415 pin_inw_ifl macro       pinspec
416         bt_w_if0 pinspec >> 4
417         endm
418
419 ;----------------------------------------------------------------------