Implementing a Custom Digital Interface with R Series Multifunction RIO

Publish Date: Jan 09, 2015 | 10 Ratings | 4.00 out of 5 | Print | 1 Customer Review | Submit your review


This tutorial is an example of how to implement a custom digital interface with LabVIEW FPGA and the related example programs can be used as a starting point for implementing any serial protocol on R Series Multifunction RIO hardware.

Table of Contents

  1. Introduction
  2. Understanding the Custom Digital Protocol
  3. Implementing the Protocol in LabVIEW FPGA
  4. Creating a Host Interface Application
  5. Conclusion

1. Introduction

Custom or proprietary digital protocols are commonly used in today's world for device or sub-system communication in everything from Aerospace to Consumer Electronics. While this often ensures hardware-timed speed and reliability, it also requires a custom digital interface to prototype and test these devices, which can involve the high development costs of custom hardware. The integrated I/O on FPGA-based Multifunction RIO (R Series) devices allows you to leverage off-the-shelf hardware to implement almost any custom digital protocol for design, control and test applications. The LabVIEW FPGA module eliminates the need for hardware design experience by compiling graphical block diagrams into routines that execute in silicon.

Figure 1: System Overview

Back to Top

2. Understanding the Custom Digital Protocol

Custom digital protocols are typically well-documented, and include information on how everything works based on byte command descriptions and timing diagrams. You first need to decide how many I/O lines are required, and how each one functions.

Since most custom digital protocols are proprietary and confidential, this tutorial will reference the serial communication protocol used by a popular gaming system to monitor the state of all buttons and joysticks on a gamepad controller.

Figure 2: Gamepad Controller

For this example protocol, there are 5 digital I/O lines that are used to serially communicate the state of each button on the controller: COMMAND, DATA, SELECT, ACK, and CLOCK.

The COMMAND line is used to send commands from the gaming console to the controller, typically asking for the controller device ID and current state of all buttons and joysticks. Each command is made up of 8 bits, or a single byte, and will be shown here in hexadecimal representation. The DATA line then sends back the requested information through a series of 8 bytes. Each byte holds information about the current state of all buttons and joysticks. The third line used is the SELECT line, which simply gets the attention of the controller by going low, and then stays low during the entire transmission, and the fourth line is the ACK line, which sends an acknowledgement from the controller to the console after every byte on the DATA line. Lastly, the CLOCK line is generated by the controller to keep all communication synchronized.

When implementing any digital communication protocol, it’s very useful to have timing diagrams to help understand how all digital lines operate.

Here’s an example of how this special serial protocol works.

Figure 3: Timing Diagram for Custom Digital Protocol

Figure 3 shows the first 5 bytes of data transmission. All values are written on the falling edge of the CLOCK line, and then read on the rising edge of the CLOCK line. The sequence begins with the SELECT line going low, and the game console sending the first byte. The COMMAND line sends the start command with a 0x01 (hexadecimal 1) which corresponds to 0000 0001 in binary. All bytes are transmitted with the least significant bit first, so the actual COMMAND output is 1000000, with one bit for every falling edge of the CLOCK line. The gamepad controller reads each bit on every rising edge of the CLOCK line and responds to the start command (0x01) by sending its device ID on the DATA line. In this example, the device ID is represented by 0x41 (hexadecimal 41) which corresponds to 0100 0001 in binary. Since all bytes are transmitted with the least significant bit first, the actual DATA output is 10000010.

The second byte sent by the game console to the gamepad controller is 0x42, which asks for the current state of all buttons and joysticks. The actual COMMAND output is 01000010, which is then answered by the controller with a series of 7 bytes that include information about which buttons are being pressed. For example, a typical response from the controller might be 0x5A 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF, where the actual bits latched-in off the DATA line would be:

01011010 11111111 11111111 11111111 11111111 11111111 11111111

The first of these bytes (0x5A) only indicates that 6 bytes that follow it will be button information bytes. Of those 6 bytes, the first two include information about digital state of all buttons, and the last four include information about the analog state of the joysticks.

After each byte (or every 8 bits) is sent, the controller also toggles the ACK line low for a single clock cycle to acknowledge the transfer of every section of data. After the final DATA byte is read, the SELECT goes back to high and the controller waits for the next sequence of commands from the game console.

Here’s the timing diagram of what a single “conversation” would look like.

Figure 4: Extended Timing Diagram for Custom Digital Protocol

Typically the custom protocol is already known, and the challenge is really a matter of implementing the interface. Now that we understand how this particular serial communication protocol works, let’s look at how this could be implemented with LabVIEW FPGA and R Series hardware.

See Also:
What Can I Do With LabVIEW FPGA?

Back to Top

3. Implementing the Protocol in LabVIEW FPGA

Figure 5: Project Explorer View

