10-25-2013 09:49 AM
Hi all;
I have downloaded the USB MCU library from the NI website to communicate between LabVIEW and the Silicon Labs USBXpress dll. This seems to be the library written to handle USBXpress from LabVIEW, but I am not getting the read and write VIs to work properly, because of the "buffer" input and outputs. The VIs have the Call Library Function "buffer"configured as u32 numeric passed by value, when I want to send or receive strings. There is a byte count input/output where I should be able to tell the dll how big my strings are or will be, but the u32 is not the sort of input to handle the strings. The app note from Silicon Labs says the "buffer" should be the address of a character buffer, so I think the Call Library Function is configured wrong, but want advice on how to properly configure it, since I don't do that very often.
bj
10-28-2013 11:11 AM
Hello, bjlv
When you run the Read/Write VIs, do you receive an error or does the fuction just not return any data? And if there is an error, what error code do you receive?
If you think it is just the configuration of the Call Library Fucntion Node that is incorrect, you can double-click the node to bring up the properties dialog. In the window that appears, select the parameters tab to see a list of all of the inputs and outputs that node is configured for. From there, you can select the buffer input and change its input type from U32 to a string.
Hope that helps,
Ryan
10-28-2013 12:15 PM
HI Ryan:
I have not run the code, because I wanted to wire a string to the input named "buffer", but it is not configured to accept a string. Knowing what I should change the property to so I could wire a string to it was exactly my question. I will try it as a string instead of a u32 and see how far I get. I will have to change this on both the Read and Write VIs, as they both have this configuration error. I was a bit surprised to find a mistake like this on a package of VIs written by an NI employee, but based on what I found, the package was written without any USBXpress device on hand, just the Silicon Labs App Note about them. There could not have been any testing done, since it is completely obvious that you can't wire a string to a u32 input or output.
bj
10-30-2013 01:41 PM
Hi Ryan:
I have made the configuration change to string for the Read, Write, and several other VIs in this library. There is one function for which this is working, but the Read and Write functions do not work. The Write function returns with an error message from the DLL that says "IO Pending", which means nothing to me. I know the device has not received the string I tried to send, because it has not reacted to that command. The worse one is the Read function, which crashes LabVIEW every time. I have tried some of the other configuration options besides string with "C string Pointer" as the string format, but they all crash the Read and never send the command from a Write. It sure seems like "C string pointer" should be correct, as a different function of the DLL does successfully get a string back when configured this way. The difference is the function that works does not want a number of bytes to read input, which the Read function (and similarly, the Write also supplies) does want. The other difference is the Read and Write functions have inputs that are supposed to be a pointer that controls if the IO is synchronous or not. Sending a NULL pointer should be the default to get synchronous IO, which would be fine. I am setting that input to 0 which might not be a NULL pointer but if I need that to be NULL, what do I wire up? Do you have any ideas what I might try to do differently to get these function to work?
bj
10-31-2013 12:02 PM
Hey, bjlv
Here's a link to a KB dicussing the process of sending a NULL pointer to an external DLL:
http://digital.ni.com/public.nsf/allkb/B86515E47C330E3086256E7E005DD109?OpenDocument
You appear to be correct in that sending a zero Int32 is the typical way this is done, which is why the Read and Write functions have an Int32 as the input for that parameter. I also found some documentation for the USBXpress DLL itself that documents and describes the inputs and outputs of each function. Here's the link:
https://www.silabs.com/Support%20Documents/TechnicalDocs/an169.pdf
The data types for the parameters of the Read and Write functions as well as the fuction declaration as listed in the document are:
SI_STATUS SI_Read (HANDLE Handle, LPVOID Buffer, DWORD NumBytesToRead,
DWORD *NumBytesReturned, OVERLAPPED* o = NULL)
1. Handle—Handle to the device to read as returned by SI_Open.
2. Buffer—Address of a character buffer to be filled with read data.
3. NumBytesToRead—Number of bytes to read from the device into the buffer (0–64 kB).
4. NumBytesReturned—Address of a DWORD which will contain the number of bytes actually
read into the buffer on return.
5. (Optional)—Address of an initialized OVERLAPPED object that can be used for asynchronous
reads.
If you go to page 28 in that document, there is a typedef for the buffer's LPVOID to be of type 'void far'. So the buffer parameter needs to be received by the DLL as a void far. LabVIEW cannot natively export that type without the use of a C Wrapper, which is a compatibility DLL to interface between LabVIEW and a 3rd-party DLL. Most likely LabVIEW exports a U32 to the C Wrapper DLL and then that DLL sends the appropriate command to the USBXpress DLL. Here are some Knowledge Base articles that discuss this topic:
http://ae.natinst.com/public.nsf/web/searchinternal/06ecdc689dda0f3d862574440074cd95?OpenDocument
http://ae.natinst.com/public.nsf/web/searchinternal/89165ede5031c68686257b2e0006fe99?OpenDocument
Regards,
Ryan
11-01-2013 09:06 AM
Hi Ryan:
I had read the an169 document when I started this project, but I have to say my C is rusty enough that I don't understand everything it describes. The biggest mystery to me is why in SI_GetProductString the type LPVOID works just fine when configured for a LabVIEW string, but in the SI_Read function the same type configured the same way crashes LabVIEW. The SI_GetProductString function has no byte count and no "o" pointer, features of the SI_Read function that are different. I successfully get a string back from SI_GetProductString but I don't from SI_Read. I have also tried using byte arrays in the CLF configuration, since it seems likely to me that I will have NULLs in my binary data stream from the device I am trying to talk with, and not all of those tries have led to crashes, but I still have never seen data returned. I will look into getting some C help to try to map a LabVIEW string to a "void far" in a wrapper dll but am curious about the * that is added on page 28 of an169. Doesn't that change it from LPVOID to pointer to LPVOID?
bj
11-04-2013 01:32 PM
Hi Ryan:
I have gotten the SI_Read function to work finally. The key was to send as input a "buffer" that was at least as large as the string I was trying to read (although I am actually using u8 arrays here) If that "buffer" input was not wired, and therefore was an empty string or array, the dll would cause LabVIEW to crash. Now I just have to figure out why the SI_Write function still has the device I am communicating with ignoring what I write to it. I am no longer getting the "IO Pending" error message, but I am also not getting the device to take the action I am trying to trigger with the write. The key to getting rid of the "IO Pending" message was to reconfigure the "o" input from pointer to value so that wiring in a value of 0 was interpreted as a NULL pointer, and thus a synchronous write. Something is still wrong, but I am closer.
bj
11-04-2013 07:29 PM
bjlv,
I'm glad to hear you got the Read function fixed. So I assume you tried to wire the buffer input on the Write fucntion similiary to the Read function without any success?
Ryan
11-05-2013 03:18 PM
Hi Ryan:
Yes, the SI_Write is wired and configured as much like the SI_Read function as possible. I need to get back to this tomorrow to see if I can find out why the hardware on the other end is ignoring me. It might be not getting the message, or it might be getting it but not liking it. More debugging to try to learn what is happening. Thanks for the continued interest. When I have it all working, you will have to help me with getting the original code I got from the NI website replaced so the next LabVIEW user doesn't have to go through all this again.
bj
11-06-2013 03:52 PM
bjlv,
I would like to help you resolve this as well. Please update me once you've checked the hardware. I'll also look into what needs to be done to update the USB MCU library.
Thank you,
Ryan