Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
RailcomBroadcastDecoder.cxx
Go to the documentation of this file.
1
36
37#include "dcc/RailCom.hxx"
38
39namespace dcc
40{
41
48{
49 if (packet.ch1Size)
50 {
51 return process_data(packet.ch1Data, packet.ch1Size) &&
52 (packet.ch2Size == 0);
53 }
54 else
55 {
56 // No channel1 data.
58 if (!packet.ch2Size)
59 {
60 return true; // empty packet.
61 }
62 return false;
63 }
64}
65
66bool RailcomBroadcastDecoder::process_data(const uint8_t *data, unsigned size)
67{
68 for (unsigned i = 0; i < size; ++i)
69 {
70 if (railcom_decode[data[i]] == RailcomDefs::INV)
71 {
72 return true; // garbage.
73 }
74 }
78 if (size < 2)
79 {
80 return true; // Dunno what this is.
81 }
82 uint8_t type = (dcc::railcom_decode[data[0]] >> 2);
83 if (size == 2)
84 {
85 uint8_t payload = dcc::railcom_decode[data[0]] & 0x3;
86 payload <<= 6;
87 payload |= dcc::railcom_decode[data[1]];
88 switch (type)
89 {
90 case dcc::RMOB_ADRLOW:
91 if (currentL_ == payload)
92 {
94 {
95 countL_ += 2;
96 }
97 }
98 else
99 {
100 currentL_ = payload;
101 countL_ = 0;
102 }
103 break;
104 case dcc::RMOB_ADRHIGH:
105 if (currentH_ == payload)
106 {
108 {
109 countH_ += 2;
110 }
111 }
112 else
113 {
114 currentH_ = payload;
115 countH_ = 0;
116 }
117 break;
118 default:
119 return false; // This is something we don't know about.
120 }
121 if (countL_ >= (MIN_REPEAT_COUNT * 2) &&
122 countH_ >= (MIN_REPEAT_COUNT * 2))
123 {
124 currentAddress_ = (uint16_t(currentH_) << 8) | currentL_;
125 }
126 return true;
127 }
128 else
129 {
130 return false;
131 }
132}
133
135{
136 if (value)
137 {
138 return;
139 }
140 notify_empty();
141}
142
144{
145 if (countH_)
146 {
147 --countH_;
148 }
149 if (countL_)
150 {
151 --countL_;
152 }
153 if ((!countH_) || (!countL_))
154 {
155 currentAddress_ = 0;
156 }
157}
158
159} // namespace dcc
const uint8_t railcom_decode[256]
Table for 8-to-6 decoding of railcom data.
Definition RailCom.cxx:47
static const uint8_t MIN_EMPTY_COUNT
This is how many empty packets we need to forget the current address when we're getting empty packets...
uint16_t currentAddress_
last valid address (0 if no valid address)
bool process_data(const uint8_t *data, unsigned size)
Helper function to process a sequence of bytes (whichever window they are coming from).
bool process_packet(const dcc::Feedback &packet)
Decodes a packet.
void set_occupancy(bool value)
Notifies the state machine about observed occupancy.
uint8_t countH_
observed repeat count of high address bits
uint8_t currentL_
last received low address bits
static const uint8_t MIN_REPEAT_COUNT
How many times we shall get the same data out of railcom before we believe it and report to the bus.
uint8_t countL_
observed repeat count of low address bits
void notify_empty()
Notifies the state machine that there is no occupancy detected.
uint8_t currentH_
last received high address bits
uint8_t ch2Size
Number of bytes in channel two.
Definition railcom.h:49
uint8_t ch1Size
Number of bytes in channel one.
Definition railcom.h:45
uint8_t ch1Data[2]
Payload of channel 1.
Definition railcom.h:47
Structure used for reading (railcom) feedback data from DCC / Railcom device drivers.
Definition RailCom.hxx:50
@ INV
invalid value (not conforming to the 4bit weighting requirement)
Definition RailCom.hxx:100