it seems ... EP0_OUT (endpoint 0 out) does not return STALL

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

it seems ... EP0_OUT (endpoint 0 out) does not return STALL

1,170 Views
shigeuratan
Contributor II

Hi.

I'm developing some USB HID device with LPC11U35FHI33/501.
    (The marking on my chip is "0 11U35 / Z 57 02 / 4492A50")

Now I have done a 'purposely return STALL' test, but I can not make
EP0_OUT to return STALL... (maybe...)

Sorry I can't see/show direct USB bus communication because
I don't have USB bus-analyzer.
I have judged/made an analogy by behavior of PC, PC application
or pseudo USB capture result by WireShark.

I have prepared some sample to show/reproduce(*) the case.
Use USB_IRQ_Handler() below
with 'nxp_lpcxpresso_11u37_usbd_rom_hid_keyboard' sample
in lpcopen_v2_03_lpcxpresso_nxp_lpcxpresso_11u37h.zip.

(*) I hope, because mine is ported for my compiler environment.
Also rprintf() drives USART to get messages.

The USB_IRQ_Handler() hooks some selected SETUP request
and immediately terminate it with STALL.

For EP0_IN, GET_DESC/REPORT request is selected and
it (seems to) returns STALL correctly maybe against DataIN stage of
control transfer.
But for EP0_OUT, SET_REPORT request is selected and it seems not to
return STALL against DataOUT stage of control transfer.

I had tried, about for one month, to confirm codes and settings
and seek method to return STALL but I couldn't.
I had also tested 'STALL against StatusIN/StatusOUT stage' with
my USB driver, I can not return STALL against StatusOUT stage (yes EP0_OUT).

Is there something missing to make EP0_OUT to STALL ?

attachments.zip:
   | USB_IRQ_Handler.c (showed below)
   | rprintf.log
   | WireShark.pcapng
   | WireShark-exported.txt
   | summary.txt (showed below)

 

<< USB_IRQ_Handler.c >>

/*
 * Handle interrupt from USB0
 */
void USB_IRQ_Handler(void)
{
	uint32_t *addr;
	uint32_t tmp;
	uint8_t *sud;			/* setup data */
	int force_stall = 0;	/* flag to make stall */
	static int at_get_desc = 1;		/* stall by 1st GET_DESC */
	static int at_set_repo = 3;		/* stall by 3rd SET_REPO */

	if( LPC_USB->DEVCMDSTAT & _BIT(8) ) {
		/*
		 * setup packet is received
		 */

		/*
		 * WORKAROUND for artf32289 ROM driver BUG
		 */
		addr = (uint32_t *)LPC_USB->EPLISTSTART;
		addr[0] &= ~_BIT(29);		/* clear EP0_OUT stall */
		addr[2] &= ~_BIT(29);		/* clear EP0_IN stall */

		/*
		 * dump SETUP data
		 */
		tmp = addr[1];
		tmp = (tmp & 0xffff) << 6;
		tmp += LPC_USB->DATABUFSTART & 0xffc00000;
		sud = (uint8_t *)tmp;
		rprintf("@%02x.%02x.%02x.%02x %02x.%02x.%02x.%02x\r\n",
			sud[0], sud[1], sud[2], sud[3], sud[4], sud[5], sud[6], sud[7]);

		/*
		 * force stall by some request and timing
		 * tune these for your device to monitor USB bus activities
		 */
		if( (sud[0] == 0x81) && (sud[1] == 0x06) && (sud[2] == 0x00)
			&& (sud[3] == 0x22)                 && (--at_get_desc == 0)
		) {
			force_stall = 1;	/* DataIN stage of n-th GET_DESC/REPORT */
		}
		else if( (sud[0] == 0x21) && (sud[1] == 0x09)  && (--at_set_repo == 0)
		) {
			force_stall = 2;	/* DataOUT stage of n-th SET_REPO */
		}
	}

	if(force_stall) {
		/*
		 *
		 */
		LPC_USB->INTSTAT = (1<<0);		/* clear EP0_OUT request */

		/*
		 * force stall for test/debug
		 */
		rprintf("STALL_EP0()\r\n");
		if(force_stall == 2) {
			USBD_API->hw->SetStallEP(g_hUsb, 0x00);		/* set EP0_OUT stall */
		} else {
			USBD_API->hw->SetStallEP(g_hUsb, 0x80);		/* set EP0_IN stall */
		}

		/*
		 * finish this request by releasing SETUP bit
		 */
#define b0SAFE ((0x7<<24)|_BIT(8))	/* DRES_C|DSUS_C|DCON_C| SETUP */
#define b1SAFE (_BIT(17))			/* DSUS */
		tmp = (LPC_USB->DEVCMDSTAT & ~b0SAFE) | b1SAFE;
		LPC_USB->DEVCMDSTAT = tmp | _BIT(8);	/* clear SETUP bit */

	}
	else {
		/*
		 * pass this request/event to ROM driver
		 */
		USBD_API->hw->ISR(g_hUsb);
	}
}

 

<< summary.txt >>

    TEST SYSTEM
     +---------+              <-- type 'NumLock'
     |         |----[ normal USB Keyboard ]
     | win7 PC |   ==> SET_REPORT
     |         |
     |         |----[ rom_hid_keyboard / LPC11U35 ]
     |         |   ==> SET_REPORT
     +---------+
            ... SET_REPORT request, used to control LEDs, is
                broadcasted for all connected USB keyboard


   ------------------------------------------------------------------------------------------------
      time    |    action      |     "rprintf.log"             |     WireShark log      // comment
   ------------------------------------------------------------------------------------------------
   [09:54:09] | start LPC11U35 |  1:                           |
   [09:54:09] |                |  2: /*                        |
   [09:54:09] |                |  3:  * hello...(48MHz/48MHz)  |
   [09:54:09] |                |  4:  */                       |
   [09:54:09] |                |  5:                           | (#n means Frame No.)
   [09:54:09] |                |  6: FLASHTIM is: 0x0000C002   |
   [09:54:09] |                |  7: SYSAHBCLKDIV is: 1        |
   [09:54:09] |                |  8: SYSAHBCLKCTRL is: 0x0800..|  (Bus Enumeration phase might not be captured)
   [09:54:09] |                |  9: e:00000000 - LPC_OK       |  (because USB capture by WireShark is pseudo function)
   [09:54:09] |                | 10: Connect                   |
   [09:54:10] |                | 11: @80.06.00.01 00.00.40.00  |          (GET_DESC)
   [09:54:10] |                | 12: @00.05.01.00 00.00.00.00  |          (SET_ADDR)
   [09:54:10] |                | 13: @80.06.00.01 00.00.12.00  |          (GET_DESC)
   [09:54:10] |                | 14: @80.06.00.02 00.00.FF.00  |          (GET_DESC)
   [09:54:10] |                | 15: @80.06.03.03 09.04.FF.00  |          (GET_DESC)
   [09:54:10] |                | 16: @80.06.00.03 00.00.FF.00  |          (GET_DESC)
   [09:54:10] |                | 17: @80.06.02.03 09.04.FF.00  |          (GET_DESC)
   [09:54:10] |                | 18: @80.06.00.06 00.00.0A.00  |          (GET_DESC)
   [09:54:10] |                | 19: @80.06.00.01 00.00.12.00  |          (GET_DESC)
   [09:54:10] |                | 20: @80.06.00.02 00.00.09.00  |          (GET_DESC)
   [09:54:10] |                | 21: @80.06.00.02 00.00.22.00  |          (GET_DESC)
   [09:54:10] |                | 22: @00.09.01.00 00.00.00.00  |          (SET_CONFIG)
   [09:54:10] |                | 23: @21.0A.00.00 00.00.00.00  | #9,10:  SET_IDLE - Request, Response (SUCCESS)
   [09:54:10] |                | 24: @81.06.00.22 00.00.7F.00  | #11,12: GET DESC/Report - Request, Response (STALL_PID)
   [09:54:10] |  (STALL@DataIN)| 25: STALL_EP0()               |                         // STALL is recorded/sensed and
              |                |                               |        <bus reset>      // retry is started immediately
   [09:54:10] |                | 26: @80.06.00.01 00.00.40.00  |          (GET_DESC)
   [09:54:10] |                | 27: @00.05.02.00 00.00.00.00  |          (SET_ADDR)
   [09:54:10] |                | 28: @80.06.00.01 00.00.12.00  |          (GET_DESC)
   [09:54:10] |                | 29: @00.09.01.00 00.00.00.00  |          (SET_CONFIG)
   [09:54:10] |                | 30: @02.01.00.00 81.00.00.00  |          (CLR_FEATURE)
   [09:54:10] |                | 31: @81.06.00.22 00.00.7F.00  | #17,18: GET DESC/Report - Request, Response (SUCCESS)
   [09:54:11] |                | 32: @21.09.00.02 00.00.01.00  | #21,22: SET_REPORT - Request, Response (SUCCESS)
(interval 60sec)  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
   [09:55:13] | type 'NumLock' | 33: @21.09.00.02 00.00.01.00  | #23,24: SET_REPORT - Request, Response (SUCCESS)
(interval 60sec)  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
   [09:56:11] | type 'NumLock' | 34: @21.09.00.02 00.00.01.00  | #25:    SET_REPORT - Request    // Request only,
   [09:56:11] | (STALL@DataOUT)| 35: STALL_EP0()               |                                 // no response comes
(interval 60sec)  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
   [09:57:12] | RESET LPC11U35 |                               | #26:    DEV_NOT_RESPONDING    // Response of #25 is here
   [09:57:12] |                |                               | #27:    CANCELED, URB_INTERRUPT in
   [09:57:12] |                |                               |   (snipped)
   ------------------------------------------------------------------------------------------------

 

Labels (2)
0 Kudos
4 Replies

1,161 Views
FelipeGarcia
NXP Employee
NXP Employee

Hello,

I was doing some research regarding this issue and realized that there is an errata on LPC11U6x and LPC15xx that states the following: USB controller is unable to generate STALL on EP0_OUT.

I understand you are using LPC11U37 device but I am wondering if this is the same issue you are facing and it has not been documented in the appropriate errata sheet. Could you please check the following link with the description in errata 3.5. If we confirm the work-around works then I will be able to report it with the applications team to update the documentation.

https://www.nxp.com/docs/en/errata/ES_LPC11U6X.pdf

Best regards,

Felipe

0 Kudos

1,146 Views
shigeuratan
Contributor II

> there is an errata on LPC11U6x and LPC15xx that states the following:
> USB controller is unable to generate STALL on EP0_OUT.

Oh what is that! but I'm convinced, my feelings calmed down.


> I understand you are using LPC11U37 device but ...

My chip is LPC11U35/501,
"Read device Signature" command by FlashMagic also says so.
   | Device ID: 0x0000BC40
   | Bootloader Ver: 7.2


> Could you please check the following link with the description
> in errata 3.5. If we confirm the work-around works then ...

Yes, of course, EP0_IN returns STALL well against StatusIN stage
(after DataOUT stage) of Control-Write-transfer, I'd confirmed it.

The work-around simply tells to give up returning STALL on EP0_OUT...

To feed/accept all DataOUT data of unsupported/illegal Control-Write
request might be not so easy for my current USB driver structure...
If LPC11U1x or LPC11U2x don't have this problem, I want to switch to them
   (if the errata sheets are correct...)

 

Thank you, Felipe.

0 Kudos

1,120 Views
FelipeGarcia
NXP Employee
NXP Employee

Hello,

I have received information from applications team and they have confirmed that the errata "USB controller is unable to generate STALL on EP0_OUT", apply to all LPC11U1x, LPC11U2x and LPC11U3x devices. The documentation team is working on this issue. Thanks!

Best regards,

Felipe

0 Kudos

1,129 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi,

I am going to ask this internally to see if applications team can confirm this errata exists in these devices. I will give you an update as soon as I receive any feedback.

Best regards,

Felipe

0 Kudos