chiark / gitweb /
Return from noop fault as intrl, not return
[trains.git] / detpic / energy.asm
index dd82672b790a9c41f0dc0f630a2240da1fa596c5..5dab54d3492eeb98041ff1d95ed6eaf4ebf7b672 100644 (file)
@@ -1,23 +1,31 @@
 ;======================================================================
 ; TRACK POWER AND SHORT CIRCUIT
 
- include common.inc
 include common.inc
 
-settling_timeout equ 10000 ; us
+settling_timeout       equ      10000 ; us
 
- udata_acs
-settling       res     1
+stop_timeout           equ     500000 ; us
+stopflash_timeout      equ      50000 ; us
+retry_timeout          equ      50000 ; us
+persist_timeout                equ      90000 ; us
 
- code
+  udata_acs
+settling       res     1 ; all counters are 0 if stopped
+stop_wait      res     1 ;  or otherwise count down
+retry_wait     res     1
+
+  code
 
 ;======================================================================
+;
 ; POLARISING/SETTLING:
 ;
 ;              NMRA            flag_p. settling        Booster PWM
 ;
-; Normal       running         0       0x00            mark
-; Polarising   paused          1       0x00            space
-; Settling     paused          1       >0, count down  space
+; Normal       running         0       stopped         mark
+; Polarising   paused          1       stopped         space
+; Settling     paused          1       running         space
 ;
 ; NMRA is paused by disabling timer 0 intr; when we restart,
 ; we restart the current message.
@@ -25,21 +33,24 @@ settling    res     1
 ;----------------------------------------------------------------------
 
 ;--------------------
-power_polarising_init
+power_polarising_init @
        clr_f   settling
+       pin_h   p0_booster_pwm
        return
 
 ;--------------------
-power_polarising_begin
-       pin_  p0_booster_pwm
-       bc_f    INTCON, TMR0IE
+power_polarising_begin @
+       pin_vl  p0_booster_pwm
+       bc_f    INTCON, TMR0IE ; disables NMRA interrupt
        bs_f    flags, flags_polarising
        clr_f   settling
        return
 
 ;--------------------
-power_polarising_settling
+power_polarising_nonetodo @
 ; idempotent
+       bt_f_if0 flags, flags_polarising
+       return
        tst_f_ifnz settling
        return
        mov_lw  settling_timeout / tick_us
@@ -47,60 +58,178 @@ power_polarising_settling
        return
 
 ;--------------------
-power_polarising_tick
+power_polarising_tick @
        tst_f_ifnz settling
        dec_f_ifnz settling ; decrement if not zero
        return ; return if not dec'd, or if decrement didn't make zero
        ; settle timeout complete:
 
        bc_f    flags, flags_polarising
-       intr_mask
+       pin_vh  p0_booster_pwm
        call    nmra_restartmessage
-       intr_unmask
+       bs_f    INTCON, TMR0IE ; reenables NMRA interrupt
        goto    i2c_consider_restartread
 
 ;======================================================================
 ;
 ; FAULTS AND POWER:
 ;
-;              Shutdown CDU    Fault timeout   User Fault      Next states
-; Off          shutdown off    stopped         off             On*, Fault+
-; On           power-up on     stopped         off             Fault, Off*
-; Fault                shutdown off    500ms           1/2x50ms        Retry
-; Retry                power-up off    50ms            on              Persists, Off
-; Persists     shutdown off    50ms            on              Retry
-;                                                      * = when host instructs
-;                                                      + = lost race, only
-
-command_power
-
-
-;  C           1 iff command is ON             undefined
- tell on or off
-
-on on:
- start nmra with empty buffers
- turn booster on
- turn cdu on
-
-
-
+;          Shutdown  CDU  Time   User Fault  Next states and action when
+;                                            fault          timeout  ON  OFF
+;
+; Off      shutdown  off  none   off                                 On
+; On       power-up  on   none   off         Stopping,FAULT              Off
+; Stopping  shutdown  on   500ms  50% 1/100ms               Retry
+; Retry            power-up  off  50ms   off         Persists       Off,FIXED    Off
+; Persists  shutdown  off  90ms          on                         Retry        Off
+;
+;                                              (no notation: event ignored)
+;
+;              shutdown LAT    stop_wait       retry_wait
+;
+; Off          H (shutdown)    0               0
+; On           L (power-up)    0               0
+; Stopping     H (shutdown)    before Retry    for LED flash
+; Retry                L (power-up)    0               before Off
+; Persists     H (shutdown)    0               before retry
+;
+;                              (uses tickdiv)  (uses tick)
 
