Skip to main content
Lead
Apr 17, 2022 2:57 PM UTC
Question

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

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

This topic has been closed for replies.

11 replies

Pavel A.
Apr 18, 2022 4:15 PM UTC

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

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

DMårtAuthor
Lead
Apr 18, 2022 5:12 PM UTC

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-ComputerSTM32MP257FAK3 custom board with STM64-OS as operating system: https://github.com/DanielMartensson/STM64-Computer
AlexFabre
Visitor II
May 27, 2022 8:00 PM UTC

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 ?

Pavel A.
May 27, 2022 8:10 PM UTC

@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.

DMårtAuthor
Lead
May 29, 2022 8:08 PM UTC

@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-ComputerSTM32MP257FAK3 custom board with STM64-OS as operating system: https://github.com/DanielMartensson/STM64-Computer
AlexFabre
Visitor II
May 27, 2022 10:27 PM UTC

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…

Pavel A.
May 27, 2022 10:32 PM UTC

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.

DMårtAuthor
Lead
May 29, 2022 8:09 PM UTC

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-ComputerSTM32MP257FAK3 custom board with STM64-OS as operating system: https://github.com/DanielMartensson/STM64-Computer