From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

usb event labwindow cvi problem

Hi,
I am trying to get the USB interrupt event when my USB raw out is sending data.
 
The device is proprietary, usb raw in and usb raw out only, kinda like a serial port
I know all about it
 
I have the visa tutorial working fine.
I have another example working based upon async IO event, but am unhappy because it looses data
I want to queue the responces
 
 
It appears I get an error when attempting this
 NON-FATAL RUN-TIME ERROR:   "example.c", line 31, col 10, thread id 0x00000A2C:   Function viEnableEvent: (return value == -1073807302 [0xbfff003a]). Unable to start operation because setup is invalid (usually due to attributes being set to an inconsistent state).
I have no idea why.
 
Any suggestions would be helpful.
 
I will eventually post the code as an example for CVI users
 
 
0 Kudos
Message 1 of 16
(5,099 Views)
Hello Jeffh12345:

Thank you for contacting National Instruments. Quick questions for you, which version of NI-VISA are you using?
Regards,

Roland A.
Applications Engineer
National Instruments

Check out VI Roadshow
0 Kudos
Message 2 of 16
(5,070 Views)

Hi Roland,

 

NI-Visa 4.0

 

Jeff

0 Kudos
Message 3 of 16
(5,063 Views)

Ok,

backed up a step

went into visa interactive mode from the M+A explorer

These are my settings

Timeout Value = 2000
Maximum Queue Length = 50
Termination Character = 0x0A
Termination Char Enable = VI_FALSE
IO Protocol = 1
Suppress End on Reads = VI_FALSE
USB Maximum Interrupt Size = 1
USB Control Pipe = 0x0000
USB Bulk-Out Pipe = 0x0002
USB Bulk-In Pipe = 0x0081
USB Interrupt-In Pipe = 0xFFFF
USB Alternate Setting = 0
USB Bulk-Out Pipe Status = 0
USB Bulk-In Pipe Status = 0
USB Interrupt-In Pipe Status = -1
USB End Mode for Reads = 5

Note that USB interrupt-in pipe=0xffff

From VISA help, it is required that I set it to the bulk in pipe, so I can queue responce when interrrupted.

I cannot change the value of USB Interrup-in pipe to anything other than 0xffff

Need to change it to 0x81, which is bulk in pipe

 

Get error:

VI_ERROR_NSUP_ATTR_STATE

BFFF001Eh

The specified state of the attribute is not valid, or is not supported as defined by the session, event, or find list.

 

Is there a bug? Does VISA support interrupt for bulk?

Help

 

Jeff

 

0 Kudos
Message 4 of 16
(5,056 Views)
This is not a bug, but is expected behavior.  If you are doing bulk transfers it is expected that you use viRead and viWrite with your bulk endpoint.  The VI_EVENT_USB_INTR event assumes that you are using an interrupt endpoint.

I would be interested in hearing why you would like to receive events from your bulk endpoint.  Perhaps you have an application that we did not consider in our design.

Shawn Bohrer
National Instruments
Use NI products on Linux? Come join the NI Linux Users Community
0 Kudos
Message 5 of 16
(5,016 Views)

Thanks!

 

The product we developed only has bulk in and bulk out supported.

Very simple application of usb: simulating a serial port

Packet size is limited, multiple packets sent, sometimes one right after the other.

 

I started by using the async io functions, but ran into problems when 2 packets were back to back:

The second one was missed consistantly when the async io read was set to get 64 bytes at a time.

 

When I went to 256 bytes async io read, I sometimes got double read of the first packet, sometimes missed the third packet, unreliable.

There is always some messages coming in, some need to be acknowledged. Felt that interrupt and or queue was the best way to handle.

Without interrupt / queue support, I don't think CVI is going to work for me. I do not think polling will be fast enough as there is no queue. Any suggestions?

I would suggest that you add functionallity to support interrupt or queue or callback on bulk, just like a serial port. I am currently porting over an application that was based on RS232 port to communicate over bulk endpoints on usb. It would be handy, as I could get one application to support multiple modes (TCPIP as well in the future).

Please let me know if I can help. (or if you can help me!)

Thanks,

Jeff Haynes

