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)
------------------------------------------------------------------------------------------------