High-Level Block Operations

NI-VISA

High-Level Block Operations

The high-level block operations viMoveInXX() and viMoveOutXX() have a simple and easy-to-use interface for reading and writing blocks of data residing at either the same or consecutive (incrementing) register addresses. Like the high-level access operations, the high-level block operations can detect and handle many errors and do not require calls to the low-level mapping operations. Unlike the high-level access operations, the high-level block operations do not have a direct low-level counterpart. To perform block operations using the low-level access operations, you must map the desired region of memory and then perform multiple viPeekXX() or viPokeXX() operation invocations, instead of a single call to viMoveInXX() or viMoveOutXX().

To use the block operations to access a device, you need to have the following information about the registers:

  • The address space where the registers are located. In a VXI interface, for example, the address space can be A16, A24, or A32. In the PXI bus, the device's address space can be the PXI configuration registers or one of the BAR spaces (BAR0-BAR5).
  • The beginning offset of the registers relative to the device for the specified address space.
    Note  With an INSTR Resource, you do not need to know the actual base address of the device, just the offset.
  • The number of registers or register values to access.

The default behavior of the block operations is to access consecutive register addresses. However, you can change this behavior using the attributes VI_ATTR_SRC_INCREMENT (for viMoveInXX()) and VI_ATTR_DEST_INCREMENT (for viMoveOutXX()). If the value is changed from 1 (the default value, indicating consecutive addresses) to 0 (indicating that registers are to be treated as FIFOs), then the block operations perform the specified number of accesses to the same register address.

Note  The range value of 0 for the VI_ATTR_SRC_INCREMENT and VI_ATTR_DEST_INCREMENT attributes may not be supported on all VISA implementations. In this case, you may need to perform a manual FIFO block move using individual calls to the high-level or low-level access operations.

If you are using the block operations in the default mode (consecutive addresses), the number of elements that you want to access may not go beyond the end of the device's memory in the specified address space.

In other words, the following code sample reads the VXI device's entire register set in A16 space:

status = viMoveIn16(instr, VI_A16_SPACE, 0, 0x20, regBuffer16);

Notice that although the device has 0x40 bytes of registers in A16 space, the fourth parameter is 0x20. Why is this? Since the operation accesses 16-bit registers, the actual range of registers read is 0x20 accesses times 2 B, or all 0x40 bytes. Similarly, the following code sample reads a PXI device's entire register set in configuration space:

status = viMoveIn32 (instr, VI_PXI_CFG_SPACE, 0, 64, regBuffer32);

When using the block operations to access FIFO registers, the number of elements to read or write is not restricted, because all accesses are to the same register and never go beyond the end of the device's memory region. The following sample code writes 4 KB of data to a device's FIFO register in A16 space at offset 0x10 (this offset has no special significance):

status = viSetAttribute(instr, VI_ATTR_DEST_INCREMENT, 0);
status = viMoveOut32(instr, VI_A16_SPACE, 0x10, 1024, regBuffer32);