0 Kudos
Message 6 of 16
(5,003 Views)
What is your packet size?  Since USB is a message based bus the smallest quantity that NI-VISA can request from the device is 1 packet.  If you request to read less than a packet VISA will still request a packet from the device and will store the rest in a buffer until the next read.  In the same way if you request to read more than a packet, but less than two packets VISA will still have to request two packets and store the rest in a buffer.

Technically I don't see how you could loose packets, receive the same packet twice.  When using bulk transfers with viRead it technically does "queue" the data as I explained previously.  The only way I could see you loosing packets is if you close the session.

Perhaps another question is are you opening multiple sessions to the same device?  Perhaps in multiple threads?

Shawn Bohrer
National Instruments
Use NI products on Linux? Come join the NI Linux Users Community
0 Kudos
Message 7 of 16
(4,992 Views)

Yup,

packet size is 8-64 bytes

there is no end terminator, size embedded inside the packet header

was using async io: did not try readio

Async IO runs in a separate thread, not blocking, event completion using handler

This caused the read problems, closed after each receive io event

 

 

read was blocking, don't want to block if possible

read io seemed to have a timeout associated with it,

I did not know that readio queues

Is there any way to know how many bytes are waiting to be read? don't want to call it if there is nothing there,

Thanks,

 

Jeff

 

 

 

 

 

 

0 Kudos
Message 8 of 16
(4,981 Views)
I'm sorry what I meant to say was that VISA always requests to read a multiple of Max Packet Sized bytes.  So if your Max Packet Size is 64 bytes, and you request an 8 byte packet we still try to read 64 bytes.  If the device returns 8 bytes then we simply give you the 8 bytes.  If the device actually returns 64 bytes (which it is allowed to) then we give you 8 bytes and queue the rest.  There isn't a way to know how many bytes we have in the queue, but if we end up getting more than you asked for from a read we return VI_SUCCESS_MAX_CNT.  In my opinion you should avoid this by always asking for what you know the device is going to send.

viRead and viReadAsync should both have the same behavior.  Except of course that viRead will block, and viReadAsync won't.  Both can timeout, but you can always set an infinite timeout.

If you are using viReadAsync, you will need to handle the VI_EVENT_IO_COMPLETION event, and ensure that you check the status with viGetAttribute on VI_ATTR_STATUS.

I would also recommend that you simply open a handle to you device, and only close it when you are done and cleaning up.

Shawn Bohrer
National Instruments
Use NI products on Linux? Come join the NI Linux Users Community
0 Kudos
Message 9 of 16
(4,971 Views)

I'm sorry what I meant to say was that VISA always requests to read a multiple of Max Packet Sized bytes.  So if your Max Packet Size is 64 bytes, and you request an 8 byte packet we still try to read 64 bytes.  If the device returns 8 bytes then we simply give you the 8 bytes.  If the device actually returns 64 bytes (which it is allowed to) then we give you 8 bytes and queue the rest. 

Ok,

switched over to VI_READ, timeout is set to several seconds

Yes, I see this activity. I now have something that almost works. I no longer appear to be dropping packets.

Since my packets can be 8-64 bytes long, and multiple payloads from each packet need to be appended together, life is complicated.

 There isn't a way to know how many bytes we have in the queue, but if we end up getting more than you asked for from a read we return VI_SUCCESS_MAX_CNT.  In my opinion you should avoid this by always asking for what you know the device is going to send.

I do not know the size of the packet ahead of time, so I choose 64

I do not see a way to avoid this, and would be real nice to know if anything is in the queue and how big the queue is.

I handle this case in RS232 land using a callback:  When a character is recieved, I find out how many characters in the buffer, and transfer them to local storage until I build a data packet, then process the packet and repeat.  


viRead and viReadAsync should both have the same behavior.  Except of course that viRead will block, and viReadAsync won't.  Both can timeout, but you can always set an infinite timeout.

Investigating this, was doing it viREADASYNC without infinite timeout: gonna try again

 


If you are using viReadAsync, you will need to handle the VI_EVENT_IO_COMPLETION event, and ensure that you check the status with viGetAttribute on VI_ATTR_STATUS.

Done, but was not checking this: This status is updated when the handler completes and closes the event, correct?


I would also recommend that you simply open a handle to you device, and only close it when you are done and cleaning up.

Done

 

 

Thanks NI!

will keep ya posted

Jeff

0 Kudos
Message 10 of 16
(4,970 Views)