LPC43x0 Errata USBROM.1. workaround doesn't work. CDC Class returns STALL instead of ACK

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC43x0 Errata USBROM.1. workaround doesn't work. CDC Class returns STALL instead of ACK

1,218 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hr on Wed Dec 04 03:18:20 MST 2013
Hi there,

i'm working currently with the LPC4330 and the NGX-Xplorer board. I'm also using the newest LPCOpen Version 2.02. I want to have a virtual serial port over usb and the example code in the  project
ngx_xplorer_4330_usbd_rom_cdc_vcom works fine besides the problem USBROM.1 described in the Errata sheet LPC4350/30/20/10. I have several NGX-boards and all of them have the rev. A Chips on it.
The problem is that i have to get a program running which establishes a remote file system over uart. This software like some other terminal programs (for example putty) cannot connect to the VCOM port due to the bug in the ROM lib.

The workaround for the USBROM.2 problem is already included in the example. I now have a problem with the code provided in the Errata sheet for the USBROM.1 problem. I included the code provided in the sheet in the cdc_vcom.c file and it looks like this.
ErrorCode_t CDC_ep0_override_hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event) {
USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*) hUsb;
USB_CDC_CTRL_T* pCdcCtrl = (USB_CDC_CTRL_T*) data;
ErrorCode_t ret = ERR_USBD_UNHANDLED;

if(event == USB_EVT_OUT) {
if (pCtrl->SetupPacket.bmRequestType.BM.Type == REQUEST_CLASS) {
if (pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_INTERFACE) {
if ((pCtrl->SetupPacket.wIndex.WB.L == pCdcCtrl->cif_num ) || /* IF number correct? */ (pCtrl->SetupPacket.wIndex.WB.L == pCdcCtrl->dif_num)) {
pCtrl->EP0Data.pData -= pCtrl->SetupPacket.wLength;
ret = pCdcCtrl->CIC_SetRequest(pCdcCtrl, &pCtrl->SetupPacket,&pCtrl->EP0Data.pData,pCtrl->SetupPacket.wLength);
if ( ret == LPC_OK) {
USBD_API->core->StatusInStage(pCtrl); /* send Acknowledge */
}
}
else {
ret = g_defaultCdcHdlr(hUsb, data, event);
}
}
else {
ret = g_defaultCdcHdlr(hUsb, data, event);
}
}
else {
ret = g_defaultCdcHdlr(hUsb, data, event);
}
}
else {
ret = g_defaultCdcHdlr(hUsb, data, event);
}
return ret;
}


I translated the && conditions in the first if to several if statements to check what condition breaks the code. I also added the second part of the code to the cdc_vcom.c file into the vcom_init() function. The code looks like this:
ret = USBD_API->cdc->init(hUsb, &cdc_param, &g_vCOM.hCdc);
{
// Code to fix the STALL Bug in the ROM lib when requesting line breaks
// This code must be placed immediately after the call to USBD_API->cdc->init()
USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*) hUsb;
/* store the default CDC handler and replace it with ours */
g_defaultCdcHdlr = pCtrl->ep0_hdlr_cb[pCtrl->num_ep0_hdlrs - 1];
pCtrl->ep0_hdlr_cb[pCtrl->num_ep0_hdlrs - 1] = CDC_ep0_override_hdlr;



The workaround function CDC_ep0_override_hdlr is called during the establishment of a connection. So the second part of the code seems to be working. The code in the CDC_ep0_override_hdlr function has now a problem with the last conditional statement.
if ((pCtrl->SetupPacket.wIndex.WB.L == pCdcCtrl->cif_num ) || /* IF number correct? */ (pCtrl->SetupPacket.wIndex.WB.L == pCdcCtrl->dif_num))


I debuged it to that point. This conditional statement is not true at the important point of the USB_EVT_OUT because of differing interface numbers cif_num and dif_num. The pCtrl structure provides the correct interface numbers as declared in the app_usbd_cfg.h. But the data (pCdcCtrl) structure shows strange numbers. In the case of the control interface it shows a 1 but it should be a zero and in case of the data interface it shows 129 but it should be a one.

I also used the USBlyzer to look at the usb traffic and the host sends the "SetLine_Coding" request to the correct interface number. 0000h. So i don't understand why in the workaround function the data structure which is passed to it has this strange interface numbers in it.

Does anyone has an idea what to check ? Or does anyone already included the workaround code from the Errate sheet ?

Thank you in advance for any help.
Best regards

Labels (1)
0 Kudos
Reply
5 Replies

1,089 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by liaochengyi on Sat Mar 22 06:04:06 MST 2014
Hi, durgesh

Is the workaround solution can apply on LPC11u37? or is LPC11u37 needs the solution?

When I built it, I can't find the "CIC_SetRequest_t" type name?
Is it need more file?

