cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet for ST32F407 gave me HAL_ETH_ERROR_DMA when I plugin the ethernet cable

DMårt
Lead

I have an STM32F407 with the ethernet PHY DP83848.

I cannot ping the device if I'm using the LwIP because I'm facing some errors.

I belive that this can be an bug in STM32CubeIDE 1.9.0.

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 my activity LED blink on the DP83848 and then I get an interrupt.

0693W00000LyBVnQAN.png 

I get the error code 0x8. That means I'm facing DMA issues. But why?

/** @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 */
/**
  * @}
  */

My STM32F407 does not have DMA for Ethernet. What should I do now? Is this a bug?

0693W00000LyBWWQA3.png 

My complete code:

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 */
 
 ADC_HandleTypeDef hadc1;
 
CAN_HandleTypeDef hcan1;
 
DCMI_HandleTypeDef hdcmi;
DMA_HandleTypeDef hdma_dcmi;
 
ETH_HandleTypeDef heth;
 
RTC_HandleTypeDef hrtc;
 
SPI_HandleTypeDef hspi2;
 
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
 
UART_HandleTypeDef huart5;
 
SRAM_HandleTypeDef hsram1;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_FSMC_Init(void);
static void MX_DCMI_Init(void);
static void MX_SPI2_Init(void);
static void MX_TIM1_Init(void);
static void MX_TIM3_Init(void);
static void MX_ADC1_Init(void);
static void MX_CAN1_Init(void);
static void MX_RTC_Init(void);
static void MX_TIM4_Init(void);
static void MX_DMA_Init(void);
static void MX_UART5_Init(void);
static void MX_ETH_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth){
	uint32_t errorCode = heth->ErrorCode;
}
 
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
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_DMA_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 */
}
 
 
/**
  * @brief DCMI Initialization Function
  * @param None
  * @retval None
  */
static void MX_DCMI_Init(void)
{
 
  /* USER CODE BEGIN DCMI_Init 0 */
 
  /* USER CODE END DCMI_Init 0 */
 
  /* USER CODE BEGIN DCMI_Init 1 */
 
  /* USER CODE END DCMI_Init 1 */
  hdcmi.Instance = DCMI;
  hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
  hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
  hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH;
  hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
  hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
  hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
  hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
  if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN DCMI_Init 2 */
 
  /* USER CODE END DCMI_Init 2 */
 
}
 
/**
  * @brief ETH Initialization Function
  * @param None
  * @retval None
  */
static void MX_ETH_Init(void)
{
 
  /* USER CODE BEGIN ETH_Init 0 */
 
  /* USER CODE END ETH_Init 0 */
 
   static uint8_t MACAddr[6];
 
  /* USER CODE BEGIN ETH_Init 1 */
 
  /* USER CODE END ETH_Init 1 */
  heth.Instance = ETH;
  MACAddr[0] = 0x80;
  MACAddr[1] = 0x80;
  MACAddr[2] = 0xA2;
  MACAddr[3] = 0xAE;
  MACAddr[4] = 0x13;
  MACAddr[5] = 0x41;
  heth.Init.MACAddr = &MACAddr[0];
  heth.Init.MediaInterface = HAL_ETH_RMII_MODE;
  heth.Init.TxDesc = DMATxDscrTab;
  heth.Init.RxDesc = DMARxDscrTab;
  heth.Init.RxBuffLen = 1524;
 
  /* USER CODE BEGIN MACADDRESS */
 
  /* USER CODE END MACADDRESS */
 
  if (HAL_ETH_Init(&heth) != HAL_OK)
  {
    Error_Handler();
  }
 
  memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
  TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
  TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
  TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
  /* USER CODE BEGIN ETH_Init 2 */
 
  /* USER CODE END ETH_Init 2 */
 
}
 
/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA2_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
 
}
 
/* FSMC initialization function */
static void MX_FSMC_Init(void)
{
 
  /* USER CODE BEGIN FSMC_Init 0 */
 
  /* USER CODE END FSMC_Init 0 */
 
  FSMC_NORSRAM_TimingTypeDef Timing = {0};
 
  /* USER CODE BEGIN FSMC_Init 1 */
 
  /* USER CODE END FSMC_Init 1 */
 
  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FSMC_NORSRAM_DEVICE;
  hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
  hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
  hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 10;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 20;
  Timing.BusTurnAroundDuration = 0;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FSMC_ACCESS_MODE_A;
  /* ExtTiming */
 
  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }
 
  /* USER CODE BEGIN FSMC_Init 2 */
 
  /* USER CODE END FSMC_Init 2 */
}

 Update:

Here is more information. I found a DMA error code.

0693W00000LyBzOQAV.pngHere comes the error code from. See arrow.

/* 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));
      }

It looks like DMA is disabled for ETH?

0693W00000LyC0HQAV.png

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer
11 REPLIES 11
Pavel A.
Evangelist III

Where in the code RX buffer memory is assigned to the RX descriptors?

Have you reviewed any ST Ethernet example? Especially, file ethernetif.c.

The RX buffer has STM32CubeIDE self been generating code for.

There is no ST Ethernet example for the 407 processor.

I think I just have discovered a bug in STM32CubeIDE!

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* 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 */
 
ADC_HandleTypeDef hadc1;
 
CAN_HandleTypeDef hcan1;

.

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer
AlexFabre
Associate II

Hi ! I'm facing exactly the same issue. Basic generated code with F429 fails with DMA bus error.

Did you get any support from anyone ?

@AlexFabre​ Have you, like the OP, forgotten to provide RX buffers memory?

Do you use pre-"rework" version of the ETH driver?

Note that "reworked" ETH driver for STM32F4 family went back to the drawing desk.

There's no updates yet, AFAIK.

AlexFabre
Associate II

Hi @Pavel A.​, I’ll check tomorrow RX buffer memory. Thank you for your answer.

I’m using the last version of HAL ETH driver.

In fact, ST provides a running web server example for NUCLEO-F429 with latest HAL drivers.

And it works well, but the project is not easily maintainable and I wanted to start from scratch…

That makes me doubt that this specific DMA problem might be related with HAL drivers…

Well, just note that the ST examples for STM32F4 are not based on cube-generated code.

They were written manually. And you're having issue with generated code.

@Pavel A.​ 

What? Do I have forgotto provide RX buffers? No, how can I provide with RX buffers?

I still think that this is a bug because I'm using standard configuration and still my problem still exist at the CubeMX code.

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer

I have the same issue with generated code. When will the fix be done?

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer

@AlexFabre​ 

I have upload my project in this thread. Try that and see if it's working for you.

https://community.st.com/s/question/0D53W00001VXhtSSAT/bug-dma-fatal-error-ethernet-in-stm32f407-processor

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer