cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-f439zi, Device Descriptor Request Failed, USB_OTG_FS from scratch

Stratosstratos
Associate

Hello

We are using the Nucleo-f439zi (STM32F439ZITbu microcontroller) https://www.st.com/resource/en/reference_manual/dm00031020-stm32f405-415-stm32f407-417-stm32f427-437-and-stm32f429-439-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf

We have set up the Nucleo in device mode for USB_OTG_FS, we are able to receive setup packets through the FIFO and read them but when we try to reply to the Device Descriptor request, even though it seems like everything is correct (size to send out packet is 0x12, pointer to the 0x50001000 FIFO address and simplest device descriptor matrix, even though XFRC bit in DIEPINT0 gets set to signal the transfer complete.

The order of events is :

  1. The device gets physically connected to the host
  2. Host sends setup packet
  3. The device reads the FIFO and stores the setup packet.
  4. when setup phase is done (DOEPINT_STUP interrupt triggered) the device reads the setup packet and checks to see if it is a Device Descriptor Request (DDR), which it is.
  5. If it is a DDR then it writes the Device Descriptor to the FIFO and sets the CNAK and EPENA bits for the IN endpoint 0 (Function USB_OTG_Send_IN_Packet ).
  6. The XFRC interrupt gets triggered for IN endpoint 0 signaling that the Transfer Completed.
  7. The host resends the setup packet for a total of 3 to 4 tries and after that the device appears as a Device Descriptor Request Failed in Device Manager.

The host (windows 11 PC) still presents the Device Descriptor Request Failed after about 30 seconds.

Why doesn't the Device Descriptor Request get to the host ? It would be expected to be received by the host and a set address failed to be appeared on Device Manager .
The above mentioned function:

 

void USB_OTG_Send_IN_Packet(uint8_t n/*endpoint*/, uint16_t length) {
//PAGE 1368 IN data transfers  Packet 
	USB_OTG_FS_DIEPTSIZ0 = ( 1 << USB_OTG_DIEPTSIZ_PKTCNT_Pos);
	USB_OTG_FS_DIEPTSIZ0 |= (/*length*/0x12 & USB_OTG_DIEPTSIZ_XFRSIZ);
// Wait until the IN endpoint is ready (TxFIFO not full)
while ((USB_OTG_FS->GINTSTS & USB_OTG_GINTSTS_PTXFE) != USB_OTG_GINTSTS_PTXFE){}
//1
while ( USB_OTG_DIEPINT_TXFE == 0x0){}
if(lock==0){ lock=1;
//-----------------TIFO--------------------------------------------
		volatile uint32_t* tifo;
		   tifo=&USB_OTG_FIFOTX ;
		   //----------------------------
		   for (uint8_t ii=0; ii<5;ii++){
			  // USB_OTG_FIFOTX=descdata[ii*4];
			  *tifo = descdata[ii]; //change to ii

				   tifo++;}
		   lock=0;
}else{lock=0;}
//2    // Enable the endpoint to transmit IN data
   USB_OTG_FS_DIEPCTL0 |= USB_OTG_DIEPCTL_CNAK ; // Clear NAK
   USB_OTG_FS_DIEPCTL0 |= USB_OTG_DIEPCTL_EPENA; // MODIFY BEFORE ENABLING
}

 

I am also attaching the whole project.

0 REPLIES 0