FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
5892 Discussions

DE2 Ethernet Primitive Solution

Altera_Forum
Honored Contributor II
1,441 Views

With the DE2 board, the Ethernet controller does not seem to work in Quartus II 8.0 or 8.1. There are several problems with the DE2_NET demonstration; it was built pre-7.1, the software driver does not work, the support is for crap, nobody seems to post anything useful on this topic etc. So here is the answer I would have killed for a month ago; in the DM9000A ISR, re-initialize the DM9000A and set a flag. In the main program loop, register the ISR again and clear the flag.  

 

Sample code: 

 

//--------------------------------------------------------------# include "basic_io.h"# include "test.h"# include "LCD.h"# include "DM9000A.C" 

# define DE2_8_7Segs_BASE 0x01901028 

 

 

unsigned int aaa,rx_len,i,packet_num; 

unsigned char RXT[68]; 

unsigned int EnetReceive; 

 

 

void ethernet_interrupts() 

packet_num++; 

aaa=ReceivePacket (RXT,&rx_len); 

 

//Do your processing here.  

 

//Reinitialize the DM9000A and set the flag to setup the  

//ISR pointer. 

DM9000_init(); 

EnetReceive = TRUE; 

 

 

int main(void) 

unsigned int Success; 

 

unsigned char TXT[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 

0x01,0x60,0x6E,0x11,0x02,0x0F, 

0x08,0x00,0x11,0x22,0x33,0x44, 

0x55,0x66,0x77,0x88,0x99,0xAA, 

0x55,0x66,0x77,0x88,0x99,0xAA, 

0x55,0x66,0x77,0x88,0x99,0xAA, 

0x55,0x66,0x77,0x88,0x99,0xAA, 

0x55,0x66,0x77,0x88,0x99,0xAA, 

0x55,0x66,0x77,0x88,0x99,0xAA, 

0x55,0x66,0x77,0x88,0x99,0xAA, 

0x00,0x00,0x00,0x20 }; 

 

 

//Initialize the LCD. 

LCD_Init(); 

 

//Test the LCD. 

Success = DM9000_init(); 

LCD_Show_Text(""); 

if (Success == DMFE_SUCCESS) 

//Tell the user if the DM9000A initialize or failed.  

LCD_Show_Text("DM9000A"); 

LCD_Line2(); 

LCD_Show_Text("Initialized."); 

alt_irq_register( DM9000A_IRQ, NULL, (void*)ethernet_interrupts );  

else 

LCD_Show_Text("DM9000 Failed."); 

 

 

packet_num=0; 

EnetReceive = FALSE; 

//Main loop. 

while (Success == 0) 

//Register the ISR again after the ISR has fired and the device has been  

//re-initialized.  

if (EnetReceive == TRUE) 

alt_irq_register( DM9000A_IRQ, NULL, (void*)ethernet_interrupts );  

EnetReceive = FALSE; 

Success = TransmitPacket(TXT,0x40); 

msleep(500); 

outport(DE2_8_7SEGS_BASE ,packet_num); 

 

LCD_Show_Text("TX Failed."); 

 

return 0; 

 

//------------------------------------------------------------------------- 

/* 

To get a full grasp of why this works read ·http://www.altera.com/literature/hb/nios2/n2sw_nii52006.pdf 

If you are doing this as a continuing project, become very familiar with  

 

the ISO-OSI 7 model and device networking. 

Note: 

Currently this code is very sloppy and needs revision. The true event 

in the init function needs to be determined. The only reason I posted this 

"as-is" was because of the crazy ammount of time I spent on this problem 

and the elation which comes with success. 

 

*/
0 Kudos
21 Replies
Altera_Forum
Honored Contributor II
62 Views

 

--- Quote Start ---  

hi, 

I found there are some problem with the ReceivePacket function: I post my code: 

unsigned int ReceivePacket (unsigned char *data_ptr,unsigned int *rx_len) 

unsigned char rx_READY,GoodPacket; 

unsigned char Tmp, RxStatus; 

unsigned int high_b,low_b; 

unsigned int i; 

 

RxStatus = rx_len[0] = 0; 

GoodPacket=FALSE; 

 

/* mask NIC interrupts IMR: PAR only */ 

iow(IMR, PAR_set); 

 

 

/* dummy read a byte from MRCMDX REG. F0H */ 

rx_READY = ior(MRCMDX); 

 

/* got most updated byte: rx_READY */ 

rx_READY = IORD(DM9000A_BASE,IO_data)&0x03; 

usleep(STD_DELAY); 

/* reset the read pointer*/  

Tmp = ior(0xF5);  

printf("RD_P:0x%02X",Tmp);  

Tmp = ior(0xF4);  

printf("%02X\n",Tmp);  

 

Tmp = ior(0x25);  

printf("WR_P:0x%02X",Tmp);  

Tmp = ior(0x24);  

printf("%02X\n",Tmp);  

 

 

/* check if (rx_READY == 0x01): Received Packet READY? */ 

if (rx_READY == DM9000_PKT_READY) 

