RTC Website

Programming the myRIO DIO lines

TX

The myRIO C library (section 0.5) includes facilities for programming the DIO lines. The header file DIO.h and source file DIO.c define a custom data type for configuring the DIO, a function for reading DIs, and a function for writing DOs. The reading and writing functions are implemented through FPGA interactions, but we need not understand all the details of these interactions to use the functions.

Configuring a DIO line (the myRIO C library calls this a “DIO channel”) for reading or writing requires the use of a structure defined in DIO.h:

typedef struct {
  uint32_t dir;   // DIO direction register
  uint32_t out;   // DIO output value register
  uint32_t in;    // DIO input value register
  uint8_t bit;    // Bit in the register to modify
} MyRio_Dio;

Defining an instance of MyRio_Dio effectively identifies the DIO line from which we are going to read or to which we are going to write. For instance, declaring MyRio_Dio A0 indicates that the variable A0 is going to represent a DIO line. How can we specify which DIO line? We see from the typedef of MyRio_Dio that there is a quadruple associated with each DIO line. Properly assigning these four structure tags will suffice to specify the DIO line.

There are DIO lines on each of the connectors: \(16\) on each of A and B, and \(8\) on C. As shown in figure 3.11, the A and B connectors each have two \(8\)-bit register banks corresponding to DIO pins \(0\)\(7\) and \(8\)\(15\) and the C connector has a single \(8\)-bit register bank for DIO pins \(0\)\(7\). Each bank has a register for direction (dir), output value (out), and input value (in).

 Figure 3.11
Figure 3.11: Register banks for myRIO DIO pin configuration.

Each register has a unique macro definition in the MyRio1900.h header file from the myRIO C library. The pattern is DIO<con>_<bank><reg>, where

  • <con> is A, B, or C
  • <bank> is 70 for bits \(0\)-\(7\) and 158 for bits \(8\)-\(15\)
  • <reg> is DIR, OUT, or IN

So, the register for pin 3 of the OUT register of connector A is called DIOA_70OUT. shows how to specify a given pin. For instance, the B connector’s DIO5 pin can be specified with

MyRio_Dio B5;
B5.dir = DIOB_70DIR;
B5.out = DIOB_70OUT;
B5.in = DIOB_70IN;
B5.bit = 5;

Reading a DIO line

Now that we can specify the register of a specific pin, it is time to read its value. Of course, we must begin as usual, by opening an FPGA session with MyRio_Open(). Then we are ready to use the Dio_ReadBit() function, the prototype of which is

NiFpga_Bool Dio_ReadBit(MyRio_Dio *channel);

Here, channel is the name given a DIO line of type MyRio_Dio—that is, precisely the type of pin specification that we learned to construct previously. The function reads and returns the current logical value of the DIO line from the specified register. The type that it returns is NiFpga_Bool, a uint8_t type defined in the myRIO C library’s NiFpga.h. If there is no error, Dio_ReadBit() returns either NiFpga_True or NiFpga_False, corresponding to the current logical value (true or false) of the specified DIO line.

Before reading the DIO line from the register, Dio_ReadBit() first sets the corresponding dir bit to input mode. Therefore, when reading a channel, we are implicitly directing that channel to be put into input mode. Using the same DIO5 pin of connector B specified above B5, reading its value is the simple call

NiFpga_Bool dio_B5 = Dio_ReadBit(&B5);  // read DIO5 on connector B

Note that the channel-specifier is passed as a pointer.

Writing a DIO line

The other function provided by DIO.c, Dio_WriteBit(), writes an NiFpga_Bool value to the specified DIO line. Its prototype is

void Dio_WriteBit(MyRio_Dio *channel, NiFpga_Bool value);

The first argument is the channel-specifier, and the second is the logical value, either NiFpga_True or NiFpga_False. The function writes the logical value to the bit corresponding to the channel and writes to the corresponding dir bit to ensure that the channel is in output mode.

Configuration for the target keypad

TX

The target system’s keypad has four rows of four keys. As with many keypads, no communication electronics are included. Instead, the keypad acts as an array of simple switches that connect row and column wires, and makes the ends of the wires available at the pinout. Therefore, the myRIO can provide DO signals to certain pins and detect DI signals at others (see figure 3.12).

 Figure 3.12
Figure 3.12: The keypad keys overlaid on the keypad circuit, with its connections to the myRIO B connector’s DIO lines.

In lab 3, we will develop an algorithm for detecting key presses that hinges on the idea that a key press corresponds to a switch in the keypad circuit connecting two DIO lines. This algorithm will require some DIO pins to be configured as outputs and others as inputs. After opening an FPGA session with MyRio_Open(), we can prepare to configure a DIO line by defining a MyRio_Dio structure. Let’s prepare this structure for connector B’s DIO0; according to figure 3.11,

MyRio_Dio B0;
B0.dir = DIOB_70DIR;
B0.out = DIOB_70OUT;
B0.in = DIOB_70IN;
B0.bit = 0;

Now if we want to configure connector B’s DIO0 as an input, we simply read it:

Dio_ReadBit(&B0);

Conversely, if we want to configure it as an output, we can write to it:

Dio_WriteBit(&B0, NiFpga_False);  // or NiFpga_True

In lab 3, we will need to read and write to the DIO lines repeatedly, and in a specific pattern, to detect key presses.

Online Resources for Section 3.10

No online resources.