Files
usb-6009/NI-VISA/Examples/C/Vxi-vme/LowReg.c
2024-11-01 11:47:29 -07:00

159 lines
6.1 KiB
C

/**************************************************************/
/* Low Level Register Access Example */
/* */
/* This example uses low level register functions to read the */
/* offset register of a VXI device at logical address 0. The */
/* program uses the viMapAddress function to map a window */
/* to the A16 VXI address space and then uses viPeek to read */
/* the value of this register. */
/* */
/* The general flow of this code is: */
/* Open Resource Manager */
/* Open VISA session to an instrument */
/* Map the desired VXI memory to the local processor's memory */
/* Use viPeek to read the offset register */
/* Unmap the memory */
/* Close the VISA session */
/**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "visa.h"
#define ADD_OFFSET(addr, offs) (((ViPByte)addr) + (offs))
static ViSession defaultRM;
static ViSession instr;
static ViUInt16 value, access;
static ViBusAddress offset;
static ViAddr mapped_address, address;
static ViBusSize size;
static ViStatus status;
int main (void)
{
/*
* First we must call viOpenDefaultRM to get the manager
* handle. We will store this handle in defaultRM.
*/
status=viOpenDefaultRM (&defaultRM);
if (status < VI_SUCCESS)
{
printf("Could not open a session to the VISA Resource Manager!\n");
exit (EXIT_FAILURE);
}
/*
* Note: at this point it would be proper programming procedure to
* to call viFindRsrc to find available instruments to which we can
* open a session. The viFindRsrc function returns the descriptor
* for the first of these instrument. viFindNext can then be used to
* get descriptors for the other instruments. These descriptors
* are then used to open a session to the desired instrument.
* For simplicity, we will assume there is a controller
* at Logical Address zero and open a session to this address.
*/
/*
* Now we will open a VISA session to the device at logical
* address zero. We must use the resource manager handle
* from viOpenDefaultRM. We must also use a string which will
* indicate which instrument to open. This is called the
* instrument descriptor. The format for this string can
* be found in the NI-VISA User Manual. After opening a session to the
* device, we will get a handle to the instrument which we
* will use in later VISA functions. The remaining two parameters
* in this function are reserved for future functionality.
* They are given the values VI_NULL.
*/
status = viOpen (defaultRM, "VXI0::0::INSTR", VI_NULL, VI_NULL, &instr);
if (status < VI_SUCCESS)
{
printf ("Cannot open a session to the device.\n");
viClose (defaultRM);
exit (EXIT_SUCCESS);
}
/* Now we will map a window to the A16 space containing the
* configuration registers of the device using the viMapAddress
* function. This function will use the session to the
* device we obtained using viOpen.
*/
offset = 0x0; /* read Offset register in A16 */
size = 0x40; /* we will map to all configuration registers */
status = viMapAddress (instr, VI_A16_SPACE, offset, size, VI_FALSE, VI_NULL,&mapped_address);
if (status < VI_SUCCESS)
{
printf ("Error mapping the address to local memory\n");
printf ("Make sure you have a User Window configured in VXIedit\n");
viClose (defaultRM);
exit (EXIT_SUCCESS);
}
/*
* Now we will use the viPeek16 function to read the value
* of the Offset register for the device at LA 0 which we have
* mapped to the A16 space. We will do this using the pointer
* returned from the viMapAddress function. The viPeek function
* basically just dereferences a pointer to the VXI address space.
* The Offset register is at offset 0x6, so we need to increment
* the mapped address.
*/
/*
* Now that we have mapped the window, we can use the pointer
* to read and write to registers. We could do this by directly
* dereferencing the pointer, or by using viPeekXX/viPokeXX. On
* some O/S's you will not be able to directly dereference the pointer,
* so your code is more portable if you use viPeekXX/viPokeXX. To
* find out if you can directly dereference the pointer, you can get
* a VISA Attribute. In the following code, we check to see if we
* can dereference the pointer. If that is permitted we will read
* the Offset register by a direct dereference, otherwise we call
* viPeek16. After this we call viPeek again.
*/
/* Now we will use a macro to manipulate the pointer. This */
/* macro will add the correct value to the pointer to make */
/* it point to the Offset register. */
address = ADD_OFFSET (mapped_address, 6);
viGetAttribute (instr, VI_ATTR_WIN_ACCESS, &access);
if (access == VI_DEREF_ADDR) /* can dereference the pointer directly */
{
printf ("Direct Pointer Dereference was used to read the Offset Register.\n");
value = *(ViPUInt16)address;
}
else /* must use viPeek16 */
{
printf ("viPeek16 was used to read the Offset Register.\n");
viPeek16 (instr, address, &value);
}
printf("The value read from the Offset register is 0x%hX\n", value);
/* Now do viPeek16 again in case you could dereference the pointer in the first access. */
viPeek16 (instr, address, &value);
printf ("The value read from the Offset Register using viPeek16 was 0x%hx", value);
/*
* Now we need to unmap the User Window for completeness of
* code.
*/
status = viUnmapAddress (instr);
/*
* Finally, we need to close all the VISA sessions that we
* opened
*/
viClose (instr);
viClose (defaultRM);
printf("\nHit Enter to continue.");
fflush(stdin);
getchar();
return 0;
}