Skip to content

Commit

Permalink
Tunes end-of-packet DCC bit timing. (#648)
Browse files Browse the repository at this point in the history
* Tunes end-of-packet DCC bit timing.

Adds a parameter to tune out a CPU specific delay from the DCC bit at the end of a packet, when resync is happening.

* Fixes timer sync command.
  • Loading branch information
balazsracz authored Sep 11, 2022
1 parent 2704636 commit 9bc4338
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/freertos_drivers/ti/TivaDCC.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -1072,10 +1072,18 @@ TivaDCC<HW>::TivaDCC(const char *name, RailcomDriver *railcom_driver)
// A small pulse in one direction then a half zero bit in the other
// direction.
fill_timing(DCC_RC_HALF_ZERO, 100 + 56, 56, 100 + 56, 5);
// At the end of the packet we stretch the negative side but let the
// interval timer kick in on time. The next bit will resync, and this
// avoids a glitch output to the track when a marklin preamble is coming.
fill_timing(DCC_EOP_ONE, (56 << 1) + 20, 58, 56 << 1);
// At the end of the packet the resync process will happen, which means that
// we modify the timer registers in synchronous mode instead of double
// buffering to remove any drift that may have happened during the packet.
// This means that we need to kick off the interval timer a bit earlier than
// nominal to compensate for the CPU execution time. At the same time we
// stretch the negative side of the output waveform, because the next packet
// might be marklin. Stretching avoids outputting a short positive glitch
// between the negative half of the last dcc bit and the fully negative
// marklin preamble.
fill_timing(
DCC_EOP_ONE, (56 << 1) + 20, 56, (56 << 1) - HW::RESYNC_DELAY_USEC);

fill_timing(MM_ZERO, 208, 26, 208, 2);
fill_timing(MM_ONE, 208, 182, 208, 2);
// Motorola preamble is negative DC signal.
Expand Down Expand Up @@ -1155,7 +1163,7 @@ TivaDCC<HW>::TivaDCC(const char *name, RailcomDriver *railcom_driver)
MAP_TimerEnable(HW::INTERVAL_BASE, TIMER_A);

#ifdef TIVADCC_TIVA
MAP_TimerSynchronize(TIMER0_BASE, TIMER_0A_SYNC | TIMER_0B_SYNC | TIMER_1A_SYNC | TIMER_1B_SYNC);
MAP_TimerSynchronize(TIMER0_BASE, HW::TIMER_SYNC);
#endif

MAP_TimerLoadSet(HW::CCP_BASE, TIMER_B, timings[DCC_ONE].period);
Expand Down

0 comments on commit 9bc4338

Please sign in to comment.