chiark / gitweb /
properly return from short circuit interrupt
[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   code
19
20 ;======================================================================
21 ;
22 ; POLARISING/SETTLING:
23 ;
24 ;               NMRA            flag_p. settling        Booster PWM
25 ;
26 ; Normal        running         0       stopped         mark
27 ; Polarising    paused          1       stopped         space
28 ; Settling      paused          1       running         space
29 ;
30 ; NMRA is paused by disabling timer 0 intr; when we restart,
31 ; we restart the current message.
32 ;
33 ;----------------------------------------------------------------------
34
35 ;--------------------
36 power_polarising_init @
37         clr_f   settling
38         pin_h   p0_booster_pwm
39         return
40
41 ;--------------------
42 power_polarising_begin @
43         pin_vl  p0_booster_pwm
44         bc_f    INTCON, TMR0IE ; disables NMRA interrupt
45         bs_f    flags, flags_polarising
46         clr_f   settling
47         return
48
49 ;--------------------
50 power_polarising_nonetodo @
51 ; idempotent
52         bt_f_if0 flags, flags_polarising
53         return
54         tst_f_ifnz settling
55         return
56         mov_lw  settling_timeout / tick_us
57         mov_wf  settling
58         return
59
60 ;--------------------
61 power_polarising_tick @
62         tst_f_ifnz settling
63         dec_f_ifnz settling ; decrement if not zero
64         return ; return if not dec'd, or if decrement didn't make zero
65         ; settle timeout complete:
66
67         bc_f    flags, flags_polarising
68         pin_vh  p0_booster_pwm
69         call    nmra_restartmessage
70         bs_f    INTCON, TMR0IE ; reenables NMRA interrupt
71         goto    i2c_consider_restartread
72
73 ;======================================================================
74 ;
75 ; FAULTS AND POWER:
76 ;
77 ;               Shutdown  CDU   Timeout User Fault      Next states
78 ;
79 ; Off           shutdown  off   none    off             *On (or +Fault)
80 ; On            power-up  on    none    off             Fault, or *Off
81 ; Stopping      shutdown  off   500ms   50% 1/100ms     ->Retry
82 ; Retry         power-up  off   50ms    off             ->Off, or Persists
83 ; Persists      shutdown  off   90ms    on              ->Retry
84 ;                                                       * = when host instructs
85 ;                                                       + = lost race, only
86 ;                                                       -> = after timeout
87 ;
88 ;               shutdown LAT    stop_wait       retry_wait
89 ;
90 ; Off           H (shutdown)    stopped         stopped
91 ; On            L (power-up)    stopped         stopped
92 ; Stopping      H (shutdown)    before Retry    for LED flash
93 ; Retry         L (power-up)    stopped         before Off
94 ; Persists      H (shutdown)    stopped         before retry
95 ;
96 ;                               (uses tickdiv)  (uses tick)
97
98 ;--------------------
99 power_fault_init @
100         bs_f    INTCON2, INTEDG1 ; rising edge
101         bc_f    INTCON3, INT1IP
102         bc_f    INTCON3, INT1IF
103         bs_f    INTCON3, INT1IE
104         clr_f   stop_wait
105         clr_f   retry_wait
106         pin_h   p0_booster_shutdown
107         pin_h   p0_booster_userfault
108         ; now we are Off
109         return
110
111 command_power_section code 0x2080
112 ;--------------------
113 command_power_on @
114 ; Off -> On; noop in other states
115         pinlat_ifl p0_booster_shutdown
116         return  ; On or Retry
117         ; might be Off, Stopping or Persists:
118
119         tst_f_ifnz retry_wait
120         return  ; that deals with Stopping or Persists
121         ; must be Off:
122
123         pin_vl  p0_booster_shutdown
124         Dl 0x81
125         goto    cdu_on
126
127 ;----------
128 command_power_off @
129 ; On -> Off; noop in other states
130         pinlat_ifh p0_booster_shutdown
131         return  ; Off, Stopping or Persists
132         ; might be On or Retry:
133
134         tst_f_ifnz retry_wait
135         return  ; that deals with Retry
136         ; must be On:
137 power_off_now
138         pin_vh  p0_booster_shutdown
139         goto    cdu_off
140
141 code2 code
142 ;--------------------
143 power_fault_intrl @
144         bt_f_if0 INTCON3, INT1IF
145         return
146         ; we have a fault:
147
148         bc_f    INTCON3, INT1IF
149         call    power_off_now
150
151         mov_fw  retry_wait
152         bra_z   power_fault_stop ; we were Off or On, goto Stopping
153         ; must be Stopping, Retry or Persists:
154
155         tst_f_ifnz stop_wait
156         bra     power_fault_stop ; we were already Stopping; restart timer
157         ; might be Retry or Persists, goto Persists (restarting any timer):
158
159         mov_lw  persist_timeout / tick_us
160         mov_wf  retry_wait
161         pin_vl  p0_booster_userfault
162         intrl_handled_nostack
163
164 ;-----
165 power_fault_stop
166         mov_lw  stop_timeout / tickdiv_us
167         mov_wf  stop_wait
168         pin_vl  p0_booster_userfault
169         mov_lw  b'00000111'
170         call    serial_addbyte
171         rcall   power_stop_doflash
172         intrl_handled_nostack
173
174 ;--------------------
175 power_fault_tick @
176         tst_f_ifnz retry_wait
177         dec_f_ifnz retry_wait
178         return
179         ; retry_wait was running but has just reached zero;
180         ; we were in Stopping, Retry or Persists:
181
182         tst_f_ifnz stop_wait
183         bra     power_stop_doflash ; that was Stopping, just flash the LED
184         ; must be Retry or Persists:
185
186         pinlat_ifh p0_booster_shutdown
187         bra     power_retry ; we were in Persists, now we can try again
188         ; we were in Retry and it worked.
189 ; go to Off:
190         pin_vh  p0_booster_shutdown
191         pin_vh  p0_booster_userfault
192         mov_lw  b'00000110'
193         goto    serial_addbyte
194
195 ;----------
196 power_stop_doflash
197         pin_vhl p0_booster_userfault
198         mov_lw  stopflash_timeout / tick_us
199         mov_wf  retry_wait
200         return
201
202 ;--------------------
203 power_fault_tickdiv @
204         tst_f_ifnz stop_wait
205         dec_f_ifnz stop_wait
206         return
207         ; stop_wait was running but has just reached zero;
208         ; we were in Stopping, now we can Retry:
209 power_retry
210         mov_lw  retry_timeout / tickdiv_us
211         mov_wf  retry_wait
212         pin_vl  p0_booster_shutdown
213         pin_vh  p0_booster_userfault
214         return
215
216 ;--------------------
217 power_panichook @
218         pin_vh  p0_booster_shutdown
219         pin_vl  p0_booster_pwm
220         pin_vh  p0_booster_userfault
221         return
222
223 ;======================================================================
224   include final.inc