lpcware

Endpoint problem with EP3_OUT when receiving data

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by andre.schmiel@ashling.com on Thu Aug 13 03:55:00 MST 2015
Hi,

I currently can communicate via Endpoint 1, 2 and 4 but have a problem receiving data via the Endpoint 3 using the LPC1837 with its USB stack.

I do see the endpoint interrupt getting triggered on the USB_EVT_OUT_NAK event but never on the USB_EVT_OUT event.

Only when I manually insert a "USBD_API->hw->ReadReqEP(pUSB->hUsb, EPC, ptyRxData->pucDataBuf, 0x400);" instruction in the interrupt handler on the USB_EVT_OUT_NAK event, I will get the USB_EVT_OUT event.

I tried to manually enable and reset the endpoint but it didn't help.

Does someone know why the USB stack doesn't automatically send the read request? What does it depend on?

This is my initialisation code:

int init_usb(uint32_t memBase, uint32_t memSize)
{
USBD_API_INIT_PARAM_T usb_param;
USB_CORE_DESCS_T desc;
ErrorCode_t ret = LPC_OK;
USB_CORE_CTRL_T *pCtrl;

/* enable clocks and USB PHY/pads */
Chip_USB0_Init();

/* Init USB API structure */
g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->usbdApiBase;

/* initialize call back structures */
memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
usb_param.usb_reg_base    = LPC_USB_BASE;
usb_param.max_num_ep      = USB_MAX_EP_NUM;
usb_param.mem_base        = memBase;
usb_param.mem_size        = memSize;
usb_param.USB_Reset_Event = ResetEvent;

/* Set the USB descriptors */
desc.device_desc      = (uint8_t *) USB_DeviceDescriptor;
desc.string_desc      = (uint8_t *) USB_StringDescriptor;
desc.high_speed_desc  = USB_HsConfigDescriptor;
desc.full_speed_desc  = USB_FsConfigDescriptor;
desc.device_qualifier = (uint8_t *) USB_DeviceQualifier;

/* USB Initialization */
ret = USBD_API->hw->Init(&g_lusb.hUsb, &desc, &usb_param);
if (ret == LPC_OK)
{
/*WORKAROUND for artf45032 ROM driver BUG:
    Due to a race condition there is the chance that a second NAK event will
    occur before the default endpoint0 handler has completed its preparation
    of the DMA engine for the first NAK event. This can cause certain fields
    in the DMA descriptors to be in an invalid state when the USB controller
    reads them, thereby causing a hang.
*/
pCtrl = (USB_CORE_CTRL_T *) g_lusb.hUsb; // convert the handle to control structure
g_Ep0BaseHdlr = pCtrl->ep_event_hdlr[0]; // retrieve the default EP0_OUT handler
pCtrl->ep_event_hdlr[0] = EP0_patch;     // set our patch routine as EP0_OUT handler

/* register WCID handler */
ret = USBD_API->core->RegisterClassHandler(g_lusb.hUsb, WCID_hdlr, &g_lusb);
if (ret == LPC_OK)
{
// register EPA interrupt handler
ret = USBD_API->core->RegisterEpHandler(g_lusb.hUsb, 2, EPA_Hdlr, &g_lusb); //EPA = 0x01 => (2 x 1)
if (ret == LPC_OK)
{
// register EPB interrupt handler
ret = USBD_API->core->RegisterEpHandler(g_lusb.hUsb, 5, EPB_Hdlr, &g_lusb); //EPB = 0x02 => (2 x 2) + 1
if (ret == LPC_OK)
{
// register EPC interrupt handler
ret = USBD_API->core->RegisterEpHandler(g_lusb.hUsb, 6, EPC_Hdlr, &g_lusb); //EPC = 0x03 => (2 x 3)
if (ret == LPC_OK)
{
// register EPD interrupt handler
ret = USBD_API->core->RegisterEpHandler(g_lusb.hUsb, 9, EPD_Hdlr, &g_lusb); //EPD = 0x04 => (2 x 4) + 1
if (ret == LPC_OK)
{
NVIC_EnableIRQ(LPC_USB_IRQ);/*  enable USB interrrupts */

/* now connect */
USBD_API->hw->Connect(g_lusb.hUsb, 1);
}
}
}
}
}
}

return ret;
}

This is my descriptor:

/* USB HSConfiguration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
ALIGNED(4) uint8_t USB_HsConfigDescriptor[] = {
/* Configuration 1 */
USB_CONFIGURATION_DESC_SIZE,/* bLength */
USB_CONFIGURATION_DESCRIPTOR_TYPE,/* bDescriptorType */
WBVAL(/* wTotalLength */
USB_CONFIGURATION_DESC_SIZE +
USB_INTERFACE_DESC_SIZE     +
4 * USB_ENDPOINT_DESC_SIZE
),
0x01,/* bNumInterfaces */
0x01,/* bConfigurationValue */
0x05,/* iConfiguration */
USB_CONFIG_BUS_POWERED,/* bmAttributes */
USB_CONFIG_POWER_MA(480),/* bMaxPower */
/* Interface 0, Alternate Setting 0, Custom Class */
USB_INTERFACE_DESC_SIZE,/* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType */
0x00,/* bInterfaceNumber */
0x00,/* bAlternateSetting */
0x04,/* bNumEndpoints */
0xFF,/* bInterfaceClass */
0xFF,/* bInterfaceSubClass */
0xFF,/* bInterfaceProtocol */
0x04,/* iInterface */
/* EPA Bulk Out Endpoint */
USB_ENDPOINT_DESC_SIZE,/* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE,/* bDescriptorType */
EPA,/* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK,/* bmAttributes */
WBVAL(512),/* wMaxPacketSize */
0xff,/* bInterval */
/* EPB Bulk In Endpoint */
USB_ENDPOINT_DESC_SIZE,/* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE,/* bDescriptorType */
EPB,/* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK,/* bmAttributes */
WBVAL(512),/* wMaxPacketSize */
0xff,/* bInterval */
/* EPC Bulk Out Endpoint */
USB_ENDPOINT_DESC_SIZE,/* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE,/* bDescriptorType */
EPC,/* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK,/* bmAttributes */
WBVAL(512),/* wMaxPacketSize */
0xff,/* bInterval */
/* EPD Bulk In Endpoint */
USB_ENDPOINT_DESC_SIZE,/* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE,/* bDescriptorType */
EPD,/* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK,/* bmAttributes */
WBVAL(512),/* wMaxPacketSize */
0xff,/* bInterval */
/* Terminator */
0/* bLength */
};

This is how the PC reads the descriptors:

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x01 (Direction=OUT  EndpointID=1)
bmAttributes             : 0x02 (TransferType=Bulk)
wMaxPacketSize           : 0x200 (max 512 bytes)
bInterval                : 0xFF (at most 1 NAK each 255 microframes)

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x82 (Direction=IN  EndpointID=2)
bmAttributes             : 0x02 (TransferType=Bulk)
wMaxPacketSize           : 0x200 (max 512 bytes)
bInterval                : 0xFF (at most 1 NAK each 255 microframes)

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x03 (Direction=OUT  EndpointID=3)
bmAttributes             : 0x02 (TransferType=Bulk)
wMaxPacketSize           : 0x200 (max 512 bytes)
bInterval                : 0xFF (at most 1 NAK each 255 microframes)

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x84 (Direction=IN  EndpointID=4)
bmAttributes             : 0x02 (TransferType=Bulk)
wMaxPacketSize           : 0x200 (max 512 bytes)
bInterval                : 0xFF (at most 1 NAK each 255 microframes)

Outcomes