2013-03-17 04:51 AM
Hi all,
I am a beginner to USB and after some days of reading USB OTG library and RM0033 in the scope of getting started with USB. I'll to try to explain the virual com port example in my own words and fore w/o garantee. The examples is the same for STM32F4xx and STM32F105/107 devices. Thanks to post your corrections/comments and suggestios by replying to this post. I will not cover the initialization and enumeration phases as it seems to be little bit complicated (for a beginner) than communication phase. The examples configures other than (EP0) the endpoints as following: - EP1: bulk IN / bulk OUT - EP2: Control INWhen sending data from terminal like application (from your host (PC)), the RXFLVL
flag (of GINTSTS register) is set and DCD_HandleRxStatusQueueLevel_ISR() is executed within USBD_OTG_ISR_Handler() In DCD_HandleRxStatusQueueLevel_ISR(): - Read OTG_HS_GRXSTSP register - check the packet status filed - if packet status is data update (PKTSTS = 0010: OUT data packet received) (defined as STS_DATA_UPDT in USB lib) * read data from FIFO USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt); When reading data from FIFO is completed, the RXFLVL flag is set again and DCD_HandleRxStatusQueueLevel_ISR() is executed within USBD_OTG_ISR_Handler() In DCD_HandleRxStatusQueueLevel_ISR(): - Read OTG_HS_GRXSTSP register - check the packet status filed - if packet status is transfer complete (PKTSTS = 0011: OUT transfer completed (triggers an interrupt)) (defined as STS_XFER_COMP in USB lib) no special processing in this case !The trasnfert complete triggers the EP1 OUT Endpoint hendler and USBD_OTG_EP1OUT_ISR_Handler()
is executed. Whithin USBD_OTG_EP1OUT_ISR_Handler(): - Read DOEPINT register - Check that xfercompl flag is set set (XFRC bit in OTG_HS_DOEPINTx register) - If so inform upper layer that data are ready and call USBD_DataOutStage() which calls pdev->dev.class_cb->DataOut(pdev, epnum) ==> usbd_cdc_DataOut() ==> VCP_DataRx() ==> USART_SendData() (==> means function call)When receiving data from external device to STM32 through USART_RX pin, the
EVAL_COM_IRQHandler() is executed which calls VCP_DataTx() which stores the received data APP_Rx_Buffer[] buffer. In usbd_cdc_SOF() which is called every SOF (125 µs in HS), check if FrameCounter is equal to CDC_IN_FRAME_INTERVAL if so call Handle_USBAsynchXfer() and this stage USB core will be aware that there are data to send over USB. In Handle_USBAsynchXfer(): - Set global variable USB_Tx_State - Configure EP1 (APP_Rx_Buffer, datalength) - Enable Tx FIFO empty interrupt source on EP1In next call of USBD_OTG_ISR_Handler(), read GINTSTS register and inepint flag
is set and DCD_HandleInEP_ISR() is executed and as EP1 has a dedicated IRQ handler the interrupt was already masked to allow the execution on OTG_HS_EP1_IN_IRQHandler()In OTG_HS_EP1_IN_IRQHandler()
- read DIEPINT register and check if Tx empty flag is set (TXFE in DIEPINT in RM0033 and emptyintr in USB lib) if so call DCD_WriteEmptyTxFifo() ==> USB_OTG_WritePacket OTG_HS_EP1_IN_IRQHandler() is triggered again with transfert complete flag set this calls USBD_DCD_INT_fops->DataInStage(pdev , 1) ==> USBD_DataInStage() ==> usbd_cdc_DataIn() which resets USB_Tx_State = 0 Thanks & Regards,
Jack Bauer
2013-03-21 02:51 AM
Nice :)
Since you have analyzed this inside out, where do you propose inserting a zero byte transfer to end a 64 byte transfer (see my bug post on this forum)? I fail to see how it could be done with a one-liner somewhere :)2013-03-21 06:04 AM