cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with STM32H747 HS USB DMA.

FTrie.1
Associate II

Hello together,

after a lot of trouble getting the USB HS port working on the STM32H747 on the STM32H747I-DISCO Discovery kit I’m stuck again. I’m using STM Cube IDE 1.7 and the HAL USB CDC lib.

I was able to get USB CDC working on the M4 thanks to https://community.st.com/s/question/0D53W000002diUsSAI/stm32cubemx-h7x5h7x7-usb-cdc-bug

On the M7 core it kind of worked out of the box. But when I want to use it with the USB interal DMA enabled it didn’t work at all.

I already figured out I have to disable the D-cache and not use the DTCM SRAM for the buffer: https://community.st.com/s/article/how-to-enable-dma-in-usb-with-stm32h7-devices

I provided a minimal example of code which already results in failure:

  ...
 
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
 
  HAL_Delay(1000);
 
  uint8_t buffer1[2000], buffer2[2000];
 
  CDC_Transmit_HS(buffer1, 1468);
  HAL_Delay(50);
  CDC_Transmit_HS(buffer2, 4);
 
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

When I use CDC_Transmit_HS() it works. I can send data from the provided buffer. I can also do this multiple times. And the DMA seems to work, as the execution time of CDC_Transmit_HS() is rather short and independent of the buffer length.

BUT: I can only send 1468 bytes of data. If I use a buffer length > 1468 bytes it doesn’t send anything.

If I send say CDC_Transmit_HS(buffer1, 1460) and than CDC_Transmit_HS(buffer1, 12) I get the first 1460 bytes transferred but the second call is not transmitted.

I also tried different memory addresses for the buffer pointer. E.g. 0x30020000 (SRAM2).

Always the same.

After the CDC_Transmit_HS() the CPU is normally executing code, just without any data being sent.

Any idea what I am doing wrong? With internal IP DMA disabled it works fine with large buffers and repeatably.

Thanks a lot

1 ACCEPTED SOLUTION

Accepted Solutions

Hello @FTrie.1​ 

Actually the following USB FIFO configuration is not correct when USB DMA is enabled.

/* USER CODE BEGIN TxRx_Configuration */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);
/* USER CODE END TxRx_Configuration */

In fact, you should not allocate more than (4096 – 72 (for DMA descs)) bytes in total -> 0x3EE words

Please try to use the following config which should work for your use case.

/* USER CODE BEGIN TxRx_Configuration */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x100);
/* USER CODE END TxRx_Configuration */

Please let me know if this solved your issue.

BeST Regards,

Walid

View solution in original post

7 REPLIES 7

Hello @FTrie.1​ ,

Your problem has been raised internally for verification. I will keep you updated.

Thanks for your contribution.

BeST Regards,

Walid

Hello @FTrie.1​ ,

Potentially an USB FIFO configuration issue on the software that corrupt USB DMA descriptors.

Can you please provide the USB FIFO settings.

Thanks in advance.

BeST Regards,

Walid 

Hello @FTrie.1​ 

Are there any news concerning this issue from your side?

BeST Regards,

Walid

FTrie.1
Associate II

Hello @Walid ZRELLI​ ,

i haven't looked into it recently, as i changed my design and don't use the USB any longer. But it would still be interesting why it is not working using the HAL driver and dma enabled.

In 2 days i have access to the STM32H747I-DISCO Discovery kit again and will try again.

Regarding fifo settings, do you mean inside the function USBD_LL_Init(...) in usbd.conf.c? I haven't changed any of this:

USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{
  /* Init USB Ip. */
  if (pdev->id == DEVICE_HS) {
  /* Link the driver to the stack. */
  hpcd_USB_OTG_HS.pData = pdev;
  pdev->pData = &hpcd_USB_OTG_HS;
 
  hpcd_USB_OTG_HS.Instance = USB_OTG_HS;
  hpcd_USB_OTG_HS.Init.dev_endpoints = 9;
  hpcd_USB_OTG_HS.Init.speed = PCD_SPEED_HIGH;
  hpcd_USB_OTG_HS.Init.dma_enable = ENABLE;
  hpcd_USB_OTG_HS.Init.phy_itface = USB_OTG_ULPI_PHY;
  hpcd_USB_OTG_HS.Init.Sof_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.low_power_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.lpm_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.use_dedicated_ep1 = DISABLE;
  hpcd_USB_OTG_HS.Init.use_external_vbus = DISABLE;
  if (HAL_PCD_Init(&hpcd_USB_OTG_HS) != HAL_OK)
  {
    Error_Handler( );
  }
 
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  /* Register USB PCD CallBacks */
  HAL_PCD_RegisterCallback(&hpcd_USB_OTG_HS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback);
  HAL_PCD_RegisterCallback(&hpcd_USB_OTG_HS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback);
  HAL_PCD_RegisterCallback(&hpcd_USB_OTG_HS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback);
  HAL_PCD_RegisterCallback(&hpcd_USB_OTG_HS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback);
  HAL_PCD_RegisterCallback(&hpcd_USB_OTG_HS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback);
  HAL_PCD_RegisterCallback(&hpcd_USB_OTG_HS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback);
  HAL_PCD_RegisterCallback(&hpcd_USB_OTG_HS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback);
 
  HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_OTG_HS, PCD_DataOutStageCallback);
  HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_OTG_HS, PCD_DataInStageCallback);
  HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOOUTIncompleteCallback);
  HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_HS, PCD_ISOINIncompleteCallback);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  /* USER CODE BEGIN TxRx_Configuration */
  HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
  HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);
  /* USER CODE END TxRx_Configuration */
  }
  return USBD_OK;
}

Hello @FTrie.1​ 

Actually the following USB FIFO configuration is not correct when USB DMA is enabled.

/* USER CODE BEGIN TxRx_Configuration */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);
/* USER CODE END TxRx_Configuration */

In fact, you should not allocate more than (4096 – 72 (for DMA descs)) bytes in total -> 0x3EE words

Please try to use the following config which should work for your use case.

/* USER CODE BEGIN TxRx_Configuration */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x100);
/* USER CODE END TxRx_Configuration */

Please let me know if this solved your issue.

BeST Regards,

Walid

FTrie.1
Associate II

Hello @Walid ZRELLI​ ,

i just tried it with the new USB FIFO settings and it works. Thanks a lot!

Hopefully this will help others with the same problem 🙂

Hello @FTrie.1​ 

Glad to help you 😊

Please click on Select as Best if my post fully answered your question. This will help other customers with the same issue to find the solution faster!

BeST Regards,

Walid