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

📄 exp13.c

📁 本程序功能为在FPGA上nios处理器的网卡接口程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
   alt_irq_register(NET_INT_IRQ,edge_captureptr,NET_INT_ISR);//分配中断服务程序
   
   IOWR_ALTERA_AVALON_PIO_DIRECTION(NET_INT_BASE,0);//中断方向
   
   IOWR_ALTERA_AVALON_PIO_EDGE_CAP(NET_INT_BASE,0);//清除中断标志
   
   IOWR_ALTERA_AVALON_PIO_IRQ_MASK(NET_INT_BASE,1);//使能中断
}

void Init_NET(void)  //8019初始化
{
   NET_Write_Data(0x0000,0x21);
                //选择页0的寄存器,网卡停止运行,因为还没有初始化。TXP=0
           //TXP在发送数据包时必须设置,当发送完毕或发送失败时会自动复位。为0时是没有发送。
           //STA=0,STP=1,stop command.
   NET_Write_Data(0x0001,0x4c);  //寄存器Pstart 页面开始寄存器,设置为接收缓冲器的起始地址
   NET_Write_Data(0x0002,0x80);  //Pstop  页面停止寄存器,设置为接收缓冲器的停止地址,一般使用8位时不超过60,使用16位时不超过80
   NET_Write_Data(0x0003,0x4c);  //BURY   边界寄存器,存放host读过的最后一个buffer的起始地址。 原有数据时0x4c
   NET_Write_Data(0x0004,0x45);  //TPSR  发送页面起始地址,存放发送数据包的起始页面地址。
   NET_Write_Data(0x0007,0xff);  //ISR  清除中断标志位
   NET_Write_Data(0x000c,0xde);  //RCR   接收结构寄存器  原来时CC
           //7,6 =1;
           //5.MON监控模式设置位=0;
           //4.PRO=0,目标地址必须与PAR0-5相匹配;
           //3.AM=1,数据包有多点传输目标地址
           //2.AB=1,数据包是广播数据包
           //1.AR=0,数据包长度必须大于64Bytes.
           //0.SEP=0,收到的数据包没有错误检测。

   NET_Write_Data(0x000d,0xe0);  //TCR 发送结构寄存器。
           //7.6.5=1,
           //4.OFST=0 冲突偏移使能
           //3.ATD=0 不使用自动传输
           //2.1.LB1,LB0=0 正常操作
           //0.CRC=0 CRC较验激活

   NET_Write_Data(0x000e,0xc8);  //DCR 数据配置寄存器 8位数据dma
           //7.=1
           //6.5 FT1.FT0 =10 FIFO片选位
           //4.ARM=0 自动远程初始化 发送数据包,命令不执行
           //3.LS=1 LookBack模式选择,正常模式,不使用LookBack
           //2.LSA=0
           //1.BOS=0 字节顺序选择(不执行) MS放在DM15-8,LS放在DM7-0,(32XXX,80X86)
           //0.WTS=0 字传输选择 宽字节的DMA传输

   NET_Write_Data(0x000f,0x00);  //IMR  屏蔽所有中断
   NET_Page_Set(1);              //选择页1的寄存器
   NET_Write_Data(0x0005,0x55);   //PAR4
   NET_Write_Data(0x0007,0x4d);   //CURR  设置当前页面寄存器。 原来数据时0x4d
   NET_Write_Data(0x0008,0x00);   //MAR0
   NET_Write_Data(0x0009,0x41);   //MAR1
   NET_Write_Data(0x000a,0xaa);   //MAR2
   NET_Write_Data(0x000b,0x80);   //MAR3
   NET_Write_Data(0x000c,0x00);   //MAR4
   NET_Write_Data(0x000d,0x00);   //MAR5
   NET_Write_Data(0x000e,0x00);   //MAR6
   NET_Write_Data(0x000f,0x00);   //MAR7
   NET_Write_Data(0x0000,0x22);   //选择页0寄存器,网卡执行命令,停止DMA传输。
}

