Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
DccOutput.hxx
Go to the documentation of this file.
1
36#ifndef _DCC_DCCOUTPUT_HXX_
37#define _DCC_DCCOUTPUT_HXX_
38
39#include <atomic>
40#include <cstdint>
41
46{
47public:
49 enum Type : int
50 {
52 TRACK = 1,
54 PGM = 2,
56 LCC = 3,
57 };
58
60 enum class DisableReason : uint8_t
61 {
67 CONFIG_SETTING = 0x02,
72 GLOBAL_EOFF = 0x04,
74 SHORTED = 0x08,
76 THERMAL = 0x10,
79 PGM_TRACK_LOCKOUT = 0x20,
83 USR1 = 0x80,
84 };
85
88
92
98 {
99 if (value)
100 {
102 }
103 else
104 {
106 }
107 }
108
110 virtual uint8_t get_disable_output_reasons() = 0;
111
113 enum class RailcomCutout
114 {
116 DISABLED = 0,
118 SHORT_CUTOUT = 1,
120 LONG_CUTOUT = 2
121 };
122
125};
126
132
135template <class HW> class DccOutputImpl : public DccOutput
136{
137public:
138 constexpr DccOutputImpl()
139 {
140 }
141
144 {
145 HW::set_disable_reason(bit);
146 }
150 {
151 HW::clear_disable_reason(bit);
152 }
153
156 {
157 HW::isRailcomCutoutEnabled_ = (uint8_t)cutout;
158 }
159
161 uint8_t get_disable_output_reasons() override
162 {
163 return HW::outputDisableReasons_;
164 }
165
167 static constexpr DccOutput *instance()
168 {
169 return const_cast<DccOutput *>(
170 static_cast<const DccOutput *>(&instance_));
171 }
172
173private:
176};
177
179template <class HW> const DccOutputImpl<HW> DccOutputImpl<HW>::instance_;
180
187template <int OUTPUT_NUMBER> struct DccOutputHw
188{
189public:
196 static std::atomic_uint_least8_t outputDisableReasons_;
197
200 static std::atomic_uint_least8_t isRailcomCutoutEnabled_;
201
205
209 {
210 return (outputDisableReasons_ == 0) && (isRailcomCutoutEnabled_ != 0);
211 }
212
215 static bool should_be_enabled()
216 {
217 return outputDisableReasons_ == 0;
218 }
219
223 {
224 outputDisableReasons_ &= ~((uint8_t)bit);
225 }
226
227protected:
232 {
233 outputDisableReasons_ |= (uint8_t)bit;
234 }
235
236private:
240};
241
242template <int N>
243std::atomic_uint_least8_t DccOutputHw<N>::outputDisableReasons_ {
245template <int N>
246std::atomic_uint_least8_t DccOutputHw<N>::isRailcomCutoutEnabled_ {
248template <int N> uint8_t DccOutputHw<N>::isRailcomCutoutActive_ {0};
249
252template <int N> struct DccOutputHwDummy : public DccOutputHw<N>
253{
254public:
256 static void hw_preinit(void)
257 {
258 }
259
262 static unsigned start_railcom_cutout_phase1(void)
263 {
264 return 0;
265 }
266
269 static unsigned start_railcom_cutout_phase2(void)
270 {
271 return 0;
272 }
273
276 static unsigned stop_railcom_cutout_phase1(void)
277 {
278 return 0;
279 }
280
283 {
284 }
285
288 static void enable_output(void)
289 {
290 }
291
294 {
295 return false;
296 }
297
298 static void set_disable_reason(DccOutput::DisableReason bit)
299 {
301 // no actual output needs to be disabled.
302 }
303};
304
318template <int N, class BOOSTER_ENABLE, class RAILCOM_ENABLE,
319 unsigned DELAY_ON_1, unsigned DELAY_ON_2, unsigned DELAY_OFF>
320struct DccOutputHwReal : public DccOutputHw<N>
321{
322public:
324 static void hw_preinit(void)
325 {
326 BOOSTER_ENABLE::hw_init();
327 BOOSTER_ENABLE::set(false);
328 RAILCOM_ENABLE::hw_init();
329 RAILCOM_ENABLE::set(false);
330 }
331
334 static unsigned start_railcom_cutout_phase1(void)
335 {
336 BOOSTER_ENABLE::set(false);
337 return DELAY_ON_1;
338 }
339
342 static unsigned start_railcom_cutout_phase2(void)
343 {
344 RAILCOM_ENABLE::set(true);
345 return DELAY_ON_2;
346 }
347
350 static unsigned stop_railcom_cutout_phase1(void)
351 {
352 RAILCOM_ENABLE::set(false);
353 return DELAY_OFF;
354 }
355
358 {
361 }
362
365 static void enable_output(void)
366 {
367 BOOSTER_ENABLE::set(true);
368 }
369
370 static void set_disable_reason(DccOutput::DisableReason bit)
371 {
373 BOOSTER_ENABLE::set(false);
374 }
375};
376
377#endif // _DCC_DCCOUTPUT_HXX_
DccOutput * get_dcc_output(DccOutput::Type type)
Public API accessor for applications to get the object representing the output hardware.
Default implementation class of the DccOutput that proxies the calls to a hardware-specific static st...
static const DccOutputImpl< HW > instance_
Default instance to be used.
void clear_disable_output_for_reason(DisableReason bit) override
Removes a disable reason flag.
void set_railcom_cutout_enabled(RailcomCutout cutout) override
Specifies whether there should be a railcom cutout on this output.
void disable_output_for_reason(DisableReason bit) override
Disables the output, marking in a bitmask why.
static constexpr DccOutput * instance()
uint8_t get_disable_output_reasons() override
Virtual base class for controlling outputs.
Definition DccOutput.hxx:46
virtual void disable_output_for_reason(DisableReason bit)=0
Disables the output, marking in a bitmask why.
Type
Enumeration describing different outputs.
Definition DccOutput.hxx:50
@ TRACK
DCC output of the integrated booster.
Definition DccOutput.hxx:52
@ PGM
DCC output of the program track.
Definition DccOutput.hxx:54
@ LCC
DCC output going towards the LCC cable.
Definition DccOutput.hxx:56
virtual void set_railcom_cutout_enabled(RailcomCutout cutout)=0
Specifies whether there should be a railcom cutout on this output.
virtual void clear_disable_output_for_reason(DisableReason bit)=0
Removes a disable reason flag.
virtual uint8_t get_disable_output_reasons()=0
void override_disable_bit_for_reason(DisableReason bit, bool value)
Sets or clears a disable reason.
Definition DccOutput.hxx:97
RailcomCutout
Defines the values for the railcom cutout enabled setting.
@ DISABLED
Generate no railcom cutout.
@ LONG_CUTOUT
Generate long cutout (standard size; ch1+ch2).
@ SHORT_CUTOUT
Generate short cutout (ch1 only).
DisableReason
Values of a bit mask why we might want to disable a given DCC output.
Definition DccOutput.hxx:61
@ GLOBAL_EOFF
A network message requested global emergency off.
@ THERMAL
The system is in thermal shutdown.
@ INITIALIZATION_PENDING
Set as 1 during construction time, to be cleared by the application when the initialization is comple...
@ LOCAL_DISABLE
A local request for disabling the output.
@ SHORTED
Short detector says this output is shorted.
@ CONFIG_SETTING
User decided via a persistent configuration that this output should not be enabled.
@ INVALID_SIGNAL_INPUT
invalid incoming DCC signal
@ PGM_TRACK_LOCKOUT
This output should be off due to the conflict between program track and normal operation mode.
@ USR1
Reserved for application specific use cases.
Interface that the actual outputs have to implement in their hardware-specific classes.
static void stop_railcom_cutout_phase2(void)
Invoked at the end of a railcom cutout.
static unsigned start_railcom_cutout_phase1(void)
Invoked at the beginning of a railcom cutout.
static void enable_output(void)
Called once every packet by the driver, typically before the preamble, if the output is supposed to b...
static bool need_railcom_cutout()
A dummy output never needs a railcom cutout.
static void hw_preinit(void)
Called once during hw_preinit boot state.
static unsigned start_railcom_cutout_phase2(void)
Invoked at the beginning of a railcom cutout after the delay.
static unsigned stop_railcom_cutout_phase1(void)
Invoked at the end of a railcom cutout.
Generic implementation of the actual HW output with a booster enable and a railcom enable GPIO.
static void enable_output(void)
Called once every packet by the driver, typically before the preamble, if the output is supposed to b...
static void hw_preinit(void)
Called once during hw_preinit boot state.
static unsigned start_railcom_cutout_phase2(void)
Invoked at the beginning of a railcom cutout after the delay.
static unsigned start_railcom_cutout_phase1(void)
Invoked at the beginning of a railcom cutout.
static void stop_railcom_cutout_phase2(void)
Invoked at the end of a railcom cutout.
static unsigned stop_railcom_cutout_phase1(void)
Invoked at the end of a railcom cutout.
This structure represents a single output channel for a DCC command station.
static bool need_railcom_cutout()
Called by the driver to decide whether to make this channel participate in the railcom cutout.
static std::atomic_uint_least8_t outputDisableReasons_
Bitmask of why this output should be disabled.
static void set_disable_reason_impl(DccOutput::DisableReason bit)
Set one bit in the disable reasons bit field.
static bool should_be_enabled()
Called once after the railcom cutout is done to decide whether this output should be reenabled.
DccOutputHw()
Private constructor.
static std::atomic_uint_least8_t isRailcomCutoutEnabled_
0 if we should not produce a railcom cutout; 1 for short cutout; 2 for regular cutout.
static uint8_t isRailcomCutoutActive_
1 if we are in a railcom cutout currently.
static void clear_disable_reason(DccOutput::DisableReason bit)
Clears a disable reason.