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

📄 exp13.c

📁 本程序功能为在FPGA上nios处理器的网卡接口程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_irq.h"
#include "stdio.h"
#include "system.h"
#include "exp13.h"
#include "net_arp.c"
#include "net_ping.c"  //Ping回应处理程序
#include "net_head.c"  //首部处理程序
#include "net_tcp.c"   //tcp处理程序
#include "net_http.c"  //http应用处理程序

volatile int edge_capture;




void NET_INT_ISR(void * context,alt_u32 id)  //中断服务子程序
{
   volatile int* edge_captureptr=(volatile int*)context;
   IOWR_ALTERA_AVALON_PIO_IRQ_MASK(NET_INT_BASE,0); //禁止中断
      
   IOWR_ALTERA_AVALON_PIO_EDGE_CAP(NET_INT_BASE,0);//清除中断标志
   printf("Interrupt!!\n");
   IOWR_ALTERA_AVALON_PIO_IRQ_MASK(NET_INT_BASE,1);//使能中断
}

int main(void)
{
   UINT i=0;
   UINT Coun_PACK=0;
   Init_system();  //系统初始化
   Init_NET();  //8019初始化
   //NET_CLEAR_Data();  //清除8019的原始数据
   SET_PAGE0;  //停止8019的DMA操作,页面设置为0
   printf("RTL8019AS ID0 is 0x%x\n",NET_ID(0)&0xff);  //8019的ID
   printf("RTL8019AS ID1 is 0x%x\n",NET_ID(1)&0xff);

   //NET_Send_Packet(TEST_ARP,sizeof(TEST_ARP));  //发送地址解析协议包

   //printf("%d\n",sizeof(html_header));
   //printf("%s\n",html_header);




   printf("复位完成,等待接收数据包\n");


   while(1)
   {
      NET_Wait_PACK();  //等待收到新的数据
      //printf("收到数据包     %d\n",++Coun_PACK);
      //printf("BURY=%x     CURR=%X\n",BURY_Data,CURR_Data);
      //NET_Receive_PACK();  //接收一页数据包到缓冲区DMA_Buffer

      /*
      for(j=0;j<8;j++)
      {
         for(k=0;k<8;k++)
            printf("%2d = %2x ",j*8+k,DMA_Buffer[j*8+k]);
         printf("\n");
      }
      */

      //for(i=0;i<256-4;i++)                     //将一页数据写入接收缓冲区
         //Receive_Buffer[i]=DMA_Buffer[i+4];
      //PACK_Type=Receive_Buffer[12]*256+Receive_Buffer[13];  //数据包类型
      //printf("数据包类型  %4x\n",PACK_Type);

      if (PACK_Type==PACK_ARP)  //ARP协议包
         if(m_Data_Compare(Receive_Buffer,14+28-4,IP_Addr,0,4)==0)  //目标地址是本地
         {
            printf("收到ARP包\n");
            IP_ARP();   //返回ARP包
         }

      if (PACK_Type==PACK_IP)  //IP协议包
         if(m_Data_Compare(Receive_Buffer,0,MAC_Addr,0,6)==0)  //目标MAC地址是本地
         {
            //printf("IP协议包\n");
            if(Receive_Buffer[14+9]==1)  //ICMP协议包
            {
               //printf("ICMP协议包\n");
               if(Receive_Buffer[14+20+0]==8)  //ICMP的请求回显(Ping请求)
               {
                  //printf("ICMP的请求回显(Ping请求)数据包\n");
                  Revert_Ping();
               }
            }
            if(Receive_Buffer[14+9]==6)  //TCP协议数据包
            {
               //printf("收到TCP协议数据包\n");
               IP_TCP();
            }
         }
   }
}

void Delay(UINT m_Delay)  //延时子程序
{
   while(m_Delay--);
}

void NET_Write_Data(UINT m_Addr,UCHAR m_Data)  //8019写一个数据的时序
{
    
   IOWR_ALTERA_AVALON_PIO_DATA(NET_ADDR_BASE,0X300+m_Addr); //地址输出
    
   IOWR_ALTERA_AVALON_PIO_DIRECTION(NET_DB_BASE,0XFFFF);//数据总线方向:输出
           
   IOWR_ALTERA_AVALON_PIO_DATA(NET_AEN_BASE,0);//地址片选拉低
           
   IOWR_ALTERA_AVALON_PIO_DATA(NET_WR_BASE,0);//写信号有效
     
   IOWR_ALTERA_AVALON_PIO_DATA(NET_DB_BASE,m_Data);//数据输出
          
   IOWR_ALTERA_AVALON_PIO_DATA(NET_WR_BASE,1);//写信号无效
       
   IOWR_ALTERA_AVALON_PIO_DATA(NET_AEN_BASE,1); //地址片选无效
}

