Hi!
Has someone experiences with ARM7 and LabVIEW connecting via USB?
I've programmed the ARM Controller and succeeded to communicate with LabVIEW. But it doesn't works solid and so, if someone know about this, it would be very kind to reply. Even if this ist not really a LabVIEW Forum.
My Problem is, that my viRead with the USBRAW in LV wouldn't communicate with my LPC2368. I can send with viWrite without any Problems, but it seems that the IN-Pipe to the HOST doesn't work fine.
But when I read out the Status, it's always fine. Even in front of the viRead, which doesn't want to receive. But it's fine. Indeed!! Fore sure it is. *grr*
So I read out the data with the 'USB-Interrupt-Event', and this works. Nearly. Not every single time, and not if I replug the USB-Connector. But I can receive, sometimes.
greeetings from germany
a) What is the endpoint type on the device, bulk or interrupt? Is it same for IN and OUT endpoint?
b) What kind of data do you send from the device? For example, - ADC data of fixed sampling rate - data stream type - Return a response when Labview VI requests - Command-Reply type
Tsuneo
Hi Tsuneo!
Thx 4 reply!
to a) I'm using an Interrupt Endpoint Type and it's the same for IN an OUT
void USB_EndPoint1 (DWORD event) { switch (event) { case USB_EVT_IN: GetInReport(); USB_WriteEP (0x81, InReport,sizeof(InReport)); break; case USB_EVT_OUT: USB_ReadEP (0x01, OutReport); SetOutReport(); break; }}
to b) I'm sending the ADC results to LabView. The Sampling Rate is not fix right now, but finally it would/should be every 1ms in Interrupt-Transfer. When the Conversion is down, it should be send to LV.
"I'm using an Interrupt Endpoint Type and it's the same for IN an OUT"
The LabView device driver for USB RAW mode doesn't support interrupt OUT endpoint (EP), just IN for interrupt. Instead, the device driver allows IN and OUT for bulk EPs.
Convert the EPs to bulk one, and test it with this LabView example.
"USB RAW Bulk Communication with LabVIEW" on NI developer zone zone.ni.com/.../3622
To convert the interrupt EPs to bulk one, it just change the endpoint descriptor, as follows.
usbdesc.c const BYTE USB_ConfigDescriptor[] = { ... /* Endpoint, Interrupt IN ---> bulk IN */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */ <--- optionally, change size (up to 64) 0x00, /* bInterval */ // <--- ignored on bulk EP /* Endpoint, Interrupt OUT ---> bulk OUT */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_OUT(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */<--- optionally, change size (up to 64) 0x00, /* bInterval */ // <--- ignored on bulk EP
"The Sampling Rate is not fix right now, but finally it would/should be every 1ms in Interrupt-Transfer."
Another point is, USB_EndPoint1() is not a good place to fill data to the IN endpoint.
USB_EndPoint1() is called - when the IN endpoint becomes empty, by sending the data OR - when the OUT endpoint is loaded by the data from LabView VI
OUT endpoint may work with USB_EndPoint1() well, but I recommend you to handle the IN endpoint in the ADC conversion-complete routine.
You may think that an interrupt IN EP is regularly polled by the host, but it is not guaranteed.
- Generic device driver doesn't poll interrupt IN EP, unless the host app read the IN pipe. HID device driver is a customized case. For HID, the device driver is coded to repeat polling. - When the interrupt IN transaction is disturbed by noise, retry occurs at the next interval (up to three times). Then, your transfer schedule is delayed by noise.
In this reason, bulk transfer is better than interrupt for absolutely periodical transfer. And keep the period on the device side.
You may think this topic interesting.
"Keil Usb example / flow control" http://www.keil.com/forum/docs/thread13257.asp
First, thx for you're Help!!!
I've found nobody right now who know something about this!! Even NI-Support didn't noticed what I want though I've written them exactly what the Problem is.
But some things I didn't understand exactly.
First: but I recommend you to handle the IN endpoint in the ADC conversion-complete routine.
What do you mean with it??
case USB_EVT_IN: GetInReport(); USB_WriteEP (0x81, InReport,sizeof(InReport));
That I have to transport the whole case USB_EVT_IN: .... in my ad_conversion Routine?? Not really, or?? Because then the USB_Event wouldn't do anything anymore, wouldn't it?
Surelly you mean USB_WriteEP() after the AD_Conversion that USB will Transmit (nearly) directly after conversion.
Second: You may think this topic interesting. "Keil Usb example / flow control"
When the HOST is doing Polling-IN Transaction why ist isn't possible http://www.keil.com/forum/docs/thread13257.asp
Indeed, it is! But what I didn't really understand is: What will I send if my USB_Evt_In isn't ready to send?
For example, if the HOST polls the device and I'm not ready to send, what will the HOST expect? Stall, AKN ?? and how cann I send it ?
Exactly I wanna do it like this: A/D_Conversion (until the buffer is full) if ( buffer == full) USB_Write_EP () But in cases that USB_EVENT_IN appears until isn't full I'm not sure what the Host expects.
"Surelly you mean USB_WriteEP() after the AD_Conversion that USB will Transmit (nearly) directly after conversion."
Yes, my words were too short, but you've exactly guessed what I want to mean, like,
"A/D_Conversion (until the buffer is full) if ( buffer == full) USB_Write_EP ()"
Thanks to your imagination!!
- Set the endpoint size (wMaxPacketSize) to 64 bytes - Fill 64 bytes buffer in the ad_conversion routine. - In this routine, when the buffer becomes full, send the buffer using USB_Write_EP ()
USB_EndPoint1() USB_EVT_IN has nothing to do. If you want to do something for USB_EVT_IN,
- Assert a TX_ready flag in USB_EVT_IN - In ad_conversion, check TX_ready flag before sending the buffer - Drop TX_ready after USB_Write_EP ()
"What will I send if my USB_Evt_In isn't ready to send?"
If TX_ready is not asserted, stop the transfer, and warn the error, for example, by lighting LED. "For example, if the HOST polls the device and I'm not ready to send, what will the HOST expect?
If the endpoint buffer is empty, the device USB engine returns NAK to the host. Host controller (hardware) repeats IN transaction, until the device returns valid DATA. When the firmware loads data to the endpoint buffer, the data is sent to the host at the next IN transaction. Unless LabView VI stops the transfer by time out, the host controller waits for the device for ever, repeating polling-IN transaction.
LabView VI requests 64xN (N=1, 2, ...) bytes data to the device. Until the device returns the requested size of the data, the Read call doesn't return and it blocks the thread execution. Therefore, this Read call should place on a separate thread from the UI thread. When a Read call finishes, unload the data to a buffer and issue another Read call immediately. The UI thread is provided the data from the buffer.
The bulk endpoint of LPC2368 has double buffer, this simple mechanism will work up to 200 Kbytes/s or so. - If you want to go more faster, place a cyclic buffer between the ad_conversion and the endpoint buffer. - If the sampling rate is much slower, reduce the endpoint size (wMaxPacketSize) and packet size.
What is the expected transfer rate (bytes/s) ?
Right now I'm not really sure about, how fast it has to be. It depends on what we wanna send and how often we'll detect the A/D Converter. Jan Axelson (USB-Book) wrote, that when the Bulk-Transfer is the only data to transfer it could be also very fast and could also reach the maximum speed.
So I believe that it can reach nearly the Maximum Speed of 1.1 for Bulk-Transfers when we we'll also use circular Buffer. Certainly is, that we'll only send with this connection & nothing else more.
Even the 200KB/s seems to be sufficient at this time.