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

📄 2457 drive

📁 网络通信处理器S3C4510B的网口驱动设计(ARM)
💻
字号:
typedef unsigned char 	  U8; 		
typedef unsigned short	  U16;
typedef unsigned long     U32;

#define FrameOwner_CPU  0x7fffffff
#define FrameOwner_BDMA  0x80000000 
//结构体变量声明
typedef struct FrameDescriptor
{ 
  U32 FrameDataPtr; 
  U32 Reserved;
  U32 StatusAndFrameLength;
  U32 NextFrameDescriptor;
}sFrameDescriptor;  

typedef struct {
    U8  dst[6];
	U8  src[6];
	U8  LengthOrType[2];
}etheader;    

typedef struct MACFrame{
	etheader 	Header ;
	U8          data[1506];
}sMACFrame;

typedef struct MacTxStatus
{
  U32 UnderErr;
  U32 ExCollErr;
  U32 TxDefferedErr;
  U32 sPaused;
  U32 DeferErr;
  U32 NCarrErr;
  U32 sSQE;
  U32 LateCollErr;
  U32 TxParErr;
  U32 sTxHalted;
  U32 MacTxGood;
}sMacTxStatus;
 

typedef struct BdmaRxStatus
{
  U32 BdmaRxCnt;
  U32 BRxNLErr;
  U32 BdmaRxGood;
  U32 BRxNOErr;
  U32 BRxMSOErr ;
 
}sBdmaRxStatus;
 

typedef struct MacRxStatus
{
  U32 OvMaxSize;
  U32 sCtlRecd;
  U32 sRx10Stat;
  U32 sAlignErr;
  U32 sCRCErr;
  U32 OverflowErr;
  U32 sLongErr;
  U32 RxParErr;
  U32 sRxHalted;
 
}sMacRxStatus;


volatile  sBdmaRxStatus  gsBdmaRxStatus = {0,0,0,0,0};
volatile  sMacTxStatus   gsMacTxStatus = {0,0,0,0,0,0,0,0,0,0,0};
volatile  sMacRxStatus   gsMacRxStatus = {0,0,0,0,0,0,0,0,0};

volatile sFrameDescriptor rx_fd[RX_FRAME_SIZE];
volatile sFrameDescriptor tx_fd[TX_FRAME_SIZE];

volatile sMACFrame  rx_buf[RX_FRAME_SIZE];
volatile sMACFrame  tx_buf[TX_FRAME_SIZE];

//初始化全局变量
void globalVar(void)
{
  gMacCon= FullDup; //双工模式
  //gMacCon= MACLoop;//Loopback模式	
  gMacTxCon = EnComp;
  gMacRxCon = StripCRC | RxEn;
  gBdmaTxCon = BTxBRST | BTxMSL110 | BTxSTSKO;
  gBdmaRxCon = BRxDIE | BRxEn | BRxLittle | BRxMAINC | BRxBRST | BRxNLIE | BRxNOIE | BRxSTSKO;
  gCamCon = CompEn | BroadAcc;
  gErrorPacketCnt = 0;
  gCam0_Addr0 = 0;
  gCam0_Addr1 = 0;
  
}

//网络初始化
void  LanInit(void)
{
  //配置物理收发设备
     ResetPhyChip();
  //获取MAC层网卡硬件物理地址
     GetMacAddr();
  //初始化MAC、BDMA控制器
     MacInit();
}

//配置物理收发设备
void ResetPhyChip(void)
{
  //10Mbps 半双工模式
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,0x0); 
  //10Mbps 全双工模式 
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,PHY_FULLDUPLEX); 
  //100Mbps 半双工模式 
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB);
  //100Mbps 全双工模式 
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB|PHY_FULLDUPLEX); 
  //自动检测配置
    MiiWrite(PHY_CNTL_REG,PHYHWADDR,ENABLE_AN|RESTART_AN);
}


//MII状态管理写操作          
void MiiWrite(U32 PhyRegID,U32 PhyID,U32 PhyWrData)  
{
  rSTADATA = PhyWrData;
  rSTACON = PhyRegID|PhyID|MiiBusy|PHYREGWRITE;
  while((rSTACON & MiiBusy));
  delay(200);
}  

//MII状态管理读操作
U32 MiiRead(U32 PhyRegID,U32 PhyID)
{
  U32 PhyRdData;
  rSTACON = PhyRegID|PhyID|MiiBusy|MDC;
  while((rSTACON & MiiBusy));
  PhyRdData = rSTADATA;
  return PhyRdData;
}


void delay(U32 count)
{
  U32 i, j;
  
  for(i = 0; i < count; i++)
  	for(j = 0; j < 1650; j++);
}