UCHAR NET_Read_Data(UINT m_Addr)     //8019读一个数据的时序
{
   UCHAR m_Data;
   
   IOWR_ALTERA_AVALON_PIO_DATA(NET_ADDR_BASE,0X300+m_Addr);//地址输出
  
   IOWR_ALTERA_AVALON_PIO_DIRECTION(NET_DB_BASE,0X0000);//数据总线方向:输入
         
   IOWR_ALTERA_AVALON_PIO_DATA(NET_AEN_BASE,0);//片选拉低
            
   IOWR_ALTERA_AVALON_PIO_DATA(NET_RD_BASE,0);//读信号有效
       
   m_Data=IORD_ALTERA_AVALON_PIO_DATA(NET_DB_BASE);//获取数据
            
   IOWR_ALTERA_AVALON_PIO_DATA(NET_RD_BASE,1);//读信号无效
             
   IOWR_ALTERA_AVALON_PIO_DATA(NET_AEN_BASE,1);//片选无效
   return m_Data;
}

void NET_Page_Set(UINT m_Page)      //设定当前页面
{
//页面寄存器 任何页 00单元(CR) 7,6位(PS1,PS0)  另 2位为‘0’
   UINT Temp;
   Temp=NET_Read_Data(0x0000);
   Temp=Temp&0x003B;                //注意不是0x3F ,TXP位在平时一定要置为0.
   m_Page=m_Page<<6;
   Temp=Temp|m_Page;
   NET_Write_Data(0x0000,Temp);
}

UINT NET_ID(UCHAR m_Num)        //获得8019的ID
{
//ID号在0页的,0x0A和0x0B两个单元 (8019ID0,8019ID1)这两个地址的读和写不是同一个寄存器
   UINT m_ID;
   NET_Page_Set(0);
   //NET_Write_Data(0x0000,0x22);    //start command;remote DMA
   m_ID=NET_Read_Data(0x000a+m_Num);
   return m_ID;
}

void Set_MAC_Addr(void)  //设置8019网卡MAC地址
{
//MAC地址寄存器在页面2,0x01~06 (PAR0-PAR5)
   UINT i;
   NET_Page_Set(1);
   for(i=0;i<6;i++)
      NET_Write_Data(i+1,MAC_Addr[i]);
}

void Read_Phy_ID(void)     //获得网卡物理地址  该程序可能有点问题
{
//
   UCHAR i,Temp;
   NET_Page_Set(0);
   NET_Write_Data(0x0008,0x00);//RSAR0 dma read lowaddress=0;
   NET_Write_Data(0x0009,0x00);//RSAR1 dma read highaddress=0
   NET_Write_Data(0x000a,12);  //RBCR0 count low
   NET_Write_Data(0x000b,0x00);//RBCR1 read count high
   NET_Write_Data(0x0000,0x0a);//dma read and start
   printf("\nPhysical Adress is:");
   for (i=0;i<6;i++)
   {
      Temp=NET_Read_Data(0x0010+i);//读取一个字节
      if(i<5)
         printf("%x-",Temp);
      else
         printf("%x\n",Temp);
      Temp=NET_Read_Data(0x0010+i);//读取一个重复的字节,这个字节被丢弃
   }
}


void NET_Hard_Reset(void)      //8019硬复位
{
//通过对8019的复位Pin的控制来达到硬件复位的效果
    
   IOWR_ALTERA_AVALON_PIO_DATA(NET_RST_BASE,1); //8019模块复位,高电平复位
   printf("等待复位过程完成,时间5秒\n");
   Delay(1000);                 //800ns以下忽略不记,高电平必须保持800ns以上
     
   IOWR_ALTERA_AVALON_PIO_DATA(NET_RST_BASE,0); //8019模块复位结束
}

void NET_Soft_Reset(void)      //8019软复位
{
//对复位地址写任意数据达到复位结果
//复位地址是任何页面的,0x18~0x1f单元
   UINT Temp;
   Temp=NET_Read_Data(0x001f);  //1F 是 Reset Port
   NET_Write_Data(0x001f,Temp);
   Delay(1000);                 //高电平复位  必须保持800ns以上 
}



void Init_system(void)   //系统初始化
{
   void* edge_captureptr=(void*)&edge_capture;
   IOWR_ALTERA_AVALON_PIO_DATA(NET_AEN_BASE,1);//8019模块无效
     
   IOWR_ALTERA_AVALON_PIO_DATA(NET_WR_BASE,1);//读、写信号无效
   
   IOWR_ALTERA_AVALON_PIO_DATA(NET_RD_BASE,1);
   NET_Hard_Reset();    //硬件复位
   NET_Soft_Reset();    //软件复位
   

⌨️ 快捷键说明

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