cancel
Showing results for 
Search instead for 
Did you mean: 

USB on STM32F746ZGT and zero length packet (ZLP) on endpoint 1. ZLP not transmitted.

Evgeny Sobolev
Associate III

Hello. I am using USB interface on STM32F746ZGT device (HAL lib, usb device mode). USB zero length packets are supproted and used by our protocol implementation on endpoint 1. It works on STM32L433, STM32F407, STM32F446 controllers. But it doesn't work on STM32F746ZGT. When I tried to send packet using HAL_PCD_EP_Transmit(), using non-zero length, it was sent. But if I tried to send HAL_PCD_EP_Transmit() zero length packet I saw nothing.

As I saw, it is presend some source code in file stm32f7xx_ll_usb.c:

  if (ep->xfer_len == 0U)

  {

   USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);

   USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));

   USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);

  }

But packet counter doesn't decremented by hardware. What sould I do to transmit ZLP?

1 ACCEPTED SOLUTION

Accepted Solutions
Evgeny Sobolev
Associate III

So, I found the solution. Accroding to datasheet I should:

  1. Set transfer size[EPNUM] = 0
  2. Set packet count[EPNUM] = 1,
  3. and say "transfer" by writing USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK;

But really you should write somthing into fifo, otherwise ZLP is not transmitted. Real solution is:

  1. Set transfer size[EPNUM] = 0
  2. Set packet count[EPNUM] = 1,
  3.  USB_WritePacket(USBx, ep->xfer_buff, ep->num, 1, 0);
  4. Say "transfer" by writing USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK;

Please add this information to errata or datasheet and fix in HAL library. Thanks.

View solution in original post

6 REPLIES 6
Evgeny Sobolev
Associate III

Is anybody knows is it bug of hardware or HAL software? How to resolve it? May be company had extended version of datasheet (reference manual)?

According to reference manual RM0385 Rev 8, page 1514-1515

– To transmit a single zero-length data packet:

Transfer size[EPNUM] = 0

Packet count[EPNUM] = 1

That is done in HAL lib, but nothing happens. Should I do somthing else to transmit ZLP?

Evgeny Sobolev
Associate III

So, I found the solution. Accroding to datasheet I should:

  1. Set transfer size[EPNUM] = 0
  2. Set packet count[EPNUM] = 1,
  3. and say "transfer" by writing USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK;

But really you should write somthing into fifo, otherwise ZLP is not transmitted. Real solution is:

  1. Set transfer size[EPNUM] = 0
  2. Set packet count[EPNUM] = 1,
  3.  USB_WritePacket(USBx, ep->xfer_buff, ep->num, 1, 0);
  4. Say "transfer" by writing USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK;

Please add this information to errata or datasheet and fix in HAL library. Thanks.

Thanks for coming back with the solution.

Which OTG module did you use? Do you use the internal PHY?

Do you purge the FIFO afterwards, or does the transfer remove the written word automatically?

Thanks,

JW

Hello!

-Which OTG module did you use? Do you use the internal PHY?

I tried to use both of the modules and had the same problem. Fix was tested on the both interfaces.

-Which OTG module did you use? Do you use the internal PHY?

Internal PHY

-Do you purge the FIFO afterwards, or does the transfer remove the written word automatically?

I didn't do anything else before next transfer. Fifo was cleared automatically, when I wrote new packet there.

Thanks for support.

Regards,

Evgeny Sobolev

Amel NASRI
ST Employee

Hello @Evgeny Sobolev​ ,

It has been a long time since you asked your question and shared your findings.

Here I would like to share with you the recommendation of our USB expert:

There is no need to write the FIFO when transmitting ZLP packet. It is suggested to to use directly our HAL API USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size) as following: USBD_LL_Transmit(&pdev, 0x81U, NULL, 0U);

Before that, make sure that EP1 is opened in IN direction.

If this doesn't work for you, could you please share a minimum code example to reproduce the problem on our side?

Thanks,

Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi Amel,

Do you mean this USBD_LL_Transmit()?

Jan

@Amel NASRI​