Programming the myRIO DIO lines
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
).
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>
isA
,B
, orC
<bank>
is70
for bits \(0\)-\(7\) and158
for bits \(8\)-\(15\)<reg>
isDIR
,OUT
, orIN
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.dir = DIOB_70DIR;
B5.out = DIOB_70OUT;
B5.in = DIOB_70IN;
B5.bit = 5; B5
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
(MyRio_Dio *channel); NiFpga_Bool Dio_ReadBit
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
= Dio_ReadBit(&B5); // read DIO5 on connector B NiFpga_Bool dio_B5
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
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).
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.dir = DIOB_70DIR;
B0.out = DIOB_70OUT;
B0.in = DIOB_70IN;
B0.bit = 0; B0
Now if we want to configure connector B’s DIO0 as an input, we simply read it:
(&B0); Dio_ReadBit
Conversely, if we want to configure it as an output, we can write to it:
(&B0, NiFpga_False); // or NiFpga_True Dio_WriteBit
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.