cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet TX complete interrupt occasionally not triggered, but frame transmitted correctly

LDroz.2
Associate II

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.

2 REPLIES 2
Piranha
Chief II

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

https://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32

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:

  • 1. Should I clear manually the RI and TI flags? The STM32H7 doc does not say they should be cleared by the driver (p. 2925), but it also says the NIS flag is set as the OR of several flags, including RI and TI, and that NIS should be cleared manually. Does clearing NIS automatically clear RI and TI?
  • 2. My code clears NIS if (RI OR TI). What if the following happens in this order:
    • RI flag comes up
    • -> NIS flag comes up
    • -> ETH IRQ comes up
    • -> ETH ISR invoked
    • ETH ISR reads RI == 1
    • -> ETH ISR clears RI
    • ETH ISR reads TI == 0
    • TI flag comes up
    • ETH ISR clears NIS and exits
  • ^ What happens here depends on my question in 1., I think. If clearing NIS clears TI automatically, then a Transmit Complete Interrupt happening shortly after a Receive Complete Interrupt may cause the ETH ISR to miss and clear the Transmit Complete Interrupt. If not, this could not happen, I think. The ISR in your updated version in https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet does not seem to clear the NIS flag, isn't that necessary as per description of bit NIS at p.2924 of the STM32H7 docs?

Apologies if I am dead wrong on something or asking dumb questions, the STM32H7 documentation is at times very unclear to me.