Introduction
The OpenDec02 decoder introduces a system wherein a defined set of GPIO (General Purpose Input/Output) pins of the MCU (Micro Controller Unit) can be associated with any of the availabel 32 DCC functions, with the use of specific registers within the CV table. Let’s delve into the process of assigning an MCU GPIO pin to a particular DCC (Digital Command Control) function, specifically focusing on activating the forward and rear headlights.
We will be talking a lot about GPIO pins here so exactly what is this !?
A GPIO (General Purpose Input/Output) pin is a versatile electronic pin found on microcontrollers (such as the RP2040 MCU used in the OpenDec02) and other digital devices. It can be programmed to either input data (receiving signals) or output data (sending signals), allowing it to interact with external components like sensors, switches, LEDs, and more. GPIO pins play a fundamental role in controlling and monitoring the behavior of electronic systems, offering flexibility and customization in various applications such as robotics, embedded systems, and IoT (Internet of Things) devices. The GPIO pins that we refer to here are digital only which means they will only be either high or low.
Mapping GPIO pins to DCC functions
One of the strong points of the OpenDec02 DCC Decoder is, as mentioned, its flexible management of the IO system. With this system you can map any GPIO pin on the MCU to any DCC Function that you like, simply by writing a new configuration to the CV table.
Examining the CV table reveals that CV registers CV257 through CV512 are designated for the purpose of mapping GPIO pins to DCC functions. All the available DCC functions (F0 – F31) are represented in the table meaning that you can configure any one of the available GPIO pins to any DCC function. This allows you to mimic other DCC decoders giving your new OpenDec02 a familiar DCC function map.
For the OpenDec02 DCC decoder the following GPIO’s are available
Name on PCB | MCU GPIO Pin | Electrical Characterstics |
---|---|---|
AUX0 | GPIO24 | 30V @ 500mA |
AUX1 | GPIO23 | 30V @ 500mA |
AUX2 | GPIO25 | 30V @ 500mA |
AUX3 | GPIO26 | 30V @ 500mA |
GPIO0 | GPIO0 | 3.3V @ 4mA |
GPIO1 | GPIO1 | 3.3V @ 4mA |
GPIO2 | GPIO2 | 3.3V @ 4mA |
GPIO3 | GPIO3 | 3.3V @ 4mA |
GPIO4 | GPIO4 | 3.3V @ 4mA |
GPIO5 | GPIO5 | 3.3V @ 4mA |
Front head light
Let’s begin with the front headlight, assuming we want to assign it to DCC function F0 (which is the standard DCC function for the lights). Within the CV file, there exist 8 registers (CV257 – CV264) governing the mapping of MCU GPIO pin(s) when function F0 is activated. These 8 registers are divided into two groups: 4 registers control the GPIO pins for the forward direction, while the remaining 4 control them for the reverse direction of function F0. Specifically, CV257 – CV260 pertain to the forward direction, and CV261 – CV264 pertain to the reverse direction. This register mapping extends to describe the relationship between other DCC functions and their corresponding GPIO pins.
Understanding the GPIO pin configuration
Let us assume that we have connected the decoder a shown in the picture below.
For our our discussion below we assume that our front headlight is connected to AUX0 and our rear headlight is connected to AUX1.
Now Lets start with the front headlight and lets assume we want to assign it to DCC function F0. In the CV file there are 8 registers (CV257 – CV264) that control what MCU GPIO pin (or pins) is mapped when function F0 is activated. And it gets even better, these 8 registers are divided into 2 groups where 4 registers controls what GPIO pins that should be used in the forward direction and the other 4 registers controls what MCU GPIO pin should be used when your loco is moving in the reverse direction for the F0 function. Specifically for DCC function F0, CV257 – CV260 controls the forward direction and CV261 – CV264 controls the reverse direction.
The register map then continues on describing the relationship between the rest of the DCC Functions and their respective GPIO pins.
OK, so how do we use this information. Well first we need to know to what MCU GPIO pin the front head light is connected to. We know that it is connected to the AUX0 pad on the PCB (which seems like a logical choice) which corresponds to GPIO24 as described in the GPIO table above.
Taking a look again on the CV’s (it’s always good to reference the CV.h file in the software repo) we can now determine, since AUX0/GPIO24 is going to be enabled only in the forward direction, that we need to create a link in the first group of CV’s (CV257 – CV260). This following description shows how the GPIO pins are represented in the CV registers:
31 30 29 28 - 27 26 25 24 -- 23 22 21 20 - 19 18 17 16 -- 15 14 13 12 - 11 10 9 8 -- 7 6 5 4 - 3 2 1 0 <- GPIO
byte_3 -- byte_2 -- byte_1 -- byte_0 <- CV register offset
7 6 5 4 - 3 2 1 0 -- 7 6 5 4 - 3 2 1 0 -- 7 6 5 4 - 3 2 1 0 -- 7 6 5 4 - 3 2 1 0 <- CV register bit value
//F0 forward
0b00000000, //CV_257 - byte 3
0b00000000, //CV_258 - byte 2
0b00000000, //CV_259 - byte 1
0b00000000, //CV_260 - byte 0
//F0 reverse
0b00000000, //CV_261 - byte 3
0b00000000, //CV_262 - byte 2
0b00000000, //CV_263 - byte 1
0b00000000, //CV_264 - byte 0
//F1 forward
0b00000000, //CV_265 - byte 3
0b00000000, //CV_266 - byte 2
0b00000000, //CV_267 - byte 1
0b00000000, //CV_268 - byte 0
//F1 reverse
0b00000000, //CV_269 - byte 3
0b00000000, //CV_270 - byte 2
0b00000000, //CV_271 - byte 1
0b00000000, //CV_272 - byte 0
This representation of 32 bits in 4 bytes is called big endian and it means that byte 3 (see CV listing) in the group of bytes (CV257 in this case) holds the higher bits (24-32) of the GPIO port and byte 0 (CV260) holds the lower bits (0-7). For Function F0 in the forward direction that is. The same pattern applies to all the function groups. To further clarify how it works:
- Byte 3 contains bits 24 – 31 of the GPIO port.
- Byte 2 contains bits 16 – 23 of the GPIO port.
- Byte 1 contains bits 8 – 15 of the GPIO port.
- Byte 0 contains bits 0 – 7 of the GPIO port.
Now we have already established that AUX0 is connected to GPIO24 so by putting a “1” in the corresponding bit (bit 0 in this case) of byte 3 of the control CV that controls this port pin (CV257) we have now connected GPIO24 to the DCC function F0 in the forward direction. And if we breake that down to some real action it means that we need to write the value 1 to CV257.
Taking all this new exciting knowledge that we now have we can also connect our rear light up. Looking in the CV table we can see that CV261 – CV264 controls the action for function F0 in the reverse direction. We also know that AUX1 (rear headlight) is connected to GPIO23 according to the GPIO table. With this information on hand we can now see that we need to write a 1 into bit 7 of CV262 which corresponds to writing 128 to CV262. Easy peasy… right =)
With this system we can also have the front headlight on all the time by simply adding a “1” to bit 0 of CV261 as well. If you want to add a light for the cab you could connect it to AUX2 and assign it to DCC function F1 by writing the value 2 to CV265, and CV269 if you want the cab light on in both direction.
The same applies to the digital (3.3V) GPIOx pins. Linking DCC function 16 to pin IO0 is done by writing the value 1 to CV388 and if you want it enabled in both forward and reverse direction you would need to write the value 1 to CV392 as well.
Just remember that if you connect anything with a voltage above 3.3V to the GPIOx pins the decoder will most likely be destroyed.
In the next installment we will be looking in to adding PWM to the mix.
0 Comments for “Lights, let there be lights”