This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Clearing the emac rx interrupt with the RXnCP completion pointers.

Other Parts Discussed in Thread: DP83640, HALCOGEN

I have a TMS570 connected to a non-TI PHY controller, a Micrel KS8721.   I have lwip working on the TMS eval board that has the TI dp83640 phy, and I can step through the rx handler and see it clears the interrupt properly.   The 570 emac reference manual indicates that the RX0CP completion pointer clears the interrupt when the descriptor pointer matches this emac register value.   I see from my debug statements and by stepping through the code that this is occurring.   But as soon as I exit the irq, a new one receive irq hits.

The emac irq is mapped to vector 77(rx) and 79(tx), and I've configured HalCogen pin muxing to enable the full MII interface (not the reduced mode RMII).   Practically the same code that runs on the TI Eval board is running on my system, except that I have a different PHY driver that I ported from another ARM9 project.

Both phy controllers have an external interrupt that is disabled, in addition I have disabled the rxpulse generation.   In the 570 emac reference, the setup of the emac controller involves 17 steps, I have found all 17 places in the hdkif.c module that initializes this chip.

I realize that most projects would just use the recommended TI phy part, but I need to salvage this design as it has already been laid down, and replacing it would require scrapping all our boards as the pinouts to the dp83640 are not compatible.

  • Chris,

    So, to summarize:   The problem you are reporting is not being able to effectively exit your EMAC ISR.   ie. you exit the ISR and are immediately put back in the ISR.   You think you've cleared the interrupt request so can't figure out why this occurs.  Is this right?   If so I don't think the phy is inolved.

  • Chris,

    If you are able, please post the contents of the EMAC module control register frame:

     0xFCF78800 - 0xFCF78878

    as the problem is occurring.  I expect we'll find some interrupt pending that's not been cleared.

     

  •  Hello Anthony,

    Thank you for your quick response.   I did not mention in my thread that I can sucessfully ping this board using a command shell and the IP address I have assigned to this board.   When I receive a "valid" irq I can trace it through the stack and see it reply with a transmit descriptor back to my wireshark sniffer and command shell.   But the rx irq is still pending and if I set a breakpoint at the irq entry it will immediately return.

    Here is the memory space you asked.  The code is stopped at the beginning of the irq, the first address is 0xFCF78800.   Is the emac control register frame described

    in the reference manual?

    Best regards,

     

    4EC80100 00000000 00000000 00000000 00000000 00000001 00000001
    00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000001 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000

  • Hi Chris,

    Thanks - this is exactly what I was looking for.

    Yes these registers are in the TRM, in the EMAC/MDIO chapter reference manual.   There are actually three different register frames in this module, which may be why it's hard to find.  There's a frame called "EMAC Control Module Registers"   which is sort of a top-level wrapper control around the MAC, it's DMA enginee, and the MDIO interface,  This is where the last steps are in interrupt generation before the interrupt goes to the VIM.     There's also a frame for the MAC, and for the MDIO.

    From what I see, it looks like the TX channel interrupt is enabled and still pending. 

     

    4EC80100 00000000 00000000 00000000 00000000 00000001 00000001  << Enabled
    00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000001 00000000 00000000  << Pending
    00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000

    But I might be counting addresses wrong...  I'm counting the second '1' as address offset 0x48,  which is C0TXSTAT and has the description below.

    Problem might be as simple as deleting the clearing of C0TXSTAT when modifying the driver files.  I'm not familiar enough with the lwIP example to know where it's done but should be easy enough to search for.

  • Interesting, now I have someplace to look.   I did write this function to print out the interrupt status, it was displaying 0,0 but the memory dump says otherwise.

    C0RXSTAT is a R/O register at 0x44, C0TXSTAT is at 0x48.   (I found the list of register offsets in the manual, thanks).   They are not cleared as they are only read only.

    But I'll look into the C0TXPULSE next.

    Now the emac core is always acknowledged with a tx or rx irq, regardless if a packet is destined for this board, the lwip interrupt handler processes a packet only if the SOP flag is set for a particular board.

    void EMACDisplayInterruptStatus(uint32 emacBase)
    {
    rt_printf("EMAC Interrupt Status RX = 0x%x TX = 0x%x",
    HWREG(emacBase + EMAC_CTRL_C0RXSTAT), HWREG(emacBase + EMAC_CTRL_C0TXSTAT));

    rt_printf("Bit 0..7 = Channel 0..7 (1) satisfies conditions to generate C0RXPULSE");


    rt_printf("EMAC Misc Interupt Status 0x%x", HWREG(emacBase + EMAC_CTRL_C0MISCSTAT));
    rt_printf("Bit 0 = Userint0stat Bit 1 = Linint0stat Bit 2 = Hostpendstat Bit 3 = statpendstat");
    }

    This is always called with each irq.

    EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
    EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);

  • Hi Chris,

    This looks like it could be very relevant (From http://processors.wiki.ti.com/index.php/HALCoGen_Ethernet_Driver_and_lwIP_Integration_Demonstration):

    The following guidelines should be observed when writing an EMAC interrupt service routine (ISR):
    • In an EMAC Transmit ISR, the interrupt must be acknowledged to the EMAC hardware using EMACCoreIntAck(). However, the interrupt will be cleared only if the completion pointer is written using the EMACTxCPWrite() API with the last processed TX buffer descriptor.

    Would you please check whether the EMACTxCPWrite() call is being made, and if so whether it's being made with the correct buffer descriptor pointer?