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

📄 ether_dev.c

📁 包括EPA协议栈
💻 C
字号:
//ether_dev.c
#define  ETHER_DEV_GLOBALS

#include "ether_dev.h"

/************************************************************************/
/*ether_dev.c                                 */  
/************************************************************************/



extern uint16 *byBuf;
 

//extern uint16 *RecvbufMalloc(void);
//Register definition
//next receive buffer pointer
uint8 byNextp[2];
//AX88796 work state        
uint16 EtherStat[2];
//data send finish flag     
uint16 SendFinished[2] = {1,1};
//AX88796 reveice buffer has data   
uint16 HasData[2] = {0,0};
//AX88796 receive data information  
uint16 RcvDataInfo[2];
//physical addr buffer      
uint8 Local_MAC[2][6];      
uint8 nichAddr[2][6];
//protocal addr buffer
uint8 nicpAddr[2][4];
//send total data counter       
INT32U trnNum[2];
//receive total data counter
INT32U recNum[2];
//error send total data counter     
INT32U trnErr[2];
//error data total receive
INT32U recErr[2];
//data overflow counter
INT32U overflowErr[2];

uint8 temp1;

#define IRQ1_INTERRUPT_LEVEL		1
#define IRQ2_INTERRUPT_LEVEL		2
extern void irq1_asm_irq_handler(void); 
extern void irq2_asm_irq_handler(void); 





//88796 register read and write sub function
void OutportByte(uint16 idx,uint8 addr,uint8 tempData)
{

    if(idx)
    {
        *((uint8*)(addr + 0x200 + Ethernet_Addr_Base1) ) = tempData;
    }
    else
    {
        *((uint8*)(addr + 0x200 + Ethernet_Addr_Base0) ) = tempData;
    }
}



//Read byte data
uint8 InportByte(uint16 idx,uint8 addr)
{
    if(idx)
    {
        return *((uint8*)(addr  + 0x200 + Ethernet_Addr_Base1));
    }
    else
    {
        return *((uint8*)(addr  + 0x200 + Ethernet_Addr_Base0));
    }
}


/************************************************************************/
/*AX88796 initialization sub fuction                    */
/************************************************************************/
uint16 etherdev_init(uint16 idx)
{
    //Software reset 
    InportByte(idx,NIC_RESET);
    //Page 0, stop, no DMA      
    OutportByte(idx,CR, 0x21);
    //8086、WORD-wide DMA mode transfer     
    OutportByte(idx,DCR, 0x81);
    //Brocast,Multicast Package receive         
    OutportByte(idx,RCR, 0x4c);
    //Internal AX88796 loop-back        
    OutportByte(idx,TCR, 0xc0);
    //Clear remote byte count register      
    OutportByte(idx,RBCR0, 0);       
    OutportByte(idx,RBCR1, 0);
    //Init interrupt mask register 
    OutportByte(idx,IMR, 0x3f);
    //Clear interrupt status register       
    OutportByte(idx,ISR, 0xFF);
    //Init data read boundary page      
    OutportByte(idx,BNDRY, RX_BUF_Start);
    //Init RX_BUF stop page 
    OutportByte(idx,PSTOP, RX_BUF_Stop);
    //Inie RX_BUF start page        
    OutportByte(idx,PSTART, RX_BUF_Start);
    //Page 1, stop, no DMA  
    OutportByte(idx,CR, 0x61);
    temp1 = InportByte(idx,CR);
    // Set local MAC address 
    
    
    OutportByte(idx,PAR0, gnitbl[idx].mac[0]);  
    OutportByte(idx,PAR1, gnitbl[idx].mac[1]);
    OutportByte(idx,PAR2, gnitbl[idx].mac[2]);  
    OutportByte(idx,PAR3, gnitbl[idx].mac[3]);
    OutportByte(idx,PAR4, gnitbl[idx].mac[4]);
    OutportByte(idx,PAR5, gnitbl[idx].mac[5]);    

    OutportByte(idx,MAR0, 0);
    OutportByte(idx,MAR1, 0);
    OutportByte(idx,MAR2, 0);
    OutportByte(idx,MAR3, 0x80);
    OutportByte(idx,MAR4, 0);
    OutportByte(idx,MAR5, 0);
    OutportByte(idx,MAR6, 0);
    OutportByte(idx,MAR7, 0);

    //Init data write pointer
    OutportByte(idx,CURR, RX_BUF_Start+1);
    //Page 0, start, no DMA
    OutportByte(idx,CR, 0x21);
    //data receive next pointer
    byNextp[idx] = RX_BUF_Start+1;
    
    if(InportByte(idx,GPI) & 2)
    {
        //Mode 0, full duplex
        OutportByte(idx,TCR, 0x80);
    }
    else
    {
        OutportByte(idx,TCR, 0x00);
    }
    //Normal power; internal PHY
    OutportByte(idx,GPOC, 0x10);
    //transmit page start addr
    OutportByte(idx,TPSR, 0x40);
    //Remote DMA Active Ax88796 
    OutportByte(idx,CR, 0x22);
    //Ax88796 work state            
    EtherStat[idx] = 1;
    return 1;
}


/************************************************************************/
/* read data                                */  
/************************************************************************/
void readData(uint16 *byBuf,uint16 length,uint16 idx)
{
    uint16 i;
    
    if(idx)
    {
        for(i = 0;i < (length/2);i++)
        {
            *(byBuf+i) = *((uint16 *)(NIC_DATA  +0x200+Ethernet_Addr_Base1));
        }
    }
    else
    {
        for(i = 0;i < (length/2);i++)
        {
            *(byBuf+i) = *((uint16*)(NIC_DATA +0x200+Ethernet_Addr_Base0));
        }
        }
        
}

