Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
TivaDCCDecoder.hxx
1
35#include "TivaDCC.hxx" // for FixedQueue
36#include "TivaGPIO.hxx" // for pin definitions
38
40
84template <class HW> class TivaDccTimerModule
85{
86public:
88 using NRZ_Pin = typename HW::NRZ_Pin;
89
90 // These constants are exported from HW to the driver.
91
94 static constexpr uint32_t TIMER_MAX_VALUE = HW::TIMER_MAX_VALUE;
96 static constexpr uint32_t SAMPLE_PERIOD_CLOCKS = HW::SAMPLE_PERIOD_CLOCKS;
98 static constexpr unsigned Q_SIZE = HW::Q_SIZE;
99
101 static uint32_t get_ticks_per_usec()
102 {
103 return configCPU_CLOCK_HZ / 1000000;
104 }
105
107 static void module_init();
108
110 static void module_enable();
111
113 static void module_disable();
114
117 {
118 MAP_IntPendSet(HW::OS_INTERRUPT);
119 }
120
123 {
124 HW::dcc_before_cutout_hook();
125 }
126
129 {
130 HW::dcc_packet_finished_hook();
131 }
132
135 {
136 HW::after_feedback_hook();
137 }
138
141 {
142 return HW::time_delta_railcom_pre_usec();
143 }
144
147 {
148 return HW::time_delta_railcom_mid_usec();
149 }
150
153 {
154 return HW::time_delta_railcom_end_usec();
155 }
156
160 static inline bool int_get_and_clear_capture_event();
161
166 static inline uint32_t get_capture_counter();
167
172 static inline bool int_get_and_clear_delay_event();
173
177 static void set_cap_timer_delay_usec(int usec)
178 {
179 Debug::DccPacketDelay::toggle();
180 uint32_t new_match_v = usec * 80;
181 MAP_TimerMatchSet(HW::TIMER_BASE, HW::RCOM_TIMER, 0xfffe - new_match_v);
182 MAP_TimerPrescaleMatchSet(HW::TIMER_BASE, HW::RCOM_TIMER, 0);
183 }
184
188 {
189 MAP_TimerDisable(HW::TIMER_BASE, HW::TIMER);
190 MAP_TimerIntDisable(
191 HW::TIMER_BASE, HW::TIMER_CAP_EVENT);
192 MAP_TimerIntClear(
193 HW::TIMER_BASE, HW::TIMER_CAP_EVENT);
194
195 MAP_TimerConfigure(
196 HW::TIMER_BASE, HW::CFG_TIM_CAPTURE | HW::CFG_RCOM_TIMER);
197 MAP_TimerControlEvent(
198 HW::TIMER_BASE, HW::TIMER, TIMER_EVENT_BOTH_EDGES);
199 MAP_TimerLoadSet(HW::TIMER_BASE, HW::TIMER, HW::TIMER_MAX_VALUE);
200 MAP_TimerPrescaleSet(HW::TIMER_BASE, HW::TIMER, HW::PS_MAX);
201
202 MAP_TimerIntEnable(HW::TIMER_BASE, HW::TIMER_CAP_EVENT);
203 MAP_TimerEnable(HW::TIMER_BASE, HW::TIMER);
204 }
205
209 static void set_cap_timer_time()
210 {
211 MAP_TimerDisable(HW::TIMER_BASE, HW::RCOM_TIMER);
212
213 MAP_TimerIntDisable(
214 HW::TIMER_BASE, HW::TIMER_RCOM_MATCH);
215 MAP_TimerIntClear(
216 HW::TIMER_BASE, HW::TIMER_RCOM_MATCH);
217 HW::clr_tim_mrsu();
218 MAP_TimerLoadSet(HW::TIMER_BASE, HW::RCOM_TIMER, 0xfffe);
219 MAP_TimerPrescaleSet(HW::TIMER_BASE, HW::RCOM_TIMER, 0);
220
221 MAP_TimerIntEnable(HW::TIMER_BASE, HW::TIMER_RCOM_MATCH);
222 MAP_TimerEnable(HW::TIMER_BASE, HW::RCOM_TIMER);
223 }
224
228 {
229 MAP_TimerDisable(HW::TIMER_BASE, HW::RCOM_TIMER);
230 }
231
233};
234
235template <class HW> void TivaDccTimerModule<HW>::module_init()
236{
237 MAP_SysCtlPeripheralEnable(HW::TIMER_PERIPH);
238 MAP_GPIOPadConfigSet(HW::NRZ_Pin::GPIO_BASE, HW::NRZ_Pin::GPIO_PIN,
239 GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
240}
241
243{
244 MAP_TimerClockSourceSet(HW::TIMER_BASE, TIMER_CLOCK_SYSTEM);
245 MAP_TimerControlStall(HW::TIMER_BASE, HW::TIMER, true);
246
247 set_cap_timer_capture();
248
249 MAP_TimerIntEnable(HW::TIMER_BASE, HW::TIMER_CAP_EVENT);
250
251 MAP_IntPrioritySet(HW::TIMER_INTERRUPT, 0x20);
252 MAP_IntPrioritySet(HW::RCOM_INTERRUPT, 0x20);
253 MAP_IntPrioritySet(HW::OS_INTERRUPT, configKERNEL_INTERRUPT_PRIORITY);
254 MAP_IntEnable(HW::OS_INTERRUPT);
255 MAP_IntEnable(HW::TIMER_INTERRUPT);
256 MAP_IntEnable(HW::RCOM_INTERRUPT);
257}
258
260{
261 MAP_IntDisable(HW::TIMER_INTERRUPT);
262 MAP_IntDisable(HW::RCOM_INTERRUPT);
263 MAP_IntDisable(HW::OS_INTERRUPT);
264 MAP_TimerDisable(HW::TIMER_BASE, HW::TIMER);
265 MAP_TimerDisable(HW::TIMER_BASE, HW::RCOM_TIMER);
266}
267
268template <class HW>
270{
271 // get masked interrupt status
272 auto status = MAP_TimerIntStatus(HW::TIMER_BASE, true);
273 if (status & HW::TIMER_CAP_EVENT)
274 {
275 //Debug::DccDecodeInterrupts::toggle();
276 HW::cap_event_hook();
277 MAP_TimerIntClear(HW::TIMER_BASE, HW::TIMER_CAP_EVENT);
278 return true;
279 }
280 return false;
281}
282
284{
285 return MAP_TimerValueGet(HW::TIMER_BASE, HW::TIMER);
286}
287
289{
290 Debug::DccDecodeInterrupts::set(true);
291 auto status = MAP_TimerIntStatus(HW::TIMER_BASE, true);
292 if (status & HW::TIMER_RCOM_MATCH)
293 {
294 MAP_TimerIntClear(HW::TIMER_BASE, HW::TIMER_RCOM_MATCH);
295 return true;
296 }
297 return false;
298}
299
300template <class HW> using TivaDccDecoder = DccDecoder<TivaDccTimerModule<HW>>;
Device driver for decoding a DCC signal using a Timer resource.
Device driver for decoding a DCC signal on a TI Tiva class microcontroller.
static void set_cap_timer_delay_usec(int usec)
Delays a give number of usec using the capture timer feature.
static void dcc_before_cutout_hook()
hook
static constexpr uint32_t SAMPLE_PERIOD_CLOCKS
After how many timer counts we should take one sample.
static void set_cap_timer_time()
Sets the timer to oneshot (timer) mode.
static uint32_t get_capture_counter()
Called from the interrupt handler if int_get_and_clear_capture_event said yes.
static void trigger_os_interrupt()
Calls a software interrupt.
typename HW::NRZ_Pin NRZ_Pin
Exports the input pin to the driver on the module interface.
static void set_cap_timer_capture()
Sets the timer to capture mode.
static void dcc_packet_finished_hook()
hook
static bool int_get_and_clear_delay_event()
Called from the timeout interrupt handler.
static void module_enable()
Called inline with Device::enable().
static bool int_get_and_clear_capture_event()
Called from the capture interrupt handler.
static constexpr uint32_t TIMER_MAX_VALUE
This is the counter from which the timer starts counting down.
static int time_delta_railcom_mid_usec()
How many usec later should the railcom cutout middle happen.
static void module_disable()
Called inline with Device::disable().
static uint32_t get_ticks_per_usec()
static void stop_cap_timer_time()
Called once inline in an interrupt.
static int time_delta_railcom_end_usec()
How many usec later should the railcom cutout middle happen.
static int time_delta_railcom_pre_usec()
How many usec later should the railcom cutout start happen.
static void module_init()
Called once during construction time.
static void after_feedback_hook()
hook
static constexpr unsigned Q_SIZE
Length of the device queue.
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Definition macros.h:171
GPIO Pin definition structure with no actual pin behind it.
Definition DummyGPIO.hxx:43