;====================================================================== ; TRACK POWER AND SHORT CIRCUIT include common.inc settling_timeout equ 10000 ; us stopping_timeout equ 500000 ; us stopflash_timeout equ 100000 ; us retriableflash_timeout equ 500000 ; us udata_acs settling res 1 ; all counters are 0 if stopped stopping_wait res 1 ; or otherwise count down ledflash_wait res 1 fault_spurious_count 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 tst_f_ifnz stopping_wait bra power_polarising_done_ifstopping pin_vh p0_booster_pwm power_polarising_done_ifstopping call nmra_restartmessage bs_f INTCON, TMR0IE ; reenables NMRA interrupt goto i2c_consider_restartread ;====================================================================== ; ; FAULTS AND POWER: ; ; ; Off On Stopping Retriable Watchdogged ; Recognise by ; stopping_wait 0 0 >0 0 0 ; ledflash_wait 0 0 >0 >0 0 ; b._shutdowwn H L H H H ; b._userfault_ H H * * L ; ; Managed here: ; shutdown H L H H H ; Fault LED - - 50% 1/100ms 50% 1/500ms on ; Timeout? - - 500ms - - ; next state Retriable ; ; Elsewhere: ; CDU - ON ON ON ON ; booster_pwm !polar !polar OFF !polar !polar[1] ; so power is - ON off! - - ; ; Events, results: ; Fault - Stopping - Stopping[2] Stopping ; Watchdog - W'dogged - - - ; ON On (On) - On On ; OFF (Off) Off - Off Off ; (- means event ignored) ; ; [1] booster_pwm `!polar' means on if we're not polarising. ; [2] this is not supposed to happen but we don't check for it ;-------------------- power_fault_init @ bs_f INTCON2, INTEDG1 ; rising edge bc_f INTCON3, INT1IP bc_f INTCON3, INT1IF bs_f INTCON3, INT1IE pin_h p0_booster_shutdown pin_h p0_booster_userfault_ clr_f ledflash_wait clr_f stopping_wait clr_f fault_spurious_count ; now we are Off return command_power_section code 0x2080 ;-------------------- command_power_on @ tst_f_ifnz stopping_wait return ; that deals with Stopping ; safe to just turn On, even if already On pin_vl p0_booster_shutdown pin_vh p0_booster_userfault_ clr_f ledflash_wait goto cdu_on ;---------- command_power_off @ tst_f_ifnz stopping_wait return ; that deals with Stopping ; safe to just turn Off, even if already Off pin_vh p0_booster_shutdown pin_vh p0_booster_userfault_ clr_f ledflash_wait goto cdu_off code2 code ;-------------------- power_fault_intrl @ bt_f_if0 INTCON3, INT1IF return ; we may have a fault: bc_f INTCON3, INT1IF call portb_read pin_inw_ifh p0_booster_overload bra fault_isactual ; spurious: inc_f_ifz fault_spurious_count ; ++f.s._count == 0x00 ? bs_f fault_spurious_count, 7 ; f.s._count = 0x80 intrl_handled_nostack ;----- fault_isactual pin_vl p0_booster_pwm pin_vh p0_booster_shutdown tst_f_ifnz stopping_wait bra fault_isactual_ifalreadystopping mov_lw b'00000111' call serial_addbyte mov_lw stopping_timeout / tickdiv_us mov_wf stopping_wait pin_vh p0_booster_userfault_ rcall power_led_start_stoppingflash fault_isactual_ifalreadystopping intrl_handled_nostack ;-------------------- power_fault_tick @ tst_f_ifnz ledflash_wait dec_f_ifnz ledflash_wait return ;... ledflash_wait was running but has just reached zero; flash the LED pin_vhl p0_booster_userfault_ power_led_start_retriableflash mov_lw retriableflash_timeout / 2 / tick_us tst_f_ifnz stopping_wait power_led_start_stoppingflash mov_lw stopflash_timeout / 2 / tick_us mov_wf ledflash_wait return ;-------------------- power_watchdog_timeout @ pinlat_ifh p0_booster_shutdown return ;... must be On, so go to Watchdogged pin_vh p0_booster_shutdown pin_vl p0_booster_userfault_ return ;-------------------- power_fault_tickdiv @ tst_f_ifnz fault_spurious_count bra fault_spurious_tickdiv ; in any case: fault_tickdiv_rest tst_f_ifnz stopping_wait dec_f_ifnz stopping_wait return ; stopping_wait was running but has just reached zero; ; we were in Stopping, go to Retriable: rcall power_led_start_retriableflash bt_f_if0 flags, flags_polarising pin_vh p0_booster_pwm mov_lw b'00000110' goto serial_addbyte ;---------- fault_spurious_tickdiv ; does not return, instead continues with fault_tickdiv_rest mov_lw 0xc1 ; SPURIOUS call serial_addbyte mov_fw fault_spurious_count bra_n fault_spurious_tickdiv_isoverflow fault_spurious_tickdiv_writeamt call serial_addbyte_another clr_f fault_spurious_count bra fault_tickdiv_rest ;----- fault_spurious_tickdiv_isoverflow mov_lw 0x7f bra fault_spurious_tickdiv_writeamt ;-------------------- power_panichook @ pin_vh p0_booster_shutdown pin_vl p0_booster_pwm pin_vh p0_booster_userfault_ return ;====================================================================== include final.inc