/************************************************************************/
/* AX88796 receive data                         */  
/************************************************************************/
uint16  EtherInput(uint8* addr, uint16 max_len,uint8 idx)
{
    uint8 RegTemp;
	uint16 RcvDataInfo[2];
	uint16 length;
    //read current page register
    RegTemp=InportByte(idx,CPR);
    while(byNextp[idx]!=RegTemp)
    {   

        OutportByte(idx,RSAR0,0x00);
        OutportByte(idx,RSAR1,byNextp[idx]);
        OutportByte(idx,RBCR0, 0x04);
        OutportByte(idx,RBCR1, 0x00);
        OutportByte(idx,CR, 0x0A);
        // get receive data information
        readData(RcvDataInfo,0x4,idx);
        // data length
        length = RcvDataInfo[1] - 4; 
        
        if(length > max_len)
        {
	return(0);
	}

        OutportByte(idx,RSAR0,0x4);
        OutportByte(idx,RSAR1,byNextp[idx]);
        //received data length
        OutportByte(idx,RBCR0, (uint8)(length& 0x00ff ));
        OutportByte(idx,RBCR1, (uint8)(length >> 8));
        
        OutportByte(idx,CR, 0x0A);
        //read from AX88796 data register
        readData((uint16 *)addr, length,idx);
		
        //set pointer to receive next package
        byNextp[idx] = (uint8)(RcvDataInfo[0] >> 8);
        
        //update current page
        RegTemp=InportByte(idx,CPR);
    }
    //update boundry register
    RegTemp=byNextp[idx]-1;
    if( RegTemp < RX_BUF_Start )
        RegTemp=RX_BUF_Stop-1;
    
    OutportByte(idx,BNDRY, RegTemp);
    return(length);       
}

/************************************************************************/
/* AX88796 data write                           */
/************************************************************************/
void writeData(uint16 *byBuf  ,uint16 length,uint16 idx) 
{
    INT32U i;
    
    if(idx)
    {
        for(i = 0;i < ((length+1) >> 1);i++)
        {
            *((uint16 *)(NIC_DATA  + 0x200 + Ethernet_Addr_Base1)) =*(byBuf+i); 
        }
    }
    else
    {
        for(i = 0;i < ((length+1) >>1 ) ;i++)       
        {
            *((uint16 *)(NIC_DATA  + 0x200 + Ethernet_Addr_Base0)) = *(byBuf+i);  
        }
    }
}
 
/************************************************************************/
/* Trigger send of data in output RAM buffer                */
/************************************************************************/
uint8 EtherOutput(uint8* addr, uint16 len, uint16 hw_id)
{
    uint8  RegTemp;
    uint16 i,j,idx;
    
    idx = hw_id;
    
    if(len < 60)
    {
    len = 60;
    }
     // Reset remote DMA status
    OutportByte(idx,CR, 0x22);
    OutportByte(idx,ISR,0x40);
    OutportByte(idx,RSAR0,0x0);
    OutportByte(idx,RSAR1,0x40);
    // Length
    OutportByte(idx,RBCR0, (uint8)(len & 0xFF));
    OutportByte(idx,RBCR1, (uint8)(len>>8));
    OutportByte(idx,CR, 0x12);

    //data from cpu to nic
    writeData((uint16 * )addr,len,idx);
    //renew send pointer
    OutportByte(idx,TBCR0, (uint8)(len & 0xFF));
    OutportByte(idx,TBCR1, (uint8)(len>>8));            
    OutportByte(idx,ISR,0x2);                      
    OutportByte(idx,TPSR, TX_BUF_Start );
    //Begin to send data
    OutportByte(idx,CR,0x26);

    for(i=0;i <1000;i++)
    {
        //ISR register show dasta send complete
        RegTemp = InportByte(idx,ISR);
        if(RegTemp & 0x02)
        {
            break;
        }
        for(j=0;j<100;j++)
        {
            ;
        } 
    }
    return SYS_NO_ERR;
}


/************************************************************************/
/*interrupt process handler                       */
/************************************************************************/
void at91_IRQ1_handler(void)
{
	uint8 RegTemp;
	
	static uint8 idx;

	idx = 0;

	RegTemp = InportByte(idx,ISR);		//read interrupt register status

	OutportByte(idx,IMR, 0x00);			//disable interrupt

	OutportByte(idx,ISR, RegTemp);		//clear interrupt status

    if(RegTemp & 0x01)
	{
	OSQPost(gpTcpIpMsgQ, &idx);
	}
	
	OutportByte(idx,IMR,0x11);			//enable interrupt
					
}



void at91_IRQ2_handler(void)
{
	uint8 RegTemp;
	
	static uint8 idx;
	
	idx = 1;

	RegTemp = InportByte(idx,ISR);		//read interrupt register status

	OutportByte(idx,IMR, 0x00);			//disable interrupt

	OutportByte(idx,ISR, RegTemp);		//clear interrupt status

    if(RegTemp & 0x01)
	{
	OSQPost(gpTcpIpMsgQ, &idx);
	}
	
	OutportByte(idx,IMR,0x11);			//enable interrupt
					
}




















⌨️ 快捷键说明

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