Thank you.
BR
Chengyi
0 Kudos
Reply

1,089 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by liaochengyi on Sat Mar 22 05:40:57 MST 2014
Hi, durgesh

Is the workaround solution can apply on LPC11u37? or is LPC11u37 needs the solution?

Thank you.
BR
Chengyi
0 Kudos
Reply

1,089 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hr on Tue Dec 17 04:15:34 MST 2013
Hi durgesh,

thank you for your help. The code you provide works well for me in the example. i will now try to move it in my application.

Sorry for replying so late i wrote my post before a short holiday trip.
0 Kudos
Reply

1,089 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by durgesh on Wed Dec 04 18:31:15 MST 2013
Use the attached files which have some more checks so that the workaround doesn't effect latest silicon.
[list]
  [*] Replace cdc_vcom.c in lpcopen\applications\lpc18xx_43xx\examples\usbd_rom\usbd_rom_cdc_vcom directory
  [*] Replace usbd_cdcuser.h in lpcopen\software\lpc_core\lpc_chip\usbd_rom directory.
[/list]


An updated LPCopen will be released for LPC18xx/43xx next week which will include the fixes.
0 Kudos
Reply

1,089 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by durgesh on Wed Dec 04 14:47:15 MST 2013
Current CDC headers distributed in LPCOpen have changed little bit which is effecting the offsets in USB_CDC_CTRL_T structure. Since this bug exists only in REV A silicon of LPC43xx and LPC18xx we need to be include workaround selectively.

Use following  USB_CDC0_CTRL_T structure instead of USB_CDC_CTRL_T for REV A parts only.

typedef struct _CDC0_CTRL_T
{
  USB_CORE_CTRL_T*  pUsbCtrl;
  /* notification buffer */
  uint8_t notice_buf[12];
  CDC_LINE_CODING line_coding;

  uint8_t cif_num;                 /* control interface number */
  uint8_t dif_num;                 /* data interface number */
  uint8_t epin_num;                /* BULK IN endpoint number */
  uint8_t epout_num;               /* BULK OUT endpoint number */
  uint8_t epint_num;               /* Interrupt IN endpoint number */
  /* user defined functions */
  ErrorCode_t (*SendEncpsCmd) (USBD_HANDLE_T hCDC, uint8_t* buffer, uint16_t len);
  ErrorCode_t (*GetEncpsResp) (USBD_HANDLE_T hCDC, uint8_t** buffer, uint16_t* len);
  ErrorCode_t (*SetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t* buffer, uint16_t len);
  ErrorCode_t (*GetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t** pBuffer, uint16_t* len);
  ErrorCode_t (*ClrCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature);
  ErrorCode_t (*SetCtrlLineState) (USBD_HANDLE_T hCDC, uint16_t state);
  ErrorCode_t (*SendBreak) (USBD_HANDLE_T hCDC, uint16_t state);
  ErrorCode_t (*SetLineCode) (USBD_HANDLE_T hCDC, CDC_LINE_CODING* line_coding);

  /* virtual functions */
  ErrorCode_t (*CIC_GetRequest)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); 
  ErrorCode_t (*CIC_SetRequest)( USBD_HANDLE_T hCdc, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length);

} USB_CDC0_CTRL_T;


so the workaround function CDC_ep0_override_hdlr should be

ErrorCode_t CDC_ep0_override_hdlr(USBD_HANDLE_T hUsb, void *data, uint32_t event)
{
USB_CORE_CTRL_T *pCtrl = (USB_CORE_CTRL_T *) hUsb;
USB_CDC0_CTRL_T *pCdcCtrl = (USB_CDC0_CTRL_T *) data;
ErrorCode_t ret = ERR_USBD_UNHANDLED;

if ( (event == USB_EVT_OUT) &&
 (pCtrl->SetupPacket.bmRequestType.BM.Type == REQUEST_CLASS) &&
 (pCtrl->SetupPacket.bmRequestType.BM.Recipient == REQUEST_TO_INTERFACE) &&
 ((pCtrl->SetupPacket.wIndex.WB.L == pCdcCtrl->cif_num)  ||/* IF number correct? */
  (pCtrl->SetupPacket.wIndex.WB.L == pCdcCtrl->dif_num)) ) {

pCtrl->EP0Data.pData -= pCtrl->SetupPacket.wLength;
ret = pCdcCtrl->CIC_SetRequest(pCdcCtrl, &pCtrl->SetupPacket, &pCtrl->EP0Data.pData,
   pCtrl->SetupPacket.wLength);
if ( ret == LPC_OK) {

USBD_API->core->StatusInStage(pCtrl);/* send Acknowledge */
}

}
else {
ret = g_defaultCdcHdlr(hUsb, data, event);
}
return ret;
}

0 Kudos
Reply