📄 ethernet.c
字号:
/*
*
* NIC(CS8900A)驱动模块
*
*/
#include "Ethernet.h"
// 物理地址,默认为22-44-66-88-AA-CC,可在初始化NIC前改写
u16 local_eth_addr[3] = {0x4422, 0x8866, 0xCCAA};
// 从NIC端口输入
inline u16 NIC_InPort(u16 reg)
{
ETH_Addr_Port = reg;
return ETH_Data_Port;
}
// 向NIC端口输出
inline void NIC_OutPort(u16 reg, u16 x)
{
ETH_Addr_Port = reg;
ETH_Data_Port = x;
}
// 发送帧请求
inline void RequestSend(u16 FrameSize)
{
ETH_TX_CMD_Port = TX_START_ALL_BYTES;
ETH_TX_LEN_Port = FrameSize;
}
// 初始化NIC
int NIC_Init(void)
{
u32 t;
// 配置STR71x的外部片选信号引脚
GPIO_Config(GPIO2, 0x000F, GPIO_AF_PP);
// 使能外部存储器BANK2(CS8900A)
EMI_Config(2, EMI_ENABLE | EMI_WAITSTATE(15) | EMI_SIZE_16);
// 软复位并初始化CS8900A(详见CS8900A数据手册)
NIC_OutPort(PP_SelfCTL, POWER_ON_RESET);
t = ETH_Port(1);
t = ETH_Port(0);
t = ETH_Port(1);
for(t = 0x1000; t && !(NIC_InPort(PP_SelfST) & INIT_DONE); t--);
if(!t)
return -1;
NIC_OutPort(PP_IA + 0, local_eth_addr[0]);
NIC_OutPort(PP_IA + 2, local_eth_addr[1]);
NIC_OutPort(PP_IA + 4, local_eth_addr[2]);
NIC_OutPort(PP_RxCTL, RX_OK_ACCEPT | RX_IA_ACCEPT | RX_BROADCAST_ACCEPT);
NIC_OutPort(PP_LineCTL, SERIAL_RX_ON | SERIAL_TX_ON);
return 0;
}
// 收包
int NIC_RecvPack(u16 *buf)
{
int stat = NIC_InPort(PP_RxEvent);
if((stat & RX_OK) && (stat & (RX_IA | RX_BROADCAST)))
{
int len, i;
stat = ETH_RX_Frame_Port;
len = ETH_RX_Frame_Port;
if(len < 60 || len > 1514)
return -1;
for(i = 0; i < len; i += 2)
*buf++ = ETH_RX_Frame_Port;
return len;
}
return 0;
}
// 发包
int NIC_SendPack(u16 *buf, int len)
{
if(!(NIC_InPort(PP_LineST) & LINK_OK))
return -1;
if(len < 60)
len = 60;
RequestSend(len);
while(!(NIC_InPort(PP_BusST) & READY_FOR_TX_NOW))
NIC_OutPort(PP_RxCFG, SKIP_1 | RX_OK_ENBL);
if(NIC_InPort(PP_BusST) & READY_FOR_TX_NOW)
{
int i;
for(i = 0; i < len; i += 2)
ETH_TX_Frame_Port = *buf++;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -