Forum Discussion
Altera_Forum
Honored Contributor
16 years agohi,
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