2024-02-14 01:46 AM - edited 2024-02-14 01:47 AM
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:
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
Solved! Go to Solution.
2024-02-14 10:13 PM
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
}
2024-02-14 10:13 PM
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
}
2024-12-17 01:04 AM
Hello,
I hope you're doing well. I've been working on UVC with the STM32U5G9ZJT6Q MCU, capturing 8-bit data through DCMI, and I am able to see the image on VLC or Windows Camera.
However, I am facing a few issues that I think you might be able to help with:
When using a 640x480 resolution, I'm unable to see the image on VLC, although I can confirm through Wireshark that the data is being sent. Interestingly, when I reduce the resolution slightly, the image appears on VLC.
I believe increasing the USBD_VIDEO_EPIN_HS_MPS could solve my problem, but when I try to increase it beyond 2000, even with smaller resolutions, the image does not appear, and I can't see the data on Wireshark.
We want to increase the USBD_VIDEO_EPIN_HS_MPS to more than 2500 to achieve higher FPS. Could you guide me on how to do this, or is there an alternative method to achieve higher frame rates?
I'm attaching my code for reference, and I'd appreciate any insights or suggestions you can provide.
Thank you in advance!
2024-12-20 02:47 AM
Hi,
normally when you see the communication the problem is the header information or the amount of transmitted data is wrong. If you have 640x480 i recommend to send only a smaller amount so you can check if the amount of data is correct and the header of the data is correct. So setup software to transfer image 640x12. Then change MPS to 640*4=2560 + Header. I use always 4 byte for Header.
0x04 (size header), 0x0Y (0x01 bit toggle every frame, 0x02 is set when last data is transmitted), 0x00 (dummy), 0x00 (dummy), <data>
Then you should send 3 times and should see the frame. If not maybe you can see in wireshark what is going wrong.
Additional it is a good idea to send only a constant buffer first and not to use DCMI to ensure that you do not have timing problems.
DMA should be enabled:
hpcd_USB_OTG_HS.Init.dma_enable
Ensure that you do not use the internal oscillator HSI for USB
Hope this will help you.
2024-12-26 01:42 AM
Thank you for your suggestions.
We tried what you mentioned, and I can confirm that DMA is enabled, and we are using the HSE 32MHz clock for the PHY. We successfully sent a static frame buffer first without DCMI, which is working at 18 FPS with HS_MPS set to 1974.
However, I'm encountering an issue when I try to increase the HS_MPS. The device stops being recognized when I do so. If you have any insights, example code, or suggestions that could help, it would be greatly appreciated.
Thank you again for your support!