cancel
Showing results for 
Search instead for 
Did you mean: 

USB HS problem when enable DMA for video stream

MKing
Associate III

Hi,

i created a project to connect the STM32F407VGTX by USB High Speed to a PC. It is enumerated as a Camera in the device manager. When start the windows camera app or VLC the videostream (Format MJPEG 400x240 pixel) starts. I use two picture toggeling. I can close and open the camera app without any problem when DMA is disabled (usb_otg.c):

hpcd_USB_OTG_HS.Init.dma_enable = DISABLE;

 

Problem:

When I enable the DMA:

hpcd_USB_OTG_HS.Init.dma_enable = ENABLE;

 It works only the first time. When the camera app is closed and start again it seems that the messages are not send.

 

Here a link to the complete project:

mkoenig334455/USB_Video_MJPEG: USB_Video_STM32F407VGTX_MJPEG example USB and VIDEO class (github.com) 

I attached the Wireshark file so you can see the commmunication.

Thanks a lot for your help!

 

STM32F407VGTX

PHY USB3310

STM32CubeIDE Version: 1.14.0

STM32CubeMX Version 6.10.0

 

1 ACCEPTED SOLUTION

Accepted Solutions
MKing
Associate III

Update:

I use the UVC which is included in the package: AL94.I-CUBE-USBD-COMPOSITE

When the camera app will be closed the NAK bit in the OTG_HS_DIEPINTx register will be set and the IISOIXFR bit in the OTG_HS_GINTSTS register.

So I guess when camera app start again the dma will not send because of the NAK bit. I have to reset the registers when I detect the stop and execute a reinitialization.

 

usbd_video.c

 

    case USB_REQ_SET_INTERFACE:
      if (pdev->dev_state == USBD_STATE_CONFIGURED)
      {
        if (req->wValue <= USBD_MAX_NUM_INTERFACES)
        {
          hVIDEO->interface = LOBYTE(req->wValue);
          if (hVIDEO->interface == 1U)
          {
            /* Start Streaming (First endpoint writing will be done on next SOF) */
            (void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
            hVIDEO->uvc_state = UVC_PLAY_STATUS_READY;
            sofcnt++;
            USBD_VIDEO_SOF(pdev); //user modify -> start the image data transfer
          }
          else
          {
            /* Stop Streaming */
        	if (hVIDEO->uvc_state == UVC_PLAY_STATUS_STREAMING)//user modify
             cntrestartusb = 1;//user modify
            hVIDEO->uvc_state = UVC_PLAY_STATUS_STOP;
            (void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
          }

 

 

 

main.c

 

  while (1)
  {
	  if (cntrestartusb)
	  {
		  cntrestartusb--;
		  USBD_VIDEO_DeInit(&hUsbDevice,0); //user modify
		  USBD_VIDEO_Init(&hUsbDevice,0); //user modify
	  }

 

 

View solution in original post

1 REPLY 1
MKing
Associate III

Update:

I use the UVC which is included in the package: AL94.I-CUBE-USBD-COMPOSITE

When the camera app will be closed the NAK bit in the OTG_HS_DIEPINTx register will be set and the IISOIXFR bit in the OTG_HS_GINTSTS register.

So I guess when camera app start again the dma will not send because of the NAK bit. I have to reset the registers when I detect the stop and execute a reinitialization.

 

usbd_video.c

 

    case USB_REQ_SET_INTERFACE:
      if (pdev->dev_state == USBD_STATE_CONFIGURED)
      {
        if (req->wValue <= USBD_MAX_NUM_INTERFACES)
        {
          hVIDEO->interface = LOBYTE(req->wValue);
          if (hVIDEO->interface == 1U)
          {
            /* Start Streaming (First endpoint writing will be done on next SOF) */
            (void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
            hVIDEO->uvc_state = UVC_PLAY_STATUS_READY;
            sofcnt++;
            USBD_VIDEO_SOF(pdev); //user modify -> start the image data transfer
          }
          else
          {
            /* Stop Streaming */
        	if (hVIDEO->uvc_state == UVC_PLAY_STATUS_STREAMING)//user modify
             cntrestartusb = 1;//user modify
            hVIDEO->uvc_state = UVC_PLAY_STATUS_STOP;
            (void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
          }

 

 

 

main.c

 

  while (1)
  {
	  if (cntrestartusb)
	  {
		  cntrestartusb--;
		  USBD_VIDEO_DeInit(&hUsbDevice,0); //user modify
		  USBD_VIDEO_Init(&hUsbDevice,0); //user modify
	  }