;====================================================================== ; TRACK POWER AND SHORT CIRCUIT include common.inc settling_timeout equ 10000 ; us stop_timeout equ 500000 ; us stopflash_timeout equ 50000 ; us retry_timeout equ 50000 ; us persist_timeout equ 90000 ; us 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 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. ; ;---------------------------------------------------------------------- ;-------------------- power_polarising_init @ clr_f settling pin_h p0_booster_pwm return ;-------------------- 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_nonetodo @ ; idempotent bt_f_if0 flags, flags_polarising return tst_f_ifnz settling return mov_lw settling_timeout / tick_us mov_wf settling return ;-------------------- 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 pin_vh p0_booster_pwm call nmra_restartmessage bs_f INTCON, TMR0IE ; reenables NMRA interrupt goto i2c_consider_restartread ;====================================================================== ; ; FAULTS AND POWER: ; ; 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) ;-------------------- 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 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 ;-------------------- 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 ;-------------------- 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 @ pin_vh p0_booster_shutdown pin_vl p0_booster_pwm pin_vh p0_booster_userfault return ;====================================================================== include final.inc