chiark / gitweb /
b4229a5b28ba4be40f957b22f47ed59c95630923
[trains.git] / detpic / energy.asm
1 ;======================================================================
2 ; TRACK POWER AND SHORT CIRCUIT
3
4   include common.inc
5
6 settling_timeout        equ      10000 ; us
7
8 stop_timeout            equ     500000 ; us
9 stopflash_timeout       equ      50000 ; us
10 retry_timeout           equ      50000 ; us
11 persist_timeout         equ      90000 ; us
12
13   udata_acs
14 settling        res     1 ; all counters are 0 if stopped
15 stop_wait       res     1 ;  or otherwise count down
16 retry_wait      res     1
17
18 fault_spurious_count    res     1
19
20   code
21
22 ;======================================================================
23 ;
24 ; POLARISING/SETTLING:
25 ;
26 ;               NMRA            flag_p. settling        Booster PWM
27 ;
28 ; Normal        running         0       stopped         mark
29 ; Polarising    paused          1       stopped         space
30 ; Settling      paused          1       running         space
31 ;
32 ; NMRA is paused by disabling timer 0 intr; when we restart,
33 ; we restart the current message.
34 ;
35 ;----------------------------------------------------------------------
36
37 ;--------------------
38 power_polarising_init @
39         clr_f   settling
40         pin_h   p0_booster_pwm
41         return
42
43 ;--------------------
44 power_polarising_begin @
45         pin_vl  p0_booster_pwm
46         bc_f    INTCON, TMR0IE ; disables NMRA interrupt
47         bs_f    flags, flags_polarising
48         clr_f   settling
49         return
50
51 ;--------------------
52 power_polarising_nonetodo @
53 ; idempotent
54         bt_f_if0 flags, flags_polarising
55         return
56         tst_f_ifnz settling
57         return
58         mov_lw  settling_timeout / tick_us
59         mov_wf  settling
60         return
61
62 ;--------------------
63 power_polarising_tick @
64         tst_f_ifnz settling
65         dec_f_ifnz settling ; decrement if not zero
66         return ; return if not dec'd, or if decrement didn't make zero
67         ; settle timeout complete:
68
69         bc_f    flags, flags_polarising
70         pin_vh  p0_booster_pwm
71         call    nmra_restartmessage
72         bs_f    INTCON, TMR0IE ; reenables NMRA interrupt
73         goto    i2c_consider_restartread
74
75 ;======================================================================
76 ;
77 ; FAULTS AND POWER:
78 ;
79 ;           Shutdown  CDU  Time   User Fault  Next states and action when
80 ;                                             fault          timeout  ON  OFF
81 ;
82 ; Off       shutdown  off  none   off                                 On
83 ; On        power-up  on   none   off         Stopping,FAULT              Off
84 ; Stopping  shutdown  on   500ms  50% 1/100ms                Retry
85 ; Retry     power-up  off  50ms   off         Persists       Off,FIXED    Off
86 ; Persists  shutdown  off  90ms   on                         Retry        Off
87 ;
88 ;                                               (no notation: event ignored)
89 ;
90 ;               shutdown LAT    stop_wait       retry_wait
91 ;
92 ; Off           H (shutdown)    0               0
93 ; On            L (power-up)    0               0
94 ; Stopping      H (shutdown)    before Retry    for LED flash
95 ; Retry         L (power-up)    0               before Off
96 ; Persists      H (shutdown)    0               before retry
97 ;
98 ;                               (uses tickdiv)  (uses tick)
99
100 ;--------------------
101 power_fault_init @
102         bs_f    INTCON2, INTEDG1 ; rising edge
103         bc_f    INTCON3, INT1IP
104         bc_f    INTCON3, INT1IF
105         bs_f    INTCON3, INT1IE
106         clr_f   stop_wait
107         clr_f   retry_wait
108         clr_f   fault_spurious_count
109         pin_h   p0_booster_shutdown
110         pin_h   p0_booster_userfault
111         ; now we are Off
112         return
113
114 command_power_section code 0x2080
115 ;--------------------
116 command_power_on @
117 ; Off -> On; noop in other states
118         pinlat_ifl p0_booster_shutdown
119         return  ; On or Retry
120         ; might be Off, Stopping or Persists:
121
122         tst_f_ifnz retry_wait
123         return  ; that deals with Stopping or Persists
124         ; must be Off:
125
126         pin_vl  p0_booster_shutdown
127         Dl 0x81
128         goto    cdu_on
129
130 ;----------
131 command_power_off @
132 ; On, Retry, Persists -> Off;  noop in Off or Stopping
133         tst_f_ifnz stop_wait
134         return  ; that deals with Stopping
135         ; must be On, Off, Retry or Persists:
136         ; (it's harmless to do this if we were already Off)
137 power_off_now
138         clr_f   retry_wait
139         pin_vh  p0_booster_userfault
140         pin_vh  p0_booster_shutdown
141         goto    cdu_off
142
143 code2 code
144 ;--------------------
145 power_fault_intrl @
146         bt_f_if0 INTCON3, INT1IF
147         return
148         ; we may have a fault:
149
150         bc_f    INTCON3, INT1IF
151
152         call    portb_read
153         pin_inw_ifh p0_booster_overload
154         bra     fault_isactual
155         ; spurious:
156
157         inc_f_ifz fault_spurious_count  ; ++f.s._count == 0x00 ?
158         bs_f    fault_spurious_count, 7 ; f.s._count = 0x80
159
160         intrl_handled_nostack
161
162 ;-----
163 fault_isactual
164 ; call  serial_addbyte
165 ; call  portb_read
166 ; call  serial_addbyte_another
167 ; call  portb_read
168 ; call  serial_addbyte_another
169 ; call  portb_read
170 ; call  serial_addbyte_another
171
172         pinlat_ifh p0_booster_shutdown
173         bra faultintrl_noop
174                 ; Off, Stopping or Persists - must have lost the race
175                 ;  or flapped while we faffed.  Well, never mind, it's
176                 ;  off now and we're taking care of it.  (If the host
177                 ;  caused Off by OFF they can at worst send an OFF and
178                 ;  immediate ON in about 2ms, so worst-case duty cycle
179                 ;  for a short (if the host is perversely timed) is
180                 ;      (our interrupt latency) / 2ms
181                 ;  and if they ever don't manage to get the OFF through
182                 ;  in time then we go into Stopping.)
183         ; must be On or Retry:
184
185         pin_vh  p0_booster_shutdown
186         tst_f_ifnz retry_wait
187         bra     fault_persists ; that deals with Retry
188         ; must be On:
189
190         mov_lw  b'00000111'
191         call    serial_addbyte
192
193         mov_lw  stop_timeout / tickdiv_us
194         mov_wf  stop_wait
195         pin_vl  p0_booster_userfault
196         rcall   power_stop_doflash
197         intrl_handled_nostack
198
199 ;-----
200 fault_persists ; Retry -> Persists (booster was shut down just a moment ago)
201         mov_lw  persist_timeout / tick_us
202         mov_wf  retry_wait
203         pin_vl  p0_booster_userfault
204 faultintrl_noop
205         intrl_handled_nostack
206
207 ;--------------------
208 power_fault_tick @
209         tst_f_ifnz retry_wait
210         dec_f_ifnz retry_wait
211         return
212         ; retry_wait was running but has just reached zero;
213         ; we were in Stopping, Retry or Persists:
214
215         tst_f_ifnz stop_wait
216         bra     power_stop_doflash ; that deals with Stopping (just flash)
217         ; must be Retry or Persists:
218
219         pinlat_ifh p0_booster_shutdown
220         bra     power_retry ; we were in Persists, now we can try again
221         ; we were in Retry and it worked.
222 ; go to Off:
223         pin_vh  p0_booster_shutdown
224         pin_vh  p0_booster_userfault
225         mov_lw  b'00000110'
226         goto    serial_addbyte
227
228 ;----------
229 power_stop_doflash
230         pin_vhl p0_booster_userfault
231         mov_lw  stopflash_timeout / tick_us
232         mov_wf  retry_wait
233         return
234
235 ;--------------------
236 power_fault_tickdiv @
237         tst_f_ifnz fault_spurious_count
238         bra     fault_spurious_tickdiv
239         ; in any case:
240 fault_tickdiv_rest
241         tst_f_ifnz stop_wait
242         dec_f_ifnz stop_wait
243         return
244         ; stop_wait was running but has just reached zero;
245         ; we were in Stopping, now we can Retry:
246         call    cdu_off
247 power_retry
248         mov_lw  retry_timeout / tickdiv_us
249         mov_wf  retry_wait
250         pin_vl  p0_booster_shutdown
251         pin_vh  p0_booster_userfault
252         return
253
254 ;----------
255 fault_spurious_tickdiv
256 ; does not return, instead continues with fault_tickdiv_rest
257         mov_lw  0xc1 ; SPURIOUS
258         call    serial_addbyte
259
260         mov_fw  fault_spurious_count
261         bra_n   fault_spurious_tickdiv_isoverflow
262 fault_spurious_tickdiv_writeamt
263         call    serial_addbyte_another
264         clr_f   fault_spurious_count
265         bra     fault_tickdiv_rest
266
267 ;-----
268 fault_spurious_tickdiv_isoverflow
269         mov_lw  0x7f
270         bra     fault_spurious_tickdiv_writeamt
271
272 ;--------------------
273 power_panichook @
274         pin_vh  p0_booster_shutdown
275         pin_vl  p0_booster_pwm
276         pin_vh  p0_booster_userfault
277         return
278
279 ;======================================================================
280   include final.inc