📄 netdrive.c
字号:
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 + -