//获取MAC层网卡硬件物理地址
void GetMacAddr(void)
{
    U8 MacAddr[6];
	int i;
	
#if //从片外IIC EEPROM中读入MAC地址 
	MacAddr=(U8 *)IICReadInt((U8)IIC_DEV_0,(U32)iMacAddrPtr);
#else	// 自行设定MAC地址
	MacAddr[0] = 0x00;
	MacAddr[1] = 0x40;
	MacAddr[2] = 0xc0;
	MacAddr[3] = 0x12;
	MacAddr[4] = 0x00;
	MacAddr[5] = 0x00;
#endif

  for(i=0;i<4;i++)
     gCam0_Addr0 = (gCam0_Addr0<<8)| MacAddr[i];
  for(i=4;i<6;i++)
     gCam0_Addr1 = (gCam0_Addr1<<8)| MacAddr[i]; 
     gCam0_Addr1 = (gCam0_Addr1<<16);
}        
     
//初始化MAC、BDMA控制器
void MacInit(void)
{
  //(1)
  Disable_irqMACRX();
  Disable_irqMACTX();
  Disable_irqBDMARX();
  Disable_irqBDMATX();
  //(2)
  SysSetInterrupt(nMAC_TX_INT, ISR_MACTx);
  SysSetInterrupt(nBDMA_RX_INT,ISR_BDMARx); 
  //(3)
  rBDMARXCON = BRxRS;  
  rBDMATXCON = BTxRS;  
  rMACON = SwReset;
  //(4)
  rBDMARXLSZ = MaxRxFrameSize; 
  rMACON = gMacCon;
  //(5)
  TxFDInit();
  RxFDInit();
  //(6)
  rCAM_Reg(0) = gCam0_Addr0;
  rCAM_Reg(1) = gCam0_Addr1;
  rCAMEN = 0x1;
  rCAMCON = gCamCon;
  //(7)
  ReadyMacTx();
  ReadyMacRx();
  //(8)
  Enable_irqBDMARX();
  Enable_irqMACTX();
    
}

void SysSetInterrupt(U8 IntID, void(*p)())
{
 //根据底层boot引导程序而定
}


void ReadyMacTx(void)
{
  rBDMATXCON = gBdmaTxCon;
  rMACTXCON = gMacTxCon;
}


void ReadyMacRx(void)
{
  rBDMARXCON = gBdmaRxCon; 
  rMACRXCON = gMacRxCon;
}

//构建BDMA发送数据帧结构循环链表
void TxFDInit(void)
{
  sFrameDescriptor *pFrameDescriptor;
  sFrameDescriptor *pStartFrameDescriptor;
  sFrameDescriptor *pLastFrameDescriptor = NULL;
  U32 FrameDataAddr;
  U32 i;
  //确定当前帧结构描述指针
  rBDMATXPTR = (U32)tx_fd + 0x4000000;
  gtx_ptr =tx_ptr = rBDMATXPTR;
  //获取数据缓冲区地址
  FrameDataAddr = (U32)tx_buf + 0x4000000;
  //构建循环链表
  pFrameDescriptor = (sFrameDescriptor *)tx_ptr;
  pStartFrameDescriptor = pFrameDescriptor;
  
  for(i=0;i<TX_FRAME_SIZE;i++)
   {
     if(pLastFrameDescriptor==NULL)
        pLastFrameDescriptor = pFrameDescriptor;
     else pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;   
     
     pFrameDescriptor->FrameDataPtr = (U32)(FrameDataAddr & FrameOwner_CPU);
     pFrameDescriptor->Reserved = (U32)0x0;
     pFrameDescriptor->StatusAndFrameLength = (U32)0x0;
     pFrameDescriptor->NextFrameDescriptor = NULL;
     
     pLastFrameDescriptor = pFrameDescriptor;
     pFrameDescriptor++;
     FrameDataAddr += sizeof(sMACFrame);
   }   

  pFrameDescriptor--;
  pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;     
}   

//构建BDMA接收数据帧结构循环链表
void RxFDInit(void) 
{
  sFrameDescriptor *pFrameDescriptor;
  sFrameDescriptor *pStartFrameDescriptor;
  sFrameDescriptor *pLastFrameDescriptor = NULL;
  U32 FrameDataAddr;
  U32 i;
  //确定当前帧结构描述指针
  rBDMARXPTR = (U32)rx_fd + 0x4000000;
  rx_ptr = rBDMARXPTR;
  //获取数据缓冲区地址
  FrameDataAddr = (U32)rx_buf + 0x4000000;
  //构建循环链表
  pFrameDescriptor = (sFrameDescriptor *)rx_ptr;
  pStartFrameDescriptor = pFrameDescriptor;
  
  for(i=0;i<RX_FRAME_SIZE;i++)
   {
     if(pLastFrameDescriptor==NULL)
        pLastFrameDescriptor = pFrameDescriptor;
     else pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;   
     
     pFrameDescriptor->FrameDataPtr = (U32)(FrameDataAddr | FrameOwner_BDMA);
     pFrameDescriptor->Reserved = (U32)0x0;
     pFrameDescriptor->StatusAndFrameLength = (U32)0x0;
     pFrameDescriptor->NextFrameDescriptor = NULL;
     
     pLastFrameDescriptor = pFrameDescriptor;
     pFrameDescriptor++;
     FrameDataAddr += sizeof(sMACFrame);
   }

  pFrameDescriptor--;
  pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;     
} 

//中断使能、禁止函数
void Disable_irqMACRX(void)
{
  rINTMSK |= BIT_MACRX;
}
  
