Digital I/O: Pin Configuration

In the above Figure, y is the port number and x is the pin number. For instance, P1.4 would mean Port 1, Pin 4. P2IN.0 would mean Pin 0 of Port 2’s input register. P3OUT.5 would mean Pin 5 of Port 3’s output register. As shown, there are several registers associated with each port. For the purposes of input and output, the ones of note are PyREN.x, PyDIR.x, PyOUT.x, and PyIN.x.

For now, we will disregard PySEL1.x and PySEL0.x and assume they are both 0. To designate a GPIO pin as an input or an output, the direction register (PyDIR.x) must be used. This register sets whether a pin is currently an input or an output. As the pin diagram shows, 0 indicates that a pin is being used as an input, and 1 indicates that a pin is being used as an output. PyDIR.x is connected to a multiplexer, which in turn is connected to two components: the activation switch of the tri-state buffer (which connects the pin to the output register), and the inverted terminal of an AND gate (which is used to enable pull-up and pull-down resistors).

We start by studying the configuration that sets the pin as an output. The goal of this configuration is to allow the values that the processor has written to a flip-flop, known as output register, to the wire that goes outside the chip boundary. In other words, we are trying to create a path from inside the chip to the outside. The first step is to set PyDIR.x to 1, which causes the tri-state buffer to act as a wire. This “wire” is connected to a multiplexer, which in turn is connected to the output register (PyOUT.x). It is also connected to the pin, thus establishing a connection between the output register and the pin. This is what we desired, since now the pin’s values will match the output register’s.

However, we have to ensure that the connection is not tied to any other outputs in the circuit. Notice that the node between the pin and the tri-state buffer is also connected to the input pins of the Schmitt trigger and the resistor. Since the connection to the Schmitt trigger goes from the node to the input of the Schmitt trigger and not to its output, there is no problem here. The resistor is also not a major issue as it only presents extra load (extra delay). Nevertheless, the direction register disconnects the resister altogether and eliminates its effects. Since PyDIR.x is set to 1 and is connected to the inverted terminal of the AND gate, the AND gate is now receiving 0 as an input. Since this is the case, the AND gate will always output 0. Because the AND gate is connected to a switch that connects the resistor to either ground or power, the switch acts as an open circuit due to receiving a 0. Thus, the resistor is not connected to anything, so it will not provide any extra load.

The input path, on the other hand, requires more configuration. With PyDIR.x now set to 0, the tri-state buffer acts as high impedance, thus preventing any connection between the output register and the pin. The pin is now connected to the Schmitt trigger, which is in turn connected to the input register (PyIN.x). Now, the input register will match the value of the wire from outside the chip boundary, thus the pin is acting as an input.


However, we have to eliminate any risk of producing short circuits as a result of connecting the pin to the circuit. If the peripheral attached to the pin already has a pull-up or pull-down resistor, then we have nothing to worry about. If not, however, then we will need to configure the resistor enable register (PyREN.x). This register is connected to the AND gate. Since one of the AND gate’s inputs is 1 (as a result of the inversion of PyDIR.x), the switch that enables the resistor is controlled by the value on the resistor enable register. If PyREN.x is 0, then the switch is an open circuit, thus the resistor is not enabled. On the other hand, if PyREN.x is 1, then the switch is closed, thus connecting the resistor to either power or ground.


Should a resistor be needed, whether this resistor is configured as a pull-up or pull-down resistor is determined by another register. Notice that the multiplexer connected to the switch is controlled by the output register, PyOUT.x. Thus, by setting PyOUT.x to 0, the resistor is connected to ground and becomes a pull-down resistor. Alternatively, setting PyOUT.x to 1 connects the resistor to power, thus becoming a pull-up resistor. Notice how the desingers have repurposed the PyOUT register in the input configuration as it is not used to hold the output value. A more appropriate but longer name for this register could have been PyOUT_RD where RD stands for Resistor Direction (either pull-up or pull-down). Nonetheless, in most cases designers avoid using long names and instead focus on creating a detailed user guide document that describes all different ways a circuit can be configured.

For a more in-depth look at the digital I/O registers and how to use them, refer to MCU user guide, chapter 12, section 2. The below table taken from that chapter summarizes basic I/O configurations based on register values. In this table, x corresponds to Don't Care, or a value that does not matter. 

 You might have realized that the pin registers have an essential role in pin configuration as well as storing the data either as input or output. The table below summarizes the list of registers in a GPIO pin and presents their functionalities. 

PU: Pull-Up resisotr, PD: Pull-Down resistor

In this chapter, we are only discussing the general-purpose input/output functionality of the pins. However, the pins can have other functions depending on the specific internal peripherals they serve. The programmer can decide what purpose the pin serves. In an analogy, you can assume the pin has multiple hats, and the programmer decided what hat the pin wears. For example, some pins can be configured to work as an analog input to the A/D converter. PySEL0 and PySEL1 are the registers that the programmer uses to specify what functionality the pin serves. When both of the PySEL values are 0, the pin is a general-purpose digital input/output. If the PySEL pair together represent 1, 2, or 3, the pin wears a different hat. They are called primary, secondary, and tertiary functions (essentially 1st, 2nd, and 3rd functionalities). These other possibilities vary based on the port and pin number and depend on the specific microcontroller model. The below table from Chapter 12 of the microcontroller manual summarizes this discussion.