⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv_8019.c

📁 在89C51上实现TCPIP协议
💻 C
📖 第 1 页 / 共 2 页
字号:
		next_frame = ethernet_8390_hdr[1];
		
		/* This _should_ never happen: it's here for avoiding bad clones. */
		if (next_frame >= RX_STOP_PG) { /* next frame inconsistency */
			next_frame = RX_START_PG;
		}
		current_page = next_frame;
		EN0_BOUNDARY = next_frame-1;
	}

	/* We used to also ack ENISR_OVER here, but that would sometimes mask
    a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
    EN0_ISR = ENISR_RX+ENISR_RX_ERR;
}

//void ei_input(byte *buf, word StartAddr, word Count)
void ei_input(byte *buf, word StartAddr, word Count) reentrant
{
    word loop;
        
    EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
    /* Set Remote byte count */
    EN0_RCNTLO = (byte)(Count & 0xff);	 /*  Low  byte of tx byte count  */
    EN0_RCNTHI = (byte)(Count >> 8);	/*  High byte of tx byte count  Transmit byte count register */

    /* Set Remote Start Address */
    EN0_RSARLO = (byte)(StartAddr & 0xff);     /*LSB Remote start address reg  */
    EN0_RSARHI = (byte)(StartAddr >> 8);     /*  MSB Remote start address reg  */
		
    EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
    for(loop=0;loop < Count;loop++){
        *buf++ = EN_DATA; 
    }
    EN0_ISR = ENISR_RDC;	/* Ack intr. to Remote DMA */
}

//void ethernet_get_8390_hdr( word StartAddr, word Count)
void ethernet_get_8390_hdr( word StartAddr, word Count) reentrant
{
    word loop;
        
    EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
    /* Set Remote byte count */
    EN0_RCNTLO = (byte)(Count & 0xff);	 /*  Low  byte of tx byte count  */
    EN0_RCNTHI = (byte)(Count >> 8);	/*  High byte of tx byte count  Transmit byte count register */

    /* Set Remote Start Address */
    EN0_RSARLO = (byte)(StartAddr & 0xff);     /*LSB Remote start address reg  */
    EN0_RSARHI = (byte)(StartAddr >> 8);     /*  MSB Remote start address reg  */
		
    EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
    for(loop=0;loop < Count;loop++){
        ethernet_8390_hdr[loop] = EN_DATA;
    }
    EN0_ISR = ENISR_RDC;	/* Ack intr. to Remote DMA */
}

void ei_rx_overrun( void )
{
	byte was_txing, must_resend = 0;

	//print_int("OVER");
	/* Record whether a Tx was in progress 
	   and then issue the stop command.	*/
	
	was_txing = EN_CMD & EN_TRANS;
	EN_CMD = EN_NODMA + EN_PAGE0 + EN_STOP;
	
	delay_1ms(2);   /* I don't know exactly time yet.. at least 2ms */

	/** Reset RBCR[01] back to zero as per magic incantation. */
	EN0_RCNTLO = 0x00;
	EN0_RCNTHI = 0x00;

	/* See if any Tx was interrupted or not. According to NS, this
	   step is vital, and skipping it will cause no end of havoc. */
	if (was_txing) { 
		if (!(EN0_ISR & (ENISR_TX + ENISR_TX_ERR))) must_resend = 1;
   	}

	/* Have to enter loopback mode and then restart the NIC before
	  you are allowed to slurp packets up off the ring.	 */
	EN0_TXCR = E8390_TXOFF;
	EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;

	/* Clear the Rx ring of all the debris(颇祈), and ack the interrupt. 	*/
	ei_receive();
	EN0_ISR = ENISR_OVER;
	
	/* Leave loopback mode, and resend any packet that got stopped.	 */
	EN0_TXCR = E8390_TXCONFIG;
	if (must_resend) EN_CMD = EN_NODMA + EN_PAGE0 + EN_START + EN_TRANS;
	
}
    