void Enable_irqBDMARX(void)
{
  rINTMSK &= ~(BIT_GLOBAL | BIT_BDMARX );
}


//发送函数
int SendPacket(U8* frame,int Size)
{
  U32  *pFrameDataPtr;
  U8   *pFrameData;
  int  FrameLength;
  sFrameDescriptor  *psTxFD;
  //(1)
  psTxFD = (sFrameDescriptor *)gtx_ptr;
  pFrameData = (U8 *)psTxFD->FrameDataPtr;
  pFrameDataPtr = (U32 *)&psTxFD->FrameDataPtr;
  FrameLength = Size + sizeof(etheader);
  //(2)
  if((*pFrameDataPtr & FrameOwner_BDMA)) return 0;
  //(3)
  memcpy(pFrameData,frame,FrameLength); 
  //(4)
  psTxFD->Reserved = (PaddingMode | CRCMode | FrameDataPtrInc | LittleEndian | WidgetAlign00 | MACTxIntEn);
  psTxFD->StatusAndFrameLength = (U32)(FrameLength & 0xffff);
  //(5)
  psTxFD->FrameDataPtr |= FrameOwner_BDMA;
  //(6)
  MacTxGo();
  //(7)
  gtx_ptr = (U32)(psTxFD->NextFrameDescriptor);
  return 1;
}
 
void MacTxGo(void)
{
	if (!(rBDMATXCON & BTxEn))  rBDMATXCON |= BTxEn;
	rMACTXCON |= TxEn;
}

void memcpy (U8 *d, U8 *s, int l)
     {
        while (l--) *d++ = *s++;
     }
///////////////////////////////////////////////////////////

//发送中断处理函数
void ISR_MACTx(void)
{
  sFrameDescriptor *pTxFDPtr;
  U32 *pFrameDataPtr;
  U32 Status;
  U32 CTxPtr;
  
  rINTPND |= BIT_MACTX; 
  CTxPtr = rBDMATXPTR;
  while(tx_ptr != CTxPtr)
  {
   pTxFDPtr = (sFrameDescriptor *)tx_ptr;
   pFrameDataPtr = (U32 *)&pTxFDPtr->FrameDataPtr;
   if((*pFrameDataPtr & FrameOwner_BDMA)) break;
  
   Status = (pTxFDPtr->StatusAndFrameLength>>16) & 0xffff;
  
   if(Status & Comp) gsMacTxStatus.MacTxGood++;
   else
   {
    //出错处理    
    if(Status & Under) Err_Under();   
    if(Status & TxPar) Err_TxPar();
    
    ReadyMacTx();
   }
  
   //复位发送帧控制位
   pTxFDPtr->StatusAndFrameLength = (U32)0x0;
   
   tx_ptr = (U32)pTxFDPtr->NextFrameDescriptor;
  }
    
 
}    

void Err_Under(void)
{
 gsMacTxStatus.UnderErr++;
} 
//接收数据帧及其中断处理函数
void ISR_BDMARx(void)
{
  sFrameDescriptor *pRxFDPtr;
  U32   RxStatus,FrameLength;
  U32   CRxPtr;
  U32   sBdmaStat;
  U32   FrameData;
  
  rINTPND |= BIT_BDMARX ;  
  //(1)
  CRxPtr = rBDMARXPTR;
  sBdmaStat = rBDMASTAT;
  //(2)
  rBDMASTAT |= S_BRxRDF;
  gsBdmaRxStatus.BdmaRxCnt++;
  
  do{
      //(3)
      if(rBDMASTAT & S_BRxNL)
        { 
          rBDMASTAT |= S_BRxNL;
          gsBdmaRxStatus.BRxNLErr++;
          MacInitialize();
          break;
        }  
      //(4)
      pRxFDPtr = (sFrameDescriptor *)rx_ptr;
      RxStatus = (pRxFDPtr->StatusAndFrameLength>>16) & 0xffff;
      //(5)
      if(RxStatus & RxGood)
        { FrameLength = pRxFDPtr->StatusAndFrameLength & 0xffff;
          FrameData = pRxFDPtr->FrameDataPtr;
          gsBdmaRxStatus.BdmaRxGood++;
          //从缓冲区取出数据
          GetRxFrameData(pFrameData,FrameLength,RxStatus);
         
         }
      else
        {
         
          gErrorPacketCnt++;   
          if(RxStatus & CRCErr) Err_CRC();
          if(RxStatus & Overflow) Err_Overflow();
         
         }
         
      //(6)
      pRxFDPtr->FrameDataPtr |= FrameOwner_BDMA;
      pRxFDPtr->StatusAndFrameLength = (U32)0x0;
      //(7)
      rx_ptr = (U32)pRxFDPtr->NextFrameDescriptor;
   }while(CRxPtr != rx_ptr);
   //(8)
   if(sBdmaStat & S_BRxNO)    
     {
       rBDMASTAT |= S_BRxNO;
       gsBdmaRxStatus.BRxNOErr++;
       ReadyMacRx();
     }
     
}      

void Err_Overflow(void)
{
  gsMacRxStatus.OverflowErr++;
} 

⌨️ 快捷键说明

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