diff --git a/boards/ti-ek-tm4c123gxl-launchpad/HwInit.cxx b/boards/ti-ek-tm4c123gxl-launchpad/HwInit.cxx index 924c5b34a..e337017e5 100644 --- a/boards/ti-ek-tm4c123gxl-launchpad/HwInit.cxx +++ b/boards/ti-ek-tm4c123gxl-launchpad/HwInit.cxx @@ -221,7 +221,10 @@ struct DccHwDefs { static const int RAILCOM_CUTOUT_START_DELTA_USEC = -20; static const int RAILCOM_CUTOUT_MID_DELTA_USEC = 0; static const int RAILCOM_CUTOUT_END_DELTA_USEC = -10; - static const int RAILCOM_CUTOUT_POST_DELTA_USEC = -10; + static const int RAILCOM_CUTOUT_POST_DELTA_USEC = -16; + /// Adds this to the negative half after the railcom cutout is done. + static const int RAILCOM_CUTOUT_POST_NEGATIVE_DELTA_USEC = -4; + /** These timer blocks will be synchronized once per packet, when the * deadband delay is set up. */ @@ -251,16 +254,16 @@ struct DccHwDefs { * '1' bit */ static int dcc_preamble_count() { return 16; } - static bool generate_railcom_halfzero() { return false; } + static bool generate_railcom_halfzero() { return true; } static void flip_led() {} /** the time (in nanoseconds) to wait between turning off the low driver and * turning on the high driver. */ - static const int H_DEADBAND_DELAY_NSEC = 250; + static const int H_DEADBAND_DELAY_NSEC = 0; /** the time (in nanoseconds) to wait between turning off the high driver and * turning on the low driver. */ - static const int L_DEADBAND_DELAY_NSEC = 250; + static const int L_DEADBAND_DELAY_NSEC = 0; /** number of outgoing messages we can queue */ static const size_t Q_SIZE = 4; diff --git a/src/freertos_drivers/ti/TivaDCC.hxx b/src/freertos_drivers/ti/TivaDCC.hxx index 1bd9637c3..3bdd3adb6 100644 --- a/src/freertos_drivers/ti/TivaDCC.hxx +++ b/src/freertos_drivers/ti/TivaDCC.hxx @@ -520,6 +520,7 @@ private: RailcomDriver* railcomDriver_; /**< Will be notified for railcom cutout events. */ /// Seed for a pseudorandom sequence. unsigned seed_ = 0xb7a11bae; + /// Parameters for a linear RNG: modulus static constexpr unsigned PMOD = 65213; /// Parameters for a linear RNG: multiplier @@ -864,17 +865,19 @@ inline void TivaDCC::interrupt_handler() if (!HW::H_DEADBAND_DELAY_NSEC) { + TDebug::Resync::toggle(); MAP_TimerDisable(HW::CCP_BASE, TIMER_A|TIMER_B); // Sets final values for the cycle. MAP_TimerLoadSet(HW::CCP_BASE, TIMER_A|TIMER_B, timing->period); MAP_TimerMatchSet(HW::CCP_BASE, TIMER_A, timing->transition_a); MAP_TimerMatchSet(HW::CCP_BASE, TIMER_B, timing->transition_b); - MAP_TimerEnable(HW::CCP_BASE, TIMER_A|TIMER_B); + MAP_TimerEnable(HW::CCP_BASE, TIMER_A | TIMER_B); MAP_TimerDisable(HW::INTERVAL_BASE, TIMER_A); MAP_TimerLoadSet( HW::INTERVAL_BASE, TIMER_A, timing->interval_period); MAP_TimerEnable(HW::INTERVAL_BASE, TIMER_A); + TDebug::Resync::toggle(); // Switches back to asynch timer update. HWREG(HW::CCP_BASE + TIMER_O_TAMR) |= @@ -916,7 +919,15 @@ inline void TivaDCC::interrupt_handler() } last_bit = current_bit; - if (current_bit == DCC_RC_HALF_ZERO) + bit_repeat_count = 0; + if (current_bit == RAILCOM_CUTOUT_POST) + { + // RAILCOM_CUTOUT_POST purposefully misaligns the two timers. We + // need to resync when the next interval timer ticks to get them + // back. + resync = true; + } + else if (current_bit == DCC_RC_HALF_ZERO) { // After resync the same bit is output twice. We don't want that // with the half-zero, so we preload the DCC preamble bit. @@ -998,7 +1009,7 @@ inline void TivaDCC::interrupt_handler() /// Converts a time length given in microseconds to the number of clock cycles. /// @param usec is time given in microseconds. /// @return time given in clock cycles. -static uint32_t usec_to_clocks(uint32_t usec) { +static const uint32_t usec_to_clocks(uint32_t usec) { return (configCPU_CLOCK_HZ / 1000000) * usec; } @@ -1094,7 +1105,8 @@ TivaDCC::TivaDCC(const char *name, RailcomDriver *railcom_driver) // some fraction of the high part, then a full low side, then we stretch // the low side to avoid the packet transition glitch. fill_timing(RAILCOM_CUTOUT_POST, remaining_high + 56 + 20, remaining_high, - remaining_high + 56 + h_deadband); + remaining_high + 56 + h_deadband + + HW::RAILCOM_CUTOUT_POST_NEGATIVE_DELTA_USEC); // We need to disable the timers before making changes to the config. MAP_TimerDisable(HW::CCP_BASE, TIMER_A);