The BM version is very similar to the FreeRTOS version, but I need to make sure I have a full understanding of the Free RTOS version. As I'm looking at the code, it seems that there is more to understand than just calling "USB_DeviceHidSend" directly.
The example code (attached to this thread with the initial question) simply echoes the packet(s) received back to the PC test program. When the out-endpoint receives a packet from the PC, an interrupt is generated which eventually leads to the function "USB_DeviceHidGenericCallback" located in hid_generic.c. For ease of reference, here is the complete "USB_DeviceHidGenericCallback" code:
/* The hid class callback */
static usb_status_t USB_DeviceHidGenericCallback(class_handle_t handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_Error;
switch (event)
{
case kUSB_DeviceHidEventSendResponse:
break;
case kUSB_DeviceHidEventRecvResponse:
if (g_UsbDeviceHidGeneric.attach)
{
// Example code echo send occurs here NBG
USB_DeviceHidSend(g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_IN,
(uint8_t *)&g_UsbDeviceHidGeneric.buffer[g_UsbDeviceHidGeneric.bufferIndex][0],
USB_HID_GENERIC_OUT_BUFFER_LENGTH);
g_UsbDeviceHidGeneric.bufferIndex ^= 1U;
return USB_DeviceHidRecv(g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_OUT,
(uint8_t *)&g_UsbDeviceHidGeneric.buffer[g_UsbDeviceHidGeneric.bufferIndex][0],
USB_HID_GENERIC_OUT_BUFFER_LENGTH);
}
break;
case kUSB_DeviceHidEventGetReport:
case kUSB_DeviceHidEventSetReport:
case kUSB_DeviceHidEventRequestReportBuffer:
error = kStatus_USB_InvalidRequest;
break;
case kUSB_DeviceHidEventGetIdle:
case kUSB_DeviceHidEventGetProtocol:
case kUSB_DeviceHidEventSetIdle:
case kUSB_DeviceHidEventSetProtocol:
break;
default:
break;
}
return error;
}
The parameter passed into the variable "event" is "kUSB_DeviceHidEventRecvResponse" which is enumerated as 2 and is used in the switch-case to initiate the receive action. The first action is to call "USB_DeviceHidSend" as you have copied in your last reply. That call completes the task of sending the data out via the in-endpoint which is confirmed by the PC program initially used to send the data to the device. The next line toggles the bufferIndex presumably to prevent the next received packet from overwriting the previous packet.
Now is the interesting part. "USB_DeviceHidRecv" is called which makes sense at first. The following are called in the thread sequence:
USB_DeviceRecvRequest --> USB_DeviceTransfer --> USB_DeviceLpc3511IpRecv ... All this makes sense, but the next call is to USB_DeviceLpc3511IpSend! It does not appear to be from endpoint 0 (not control) and when this send is complete it does not show up as echoed data in the PC monitor program.
I theorized that both were included for the purpose of echoing the received data but my initial test by commenting out the first USB_DeviceHidSend call resulted in no data being echoed back to the PC.
At this point I have two questions (I'm sure more will follow):
1) Do you know the purpose of the 2nd call to the SEND procedure?
2) Rather than directly calling USB_DeviceHidSend from my application task, would it be a more appropriate/intended use of the stack to call USB_DeviceHidGenericCallback instead?