-       panic   morse_UEC
+;--------------------
+power_fault_init @
+       bs_f    INTCON2, INTEDG1 ; rising edge
+       bc_f    INTCON3, INT1IP
+       bc_f    INTCON3, INT1IF
+       bs_f    INTCON3, INT1IE
+       clr_f   stop_wait
+       clr_f   retry_wait
+       pin_h   p0_booster_shutdown
+       pin_h   p0_booster_userfault
+       ; now we are Off
+       return
 
-;power_on ???
-; from cebpic/nmra-stream.asm's setup
-       bcf     PORTB,2,0       ; booster shutdown L
-       bcf     TRISB,2,0       ; booster shutdown not-Z
+command_power_section code 0x2080
+;--------------------
+command_power_on @
+; Off -> On; noop in other states
+       pinlat_ifl p0_booster_shutdown
+       return  ; On or Retry
+       ; might be Off, Stopping or Persists:
+
+       tst_f_ifnz retry_wait
+       return  ; that deals with Stopping or Persists
+       ; must be Off:
+
+       pin_vl  p0_booster_shutdown
+       Dl 0x81
+       goto    cdu_on
+
+;----------
+command_power_off @
+; On, Retry, Persists -> Off;  noop in Off or Stopping
+       tst_f_ifnz stop_wait
+       return  ; that deals with Stopping
+       ; must be On, Off, Retry or Persists:
+       ; (it's harmless to do this if we were already Off)
+power_off_now
+       clr_f   retry_wait
+       pin_vh  p0_booster_userfault
+       pin_vh  p0_booster_shutdown
+       goto    cdu_off
+
+code2 code
+;--------------------
+power_fault_intrl @
+       bt_f_if0 INTCON3, INT1IF
+       return
+       ; we have a fault:
+
+       bc_f    INTCON3, INT1IF
+
+       pinlat_ifh p0_booster_shutdown
+       bra faultintrl_noop
+               ; Off, Stopping or Persists - must have lost the race
+               ;  or flapped while we faffed.  Well, never mind, it's
+               ;  off now and we're taking care of it.  (If the host
+               ;  caused Off by OFF they can at worst send an OFF and
+               ;  immediate ON in about 2ms, so worst-case duty cycle
+               ;  for a short (if the host is perversely timed) is
+               ;      (our interrupt latency) / 2ms
+               ;  and if they ever don't manage to get the OFF through
+               ;  in time then we go into Stopping.)
+       ; must be On or Retry:
+
+       pin_vh  p0_booster_shutdown
+       tst_f_ifnz retry_wait
+       bra     fault_persists ; that deals with Retry
+       ; must be On:
+
+       mov_lw  b'00000111'
+       call    serial_addbyte
+
+       mov_lw  stop_timeout / tickdiv_us
+       mov_wf  stop_wait
+       pin_vl  p0_booster_userfault
+       rcall   power_stop_doflash
+       intrl_handled_nostack
+
+;-----
+fault_persists ; Retry -> Persists (booster was shut down just a moment ago)
+       mov_lw  persist_timeout / tick_us
+       mov_wf  retry_wait
+       pin_vl  p0_booster_userfault
+faultintrl_noop
+       intrl_handled_nostack
 
-       bcf     PORTB,0,0       ; user fault L or Z
+;--------------------
+power_fault_tick @
+       tst_f_ifnz retry_wait
+       dec_f_ifnz retry_wait
+       return
+       ; retry_wait was running but has just reached zero;
+       ; we were in Stopping, Retry or Persists:
+
+       tst_f_ifnz stop_wait
+       bra     power_stop_doflash ; that deals with Stopping (just flash)
+       ; must be Retry or Persists:
+
+       pinlat_ifh p0_booster_shutdown
+       bra     power_retry ; we were in Persists, now we can try again
+       ; we were in Retry and it worked.
+; go to Off:
+       pin_vh  p0_booster_shutdown
+       pin_vh  p0_booster_userfault
+       mov_lw  b'00000110'
+       goto    serial_addbyte
+
+;----------
+power_stop_doflash
+       pin_vhl p0_booster_userfault
+       mov_lw  stopflash_timeout / tick_us
+       mov_wf  retry_wait
+       return
 
- pause nmra
-       panic   morse_UER
+;--------------------
+power_fault_tickdiv @
+       tst_f_ifnz stop_wait
+       dec_f_ifnz stop_wait
+       return
+       ; stop_wait was running but has just reached zero;
+       ; we were in Stopping, now we can Retry:
+       call    cdu_off
+power_retry
+       mov_lw  retry_timeout / tickdiv_us
+       mov_wf  retry_wait
+       pin_vl  p0_booster_shutdown
+       pin_vh  p0_booster_userfault
+       return
 
-power_panichook
-       panic   morse_UEP
+;--------------------
+power_panichook @
+       pin_vh  p0_booster_shutdown
+       pin_vl  p0_booster_pwm
+       pin_vh  p0_booster_userfault
+       return
 
 ;======================================================================
- include final.inc
 include final.inc