void DMA_Write_Data(UCHAR *m_Buffer,UINT m_StartAddr,UINT m_Len)   //DMA写数据,指定数据,指定8019存储地址,指定长度
{
   UINT i;
   NET_Write_Data(0x0000,0x22);   //停止DMA传输
   //NET_Write_Data(0x0007,0x40);   //清楚DMA传输中断
   NET_Write_Data(0x000a,m_Len%256);  //  设定长度低8位
   NET_Write_Data(0x000b,m_Len/256);  //  设定长度高8位
   NET_Write_Data(0x0008,m_StartAddr%256);   //  设定地址低8位
   NET_Write_Data(0x0009,m_StartAddr/256);   //  设定地址高8位
   NET_Write_Data(0x0000,0x12);    // 启动DMA写数据命令
   for(i=0;i<m_Len;i++)
   {
      NET_Write_Data(0x0010,m_Buffer[i]);
      Delay(1);
   }
   i=10000;
   while(i&&(NET_Read_Data(0x0007)&0x40)==0)   //等待写数据完成
      i--;
   NET_Write_Data(0x0000,0x22);
}

void NET_CLEAR_Data(void)   //清除8019的原始数据
{
   UINT i;
   NET_Write_Data(0x0000,0x22);   //停止DMA传输
   //NET_Write_Data(0x0007,0x40);   //清楚DMA传输中断
   NET_Write_Data(0x000a,0x00);  //  设定长度低8位
   NET_Write_Data(0x000b,0x40);  //  设定长度高8位
   NET_Write_Data(0x0008,0x00);   //  设定地址低8位
   NET_Write_Data(0x0009,0x40);   //  设定地址高8位
   NET_Write_Data(0x0000,0x12);    // 启动DMA写数据命令
   for(i=0;i<0x4000;i++)
   {
      NET_Write_Data(0x0010,0);
      Delay(1);
   }
   i=10000;
   while(i&&(NET_Read_Data(0x0007)&0x40)==0)   //等待写数据完成
      i--;
   NET_Write_Data(0x0000,0x22);
}

void DMA_Read_Data(UCHAR *m_Buffer,UINT m_StartAddr,UINT m_Len)  //DMA读数据,指定8019地址,指定数据存放地址,指定长度
{
   UINT i;
   NET_Write_Data(0x0000,0x22);   //停止DMA传输
   NET_Write_Data(0x0007,0x40);   //清楚DMA传输中断
   NET_Write_Data(0x000a,m_Len%256);  //  设定长度低8位
   NET_Write_Data(0x000b,m_Len/256);  //  设定长度高8位
   NET_Write_Data(0x0008,m_StartAddr%256);   //  设定地址低8位
   NET_Write_Data(0x0009,m_StartAddr/256);   //  设定地址高8位
   NET_Write_Data(0x0000,0x08);  //启动DMA读数据命令
   for(i=0;i<m_Len;i++)
   {
      m_Buffer[i]=NET_Read_Data(0x0010);
      Delay(1);
   }
   NET_Write_Data(0x0000,0x22);
}

void NET_Send_Packet(UCHAR *m_Buffer,UINT m_Len) //发送数据包,数据的起始地址和数据长度
{
   UCHAR H_m_Len,L_m_Len;
   m_Len=(m_Len>64)? m_Len:64;
   H_m_Len=m_Len>>8;
   L_m_Len=m_Len&0xff;
   while(NET_Read_Data(0x0000) & 0x04); //等待发包完成
   NET_Write_Data(0x0000,0x22);  //停止DMA操作,并将寄存器页面设置为0
   DMA_Write_Data(m_Buffer,0x4000,m_Len);  //写数据到缓冲区
   NET_Write_Data(0x0004,0x40); //设置发送数据包的起始页面
   NET_Write_Data(0x0005,L_m_Len);  //传输字节数的低8位
   NET_Write_Data(0x0006,H_m_Len);  //传输字节数的高8位
   NET_Write_Data(0x0000,0x26);  //启动发包命令
   while(NET_Read_Data(0x0000) & 0x04); //等待发包完成
}

