Skip to main content
Visitor II
October 17, 2007
Question

ENET DMA overflow on receive

  • October 17, 2007
  • 13 replies
  • 2569 views
Posted on October 17, 2007 at 06:38

ENET DMA overflow on receive

    This topic has been closed for replies.

    13 replies

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:47

    Next tip:

    What is the purpose of that endless while(1) ???

    cheers,

    Andras

    jwester9Author
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:47

    Jsarao

    I had same problem, on heavy traffic it suddenly stoped, no more interrupts.

    I take lot of code from Keil ENET driver and also modified, and now its works.

    First, Keil use its own software to handle descriptors, and I think it is a bug in ST software (version 1.1), the init routine of RX descriptor don't set the NPOL_EN bit on the last descriptor, maybe the problem is there.

    Here is my interrupt code

    void

    ENET_interrupt(struct netif *netif)

    {

    struct ethernetif *ethernetif = netif->state;

    int err = 0;

    u16 len;

    u32 i, j, int_stat, RxLen;

    u32 *sp,*dp;

    while((int_stat = (ENET_DMA->ISR & ENET_DMA->IER)) != 0) {

    /* Acknowledge the ENET interrupts. */

    ENET_DMA->ISR = int_stat;

    /* RX interrupt */

    if(int_stat & DMI_RX_CURRENT_DONE) {

    /* Valid frame has been received. */

    for(j = 0, i = RxBufIndex; j < NUM_RX_BUF; j++) {

    /* Find it in the DMA Descriptor List. */

    if((Rx_Desc[i].Stat & DMA_DSCR_RX_STATUS_VALID_MSK) == 0) {

    /* OK, a packet is found, check if any error */

    if(Rx_Desc[i].Stat & DMA_DSCR_RX_STATUS_ERROR_MSK) {

    /* Error, free packet. */

    err = TRUE;

    }

    /* Check frame length. */

    RxLen = (Rx_Desc[i].Stat & DMA_DSCR_RX_STATUS_FLEN_MSK);

    if(RxLen > netif->mtu) {

    /* Packet length too big */

    err = TRUE;

    }

    if(!err) {

    /* Valid packet, wake up input Thread */

    if(!ethernetif->rxData) { // No pending inputs ?..

    QPut(THREAD_LWIP, PRIO_NORMAL, EVT_RCV0, 0);

    }

    ethernetif->rxData++; // Coun up pending inputs

    } else {

    /* No valid packet, free packet. */

    Rx_Desc[i].Stat = DMA_DSCR_RX_STATUS_VALID_MSK;

    }

    /* Count to next */

    if(++i == NUM_RX_BUF) i = 0;

    } else {

    /* Count to next */

    if(++i == NUM_RX_BUF) i = 0;

    /* Set next receive */

    RxBufIndex = i;

    }

    }

    }

    /* TX interrupt */

    if(int_stat & DMI_TX_CURRENT_DONE) {

    /* Frame transmit completed. */

    for (i = 0; i < NUM_TX_BUF; i++) {

    if ((Tx_Desc[i].Ctrl & DMA_DSCR_TX_STATUS_VALID_MSK) == 0) {

    /* Release Transmited frames from DMA buffer. */

    Tx_Desc[i].Ctrl = 0;

    }

    }

    }

    }

    /* Acknowledge the VIC interrupt. */

    VIC0->VAR = 0;

    }

    The Qput function mails input to wakeup the input-thread and the thread moves data from descriptors to buffers in my system

    jwester9Author
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:47

    Hi

    If you missing interrupt, also check spurious interrupt.

    you have to setup

    VIC0_DVAR = (u32)Default0_IRQHandler;

    VIC1_DVAR = (u32)Default1_IRQHandler;

    Search in forum for how todo