Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Linux VISA 3.4 viEnableEvent() fails with VI_ERROR_INV_SETUP

I'm trying to attach an event handler to service interrupts generated by a PCI device.
 
I can successfully installed the handler:
viInstallHandler(m_SessHandle, VI_EVENT_PXI_INTR, m_EventHandler, this) results in VI_SUCCES.
However,
viEnableEvent(m_SessHandle, VI_EVENT_PXI_INTR, VI_HNDLR, VI_NULL) results in VI_ERROR_INV_SETUP.
 
The documentation in the NI-VISA Programmer's Reference Manual isn't much help.  The only description of the error is:
"Unable to start write operation because setup is invalid (due to attributes being set to an inconsistent state)."
 
I can successfully read and write registers to and from BAR0 of the device (i.e. viOut16, viIn16, etc work fine).  If I scan the PCI bus (lspci -vv)I can see that the config space of the device does report that the interrupt (A) is mapped to IRQ5 in this case.
 
I'm developing under Linux using NI-VISA 3.4.
 
Does anyone know what condition(s) can cause this error or know what the problem may be?
0 Kudos
Message 1 of 10
(5,391 Views)
Hi Matt,

I do not have an exact answer to your questions, but I have some ideas you could try. 

1. Replace VI_HNDLR with VI_QUEUE and see if the error is still generated.  This will help us identify whether the problem is related to the Event Handler, or some other aspect of the system.

2. Try creating a very small program which does nothing more than open the resource, install the event handler, and enable the event handler.  This will eliminate the possibility that something else in your application is generating the problem.  If you still experience the same error, post your code to the forum here so that we can see the whole sequence you are using.  I expect that the code for an application such as this shouldn't be more than 50 lines or so.
0 Kudos
Message 2 of 10
(5,375 Views)
Have you tried that INF file and hardware on a Windows machine? Again we just want to narrow the problem down.

-Josh
0 Kudos
Message 3 of 10
(5,370 Views)
Hi Jason,
 
Thanks for your suggestions.
 
1.  I tried that very early on.  It fails with the same error code, 0xbfff003a.
 
2.  I simplified things to a simple app as you suggested and I get the same failure.  Code is pasted below:
 
#define NIVISA_PXI
#include <visa.h>
#include <stdio.h>
#include <unistd.h>
ViStatus _VI_FUNC InterruptHandler(ViSession /*vi*/, ViEventType /*eventType*/, ViEvent /*context*/, ViAddr /*userHandle*/)
{
 printf("Received an interrupt\n");
 
 return VI_SUCCESS;
}
int main(int argc, void* argv[])
{
 ViSession      RmSessHandle;
 ViSession      SessHandle;
 ViStatus       status;
 
 if ((status = viOpenDefaultRM(&RmSessHandle)) != VI_SUCCESS)
  printf("Failed to get the VISA default resource manager: %08x\n", status);
 
 if ((status = viOpen(RmSessHandle, "PXI0::17::INSTR", VI_NULL/*OpenAccessMode*/, 1000/*OpenTimeout*/, &SessHandle)) != VI_SUCCESS)
  printf("Failed to open a VISA session: %08x\n", status);
 else
 {
  // setup interrupt handling
  if ((status = viInstallHandler(SessHandle, VI_EVENT_PXI_INTR, InterruptHandler, 0)) != VI_SUCCESS)
   printf("Failed to install interrupt handler: %08x\n", status);
  else if ((status = viEnableEvent(SessHandle, VI_EVENT_PXI_INTR, VI_HNDLR, VI_NULL)) != VI_SUCCESS)
   printf("Failed to enable interrupt event: %08x\n", status);
  else
   printf("Successfully installed interrupt handler and enabled IRQ events\n");
 }
 
 while (1)
 {
  usleep(10000);
 }
 
 return 0;
}
0 Kudos
Message 4 of 10
(5,347 Views)

Hi Josh,

That is a very good suggestion.  If all else fails I may spend some time going that direction.  Also, I've pasted my inf file below...maybe there is a problem with it?  I know the device ID looks suspicious, but yes, it's supposed to be 0x1234.

[Version]
Signature=$WINDOWS NT$
Class=visaPxiDevice
ClassGUID={E1590550-9B9C-11d3-A250-0040055732CC}
ClassName="visaPxiDevice"
Provider=%Vendor0%

;===========================================================================
;   Default Installer
;===========================================================================

[DefaultInstall]
CopyFiles=Af1234.Cfg.CopyFiles.Inf

[DestinationDirs]
Af1234.Cfg.CopyFiles.Inf = 17

[Af1234.Cfg.CopyFiles.Inf]
Af1234.inf

;===========================================================================
;   Class Installer
;===========================================================================