As shown by the project explorer in figure 5, the FPGA target used for this example is the USB-7856R, which features a Kintex-7 160T FPGA chip with both analog and digital I/O. 5 of the digital I/O lines on connector 1 have been added to the project and labeled as ACK, CLOCK, SELECT, COMMAND and DATA. The LabVIEW FPGA code is the file called Custom Digital FPGA and host program that runs in Windows is the file called Custom Digital Host (All example files are attached at the bottom of this document.) 

If we open up the FPGA code and look at the block diagram, here is what the graphical LabVIEW code looks like.

Figure 6: Entire block diagram for LabVIEW FPGA code

Figure 6 shows all code that is necessary to implement the custom digital protocol described in section 1. Note that all code is encapsulated by a While Loop, with the stop condition set to constantly false. This will ensure that all graphical code inside the loop will continuously execute and the program will never stop running. The best way to configure loop timing in LabVIEW FPGA, and ensure that each iteration executes at a specified rate, is to use a Sequence Structure with only a Loop Timer function in the first frame. The structure just inside the While Loop of this block diagram is a Flat Sequence Structure, and the first frame is highlighted in the following figures.

Figure 7: First Frame Highlighted on Entire Block Diagram

Figure 8: First Frame in Outer Sequence Structure

As mentioned before, the only operation in this sequence frame is the Loop Timer function, which ensures a specific delay in time between all iterations of the outer While Loop. The first time this function is called, it records the current timestamp and doesn’t wait at all until the second iteration of the loop. The delay time can be set in units of milliseconds, microseconds or even individual ticks of the compiled FPGA clock rate. Without using a Sequence Structure with the Loop Timer function, all code in the While Loop will execute twice without any delay, which can create timing issues depending on application. By inserting all code after this first frame of the sequence structure, the loop timer can guarantee a minimum loop time between all iterations. This common technique of loop timing is used two more times in this example block diagram.

Figure 9: Second Frame Highlighted on Entire Block Diagram

From the digital protocol description in section 1, we know that the first step is setting the SELECT line to false before any data is sent. This is done in the second frame of the outer Sequence Structure shown in figure 10. A FALSE constant is wired directly to the SELECT digital I/O node, to write a logical 0, or 0 volts, on the SELECT digital output line. A Wait function is also used in this frame to add a short delay and allow time for this new value to be read.

Figure 10: Second Frame in Outer Sequence Structure

We will now analyze graphical code in the third frame of the outer Sequence Structure as shown in figure 11.

Figure 11: Third Frame Highlighted on Entire Block Diagram

This last frame of the outer Sequence Structure has the majority of LabVIEW FPGA code to implement our custom digital protocol. You’ll see in figure 12 that this frame has nested For Loops and Sequence Structures to control loop timing for generating the CLOCK and COMMAND signals, while simultaneously reading the DATA line.

Figure 12: Third Frame in Outer Sequence Structure

The highlighted section of code in figure 13 shows the first frame of the outer For Loop, and that section is enlarged in figure 14.

Figure 13: First Frame Highlighted Within Outer For Loop

Figure 14: Enlarged Section Highlighted in Figure 13

The COMMAND control shown in figure 14 is a 9-element array of unsigned 8-bit (U8) numbers, each element corresponding to a byte command that is sent to the controller. From the protocol description in section 1, we know that the first two bytes need to be 0x01 (hexadecimal 1) and 0x42 (hexadecimal 42), but the other 7 bytes do not matter as they are ignored by the controller. The array data is wired to a tunnel on the For Loop structure, where it is automatically indexed with each iteration of the For Loop. Since this is a 9-element array, the For Loop executes 9 times with each iteration corresponding to a single byte of transferred data.

Directly above the COMMAND control is an initialize array function that creates an 8-element array of Booleans. This is used to hold each byte transferred from the DATA input line before it is converted to a single U8 number. Lastly, the first frame of the Sequence structure is again used to control the loop rate with a Loop Timer function. In this instance the units of time are in microseconds, but the functionality is the same as shown in figure 8. Let’s take a look at the data transfer For Loop as highlighted in figure 15.

Figure 15: Byte Transfer For Loop Highlighted Within Second Frame

The highlighted section in figure 15 contains the For Loop and Sequence Structure used to transfer bits of data two and from the game console and gamepad controller. Figure 16 shows that the For Loop will execute sixteen times by the constant 16 wired to count terminal on the top left. A Boolean shift register is initialized to FALSE and then toggled back and forth to generate the CLOCK output values. A numeric shift register is initialized by a 0 and then used to index through each bit value for DATA and COMMAND bytes to be transferred.

Figure 16: Byte Transfer For Loop With False Case Shown

Each byte of the COMMAND control is converted to an 8 element array of Boolean data which is indexed and written to the COMMAND digital output line on every false case of the Case Structure (figure 16). Figure 17 shows that When the CLOCK value goes TRUE, the True case of the Case Structure is selected and a single bit of the DATA byte is read by the DATA digital I/O node. The DATA bit from every iteration is inserted into the same initialized 8-element Boolean array that was shown in figure 14, and the value of the numeric shift register is incremented to index the next bit. Note that the same Loop Timer in the first frame technique is used to regulate the time delay between every loop iteration. This time the loop speed is terms of ticks, where a single tick corresponds to 25 nanoseconds when FPGA code is compiled at 40MHz. On the Front Panel, the clock speed is set to 80 ticks to hold the CLOCK value low for 2 microseconds and then high for 2 microseconds. This generates a total CLOCK period of 4 microseconds, or CLOCK frequency of 250 kHz.

Figure 17: Byte Transfer For Loop With True Case Shown

Once 8 bits of a single byte are written to the COMMAND output and 8 bits of a single byte are read from the DATA input, the COMMAND output line is set to true and the 8 bits in the Boolean array for DATA are converted to a single U8 number to be stored in an array of bytes. Figure 18 includes the last part few parts of the outer For Loop when the final DATA array is created that the SELECT line goes back to TRUE.

Figure 18: Last Few Operations on Block Diagram

Once the SELECT line has gone back to TRUE, all communication is over until the next time the value of SELECT changes. Figure 19 show the final block diagram of the custom digital protocol implemented in LabVIEW FPGA. This application ultimately polls the state of the game controller at a rate specified by the Loop Rate control.

Figure 19: Entire block diagram for LabVIEW FPGA code

Each of the control and indicator terminals on the block diagram correspond to a Front Panel object that acts as a register for reading and writing parameters to the FPGA chip. Figure 20 shows the Front Panel for the FPGA code explained in this example.

Figure 20: Front Panel of LabVIEW FPGA code

As shown in figure 20, the Loop Delay is set to 20ms, which means that every 20 millisecond the FPGA will query the game controller for its current state. The SELECT line will go low and 10 microseconds later the clock will start toggling and COMMAND and DATA bytes will be written and read respectively. There will be a 10 microsecond delay between each byte that is transferred and after 9 bytes the current state of the controller will be indicated by the DATA array.

See Also:
Implementing a Custom Digital Interface with R Series Multifunction RIO – Example Code

Back to Top

4. Creating a Host Interface Application

All controls and indicators on the Front Panel of a LabVIEW FPGA program correspond to registers that can be read or written to from a host interface application. The NI-RIO drive includes Host Interface functions that can be called from a LabVIEW for Windows or LabVIEW Real-Time environment, and all other operating systems can use the Measurement Hardware Driver Development Kit to do interface with the FPGA through register level programming. Below is the block diagram of a host interface application written in LabVIEW for Windows.

Figure 21: Block Diagram for LabVIEW Host Program in Windows

The first function on the block diagram opens a reference to the LabVIEW FPGA program to get access to all objects on the FPGA Front Panel (figure 20). This is how the various parameters can be set before the FPGA application actually begins to run. Step 2 writes timing and COMMAND values to registers on the FPGA, and step 3 initiates FPGA code execution. The while loop in step 4 continuously reads the current value of the DATA register, and passes those values to objects on the Host front panel. As described in Section 1, the 4th through 9th bytes of the DATA array hold information about the current state of all controls on the gamepad controller. Bytes 4 and 5 tell us which digital buttons are being pressed, bytes 6 and 7 have X and Y analog values for the right-hand joystick and bytes 8 and 9 have X and Y values for the left-hand joystick. These values are then passed to indicators on the Front Panel for visualization purposes. Figure 22 displays the front panel for this Host interface application.

Figure 22: Front Panel for LabVIEW Host Program in Windows
See Also:
Implementing a Custom Digital Interface with R Series Multifunction RIO – Example Code

Back to Top

5. Conclusion

The ability to create a custom digital interface with commercial off-the-shelf hardware can completely alleviate the time and expense of developing a custom hardware solution. Leveraging reconfigurable FPGA-based hardware provides the flexibility and performance to communicate with almost any digital protocol, and with the LabVIEW FPGA module, complex hardware engineering is abstracted out by graphical block diagrams that execute in silicon. For more information on digital communication protocol with R Series Multifunction RIO and LabVIEW FPGA, please see the related links below.

See Also:
What Can I Do With LabVIEW FPGA?
Advanced Data Acquisition Techniques with NI R Series
R Series Multifunction RIO Frequently Asked Questions (FAQ)

Related Links:
Learn More About Using R Series with Custom Digital Protocols

Back to Top

Customer Reviews
1 Review | Submit your review

Enlarged images too small  - May 9, 2007

After clicking on the various "Enlarge Image" links I get images that are still too small to see any detail. They need to be much larger. I've noticed that is a problem throughout the site, including the images of products that I want to see in more detail. Most of the enlarged images don't help at all.

Bookmark & Share


Rate this document

Answered Your Question?
Yes No