include program+clocks.inc
include i2clib.incm
+tickdiv equ 16
+tickdiv_us equ tick_us * tickdiv
+
;----------------------------------------------------------------------
; Common conventions for function register notation:
;
; Master Slave
; Timer 0 nmra Disabled
-; Timer 2 tick: 10ms, int. low -
+; Timer 2 tick, int. low -
; Timer 1 - -
; CCP1 - -
; Timer 3 point fire timer point fire timer
; TRACK POWER AND SHORT CIRCUIT
include common.inc
+
+settling_timeout equ 10000 ; us
+
+ udata_acs
+settling 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
+;
+; 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
+ 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
+ intr_mask
+ call nmra_restartmessage
+ intr_unmask
+ 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
+
+
+
+
panic morse_UEC
;power_on ???
bcf PORTB,0,0 ; user fault L or Z
-power_polarising
+ pause nmra
+
panic morse_UER
power_panichook
sub do_T1ov { do_T13ov(1); }
sub do_T3ov { do_T13ov(3); }
+sub provide_interval ($$$$) {
+ my ($iname, $thisval, $unitname, $unitval) = @_;
+ my ($inthisunit, $inthisunitint);
+ $inthisunit= $thisval / $unitval;
+ return if $inthisunit > 256000000.0;
+ $inthisunitint= sprintf "%d", $inthisunit;
+ return if abs(($inthisunitint - $inthisunit) / $inthisunit) > 0.001;
+ p("${iname}_${unitname} equ $inthisunitint\n");
+}
+
sub doline () {
my ($orgname,$mswant,$specd,$unit,$how);
chomp;
if ($unit =~ m/u/) { $interval *= 1.e-6; }
if ($unit =~ m/n/) { $interval *= 1.e-9; }
if ($unit =~ s/Hz//) { $interval = 1.0 / $interval; }
+ p(";========== $name ($specd, $interval) ==========\n");
+ provide_interval($orgname, $interval, 'us', 1.e-6);
+ provide_interval($orgname, $interval, 'ms', 1.e-3);
+ provide_interval($orgname, $interval, 's', 1.0);
foreach $ms (qw(m s)) {
next unless $mswant =~ m/$ms/i;
$msclock= "${ms}clock";
die $msclock unless exists $defs{$msclock};
$msclock= $defs{$msclock};
$name = $orgname.'_'.($ms eq 'm' ? 'master' : 'slave');
- p(";---------- $name ($specd, $interval) ----------\n");
&{ "do_$how" };
}
}
bra arrange_write
nextslave_nowrite
; no writing needed, we consider reading:
+ bt_f_if1 flags, flags_polarising
+ return ; do not scan while booster PWM is off while polarising
+ ; to avoid all trains disappearing and reappearing
+
neg_fw outmsg_begin
add_wfw outmsg_end
and_lw outbuf_size - 1
bs_fa nmractrl,nextaction
bs_fa nmractrl,transmitbit
+nmra_restartmessage ; Entrypoint from power_polarising_tick, at end
+ ; of settle time. Goes back to beginning of
+ ; current message (if any) and retransmits it.
+ ; Also, enables booster PWM and Timer 0 interrupts.
+ mov_lw 0x0f
+ and_wff totrack
+
; initialise totrackbit bitmask
mov_lw 0x80
mov_wfa totrackbit ; make bit mask be 1000 0000
;...
;-----
cdu_discharged
- mov_lw cdu_timeout / 10 ; time in ms, converted to 10ms ticks
+ mov_lw (cdu_timeout * 1000) / tickdiv_us + 1
mov_wf cducharging
return
return
;--------------------
-cdu_tick
+cdu_tickdiv
bt_f_if0 LATB, p0_cdu_enable >> 4
return
extern points_getwritebyte
extern got_pointed
extern cdu_init
- extern cdu_tick
+ extern cdu_tickdiv
extern cdu_on
extern cdu_off
extern cdu_panichook
call serialtxfc_init
call mascan_init
call tick_init
+ call power_polarising_init
return
;----------------------------------------
#morse MS T0ov16 66ms
points MS T3ov 10ms
-tick MS T2period 10ms
+tick MS T2period 1ms
; now we're exiting from the loop in when_reverse_message_found
pop ; that disposes of the call to `board'
- call power_polarising
+ call power_polarising_begin
mov_fw polarity_cmds ; there's always a board 0, us
call polarity_local_do
; W = 0000000? C=0 no existing command
; W = 1000000? C=0 sentinel
bra_nn polarity_needwrite_loop
- bt_f_if0 STATUS, C
- return ; we found the sentinel
- ; we found a pic to tell to polarise:
+ bt_f_if1 STATUS, C
+ bra polarity_needwrite_found
+ ; we found the sentinel:
+ bt_f_if0 flags, flags_polarising
+ return
+ goto power_polarising_alldone
+
+polarity_needwrite_found
mov_fw FSR1L
add_lw -polarity_cmds
pop
; TICK - REGULAR 10MS TIMER INTERRUPT
;
; after tick_init, and after interrupts enabled,
-; we call <foo>_tick every 10ms.
+; we call <foo>_tick every 1ms and <foo>_tickdiv every <tickdiv>ms.
include common.inc
- code
+udata_acs
+tickdiv_count res 1
+
+ code
;----------------------------------------
tick_init
; Timer 2 any used for tick
bc_f IPR1, TMR2IP ; low priority
bs_f IPR1, TMR2IE ; enable interrupts
bs_f T2CON, TMR2ON ; enable timer
+ mov_lw tickdiv
+ mov_wf tickdiv_count
return
;----------------------------------------
bc_f PIR1, TMR2IF
; add calls to <foo>_tick here:
- call cdu_tick
+ call power_polarising_tick
+ call power_fault_tick
; end of list of calls to <foo>_tick
+ dec_f_ifz tickdivcount
+ bra tickdiv_do
+
+ intrl_handled_nostack
+
+;----------------------------------------
+tickdiv_do
+ ; add calls to <foo>_tickdiv here:
+ call cdu_tickdiv
+ ; end of list of calls to <foo>_tickdiv
+
+ mov_lw tickdiv
+ mov_wf tickdiv_count
intrl_handled_nostack
;----------------------------------------------------------------------
picno res 1 ; from first idlocs byte
idloc1 res 1 ; from 2nd idlocs byte; bit 7 is master:
-idloc1_master equ 7
-idloc1_boarddet equ 6
+idloc1_master equ 7
+idloc1_boarddet equ 6
acknmra res 1 ; must tell host about NMRA buffer state
flags res 1 ; miscellaneous state flags
+flags_polarising equ 6
t res 1 ; general temporary
u res 1 ; general temporary (another)