;====================================================================== ; TRACK POWER AND SHORT CIRCUIT include common.inc settling_timeout equ 10000 ; us stop_timeout equ 500000 ; us stopflash_timeout equ 25000 ; 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 return ;-------------------- power_polarising_begin pin_l p0_booster_pwm bc_f INTCON, TMR0IE ; disables NMRA interrupt bs_f flags, flags_polarising clr_f settling return ;-------------------- power_polarising_settling ; idempotent 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 call nmra_restartmessage bs_f INTCON, TMR0IE ; reenables NMRA interrupt goto i2c_consider_restartread ;====================================================================== ; ; FAULTS AND POWER: ; ; Shutdown CDU Timeout User Fault Next states ; ; Off shutdown off none off *On (or +Fault) ; On power-up on none off Fault, or *Off ; Stopping shutdown off 500ms 50% 1/50ms ->Retry ; Retry power-up off 50ms off ->Off, or Persists ; Persists shutdown off 90ms on ->Retry ; * = when host instructs ; + = lost race, only ; -> = after timeout ; ; shutdown LAT stop_wait retry_wait ; ; Off H (shutdown) stopped stopped ; On L (power-up) stopped stopped ; Stopping H (shutdown) before Retry for LED flash ; Retry L (power-up) stopped before Off ; Persists H (shutdown) stopped 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_vl p0_booster_userfault pin_z p0_booster_userfault ; now we are Off return ;-------------------- command_power bra_nc command_power_off ; command is ON: ; Off -> On; noop in other states pinlat_ifh 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_l p0_booster_shutdown goto cdu_on ;---------- command_power_off ; On -> Off; noop in other states pinlat_ifl p0_booster_shutdown return ; Off, Stopping or Persists ; might be On or Retry: tst_f_ifnz retry_wait return ; that deals with Retry ; must be On: power_off_now pin_h p0_booster_shutdown goto cdu_off ;-------------------- power_fault_intrl bt_f_if1 INTCON3, INT1IF return ; we have a fault: mov_fw retry_wait bra_z power_stop ; we were Off or On, goto Stopping ; must be Stopping, Retry or Persists: tst_f_ifnz stop_wait bra power_stop ; we were already Stopping; restart timer ; might be Retry or Persists, goto Persists (restarting any timer): rcall power_off_now mov_lw persist_timeout / tick_us mov_wf retry_wait return ;-------------------- 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 was Stopping, just flash the LED ; must be Retry or Persists: pinlat_ifl p0_booster_shutdown bra power_retry ; we were in Persists, now we can try again ; we were in Retry but it didn't work: ; go to Persists: pin_h p0_booster_shutdown mov_lw persist_timeout / tickdiv_us mov_wf retry_wait pin_nz p0_booster_userfault return ;---------- power_stop rcall power_off_now mov_lw stop_timeout / tickdiv_us mov_wf stop_wait pin_z p0_booster_userfault mov_lw b'00000111' call serial_addbyte power_stop_doflash pin_znz p0_booster_userfault mov_lw stopflash_timeout / tickdiv_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: power_retry mov_lw retry_timeout / tickdiv_us mov_wf retry_wait pin_l p0_booster_shutdown pin_z p0_booster_userfault return ;-------------------- power_panichook pin_h p0_booster_shutdown pin_l p0_booster_pwm pin_z p0_booster_userfault return ;====================================================================== include final.inc