-
Notifications
You must be signed in to change notification settings - Fork 4
Clock and bit lengths for DCC
Whether we're using the PWM or PCM clock as a hardware timing source, we have to consider the appropriate bit rate and bit length for DCC.
DCC uses a nominal transmission of 58µs high, followed by 58µs low, for a 1 bit; and a nominal transmission of 100µs high, followed by 100µs low, for a 0 bit. The only common factor of these numbers, probably deliberately, is 2.
While the tolerances for decoders accepting a signal are wider, the tolerances for a command station transmitting are also specified in the standard and are what we should confirm to.
For a 1 bit, the standard allows us to transmit for 55–61µs high, followed by a low of the same length within ±3µs. Fortunately for us, keeping the high and low within the same time is easier than diverging, so that's not something we have to worry about.
For a 0 bit, the standard requires us to transmit for at least 95µs high and low. The maximum length of transmission is long enough that it's uninteresting to us.
Remmber in the discussion on using the PWM that the clock rate only uses the integer part of the divisor, and ignores the fractional part. This can be adjusted by using the MASH control bits of the register.
Setting to MASH-1 introduces the fractional part, which is given in the range 0–1,024. This allows us to achieve an average resulting clock rate much closer to our intent, though with the actual values spread. Continuing the above example, setting the fractional divisor to 204 (0.2 × 1024 = 204) we would achieve an average clock rate of our target of 1 MHz (19.2 Mhz ÷ 19.2 = 1 Mhz), but the actual values would be spread from 0.96–1.01 Mhz.
MASH-2 and MASH-3 introduce even more jitter, which is useful for eliminating sound distortion and clicks for audio, but not useful at all for our purposes.
The danger of this jitter is that it can apply in ways that we do not expect, and becomes cumulative when we use multiple GPIO bits per DCC bit. It seems better to be consistent in our values, even if they're not exactly the standard recommendation, than to jitter about and potentially exceed its parameters.
The use of integer divisors, on a relatively high frequency source compared to the DCC bit rate, means it's not actually possible to precisely align the bit rate. The following table shows the actual resulting bit rate for a given value in the register:
Bits per 1 | µs per bit | OSC DivI | Osc µs per bit | PLLD DivI | PLLD µs per bit |
---|---|---|---|---|---|
1 | 58.000 | 1,113 | 57.969 | ||
2 | 29.000 | 556 | 57.917 | ||
3 | 19.333 | 371 | 57.969 | ||
4 | 14.500 | 278 | 57.917 | ||
5 | 11.600 | 222 | 57.813 | ||
6 | 9.667 | 185 | 57.813 | ||
7 | 8.286 | 159 | 57.969 | ||
8 | 7.250 | 139 | 57.917 | 3,625 | 58.000 |
9 | 6.444 | 123 | 57.656 | 3,222 | 57.996 |
10 | 5.800 | 111 | 57.813 | 2,900 | 58.000 |
11 | 5.273 | 101 | 57.865 | 2,636 | 57.992 |
12 | 4.833 | 92 | 57.500 | 2,416 | 57.984 |
13 | 4.462 | 85 | 57.552 | 2,230 | 57.980 |
14 | 4.143 | 79 | 57.604 | 2,071 | 57.988 |
15 | 3.867 | 74 | 57.813 | 1,933 | 57.990 |
16 | 3.625 | 69 | 57.500 | 1,812 | 57.984 |
17 | 3.412 | 65 | 57.552 | 1,705 | 57.970 |
18 | 3.222 | 61 | 57.188 | 1,611 | 57.996 |
19 | 3.053 | 58 | 57.396 | 1,526 | 57.988 |
20 | 2.900 | 55 | 57.292 | 1,450 | 58.000 |
21 | 2.762 | 53 | 57.969 | 1,380 | 57.960 |
22 | 2.636 | 50 | 57.292 | 1,318 | 57.992 |
23 | 2.522 | 48 | 57.500 | 1,260 | 57.960 |
24 | 2.417 | 46 | 57.500 | 1,208 | 57.984 |
25 | 2.320 | 44 | 57.292 | 1,160 | 58.000 |
26 | 2.231 | 42 | 56.875 | 1,115 | 57.980 |
27 | 2.148 | 41 | 57.656 | 1,074 | 57.996 |
28 | 2.071 | 39 | 56.875 | 1,035 | 57.960 |
29 | 2.000 | 38 | 57.396 | 1,000 | 58.000 |
Notice that since the maximum divisor is 4,095, it's not possible to use the PLLD source for all potential bit rates; but that the higher resolution available from it more closely matches the intended bit rate.
For the oscillator source, the lower resolution means it's possible to be off by amounts that come close to the tolerances of the specification.
A simplistic approach would be to set the clock such that one GPIO bit equals as close to 58µs as we can, using the sequence 10
for a DCC 1 bit and 1100
for a DCC 0 bit. This conforms to the specification, however does mean that our 0 bits are slightly longer than necessary, 116µs, which decreases the amount of DCC bandwidth available and increases the latency of getting commands to the locomotives.
By increasing the clock rate, and using more memory of the controlling computer, we can compromise between the two until a happy medium is reached. The table below presents the options:
Bits per 1 | Bits per 0 | Osc µs for 1 | Osc µs for 0 | PLLD µs for 1 | PLLD µs for 0 |
---|---|---|---|---|---|
1 | 2 | 57.969 | 115.938 | ||
2 | 4 | 57.917 | 115.833 | ||
3 | 6 | 57.969 | 115.938 | ||
4 | 7 | 57.917 | 101.354 | ||
5 | 9 | 57.813 | 104.063 | ||
6 | 11 | 57.813 | 105.990 | ||
7 | 13 | 57.969 | 107.656 | ||
8 | 14 | 57.917 | 101.354 | 58.000 | 101.500 |
9 | 16 | 57.656 | 102.500 | 57.996 | 103.104 |
10 | 18 | 57.813 | 104.063 | 58.000 | 104.400 |
11 | 19 | 57.865 | 99.948 | 57.992 | 100.168 |
12 | 21 | 57.500 | 100.625 | 57.984 | 101.472 |
13 | 23 | 57.552 | 101.823 | 57.980 | 102.580 |
14 | 25 | 57.604 | 102.865 | 57.988 | 103.550 |
15 | 26 | 57.813 | 100.208 | 57.990 | 100.516 |
16 | 28 | 57.500 | 100.625 | 57.984 | 101.472 |
17 | 30 | 57.552 | 101.563 | 57.970 | 102.300 |
18 | 32 | 57.188 | 101.667 | 57.996 | 103.104 |
19 | 33 | 57.396 | 99.688 | 57.988 | 100.716 |
20 | 35 | 57.292 | 100.260 | 58.000 | 101.500 |
21 | 37 | 57.969 | 102.135 | 57.960 | 102.120 |
22 | 38 | 57.292 | 98.958 | 57.992 | 100.168 |
23 | 40 | 57.500 | 100.000 | 57.960 | 100.800 |
24 | 42 | 57.500 | 100.625 | 57.984 | 101.472 |
25 | 44 | 57.292 | 100.833 | 58.000 | 102.080 |
26 | 45 | 56.875 | 98.438 | 57.980 | 100.350 |
27 | 47 | 57.656 | 100.365 | 57.996 | 100.956 |
28 | 49 | 56.875 | 99.531 | 57.960 | 101.430 |
29 | 50 | 57.396 | 98.958 | 58.000 | 100.000 |
Obviously the worst conformance is achieved by the most frugal use of memory, and the low resolution oscillator source, where as noted transmitting a 0 will take almost 32µs longer than required by the standard.
The best confirmance, again unsurpisingly, is achieved by using the most memory, and the high resolution PLLD source, where we can exactly match the recommendation of the standard; while requiring 29x the amount of memory as the worst conformance example.
A standout compromise appears surprisingly early, by using 4 GPIO bits for a 1, and 7 for a 0, and the low resolution oscillator source (which is the only option at this bit rate), we lose less than 3µs per 0 transmitted; a 10x improvement in latency with only a 4x increase in memory requirements.
At the same time, the transmission time of a 1 is only 83 nanoseconds under the recommendation of the specification, and well within the requirements.