cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Cube USB Host wmaxpacketsize problem

emre
Associate II
Posted on August 14, 2014 at 00:13

Hi,

I use STM32F205ZE USB FS Host library for UVC device.

Some UVC device has ISOC EP wMaxPacketSize=192Bytes, but others device's wmaxpacketsize > 500Bytes.

I can get JPEG stream if device wMaxPacketSize=192Bytes or =<500Bytes. When i use some UVC devices (wmaxpacketsize > 500bytes) i can't receive to any JPEG stream packet. How can i fix this problem?

Thanks.

#usbh_isocreceivedata-buffer-read #stm32-usb-host-uvc #cube-usb-host
3 REPLIES 3
tsuneo
Senior
Posted on August 14, 2014 at 07:53

In USB_HostInit(), Cube assigns fixed size to the RX FIFO (GRXFSIZ register), which is 0x80 words (512 bytes). This FIFO size should be greater than the MPS (MaxPacketSize) of the isoc IN EP.

\STM32Cube_FW_F4_V1.3.0\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_usb.c
HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
{
..
if(USBx == USB_OTG_FS)
{
/* set Rx FIFO size */
USBx->GRXFSIZ = (uint32_t )0x80; // <------------
USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 
16
)& USB_OTG_NPTXFD) | 0x80);
USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);
}

When the RX FIFO increases, the address of other FIFOs move. Also, by the limitation of total FIFO size (1.25 Kbytes, 0x140 words), the size of these FIFOs is shrunk.

/* set Rx FIFO size */
USBx->GRXFSIZ = (uint32_t )0x110; // 0x110 words = 1024 + 64 bytes
USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x20 << 
16
)& USB_OTG_NPTXFD) | 0x110);
USBx->HPTXFSIZ = (uint32_t )(((0x10 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0x130);

Tsuneo
emre
Associate II
Posted on August 18, 2014 at 16:23

it works. Thank you.

I have another problem. I want to check ''in buffer is ready'' after USBH_IsocReceiveData function. I tried USBH_LL_GetURBState, but not working. How can i detect buffer is ready for reading?

USBH_IsocReceiveData(phost, (uint8_t *)buff, 896, test_pipe1);

URB_Status = USBH_LL_GetURBState(phost, test_pipe1);

    

    if(URB_Status == USBH_URB_DONE)

    {

      len = USBH_LL_GetLastXferSize (phost, test_pipe1);

tsuneo
Senior
Posted on August 19, 2014 at 19:47

> I tried USBH_LL_GetURBState, but not working.

In the XFRC interrupt handler, Cube v1.3.0 host stack drops isoc process, which should set URB_DONE to urb_state. Isoc XFRC should be processed in the same way as interrupt endpoint. Modify HCD_HC_IN_IRQHandler() as follows.

\STM32Cube_FW_F4_V1.3.0\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_hcd.c
static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
{
...
else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
{
...
if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
(hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
{
__HAL_HCD_UNMASK_HALT_HC_INT(chnum);
USB_HC_Halt(hhcd->Instance, chnum);
__HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
}
// else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR) // <—— Replace this line
else if((hhcd->hc[chnum].ep_type == EP_TYPE_INTR)|| // into these two lines
(hhcd->hc[chnum].ep_type == EP_TYPE_ISOC)) //
{
USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
hhcd->hc[chnum].urb_state = URB_DONE;
HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
}
hhcd->hc[chnum].toggle_in ^= 1;

Tsuneo