void NET_Wait_PACK(void)  //等待收到新的数据,并将一个完整的数据包写入Receive_Buffer中,并检出包类型
{
   UINT i,PAGE_Data;
   UCHAR NEW_PACK=1;   //NEW_PACK=1时表示无新的数据,=0时表示有新的数据
   UCHAR DMA_Buffer[ARP_PACK_Len+4];  //新数据的第一次缓冲
   while(NEW_PACK)  //无新数据时不停的循环
   {
      SET_PAGE0;
      BURY_Data=NET_Read_Data(BURY_Addr);
      SET_PAGE1;
      CURR_Data=NET_Read_Data(CURR_Addr);
      if(((BURY_Data==0x7f)&&(CURR_Data ==0x4c))||((BURY_Data!=0x7f)&&(CURR_Data==BURY_Data+1))) //判断语句表示缓冲区为空时=真
         NEW_PACK=1;
      else
         NEW_PACK=0;
   }
   //printf("收到新的数据包\n");
   //printf("BURY_Data=%x\n",BURY_Data);
   BURY_Data=(BURY_Data==0x7f)? 0x4c:BURY_Data+1;  //修改BURY_Data
   DMA_Read_Data(DMA_Buffer,BURY_Data*256,ARP_PACK_Len+4);    //从8019读数据倒DMA_Buffer,长度按ARP包长度计算,如果是IP包,包括IP包的大小

   /*
   for (i=1;i<5;i++)
      printf("|- %x -| ",DMA_Buffer[i-1]);
   printf("\n");
   */

   PACK_Type=DMA_Buffer[4+12]*256+DMA_Buffer[4+13];  //数据包类型
   if(PACK_Type==PACK_ARP)           //如果是ARP数据包,将数据从DMA_Buffer写入Receive_Buffer中
      for(i=0;i<ARP_PACK_Len;i++)
         Receive_Buffer[i]=DMA_Buffer[i+4];
   if(PACK_Type==PACK_IP)            //如果是IP包,将IP包指定长度的数据,从8019直接写入倒Receive_Buffer中
   {

      IP_PACK_Len=DMA_Buffer[4+14+2]*0x100+DMA_Buffer[4+14+2+1]; //读取IP数据包的长度
      PACK_Len=IP_PACK_Len+4+14;

      //printf("数据包长度 %x \n",PACK_Len);

      DMA_Read_Data(Receive_Buffer,BURY_Data*256+4,PACK_Len);    //将完整的IP包数据写入Receive_Buffer中
   }
   PAGE_Data=PACK_Len/256;  //计算IP包总共占用了多少页,考虑倒下一步的处理,可能要-1
   while(PAGE_Data--)
      BURY_Data=(BURY_Data==0x7f)? 0x4c:BURY_Data+1;  //计算BURY_Data的值

   //printf("最后BURY_Data的值 %x\n\n",BURY_Data);


   SET_PAGE0;
   NET_Write_Data(BURY_Addr,BURY_Data);  //修改BURY寄存器的值
}

UINT m_Data_Compare(UCHAR *Addr1,UINT Start_Addr1,UCHAR *Addr2,UINT Start_Addr2,UINT Len)  //多个数据判断
{
   UINT Type=0;  //表示两组数据中,不同数据的个数
   UINT i;
   for (i=0;i<Len;i++)
      if (Addr1[Start_Addr1+i]!=Addr2[Start_Addr2+i])
         Type++;
   return Type;
}

UINT CHECK_SUM(UCHAR *Addr,UINT Start_Len,UINT Len)   //计算校验和
{
   UINT Data=0,i;
   if(Len==1)
      Data+=Addr[Start_Len]*0x100;
   else if(Len%2 ==0)
   {
      for(i=0;i<Len;i+=2)
         Data+=Addr[Start_Len+i]*0x100+Addr[Start_Len+i+1];
   }
   else
   {
      for(i=0;i<Len-1;i+=2)
         Data+=Addr[Start_Len+i]*0x100+Addr[Start_Len+i+1];
      Data+=Addr[Start_Len+Len-1]*0x100;
   }
   Data=(Data/0x10000)+(Data&0xffff);
   Data+=Data/0x10000;
   return ~Data&0xffff;
}









⌨️ 快捷键说明

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