[ClassInstall32]
AddReg=AddClassToRegistry

[ClassInstall]
AddReg=AddClassToRegistry

[AddClassToRegistry]
HKR,,,0,%DeviceClassString%

;===========================================================================

[ControlFlags]
ExcludeFromSelect=PCI\VEN_146A&DEV_1234
ExcludeFromSelect=PCI\VEN_146A&DEV_1234&SUBSYS_00000000&REV_00

;===========================================================================

[Manufacturer]
%Vendor1%=PCIList

;===========================================================================
;   PCI Plug and Play Devices
;===========================================================================

[PCIList]
%Af1234.DeviceDesc%=Af1234.Cfg,PCI\VEN_146A&DEV_1234
%Af1234.DeviceDescN%=Af1234.Cfg,PCI\VEN_146A&DEV_1234&SUBSYS_00000000&REV_00

;===========================================================================

[Af1234.Cfg]
AddReg=Af1234.AddReg

[Af1234.Cfg.Services]
AddService=nipalk, 0x00000002, nipal_Service_Inst

[Af1234.AddReg]
HKR,,DeviceClass,1,72,65,73,75
HKLM,"SOFTWARE\National Instruments\Common\NI-PAL Database\NI-VXI\PCI\146A1234","HowToSquelch",0,""
HKLM,"SOFTWARE\National Instruments\Common\NI-PAL Database\NI-VXI\PCI\146A1234","EmergencyDisarm",0,""
HKLM,"SOFTWARE\National Instruments\Common\NI-PAL Database\NI-VXI\PCI\146A1234","IsThisMine0",0,"C16 BAR0 0x0000000C 0x1000 0x1000;"
HKLM,"SOFTWARE\National Instruments\Common\NI-PAL Database\NI-VXI\PCI\146A1234","numIsThisMineEntries",0x00010001,1
HKLM,"SOFTWARE\National Instruments\Common\NI-PAL Database\NI-VXI\PCI\146A1234","ManufName",0,"Aeroflex"
HKLM,"SOFTWARE\National Instruments\Common\NI-PAL Database\NI-VXI\PCI\146A1234","ModelName",0,"HCB-PC104"
;===========================================================================

[nipal_Service_Inst]
DisplayName   = %nipal.SvcDesc%
ServiceType   = 1         ;SERVICE_KERNEL_DRIVER
StartType     = 0         ;SERVICE_BOOT_START
ErrorControl  = 1         ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\nipalk.sys
;===========================================================================

[Strings]
Vendor0="Aeroflex"
Vendor1="Aeroflex"
Af1234.DeviceDesc="HCB-PC104"
Af1234.DeviceDescN="HCB-PC104"
DeviceClassString="NI-VISA PXI Devices"
nipal.SvcDesc="NI-PAL Driver"

0 Kudos
Message 5 of 10
(5,341 Views)
I noticed that in your INF file you had the subsystem vendor and subsystem product ID set to zero. One "interesting" thing about VISA is that if your device has non-zero subsystem ID's the device will be detected, but you will not be able to use interrupts. Trust me that there is a valid reason for this, but it would take a very long time to explain. Can you check to see that your subsystem ID's are not zero. I could tell you very quickly if you INF file matches your device if you could post a print out of your "lspci -nxv".

-Josh
0 Kudos
Message 6 of 10
(5,344 Views)
Josh, here is the PCI scan you ask for.  From this, should I set the subsystem vendor ID to 0x146A and subsystem device ID to 0x0000?
 
other stuff...
0000:00:11.0 0000: 146a:1234
        Subsystem: 146a:0000
        Flags: bus master, medium devsel, latency 32
        Memory at e0040000 (32-bit, non-prefetchable) [size=4K]
00: 6a 14 34 12 06 00 00 02 00 00 00 00 00 20 00 00
10: 00 00 04 e0 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 6a 14 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
0 Kudos
Message 7 of 10
(5,334 Views)
Josh, this is a board the we (Aeroflex) build in-house.  If making the subsystem device ID non-zero will address this issue I will have it changed to 0x1234 also.  I'll try it and post the result.  Thanks.
0 Kudos
Message 8 of 10
(5,327 Views)
The main thing you probably would need to do for now is re-run the VISA driver development wizard and check the box that says uses subsystem IDs and set the Manufacturer subsystem ID to 146a. You can leave the other one zero to match your device. However, I think the PCI spec recommends that you set both to something non-zero and then you would need to set that in the wizard as well.

-Josh
0 Kudos
Message 9 of 10
(5,323 Views)

Bingo!  Interrupts are working fine now.  Thanks for all your help Josh and Jason.

-Matt

0 Kudos
Message 10 of 10
(5,310 Views)