📄 hardware.c
字号:
WriteToNet(0x10,send_buff.words);
}
ExPtr=ExPtr->STPTR;
}
//如果少于60
/***************************************/
//以下为终止DMA操作
WriteToNet(0x0b,0x00);
WriteToNet(0x0a,0x00);
WriteToNet(0x00,0x22); //结束或放弃DMA操作
WriteToNet(0x07,0xff); //clear interrupt status register
if(Tx_Buff_Sel)
{
WriteToNet(0x04,0x40); //txd packet start;
}
else
{
WriteToNet(0x04,0x46); //txd packet start;
}
ii=length;
if(length<60)
{
//如果数据长度<60字节,设置长度为60字节
ii=60;
}
WriteToNet(0x06,ii>>8); //high byte counter
WriteToNet(0x05,ii&0x00ff);//low byte counter
WriteToNet(0x07,0xff);//clear interrupt status register
WriteToNet(0x00,0x3e); //to sendpacket;
/***************************************/
//重发数据的处理
for(length=0;length<6;length++) //最多重发6次
{
for(ii=0;ii<1000;ii++)
{//检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃
if((ReadFromNet(0X00)&0x04)==0)
{ break; }
}
if((ReadFromNet(0X04)&0x01)!=0)//表示发送成功,判断发送状态寄存器TSR,决定是否出错
{break;};
WriteToNet(0x00,0x3e); //to sendpacket;
}
/**************************************/
//OS_EXIT_CRITICAL();
}
/**********************************************************************
**函数原型: unsigned char * Rec_Packet()
**入口参数:?无
**出口参数: 返回数据指针 unsigned char *
**返 回 值: NULL 没有新数据包
** unsigned char * 接收到新数据包
**说 明: 查询是否有新数据包并接收进缓冲区
************************************************************************/
uint8 Rec_Packet()
{
static uint8 REC_BUFF_NUM=0;
static uint8 bnry,curr; //?可否只做局部?
static uint16 tmp[2];
//static uint16 crt=0;
uint16 * REC_BUFF_PTR_WORDS;
uint8 * REC_BUFF_PTR_BYTES;
uint8 i;
uint16 ii,length;
//OS_ENTER_CRITICAL();
rea1:
page(0);
i = ReadFromNet(0X07); //读取中断状态
if(( i & 0x90) != 0)//如果复位或益出就重新初试化
{
InitNic(0);
//OS_EXIT_CRITICAL();
return(0);
}
bnry=ReadFromNet(0X03); //bnry page have read 读页指针
page(1);
curr=ReadFromNet(0X07); //curr writepoint 8019写页指针
page(0);
if(curr==0)
{
//OS_EXIT_CRITICAL();
return(0); //读的过程出错
}
bnry++;//bnry=bnry++;
if(bnry>0x7f)
{
bnry=0x4c;
//crt++;//统计内部16K循环了多少次(仿真器29次后出错)52、
}
if(bnry!=curr) //此时表示有新的数据包在缓冲区里
{ //在任何操作都最好返回page0
if(REC_BUFF_NUM==MAX_REC_BUFF)//接收缓冲区号清零
{
REC_BUFF_NUM=0;
}
REC_BUFF_PTR_WORDS=REC_BUFF[REC_BUFF_NUM].words;//设定接收缓冲区的起始地址
//=======================================
WriteToNet(0x09,bnry); //RSAR1写入读页地址的高字节
WriteToNet(0x08,0x00); //RSAR0写入读页地址的低字节
WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节
WriteToNet(0x0a,18); //RSCR0写入读取字节计数高字节
WriteToNet(0x00,0x0a); //启动Remote DMA读操作
//读取一包的前4个字节:4字节的8019头部
for(i=0;i<2;i++)
{
*REC_BUFF_PTR_WORDS=ReadFromNet(0x10);
tmp[i]=*REC_BUFF_PTR_WORDS;
REC_BUFF_PTR_WORDS++;
}
//0:接收状态;1:下一包的指针;2:本包低位;3:本包高位;
//=======================================中止DMA操作
WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节
WriteToNet(0x0a,0x00); //RSCR0写入读取字节计数高字节
WriteToNet(0x00,0x22); //结束或放弃DMA操作
//=======================================
tmp[1]=tmp[1]-4;//去掉4个字节的CRC
REC_BUFF[REC_BUFF_NUM].words[1]=tmp[1]; //把真正的接收的帧的长度保存到缓冲区
//=====================以上各步操作表示读入的数据包有效
//0:接收状态;1:下一包的指针;2:本包高位;3:本包低位;
if(((tmp[0]&0x0001)==0)||((tmp[0]&0xff00)>0x7f00)
||((tmp[0]&0xff00)<0x4c00)||(tmp[1]>0x0600))
{//接收状态错误或下一数据包的起始页地址错误或接收的数据包长度>1536字节
page(1);
curr=ReadFromNet(0X07); //page1读取CURR的值
page(0); //切换回page0
bnry = curr -1; //把bnry恢复为下16K中的空余部分
if(bnry < 0x4c)
{
bnry =0x7f;
}
WriteToNet(0x03,bnry); //把BNRY恢复到指向下一帧write to bnry
WriteToNet(0x07,0xff); //清除中断标志
//goto rea1;
//OS_EXIT_CRITICAL();
return(0);
}//end of if(((tmp[0]&0x0001)
//=============================================
else//表示数据包是完好的.读取剩下的数据
{
WriteToNet(0x09,bnry); //RSAR1写入读页地址的高字节//read page address high
WriteToNet(0x08,4); //RSAR0写入读页地址的低字节//read page address low
//WriteToNet(0x0b,tmp[0]); //RSCR1写入读取字节计数高字节//read count high
//WriteToNet(0x0a,tmp[1]); //RSCR0写入读取字节计数低字节//read count low;
WriteToNet(0x0a,tmp[1]);
WriteToNet(0x0b,tmp[1]>>8);
WriteToNet(0x00,0x0a); //启动Remote DMA读操作
//read dma
SendByte(0xff);
SendByte(0xff);
SendByte(tmp[1]);
SendByte(tmp[1]>>8);
length=tmp[1];//计算出要读取的帧的长度
for(ii=0;ii<((length+1)/2);ii++)
{
*REC_BUFF_PTR_WORDS=ReadFromNet(0x10);
REC_BUFF_PTR_WORDS++;
}
//================终止DMA操作
WriteToNet(0x0b,0x00); //RSCR1写入读取字节计数高字节//read count high
WriteToNet(0x0a,0x00); //RSCR0写入读取字节计数高字节//read count low;
WriteToNet(0x00,0x22); //结束或放弃DMA操作//结束或放弃DMA
//============================
}//end of else
//=========================================
bnry=(tmp[0]/256)-1; //tmp[1]是当前有效的CURR
if(bnry<0x4c)
bnry=0x7f;
WriteToNet(0x03,bnry); //写入有效的BNRY //write to bnry
WriteToNet(0x07,0xff); //清除中断标志
REC_BUFF_PTR_BYTES=REC_BUFF[REC_BUFF_NUM].bytes;
REC_BUFF_PTR_BYTES=REC_BUFF_PTR_BYTES+4;//把指针恢复到数据包的起始
#ifdef Little_End
if((((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0008)//可以减少对数据缓冲取的利用
||(((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0608))//不过如果缓冲区足够大就最好不要
#endif
#ifdef Big_End
if((((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0800)//可以减少对数据缓冲取的利用
||(((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0806))//不过如果缓冲区足够大就最好不要
#endif
{
REC_BUFF_NUM++;
//OS_EXIT_CRITICAL();
Rec_Ethernet_Packed(REC_BUFF_PTR_BYTES,0);
//OS_ENTER_CRITICAL();
goto rea1;
//可以直接退出。
}
else
{SendByte('y');goto rea1;}
}//end of if(bnry!=curr)
//OS_EXIT_CRITICAL();
return(0);
}
uint16 swap_int16(uint16 temp)
{uint16 temp1;
temp1=(temp&0xff00)>>8;
temp=(temp&0x00ff)<<8;
return(temp+temp1);
}
uint32 swap_int32(uint32 temp)
{
u16 temp1,temp2;
temp1 = temp & 0xffff;
temp2 = temp >> 16;
temp = 0;
swap_int16(temp1);
swap_int16(temp2);
temp = temp2 | (temp1 << 16);
return(temp);
}
uint16 Char2ToInt16(uint8 * temp)
{
uint16 temp16;
temp16=((uint16)(*temp))<<8;
temp++;
temp16=temp16+(uint16)(*temp);
return(temp16);
}
uint32 Char4ToInt32(uint8 * temp)
{
uint32 temp32;
temp32=((uint32)(*temp))<<24;
temp++;
temp32=temp32+(((uint32)(*temp))<<16);
temp++;
temp32=temp32+(((uint32)(*temp))<<8);
temp++;
temp32=temp32+(uint32)(*temp);
return(temp32);
}
/*
+FFTR--------------------------------------------------------------------
$Log: hardware.c,v $
Revision 1.3 2006/12/31 16:08:37 tony
由于write_file慢(1KB/S)导致FTP服务器put file失序,不写file时序正常
Revision 1.2 2006/12/31 16:05:20 tony
增加FTP代码,SOCKET_status字段
-FFTR--------------------------------------------------------------------
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -