Skip to main content
Graduate II
April 19, 2022
Question

BUG: DMA Fatal Error - Ethernet in STM32F407 processor

  • April 19, 2022
  • 13 replies
  • 12466 views

Hi!

Problem:

I found a bug when I enabling the ETH perpherial in the STM32F407 processor. The error is a DMA bus error.

What's happening:

It occurs when the ethernet PHY recieve a message from my router.

How to produce the error:

I do the following steps to reproduce the error.

  1. I start up my PCB board
  2. I let the initialization do its job and I get no error back.
  3. I plugin my ethernet cable
  4. I ping a random device with a random number

Then this call back function HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); will be called.

0693W00000LyBzOQAV.pngThe error code is a DMA error.

/** @defgroup ETH_Error_Code ETH Error Code
 * @{
 */
#define HAL_ETH_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error */
#define HAL_ETH_ERROR_PARAM ((uint32_t)0x00000001U) /*!< Busy error */
#define HAL_ETH_ERROR_BUSY ((uint32_t)0x00000002U) /*!< Parameter error */
#define HAL_ETH_ERROR_TIMEOUT ((uint32_t)0x00000004U) /*!< Timeout error */
#define HAL_ETH_ERROR_DMA ((uint32_t)0x00000008U) /*!< DMA transfer error */
#define HAL_ETH_ERROR_MAC ((uint32_t)0x00000010U) /*!< MAC transfer error */
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
#define HAL_ETH_ERROR_INVALID_CALLBACK ((uint32_t)0x00000020U) /*!< Invalid Callback error */
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
/**
 * @}
 */

The DMA error is a DMA bus error.

0693W00000LyC0HQAV.pngThis part of the code creates the DMA error code. See the arrow <---- HERE!

/* ETH DMA Error */
 if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_AIS))
 {
 if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_AISE))
 {
 heth->ErrorCode |= HAL_ETH_ERROR_DMA;
 
 /* if fatal bus error occurred */
 if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_FBES))
 {
 /* Get DMA error code */
 heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS)); <<--- HERE!
 
 /* Disable all interrupts */
 __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE); 
 
 /* Set HAL state to ERROR */
 heth->gState = HAL_ETH_STATE_ERROR;
 }
 else
 {
 /* Get DMA error status */
 heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
 ETH_DMASR_RBUS | ETH_DMASR_AIS));
 
 /* Clear the interrupt summary flag */
 __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
 ETH_DMASR_RBUS | ETH_DMASR_AIS));
 }

 My main function

 
 
/* Private variables ---------------------------------------------------------*/
 
ETH_TxPacketConfig TxConfig;
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
 
void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth){
	uint32_t errorCode = heth->ErrorCode;
}
 
int main(void)
{
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
 
 /* MCU Configuration--------------------------------------------------------*/
 
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 
 /* USER CODE BEGIN Init */
 
 /* USER CODE END Init */
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* USER CODE BEGIN SysInit */
 
 /* USER CODE END SysInit */
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_FSMC_Init();
 MX_DCMI_Init();
 MX_SPI2_Init();
 MX_TIM1_Init();
 MX_TIM3_Init();
 MX_ADC1_Init();
 MX_CAN1_Init();
 MX_RTC_Init();
 MX_TIM4_Init();
 MX_UART5_Init();
 MX_ETH_Init();
 /* USER CODE BEGIN 2 */
 
 /* Start up LCD */
 HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_SET);
 LCD_BL_ON();
 lcdInit();
 
 HAL_GPIO_WritePin(ETH_RESET_GPIO_Port, ETH_RESET_Pin, GPIO_PIN_RESET);
 HAL_Delay(1);
 HAL_GPIO_WritePin(ETH_RESET_GPIO_Port, ETH_RESET_Pin, GPIO_PIN_SET);
 
 /* Enable interrupt */
 HAL_ETH_Start_IT(&heth);
 
 
 /* USER CODE END 2 */
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 
 }
 /* USER CODE END 3 */
}

Hardware settings

The hardware settings are for RMII for the Ethernet PHY DP83848 .

Yes! The LED D1 flashes when something happen at the network. The pin ACT_LED/COL should go low when something happens. The oscillator is at 50 MHz and very close to the DP83848 chip.

0693W00000LyNQVQA3.png0693W00000LyNQaQAN.pngSoftware settings:

Download my project here:

STM32 project:

https://easyupload.io/xhrn8d

Schematic project (KiCAD):

https://easyupload.io/9x3xig

Why I'm thinking this be a bug?

Because I have not configured ETH DMA and it give me a bug about that when my Ethernet PHY got a message and pass it over to the STM32 processor. I assume that STM32CubeIDE 1.9.0 have some issues then.

What am I 100% sure that I have been constructed the hardware correctly?

The Ethernet PHY address is 0x1 and I have been veryfied that this is correct address. The LED D1 is flashing when activity occurs at the network.

The callback function calls when the LED D1 flashes after initialization.

    This topic has been closed for replies.

    13 replies

    Super User
    April 19, 2022

    Your hardware likely is good, because it seems to "do something" when the cable is connected.

    But the software obviously has issues.

    > Because I have not configured ETH DMA

    ETH has its own DMA master. It does not use DMA controllers of STM32. This DMA starts when you call HAL_ETH_Start_IT.

    Again: your code does not assign RX buffer memory to the descriptors. So the ETH DMA fails. What else can it do.

    DMårtAuthor
    Graduate II
    April 19, 2022

    I call `HAL_ETH_Start_IT` at the beginning.

    >> Your code does not assign RX buffer memory to the descriptors.

    How can I do that?

    Super User
    April 19, 2022

    Please see the LwIP examples. File ethernetif.c.

    DMårtAuthor
    Graduate II
    April 21, 2022

    Nobody knows? I haven't found a solution to this problem.

    Graduate II
    April 23, 2022

    > Sorry. I cannot implement that.

    ST's lwIP implementation and FreeRTOS+ are both using HAL. Pavel was giving you an advice where you can look at an example of how to use HAL ETH driver.

    Graduate II
    April 24, 2022

    Read my post in this topic:

    https://community.st.com/s/question/0D53W00001VYkb5SAD/stm32f417-lwip-udp-packets-are-being-truncated

    The new rewritten ETH driver for F4 is basically dysfunctional. Revert to the legacy one...

    And also look at this:

    https://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32

    Super User
    April 25, 2022

    > I have problems to import these ST-made projects into STM32CubeIDE. I don't know how to import it.  I know how to import .ioc projects. But not MDK-ARM, SW4STM32 etc.

    Unfortunately this is... complicated. Examples for old STM32 lines like F4 have been created before CubeMX and CubeIDE, so there are no .ioc files and no native CubeIDE projects. One has to import SW4STM32/ac6 project to CubeIDE (look for this item in CubeIDE import options menu).

    The import is not perfect, it can mess some things such as linker script - which is very important for ethernet projects; check that important details are not lost after import and restore if needed.

    Linker scripts of CubeIDE and SW4STM are practically same, as both are based on the same GCC toolchain type.

    As for missing ioc file, it is simply not there. Have to re-create it, or google, or persuade someone else to make it for you. Unless you decide to write the initialization code yourself without the Cube generator.

    > I'm also don't know which example I should use. 

    You want only "pure" ethernet packets - so take only the buffer RAM allocation from any LwIP example and throw away all the rest.

    Unfortunately again, after the "ETH driver rework" this RX buffer allocation is wrapped in confusing callbacks and LwIP headers. Basically you keep one big enough memory buffer per RX descriptor and put address of each buffer into the descriptor before starting the ETH.

     [CORRECTION] what happens in the RX callback in "reworked" version is allocation of LwIP packet descriptors, not the buffers. The buffers must be assigned before RX occurs.

    DMårtAuthor
    Graduate II
    April 25, 2022

    Hi! I tried this project, it fits my processor. But it did not work for me. Still "Time out" when I ping it.

    DeeFuse/STM32F4-liwp: STM32F4 lwip Ethernet with easy swtiching between static IP and DHCP (github.com)

    Super User
    April 26, 2022

    @Daniel Mårtensson​ Sorry, I don't understand to which direction you're going now.

    Looks like you want to use LwIP.

    That github project is 5 years old, so it is based on pre-"rework" ETH driver version.

    Do you use a compatible older STM32Cube_F4 library package containing the ETH driver and older LwIP version as well?

    The github author has no documentation or even mention for which board this project is for.

    At least, it's the time to run wireshark and see the packets on the wire.

    Super User
    April 25, 2022

    @Piranha​ Your suggested fix to FreeRTOS+ STM32xx eth driver has been implemented and merged on github :dizzy: . Amazon is speedy )

    https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/pull/458

    https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/pull/459#event-6492385210

    Graduate II
    May 1, 2022

    They fixed it in less than 24 hours. A mission impossible for ST!

    DMårtAuthor
    Graduate II
    May 1, 2022

    The bugs is fixed? I thought you said it would take a very long time?

    Super User
    April 28, 2022

    @Daniel Mårtensson​ Sorry I'm a bit confused now. Do you suspect PHY?

    From your last reply it looks that RX event (callback) scans RX descriptors but cannot find a complete packet to return.

    Can there be a bug somewhere? Maybe, but it is hard to debug here in the forum. Do you have wireshark captures?

    DMårtAuthor
    Graduate II
    April 28, 2022

    I do not suspect PHY. I think PHY is correct designed.

    I think it's a STM32 software issue.

    I can recieve data, but I cannot send data.

    So I assume that RX is OK, but TX is never called, except at the start up.

    I did a double check and the RX descriptors works when I ping the ST controller.

    But even if I ping. No TX function or "Transmit to PHY" is called. Why?

    Only "Read from PHY" and other RX-callbacks is called.

    Super User
    April 29, 2022

    It looks like "reworked" ETH driver for F4 series needs thorough fixing.

    The incoming ping request is corrupted, thus no response.

    https://community.st.com/s/question/0D53W00001WIg4aSAD/ethernet-hal-driver-cubemx-65-and-stm32f4-broken-icmp-ping-anyone-knows-how-to-fix

    DMårtAuthor
    Graduate II
    April 29, 2022

    Yes! It seems that F4 series with STM32CubeIDE 1.9.0 have some bugs when it comes to LwIP.

    How can we confirm that for the ST-team here at this forum?

    Super User
    April 29, 2022

    This work is already done by @Piranha​ :gem_stone:

    Let's hope it will be fixed timely (until we retire)

    Graduate II
    May 1, 2022

    > So there is a bug in STM32CubeIDE 1.9.0 for the F4 series about LwIP ... of the future fix?

    Not a bug, but tenths of bugs, including a critical and non-trivial to fix ones. Not in a CubeIDE, but in a HAL drivers, CubeMX generated code and examples. And with a current attitude ST can fix those by the end of the century. But maybe I'm exaggerating and Pavel is more realistic - until we retire.

    DMårtAuthor
    Graduate II
    May 1, 2022

    I understand. Very bad for ST if their customers find out that there are bugs in their HAL-libraries. Very critical....

    Super User
    May 2, 2022

    Maybe not critical at all. ST's product is chips, not the free software.

    As far as they are confident that the hardware is solid (validated by internal tests, 3rd party proprietary software, partners) - no reason to worry,

    DMårtAuthor
    Graduate II
    May 29, 2022

    @Pavel A.​ @Piranha​ 

    What's the status of ST's bug fix? Have you heard anything about this issue?

    Graduate II
    June 2, 2022

    ST... after a month? For them it takes on average a year to fix anything and even then half of the fixes are still flawed. Return to the version before the rewrite (v1.27) - for F4 it was more or less working.