2026-01-30 5:58 AM - edited 2026-01-30 6:26 AM
Hello!
I am writing a program for STM32F769I-DISCO board that uses FreeRTOS and LwIP to communicate with the server and send data to it. It generally works, but unplugging and plugging Ethernet cable (especially doing it several times within a few seconds) usually causes Ethernet DMA errors which make program stop calling HAL_ETH_IRQHandler and thus board can't even try to reconnect to server. I don't know how I should handle those errors and where to look for information that could offer a solution to my problem.
Any kind of help, whether a direct response or a link to helpful resources, is appreciated.
Ethernet DMASR register
heth error code
MPU and Ethernet descriptors
EDIT 1: Added ethernetif.c and lwip.c files to attachments and screenshot of MPU configuration.
2026-02-03 7:08 AM
Unfortunately I don't see any piece of code responsible for resetting Ethernet's DMA in related project. Thank You for suggestion though.
2026-02-03 7:10 AM
I don't know, it's some time ago that I did this.
I started with CubeMX with ETH and HAL on F767 in 2022 (I think), then I removed all HAL_ETH stuff and wrote my own driver (later for H723/H733), and I also had to modify lwip a little.
Maybe it also depends on the "parameters" you can set in CubeMX what is copied from lwip?
"ethernetif_notify_conn_changed()" - I thought this cam from lwip...
Or I copied it from some examples like this:
snmp_stm32F7/LWIP/Target/ethernetif.c at master · m2030/snmp_stm32F7 · GitHub
Anyway, ETH & lwip is something that needs a lot of work, depending on your application.
Now I have it running smoothly on STM32H7x3 with http webserver, TCP data streaming (not UDP), firmware update over webserver with POST, PTP sync, ... works like a charm - but tool a LOT of effort.
2026-02-03 11:31 PM
Isn’t that part in the driver files?
Where you wait for the SWR bit?
2026-02-04 1:42 AM
Yes, software reset is performed in HAL_ETH_Init() function, but calling it after DMA error occurence is not enough to make Ethernet work again.
Here is the current body of my Ethernet resetting function:
///
if (resetDMA==1 || heth.gState==HAL_ERROR || (heth.ErrorCode & HAL_ETH_ERROR_DMA)!=0 ) {
netif_set_down(&gnetif);
netif_set_link_down(&gnetif);
HAL_ETH_Stop_IT(&heth);
HAL_ETH_DeInit(&heth);
//heth.Instance->DMASR &= 0x0;
extern lan8742_Object_t LAN8742;
LAN8742_DeInit(&LAN8742);
////heth.Instance->DMAOMR &= ~(ETH_DMAOMR_ST | ETH_DMAOMR_SR); //clear start/stop transmit and receive flags
//heth.Instance->DMABMR |= (ETH_DMABMR_SR); //set software reset flag
//while (heth.Instance->DMABMR & ETH_DMABMR_SR) {
// //wait
//}
//setting MAC address again is required as by default it's set in low_level_init() before HAL_ETH_Init() call
uint8_t MACAddr[6];
MACAddr[0] = 0x00;
MACAddr[1] = 0x80;
MACAddr[2] = 0xE1;
MACAddr[3] = 0x00;
MACAddr[4] = 0x00;
MACAddr[5] = 0x00;
heth.Init.MACAddr = &MACAddr[0];
HAL_StatusTypeDef ethInit=HAL_ETH_Init(&heth);
extern ETH_TxPacketConfig TxConfig;
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;
int32_t phyInit=LAN8742_Init(&LAN8742);
//volatile HAL_StatusTypeDef ethStartIt=0x04; //sample value different from enum values
//
//if (netif_is_up(&gnetif) && netif_is_link_up(&gnetif)) {
//ethStartIt=HAL_ETH_Start_IT(&heth); //ethernet_link_thread checks PHY state already
//}
if (ethInit!=HAL_OK /*|| ethStartIt!=HAL_OK*/) {
asm("NOP");
}
resetDMA=0;
osDelay(4000);
}
///
2026-02-08 11:16 PM
I still wasn't able to solve my problem. I have to wait for watchdog reset when Ethernet DMA error appears. Also netconn_connect() function sometimes returns ERR_MEM due to no memory available for enqueueing the SYN segment. If anybody has solution for that, I would be thankful for sharing it here.