How to Use a Chip Object as Part of the MHDDK

Publish Date: Feb 07, 2018 | 0 Ratings | 0.00 out of 5 | Print | Submit your review

Overview

This tutorial explains how to program a device using Chip Objects.

Table of Contents

  1. Introduction
  2. Compiling a Chip Object
  3. Acquiring a Chip Object
  4. Accessing Registers with a Chip Object
  5. Why use a Chip Object
  6. Additional Resources

1. Introduction

A Chip Object is a C++ class which simplifies register level programming (RLP). Chip Objects are part of the Measurement Hardware Driver Development Kit (MHDDK) and make RLP easier. They  treat each register as a collection of register fields, and let the RLP example or driver read and write register fields instead of manually calculating hexadecimal register values. This document gives a cursory overview of using a Chip Object.

 

 

Back to Top

2. Compiling a Chip Object

Chip Objects link to a tAddressSpace and the device's iBus. There are several iBus examples already made (including Windows, Linux, and others), so you may not need to make an iBus for your target OS platform.  If you need to make an iBus, refer to How to Make an iBus.

Chip Objects rely heavily on inline function calls. They have been compiled with Visual C++ 9.0 and GCC, however they use C++ features conservatively and should compile on most other C++ compilers.  GCC 2.96 inefficiently compiles inline functions, while later versions compile inline functions much faster while using much less memory.  If a Chip Object takes several minutes to compile, consider upgrading to a newer version of the compiler.

 

Back to Top

3. Acquiring a Chip Object

A Chip Object needs both an iBus and a tAddressSpace. An iBus tells it which board to use, and the tAddressSpace tells it which BAR to use:

iBus* bus = NULL;
tAddressSpace deviceSpace;
t671x* board = NULL;

bus = acquireBoard("PXI::7::4::INSTR");
deviceSpace = bus->createAddressSpace(kPCI_BAR1);
board = new t671x(deviceSpace);

Several Chip Objects can be used together as long as they don't talk to the same registers on the device.  For instance, a PCI-6602 has two TIO ASICs (one at offset 0x000, the other at offset 0x800).  Each TIO can have its own Chip Object:

deviceSpace = bus->createAddressSpace(kPCI_BAR1);
tio = new tTIO(deviceSpace);
tio2 = new tTIO(deviceSpace);
tio2.setAddressOffset(0x800);

The Chip Object should be deleted once all register accesses are finished:

delete board;
bus->destroyAddressSpace(deviceSpace);
releaseBoard(bus);

 

Back to Top

4. Accessing Registers with a Chip Object

Chip Objects provide four methods for each register field. They can also work with an entire register, instead of just one field at a time.

readFieldName();
Reads the register from the device, saves the value of the register in a "soft copy" for later reference, and returns the value of the field.

softcopy = read(registerAddress);
return desired_field_of_softcopy;

writeFieldName(value);
Reads the "soft copy" of the register, sets the specified field of the "soft copy" to the new value, then writes the value to the device.

softcopy = softcopy & FieldMask;
softcopy = softcopy | (value << FieldShift);
write(registerAddress, softcopy);

getFieldName();
Reads the "soft copy" of the register and returns the specified field.

return desired_field_of_softcopy;

setFieldName(value);
Reads the "soft copy" of the register, and then sets the specified field of the "soft copy" to its new value.

softcopy = softcopy & FieldMask;
softcopy = softcopy | (value << FieldShift);

 

There are three ways to program a register with more than one field:

    1. Fastest (one bus access, but least readable):

      board->RegisterName.writeRegister(RegisterValue);

    2. Fast (one bus access, but two memory accesses):

      board->RegisterName.setFieldName(FieldValue);
      board->RegisterName.setOtherField(OtherValue);
      board->RegisterName.flush();


      flush() writes the soft copy to the register on the device.
    3. Slowest (two bus accesses, but most readable):

      board->RegisterName.writeFieldName(FieldValue);
      board->RegisterName.writeOtherField(OtherValue);

Strobe bits and fields are cleared from the softcopy after they are written to the device, which avoids writing the strobe bits every time the register is accessed.

 

Back to Top

5. Why use a Chip Object

    1. A Chip Object is a debugged interface to the device's registers.  Chip Objects abstract windowed accesses, register sizes, strobe bits, and register soft copies.  A Chip Object removes the possibility of these very common RLP errors, reducing development time and time spent troubleshooting these bugs both for you and for National Instruments. These errors are very common, even for experienced driver developers.
    2. Chip Objects provide fast, safe access to register fields. Chip Objects are fast because they are inline functions which can be optimized by the compiler. Register field sizes are enforced, so a write to one field can not overlap another field in a register.
    3. Chip Objects are readable, so the programmer spends time learning the hardware register interface instead of calculating hexadecimal register values.

 

Back to Top

6. Additional Resources

Back to Top

Bookmark & Share


Ratings

Rate this document

Answered Your Question?
Yes No

Submit