📄 lib_emac.c
字号:
OSAPISemSend(hEthernetInput);
// OSSchedUnlock();
}
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : EMACSendPacket
//* 功能描述 : 由__low_level_output()函数调用,完成实际的数据发送。
//* 入口参数 : <pbFrom>[in] 指向pbuf中数据的指针
//* : <ulLength>[in] pbuf中的数据长度
//* : <blIsEndOfFrame>[in] 是否是pbuf链中的最后一个,也就是帧尾
//* 出口参数 : 如果无法申请下内存则返回ERR_MEM,成功则返回ERR_OK
//*------------------------------------------------------------------------------------------------
BOOLEAN EMACSendPacket(char *pbFrom, INT32U ulLength, BOOLEAN blIsEndOfFrame)
{
INT32U i=0;
INT8U err=0;
if(pbFrom==NULL)
return ERR_MEM;
OSSemPend(hEthernetInput,0,&err);
// dm9000_reg_write(DM9000_IMR,0x80); //先禁止网卡中断,防止在发送数据时被中断干扰
///*写数据到发送缓冲寄存器中等待发送
//Printf("\nEMACSendPacket\n");
DM_ADD = DM9000_MWCMD;
for(i=0; i<ulLength; i+=2) //16 bit mode
{
// udelay(2);
DM_CMD = pbFrom[i] | (pbFrom[i+1]<<8);
}
if(blIsEndOfFrame)////*说明是末尾的pbuf了
{
sendlengh+=ulLength;
//*将这个最终的长度写入发送长度寄存器中
dm9000_reg_write(DM9000_TXPLH, (sendlengh>>8) & 0x0ff);
dm9000_reg_write(DM9000_TXPLL, sendlengh & 0x0ff);
sendlengh=0;
dm9000_reg_write(DM9000_TCR, 0x01); //发送数据到以太网上
}
OSAPISemSend(hEthernetInput);
// dm9000_reg_write(DM9000_IMR,0x81);////开启网卡中断
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : EMACReadPacket
//* 入口参数 :
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
void EMACReadPacket(struct buffer_pool * temp,char *pbTo, INT16S uwSegmentLen, BOOLEAN blIsLastPbuf)
{
//*首先是接着上次的检查开始,或者是上次的传送开始的。也就是说这里的指针值
//*是没有什么变化的
INT16U i=0;
static unsigned int countt=0;
if(uwSegmentLen<=0||uwSegmentLen>=1600) return;
if(temp==NULL) return ;
//countt++;
//if(countt%200==0)
//{
// if(!blIsLastPbuf) Printf("bug in the EMACReadPacket\n");
//Printf("\nEMACReadPacket length %d packet is %d\n",uwSegmentLen,countt);
//}
for(;i<uwSegmentLen;i++)
{
pbTo[i]=temp->data[i];
// Printf(" %x ",temp->data[i]);
// if((i+1)%10==0) Printf("\n");
}
// Printf(" \n***********\n");
//*将表加入到空闲表中
OSSchedLock();
if(head_free==NULL)
head_free=temp;
else
{
temp->next=head_free;
head_free=temp;
}
OSSchedUnlock();
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : DM9000_init
//* 功能描述 : 初始化EMAC:不会打开网卡中断寄存器
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
static void DM9000_init(void)
{
INT32U i;
extern OS_EVENT * hEthernetInput;
//opera_timer(0);
__CheckPHYID();
//初始化设置步骤: 1
dm9000_reg_write(DM9000_GPCR, 0x01); //设置 GPCR(1EH) bit[0]=1,使DM9000的GPIO3为输出。
dm9000_reg_write(DM9000_GPR, 0x00); //GPR bit[0]=0 使DM9000的GPIO3输出为低以激活内部PHY。
udelay(2000); //延时2ms以上等待PHY上电。
//初始化设置步骤: 2
dm9000_reg_write(DM9000_NCR, 0x03); //软件复位
udelay(500); //延时20us以上等待软件复位完成
dm9000_reg_write(DM9000_NCR, 0x00); //复位完成,设置正常工作模式。
dm9000_reg_write(DM9000_NCR, 0x03); //第二次软件复位,为了确保软件复位完全成功。此步骤是必要的。
udelay(500);
dm9000_reg_write(DM9000_NCR, 0x00);
//初始化设置步骤: 3
dm9000_reg_write(DM9000_IMR, 0x80); //中断禁止
//初始化设置步骤: 4
dm9000_reg_write(DM9000_TCR, 0x00); //发送控制
dm9000_reg_write(DM9000_BPTR, 0x3f);
dm9000_reg_write(DM9000_FCTR, 0x38); //接收FIFO门限3k 8k
dm9000_reg_write(DM9000_FCR, 0xff);
dm9000_reg_write(DM9000_SMCR, 0x00);
//初始化设置步骤: 5
for(i=0; i<6; i++)
dm9000_reg_write(DM9000_PAR + i, mac_addr[i]);
//初始化设置步骤: 6
dm9000_reg_write(DM9000_NSR, 0x2c); //清除各种状态标志位
dm9000_reg_write(DM9000_ISR, 0x3f); //清除所有中断标志位
dm9000_reg_write(DM9000_RCR, 0x39); //接收控制
dm9000_reg_write(DM9000_IMR, 0x81); //中断使能
Printf("DM9000 config OK\n");
// opera_timer(1);
}
static void OpenDM9000Isr(void)
{
//初始化设置步骤: 6
dm9000_reg_write(DM9000_ISR, 0x3f); //清除所有中断标志位
dm9000_reg_write(DM9000_IMR, 0x81); //中断使能
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : EMACInit
//* 功能描述 : 初始化EMAC:对PHY、MII口线、EMAC操作模式进行配置,设置接收和发送缓冲区描述符。设置
//* : EMAC接收和发送中断
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
void EMACInit(void)
{
//* 就是一个时间控制结构体的指针
extern OS_EVENT * hEthernetInput;
buffer_pool_init();
//* 建立接收任务使用的信号量,对uCOS的配置保证信号量在软件逻辑上能够百分百建立成功
hEthernetInput = OSAPISemNew(1);
hEMACInput= OSAPISemNew(0);
EthernetInput= OSAPISemNew(0);
//*为了减少包的丢失,专门用一个底层函数处理得到的数据包,其中使用自己的缓冲区,这个底层函数优先级很高
OSTaskCreate(MACPackets,(void *)0, &MACPACKETS_STK[MACPACKETS_STK_LENGH - 1], 4);
//*设置外部中断开启
IOSetInit();
//*初始化网卡,主要是为下一步检查网卡连接状态做准备
DM9000_init();
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : GetInputPacketLen
//* 功能描述 : 获取到达的信息包的长度
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
struct buffer_pool * GetInputPacketLen( void)
{
struct buffer_pool * pp;
if(head_used==NULL)
return NULL;
else
{
OSSchedLock();
pp=head_used;
head_used=head_used->next;
pp->next=NULL;
OSSchedUnlock();
return pp;
}
return pp;
}
char DATA[1500]={
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10
};
INT8S pacg[2000];
void testmac(void * pada)
{
INT16S leng=0,i=0;
struct buffer_pool * tk=NULL;
pada=pada;
EMACInit();
while(1)
{
/* 等待网卡端送来数据 */
OSAPISemWait(hEthernetInput, 0);
tk=GetInputPacketLen();
if(tk)
{
i++;
leng=tk->leng;
// Printf("\nThe packet is %d the lengh=%d \n",i,leng);
EMACReadPacket(tk,pacg,leng,1);
// EMACSendPacket(DATA,1500,1);
}
}
}
//static mun=0;
void MACPackets(void *pada)
{
pada=pada;
while(1)
{
//* 首先获取信号量,如果有信号量 那么获取,这样当多个事件的时候就能不丢失
OSAPISemWait(hEMACInput, 0);
//*然后去DM9000的RAM中取数据块,取到的数据块首先放置在缓冲区中。这个区的大小要依据自己的需要定义,要能保证不溢出
// mun++;
// Printf("\nThe packet is %d\n",mun);
readthemacbuffer();
//*给上层协议栈的buf发送信号,使它过来搬取数据
}
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : PrintfDM9000Reg
//* 功能描述 : 供调试用
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
static void PrintfDM9000Reg(void)
{
uint16 data,i;
Printf("------Print the reg of dm9000\n");
for(i=0x0;i<0x10;i++)
{
data = dm9000_reg_read(i);
Printf("RET_0x%02x = %x\n",i,data);
}
for(i=0x10;i<0x16;i++)
{
data = dm9000_reg_read(i);
Printf("RET_0x%02x = %02x\n",i,data);
}
i=0x16;
data = dm9000_reg_read(i);
Printf("RET_0x%2x = %x\n",i,data);
for(i=0x1e;i<0x26;i++)
{
data = dm9000_reg_read(i);
Printf("RET_0x%2x = %x\n",i,data);
}
for(i=0x28;i<0x2c;i++)
{
data = dm9000_reg_read(i);
Printf("RET_0x%2x = 0x%x\n",i,data);
}
i=0x2f;
data = dm9000_reg_read(i);
Printf("RET_0x%2x = %x\n",i,data);
for(i=0xf0;i<0xff;i++)
{
data = dm9000_reg_read(i);
Printf("RET_0x%2x = %x\n",i,data);
}
data = dm9000_reg_read(i);
Printf("RET_0x%2x = %x\r\n",i,data);
data = dm9000_reg_read(0xfe);
Printf("dm9000 IO mode:%x\r\n",((uint8)data)>>6);
data = dm9000_reg_read(0x01);
if(((uint8)data)>>1)
Printf("10M mode\r\n");
else
Printf("100M mode\r\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -