2022-04-19 11:35 AM
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.
Then this call back function HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); will be called.
The 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.
This 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.
Software settings:
Download my project here:
STM32 project:
Schematic project (KiCAD):
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.
2022-06-02 09:06 AM
Hi @Daniel Mårtensson
Your project is not downloadable anymore, could you re-upload it ?
Could you explain what correction you made to the Rx Descriptors and buffers to make ping work.
2022-06-02 01:20 PM
Hello @AlexFabre
Here is the project: https://github.com/DanielMartensson/STM32-Ethernet-Camera
I have not touch the RX descriptors. I just use default. See the .ioc file
2022-06-02 04:09 PM
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.
2022-07-06 11:34 AM
Since STM32CubeIDE 1.10.0, then this issue has been fixed. Thank you.
Done!
2022-07-06 03:31 PM
But the driver ir CubeF4 v1.27 is completely broken:
2022-07-08 03:34 AM
So why can I ping right now? I just changed the STM32CubeIDE to next version, and then it works to ping to my PCB board.
2022-09-20 03:11 AM
@Daniel Mårtensson I faced the same issue for a week with theSTM32Cube MCU Package FW 1.27.1 but could finally solve it!!!
1) If you use LwIP CubeMX Configuration you need to set the LWIP_RAM_HEAP_POINTER. Default value points in a memory region witch is not available with F4. This causes the DMA FBES ERROR. See for that the last comment in the following post on stackexchange:
2) Further you should include the netif_set_up(&gnetif) function in MX_LWIP_Init() at USER CODE BEGIN 3 section to be shure that the periphery get correct initialized.
Hope this helps you or other in the community they faces this ugly issue.