void ethernet_register_test(void)   /* All Register test */
{
    byte i,read,write;
    
    print("\n\r------------------------------------------------------------------------");
    print("\n\rAddr       Page0         Page1         Page2         Page3");
    print("\n\r         Write/Read   Write/Read     Write/Read    Write/Read");
    print("\n\r------------------------------------------------------------------------");                    
    for (i=0; i < 16; i++) {
         /* Page0 select  */
         EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
         print("\n\r"); putb_ser(i);print("       ");         
         write = EN_PAGE0 + EN_NODMA + EN_START; 
      /*   outportb(i,write);  */
         putb_ser(write);  
         print("    "); read = inportb(i);
         putb_ser(read); print("     ");

         /* Page1 select */
         EN_CMD = EN_PAGE1 + EN_NODMA + EN_START;
         write = EN_PAGE1 + EN_NODMA + EN_START;
         /* outportb(i,write);  */
         putb_ser(write); print("    ");
         read = inportb(i);
         putb_ser(read); print("       ");

         /* Page2 select */
         EN_CMD = EN_PAGE2 + EN_NODMA + EN_START;
         print("x     ");
         read = inportb(i);
         putb_ser(read); print("      ");

         /* Page3 select */
         EN_CMD = EN_PAGE3 + EN_NODMA + EN_START;
         write = EN_PAGE3 + EN_NODMA + EN_START;
    /*     outportb(i,write);  */
         putb_ser(write);  
         print("    ");
         read = inportb(i);
         putb_ser(read); print("      ");
    }
    print("\n\r------------------------------------------------------------------------\n\r");
}

//*****************************************************************************/
//*		D M A   Write                                                                                                                */
//*****************************************************************************/
void DMA_write(byte *buffer, word StartAddr, word Count)
{
    word loop;
    
    //print("\n\rDMA write : "); 
    EN_CMD = EN_PAGE0 + EN_NODMA + EN_START; /* Remote DMA, Start the chip, clear reset */
    
    EN0_RCNTLO = (byte)(Count & 0xff);  /*  LSB Remote byte count reg  */
    EN0_RCNTHI = (byte)(Count >> 8);  /*  MSB Remote byte count reg  */

    EN0_RSARLO = (byte)(StartAddr & 0xff);   /*  LSB Remote start address reg  */
    EN0_RSARHI = (byte)(StartAddr >> 8);     /*  MSB Remote start address reg  */
    
    EN_CMD = EN_PAGE0 + EN_RWRITE + EN_START; /* Remote Write, Start the chip, clear reset */
    for(loop=0;loop < Count;loop++){
        EN_DATA = *buffer++;
        //putb_ser(*buffer++);       
    }
      
}


/*****************************************************************************/
/*		D M A   Read                                                         */
/*****************************************************************************/
void ethernet_test(void)
{
    byte    temp1,temp2;
    
    print("\n\n\r/*****************************************************************/\n\r");
	print("/*   RTL8019AS TEST ROUTINE     0.5.2                            */\n\r");
	print("/*   If you see 0x50 and 0x70 or 'P' and 'p', it operate well    */\n\r");
    print("/*****************************************************************/\n\r");
       
    temp1 = EN0_8019ID0;  /* EN0_8019ID0 */
    temp2 = EN0_8019ID1;  /* EN0_8019ID1 */
    putb_ser(temp1);
    putb_ser(temp2);

    if ((temp1 != 0x50)|(temp2 != 0x70)) {
        print("       Circuit have H/W problem.\n\r");
        
    }
    print("      Circuit OK!\n\r");

    
#ifdef STRING_TEST
    test = 0x1234;
    printf("\n\n\r%x         %d  ",test,test);
    putb_ser(test);
    test1 = (byte)test;
    printf("\n\n\r%x         %d  ",test1,test1);
#endif

}

