Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
19 years ago

dma and lan91 test problem

int alt_avalon_lan91c111_output(alt_avalon_lan91c111_if *dev, void *buffer, alt_u32 length)

{

alt_u8 irq_value;

alt_u16 mmu_status;

alt_u32 remainder;

alt_u32 len = length;

alt_u8 buffer1[200];

void *buf =(void *) buffer;

void *test;

alt_dma_txchan txchan;

int tx,i,k;

buffer1[0]=0x10;

buffer1[1]=0x11;

buffer1[2]=0x12;

buffer1[3]=0x13;

buffer1[4]=0x14;

buffer1[5]=0x15;

IOWR_32DIRECT(0x1055248, 0, 0x87654321);

/* Wait for the last Tx to complete */

do

{

irq_value = IORD_ALTERA_AVALON_LAN91C111_IST(dev->base_addr);

}while(!(irq_value & ALTERA_AVALON_LAN91C111_INT_TX_EMPTY_INT_MSK));

/* Clear the interrupt */

IOWR_ALTERA_AVALON_LAN91C111_ACK( dev->base_addr,

ALTERA_AVALON_LAN91C111_INT_TX_EMPTY_INT_MSK);

/* Always re-use the same packet */

IOWR_ALTERA_AVALON_LAN91C111_PNR( dev->base_addr,

dev->tx_packet_no);

IOWR_ALTERA_AVALON_LAN91C111_PTR( dev->base_addr,

ALTERA_AVALON_LAN91C111_PTR_AUTO_INCR_MSK);

/* The status word */

IOWR_ALTERA_AVALON_LAN91C111_DATA_HW( dev->base_addr, 0);

/*

* The byte count including the 6 control bytes

*

* Bit odd this, but the length is always written as even, if the frame is an odd length

* then the byte is written as one of the control words and an appropriate bit is set

*

*/

IOWR_ALTERA_AVALON_LAN91C111_DATA_HW( dev->base_addr, ((length & ~1) + 6));

/*

* Write buffer of data to the device

*

* Nios requires accesses to be aligned on the correct boundary

*

*/

while ((int)buf & 3)

{

IOWR_ALTERA_AVALON_LAN91C111_DATA_BYTE( dev->base_addr, *((alt_u8*)buf)++);

len--;

}

remainder = len & 3;

/* Write out the 32 bit values */

len>>=2;

if (len < 186){

while (len & ~7) /* Write 8-tuples of 32 bit values */

{

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

len-=8;

}

while (len)

{

IOWR_ALTERA_AVALON_LAN91C111_DATA_WORD( dev->base_addr, *((alt_u32*)buf)++);

len--;

}

}else{

test = buf;

for(i=0; i<= 200; i+=1)

{

printf("00:%x,%x\n",((alt_u32*)test)+i,*((alt_u32*)test+i));

}

if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL)

{

exit (1);

}

//printf ("0: %d,%d,%d\n",remainder,(alt_u8*)buf,*(alt_u8*)buf);

printf ("0: %d,%d,%d\n",len*4,(alt_u8*)buf,*(alt_u8*)buf);

alt_dma_rxchan_ioctl (txchan,0x3, dev->base_addr+8);

alt_dma_rxchan_ioctl (txchan,0x7, dev->base_addr+8);

if ((tx = alt_dma_txchan_send (txchan,buf,len*4,dma_tx,NULL)) < 0)

{

printf ("1: %d\n", tx);

exit(1);

}

while (!tx_done);

//printf ("2: %d\n", tx);

(alt_u8*)buf=(alt_u8*)buf+len*4;

IOWR_ALTERA_AVALON_LAN91C111_PTR( dev->base_addr,0x6000);

for(i=0; i<= 800; i+=4)

{

k = IORD_32DIRECT(dev->base_addr,8);

printf("%x\n",k);

}

//printf ("2: %d,%d,%d\n",remainder,(alt_u8*)buf,*(alt_u8*)buf);

printf ("2: %d,%d,%d\n",len*4,(alt_u8*)buf,*(alt_u8*)buf);

alt_dma_txchan_close (txchan);

len = 0;

tx_done = 0;

}

while (remainder)

{

IOWR_ALTERA_AVALON_LAN91C111_DATA_BYTE( dev->base_addr, *((alt_u8*)buf)++);

remainder--;

}

if (length & 1)

{

IOWR_ALTERA_AVALON_LAN91C111_DATA_BYTE( dev->base_addr,

ALTERA_AVALON_LAN91C111_CONTROL_ODD_MSK);

}

else

{

IOWR_ALTERA_AVALON_LAN91C111_DATA_HW( dev->base_addr, 0);

}

/*

* Accesses to the MMUCR have to be protected with a semaphore as it&#39;s possible

* that we could wait for this register not to be busy and in between our read

* and the write an interrupt could occur which causes the scheduler to run and

* the ethernet_rx thread could be run!

*/

# if 0

ALT_SEM_PEND(dev->semaphore, 1);# endif

/* Wait for any pending commands to complete */

do

{

mmu_status = IORD_ALTERA_AVALON_LAN91C111_MMUCR(dev->base_addr);

}while (mmu_status & ALTERA_AVALON_LAN91C111_MMUCR_BUSY_MSK);

/* Queue the packet */

IOWR_ALTERA_AVALON_LAN91C111_MMUCR( dev->base_addr,

ALTERA_AVALON_LAN91C111_MMUCR_ENQUEUE_MSK);# if 0

ALT_SEM_POST(dev->semaphore);# endif

return 0;

}

the code is altera_avalon_lan91c111.c in lwip.I write some change to test!!when i change if ((tx = alt_dma_txchan_send (txchan,buf,len*4,dma_tx,NULL)) < 0) to if ((tx = alt_dma_txchan_send (txchan,buffer1,len*4,dma_tx,NULL)) < 0) then k = IORD_32DIRECT(dev->base_addr,8);is 0x13121110;but when ((tx = alt_dma_txchan_send (txchan,buf,len*4,dma_tx,NULL)) < 0) to ((tx = alt_dma_txchan_send (txchan,buf,len*4,dma_tx,NULL)) < 0) .the k =0;why?

i think niosII ide have some bug?can you help me?or somebody change the lwip use dma operation on lan91c111?
No RepliesBe the first to reply