2021-06-01 02:03 AM
Hello, I am developing a driver for the STM32H743 Ethernet Interface with external LAN8742A PHY on the NUCLEO H743ZI2 board.
I am doing stress tests. When transmitting and receiving a large amount of frames simultaneously, sometimes the TI interrupt is not triggered, even though I can see the frame was transmitted correctly to the other endpoint. Even though the interrupt is not triggered, the descriptor of the frame I transmitted is released by the ETH DMA, and shows no error. Lowering the transmission rate seems to solve the issue.
I checked the state of the descriptor and the internal current descriptor pointer of the ETH, before transmitting and some time after I know the frame was transmitted. Before transmission, my driver prepares the descriptor, sets its OWN bit, and sends the transmit command via the tail pointer. Just before the transmit command, the ETH internal descriptor pointer points to the descriptor I just prepared.
After transmission, this descriptor is released by the DMA and shows no error. The ETH internal current descriptor pointer points to the next descriptor, as expected.
Do you have any idea what might be happening, and how I could debug this further?
Thank you.
2021-06-05 08:01 AM
How do you detect that the interrupt is not triggered? Interrupt really means "at least one frame was transmitted". Therefore, for example, expecting the same number of interrupts as there are frames transmitted is just wrong.
Just a useful links:
https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet
2021-06-14 03:06 AM
Sorry for late reply. Thank you for your explanation and your links.
My TX process transmits frames one by one. It prepares the descriptors for one single frame, updates the tail pointer, then waits on a semaphore. In parallel, when the ETH ISR handler is called, it acts as the following (pseudocode, I include the RX code for completeness, as this may be the cause of my issue):
IF ETH_DMACSR.NIS == 1:
IF ETH_DMACSR.RI == 1:
signal RX semaphore // Signal RX process to continue
ETH_DMACSR.RI == 1 // Clear the RI flag by writing 1 to it
IF ETH_DMACSR.TI == 1:
signal TX semaphore // Signal TX process to continue
ETH_DMACSR.TI == 1 // Clear the TI flag by writing 1 to it
ETH_DMACSR.NIS == 1 // Clear the NIS flag by writing 1 to it
For context, an RX thread is running in parallel, and uses the same mechanism with a separate semaphore to wait for the Receive Complete Interrupt. As I send frames one by one, I don't believe this should cause an issue. However, I realize there are two things I don't fully understand:
Apologies if I am dead wrong on something or asking dumb questions, the STM32H7 documentation is at times very unclear to me.