/* got RX_Status & RX_Length from RX SRAM */ 

 

 

 

IOWR(DM9000A_BASE, IO_addr, MRCMD); /* set MRCMD REG. F2H RX I/O port ready */ 

usleep(STD_DELAY); 

IORD(DM9000A_BASE,IO_data); /*move pointer to status address*/  

RxStatus = IORD(DM9000A_BASE,IO_data); 

usleep(STD_DELAY); 

low_b = IORD(DM9000A_BASE,IO_data); 

high_b = IORD(DM9000A_BASE,IO_data); 

rx_len[0] = high_b<<8; 

rx_len[0] = rx_len[0]+low_b - 4; 

 

/* Check this packet_status GOOD or BAD? */ 

if ( !(RxStatus & 0xBF) && (rx_len[0] < MAX_PACKET_SIZE) ) 

/* read 1 received packet from RX SRAM into RX buffer */ 

for (i = 0; i < rx_len[0]; i += 1) 

usleep(STD_DELAY); 

data_ptr[i] = IORD(DM9000A_BASE, IO_data); 

 

/* dump the 4 BYTE FCS */ 

IORD(DM9000A_BASE, IO_data); 

IORD(DM9000A_BASE, IO_data); 

IORD(DM9000A_BASE, IO_data); 

IORD(DM9000A_BASE, IO_data); 

GoodPacket=TRUE; 

} /* end if (GoodPacket) */ 

else 

/* this packet is bad, dump it from RX SRAM */ 

for (i = 0; i < rx_len[0]; i += 1) 

usleep(STD_DELAY); 

Tmp = IORD(DM9000A_BASE, IO_data);  

/* dump the 4 BYTE FCS */ 

IORD(DM9000A_BASE, IO_data); 

IORD(DM9000A_BASE, IO_data); 

IORD(DM9000A_BASE, IO_data); 

IORD(DM9000A_BASE, IO_data); 

printf("\nError\n"); 

rx_len[0] = 0; 

} /* end if (!GoodPacket) */ 

} /* end if (rx_READY == DM9000_PKT_READY) ok */ 

else if(!rx_READY) /* status check first byte: rx_READY Bit[1:0] must be "00"b or "01"b */ 

 

/* software-RESET NIC */ 

iow(NCR, 0x03); /* NCR REG. 00 RST Bit [0] = 1 reset on, and LBK Bit [2:1] = 01b MAC loopback on */ 

usleep(20); /* wait > 10us for a software-RESET ok */ 

iow(NCR, 0x00); /* normalize */ 

iow(NCR, 0x03); 

usleep(20); 

iow(NCR, 0x00);  

/* program operating registers~ */ 

iow(NCR, NCR_set); /* NCR REG. 00 enable the chip functions (and disable this MAC loopback mode back to normal) */ 

iow(0x08, BPTR_set); /* BPTR REG.08 (if necessary) RX Back Pressure Threshold in Half duplex moe only: High Water 3KB, 600 us */ 

iow(0x09, FCTR_set); /* FCTR REG.09 (if necessary) Flow Control Threshold setting High/ Low Water Overflow 5KB/ 10KB */ 

iow(0x0A, RTFCR_set); /* RTFCR REG.0AH (if necessary) RX/TX Flow Control Register enable TXPEN, BKPM (TX_Half), FLCE (RX) */ 

iow(0x0F, 0x00); /* Clear the all Event */ 

iow(0x2D, 0x80); /* Switch LED to mode 1 */ 

/* set other registers depending on applications */ 

iow(ETXCSR, ETXCSR_set); /* Early Transmit 75% */ 

/* enable interrupts to activate DM9000 ~on */ 

iow(IMR, INTR_set); /* IMR REG. FFH PAR=1 only, or + PTM=1& PRM=1 enable RxTx interrupts */ 

/* enable RX (Broadcast/ ALL_MULTICAST) ~go */ 

iow(RCR , RCR_set | RX_ENABLE | PASS_MULTICAST); /* RCR REG. 05 RXEN Bit [0] = 1 to enable the RX machine/ filter */ 

} /* end NIC H/W system Data-Bus error */ 

iow(ISR, 0x01); 

iow(IMR, INTR_set); 

// iow(0x0F, 0x00); 

//iow(IMR, INTR_set); 

return GoodPacket ? DMFE_SUCCESS : DMFE_FAIL; 

 

I added the code(red), the problem you mentioned is solved.  

 

the reason is MII added 4 byte FCS, When you read the packet, you should discard them, otherwise when you read the packet next time,you SRAM read pointer will point to the address less 4 byte than the right address,so it doesn't work. 

 

I also find the receive packet function doesn't clear the interrupt and re enable the receive packet interrupt again, so I added the code for it. 

 

Now ,you can try it , good luck 

--- Quote End ---  

 

 

 

 

 

 

thanks a lot i succesfully received data from PC to my DE2-70 board . But sometime i am getting wrong values. what should i do to get correct packet which send by some source to my DE2-70 board . thankyou lot
0 Kudos
Reply