/*****************************************************************************/
/*		              RTL8019AS  Initialize                                  */
/*****************************************************************************/
void ethernet_init(void)
{
    word i;

#ifdef RTL8019AS_ID_CHECK
    ethernet_test();
#endif
    
    EN_RESET = 0x00;        /* very important !!!!!    */
    for (i=0;i<DELAY;i++);

    EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
    EN0_DCFG = ENDCFG_FT10 + ENDCFG_BMS + ENDCFG_BOS;   /*  ?FIFO treshold 8byte !!,normal operation, byte transfer mode selection */

    /* Clear the remote	byte count registers. */
    EN0_RCNTHI = 0x00; /* MSB remote byte count reg */
    EN0_RCNTLO = 0x00; /* LSB remote byte count reg */

    EN0_RXCR = E8390_RXOFF; /* RX configuration reg    Monitor mode (no packet receive) */
    EN0_TXCR = E8390_TXOFF; /* TX configuration reg   set internal loopback mode  */
    
    EN0_TPSR = NE_START_PG;
    EN0_STARTPG = RX_START_PG ; /* 菩哦 荐脚矫俊 肺拿 DMA啊 荐脚窍绰 其捞瘤甫 瘤沥茄促. 46h */ 
                                /* Starting page of ring buffer. First page of Rx ring buffer 46h*/
    EN0_BOUNDARY = RX_START_PG;	/* Boundary page of ring buffer */
    EN0_STOPPG = NE_STOP_PG;    /* Ending page +1 of ring buffer */
    
    EN_CMD = EN_PAGE1 + EN_NODMA + EN_STOP;
    EN1_CURR = RX_START_PG + 1; /* RX_CURR_PG; Current memory page = RX_CURR_PG  ? */
	current_page = RX_START_PG + 1;	/* assert boundary+1 */
    next_pkt = RX_START_PG + 1; 
    EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP;
    EN0_ISR = 0xff; /* INTerrupt stauts reg */
      /* Host绰 牢磐反飘甫 老栏虐绰 巴阑 茫酒郴扁困秦 佬绰促. 
      阿 厚飘绰 包访等 bit俊 1阑 结 持澜栏肺辑 努府绢 等促. 
      弊巴篮 颇况诀 饶俊 馆靛矫 努府绢 登绢具茄促.(must)     */
    EN0_IMR = 0; /* INTerrupt mask reg = Disable all Interrupt */
    
    EN_CMD = EN_NODMA + EN_PAGE1 +  EN_STOP; /* Select page 1, remote DMA */
       
    EN1_PAR0 = 0x12;
    EN1_PAR1 = 0x34;
    EN1_PAR2 = 0x56;
    EN1_PAR3 = 0x78;
    EN1_PAR4 = 0x9A;
    EN1_PAR5 = 0xBC;
    /* Initialize the multicast list to accept-all.  If we enable multicast
	   the higher levels can do the filtering. multicast filter mask array (8 bytes) */
    EN1_MAR0 = 0xff;  
    EN1_MAR1 = 0xff;
    EN1_MAR2 = 0xff;
    EN1_MAR3 = 0xff;
    EN1_MAR4 = 0xff;
    EN1_MAR5 = 0xff;
    EN1_MAR6 = 0xff;
    EN1_MAR7 = 0xff;
    
    EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP;  /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
 
    EN0_ISR = 0xff; 	/* Individual bits are cleared by writing a "1" into it. */
    					/* It must be cleared after power up. */
    EN0_IMR = ENISR_ALL; /* INTerrupt mask reg */

    EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
    EN0_TXCR = ENTXCR_TXCONFIG;      /* xmit on. */
    /* 3c503 TechMan says rxconfig only after the NIC is started. */
    EN0_RXCR = ENRXCR_RXCONFIG;      /* rx on(broadcasts, no multicast,errors */
	
	CONFIG1 = 0x90;   /* IRQ enable + INT0:IRQ2/9(pin 4) + I/O BASE(300H) */
	CONFIG2 = 0x00;
	CONFIG3 = 0xf0;
	CONFIG4 = 0x00;
	
	EthRxBufRdPtr = 0;
	EthRxBufWrPtr = EthRxBufRdPtr + 1;
	
	EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -