cancel
Showing results for 
Search instead for 
Did you mean: 

ENET DMA overflow on receive

jwester9
Associate II
Posted on October 17, 2007 at 06:38

ENET DMA overflow on receive

13 REPLIES 13
sarao
Associate II
Posted on May 17, 2011 at 09:47

Andras,

Thanks for the tip. I got real excited and thought this might be it! But it looks like this is taken care of in the IRQ.s code.

Code:

LDR R1, =VectorAddrDaisy ; Write to the VectorAddressDaisy to

STR R1, [R1] ; clear the respective Interrupt

Good thought though!

alandras
Associate II
Posted on May 17, 2011 at 09:47

Next tip:

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

cheers,

Andras

jwester9
Associate II
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

jwester9
Associate II
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