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

📄 exp12.c

📁 本程序功能是在FPGA上nios处理器的usb接口程序。
💻 C
字号:

 
#include <stdio.h>
#include "system.h"
#include "alt_types.h"
#include "Exp12.h"
#include "sys/alt_irq.h"
#include "altera_avalon_pio_regs.h"
volatile int edge_capture;
alt_u8 USB_Buff[Bulk_Len];
alt_u8 Setup_Step=FALSE,Config;
int main()
{
  void *edge_capture_ptr=(void *)&edge_capture;
  IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1);
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_CS_BASE,1);
  IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1);
  IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1);   
  
 

  alt_irq_register(D12_INT_IRQ,edge_capture_ptr,D12_INT_ISR);
  IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_INT_BASE,0);
  IOWR_ALTERA_AVALON_PIO_EDGE_CAP(D12_INT_BASE,0);
  IOWR_ALTERA_AVALON_PIO_IRQ_MASK(D12_INT_BASE,1);
  USB_Port_Init();    //枚举USB
  while(1)
    ;
  return 0;
}

void D12_INT_ISR(void * context,alt_u32 id)
{ 
  volatile int* edge_capture_ptr = (volatile int*) context;
  alt_u32 Int_Flag;
 //  DISABLE;
 IOWR_ALTERA_AVALON_PIO_IRQ_MASK(D12_INT_BASE,0);
  IOWR_ALTERA_AVALON_PIO_EDGE_CAP(D12_INT_BASE,0);    //清除中断标志
   Int_Flag=USB_Read_INT_Flag();    //读取中断标志
   printf("\nInterrupt:%x\n",Int_Flag);
   if(Int_Flag & 0x0001)    //端点0 OUT中断
      USB_EndPoint0_OUT();
   if(Int_Flag & 0x0002)    //端点0 IN 中断
      USB_EndPoint0_IN();
   if(Int_Flag & 0x0004)    //端点1 OUT中断
      USB_EndPoint1_OUT();
   if(Int_Flag & 0x0008)    //端点1 IN 中断
      USB_EndPoint1_IN();
   if(Int_Flag & 0x0010)    //端点2 OUT中断
      USB_EndPoint2_OUT();
   if(Int_Flag & 0x0020)    //端点2 IN 中断
      USB_EndPoint2_IN();
   if(Int_Flag & 0x0040)    //总线复位
   {
    USB_SetEndPoint_Enable(0);
    IOWR_ALTERA_AVALON_PIO_DATA(D12_SUSPEND_BASE,1);
   }
   if(Int_Flag & 0x0080)    //挂起改变
   {
     USB_SetEndPoint_Enable(0);
     IOWR_ALTERA_AVALON_PIO_DATA(D12_SUSPEND_BASE,1);
   }
//   ENABLE;   
 IOWR_ALTERA_AVALON_PIO_IRQ_MASK(D12_INT_BASE,1);

}

/**********延迟程序*****************/
void Delay(alt_u32 m_Delay)
{
   while(m_Delay--);  
}
/**********D12操作程序*****************/
void USB_Write_Command(alt_u8 m_Command)//写命令
{
    IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0xff);  //数据总线:输出
    IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,1);   //选择命令
    IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0);   //片选拉低
    IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0);   //写信号有效
    IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Command);
    IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1);   //写信号无效
    IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1);   //片选无效
}
void USB_Write_Data(alt_u8 m_Data) //写数据
{
    IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0xff);  //数据总线:输出
    IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0);   //选择数据
    IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0);   //片选拉低
    IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0);   //写信号有效
    IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Data);
    IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1);   //写信号无效
    IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1);   //片选无效
}
alt_u8 USB_Read_Data(void)      //读数据
{
    alt_u8 Temp;
    IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0x00);  //数据总线:输入
    IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0);   //选择数据
    IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0);   //片选拉低
    IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0);  //读信号有效
    Temp=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
    IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1);   //读信号无效
    IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1);   //片选无效
    return Temp;
}

void USB_Port_Init(void)
{
   IOWR_ALTERA_AVALON_PIO_DATA(D12_SUSPEND_BASE,0);               //唤醒USB芯片
   USB_SetDMA_Mode(0x00);   //设置USB DMA
   USB_Connect(0x02,0x4b);  //断开USB
   Delay(1000);          //等待大约1秒钟
   USB_Connect(0x12,0x45);  //重新连接USB
   USB_Read_INT_Flag();   
}
void USB_Connect(alt_u8 m_Mode,alt_u8 m_Clk)
{
   USB_Write_Command(0xf3);
   USB_Write_Data(m_Mode);
   USB_Write_Data(m_Clk);
}
void USB_SetAddr_Enable(alt_u8 m_Addr,alt_u8 m_Enable)
{
   USB_Write_Command(0xd0);
   if(m_Enable)
      USB_Write_Data(m_Addr | 0x80);
   else
      USB_Write_Data(m_Addr);
}
void USB_SetEndPoint_Enable(alt_u8 m_Enable)
{
   USB_Write_Command(0xd8);
   if(m_Enable)
      USB_Write_Data(0x01);
   else
      USB_Write_Data(0x00);
}
void USB_SetDMA_Mode(alt_u8 m_Mode)
{
   USB_Write_Command(0xfb);
   USB_Write_Data(m_Mode);
}
alt_u32 USB_Read_INT_Flag(void)       //读中断标志
{
   alt_u32 Temp1,Temp2;
   USB_Write_Command(0xf4);
   Temp2=USB_Read_Data();
   Temp1=USB_Read_Data();
   Temp1<<=8;
   return Temp1+Temp2;
}
alt_u8 USB_Read_LastStatus(alt_u8 m_EndPoint)    //读最后处理状态寄存器
{
   alt_u8 Temp;
   USB_Write_Command(0x40+m_EndPoint);
   Temp=USB_Read_Data();
   return Temp;
}
alt_u8 USB_Read_EndPoint_Buff(alt_u8 m_EndPoint,alt_u8 m_Len,alt_u8 *m_Buff)  //读缓冲区
{
   alt_u8 len,i,Temp;
   USB_Write_Command(m_EndPoint);  //选择目标端点
   if(USB_Read_Data() & 0x01==0)  //如果缓冲区为空,则返回
      return 0;
   else
   {
      USB_Write_Command(0xf0);
      IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0x00);  //数据总线:输入
      IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0);   //选择数据
      IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0);   //片选拉低
      //Temp=USB_Read_Data();
      IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0);   //读信号有效
      Temp=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
      IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1);   //读信号无效
      //len=USB_Read_Data();
      IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0);   //读信号有效
      len=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
      IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1);   //读信号无效
      printf("receive data len: %d\n",len);
      if(len>m_Len)
         len=m_Len;
      for(i=0;i<len;i++)
      {
         //m_Buff[i]=USB_Read_Data();
         IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0);   //读信号有效
         m_Buff[i]=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
         IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1);   //读信号无效
      }
      USB_Write_Command(0xf2);  //清除缓冲区
      return len;      
   }
}
void USB_Write_EndPoint_Buff(alt_u8 m_EndPoint,alt_u8 m_Len,alt_u8 *m_Buff)    //写缓冲区
{
   alt_u8 i;
   USB_Write_Command(m_EndPoint);
   USB_Write_Command(0xf0);
   IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0);   //选择数据
   IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0);   //片选拉低
   //USB_Write_Data(0);
   IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0);   //写信号有效
   IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,0);
   IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1);   //写信号无效
   //USB_Write_Data(m_Len);
   IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0);   //写信号有效
   IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Len);
   IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1);   //写信号无效
   for(i=0;i<m_Len;i++)
   {
      //USB_Write_Data(m_Buff[i]);
      IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0);   //写信号有效
      IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Buff[i]);
      IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1);   //写信号无效
   }
   USB_Write_Command(0xfa);    //使缓冲区有效
}
void USB_EndPoint_Setup_Ack(alt_u8 m_EndPoint)   //SetUp包应答
{
   USB_Write_Command(m_EndPoint);
   USB_Write_Command(0xf1);
   if(m_EndPoint == 0)
      USB_Write_Command(0xf2);
}
void USB_SetEndPoint_Status(alt_u8 m_EndPoint,alt_u8 m_Stall)    //设置端点状态
{
   USB_Write_Command(0x40+m_EndPoint);
   USB_Write_Data(m_Stall);
}
alt_u8 USB_GetEndPoint_Status(alt_u8 m_EndPoint)    //获取端点状态
{
   alt_u8 Temp;
   USB_Write_Command(0x40+m_EndPoint);
   Temp=USB_Read_Data();
   return Temp;
}
void USB_Stall(void)         //设备停止
{
   USB_SetEndPoint_Status(0,1);
   USB_SetEndPoint_Status(1,1);
}

void USB_EndPoint0_IN(void)     //端点0 IN 中断服务子程序
{
   alt_u8 m_Status;
   m_Status=USB_Read_LastStatus(1);
   //printf("usb0in_read_last_Status:%x\n",m_Status);
   if(Setup_Step==USB_Device_Setup_Flag)            //发送设备描述符剩下的2字节
   {  
     // printf("transmit_device_discrpitor+2:\n");
      USB_Write_EndPoint_Buff(1,2,DEVICE_DISCRIPTOR+16);
      Setup_Step=FALSE;
   }
   else if(Setup_Step==USB_Interface_Setup_Flag)     //发送接口描述符
   {
      //printf("transmit_interface_discriptor+16:\n");
      USB_Write_EndPoint_Buff(1,16,CONFIG_DISCRIPTOR+16);
      Setup_Step=USB_EndPoint_Setup_Flag;
   }
   else if(Setup_Step==USB_EndPoint_Setup_Flag)     //发送端点描述符
   {
      //printf("transmit_endpoint_discriptor:\n"); 
      USB_Write_EndPoint_Buff(1,14,CONFIG_DISCRIPTOR+32);
      Setup_Step=FALSE;
   }
   else 
      USB_Write_EndPoint_Buff(1,0,0);
}
void USB_EndPoint0_OUT(void)    //端点0 OUT中断服务子程序
{
   alt_u8 m_Status,i;
   alt_u32 Data_Len=0;
   for(i=0;i<8;i++)
      USB_Buff[i]=0;
   m_Status=USB_Read_LastStatus(0);
  // printf("usb0out_read_last_Status:%x\n",m_Status);
   Data_Len=USB_Read_EndPoint_Buff(0,8,USB_Buff);   //读取数据到USB_Buff
  // printf("receive data_len: %d\n",Data_Len);
   USB_EndPoint_Setup_Ack(0);    //应答Setup包
   USB_EndPoint_Setup_Ack(1);
   Data_Len = USB_Buff[7]*255 + USB_Buff[6];   //获取字节长度
  // printf("read data_len:%d\n",Data_Len);
   printf("Data:");
   for(i=0;i<8;i++)
      printf(" %x  ",USB_Buff[i]);
   printf("\n");
   if((m_Status & 0x21) == 0x21)  //接收到正确的setup包
   {
      if(USB_Buff[0]==0x00)
      {
         if(USB_Buff[1]==0x05)   //设置地址
         {
            //printf("set_address:\n");
            USB_SetAddr_Enable(USB_Buff[2],TRUE);
            USB_Write_EndPoint_Buff(1,0,0);
         }
         else if(USB_Buff[1]==0x09)  //设置配置
         {
          //printf("set_cinfig:\n");
            if(USB_Buff[2]==0x00 && USB_Buff[3]==0x00)
            {
               
               Config=0;
               USB_Write_EndPoint_Buff(1,0,0);
               USB_SetEndPoint_Enable(0);
            }   
            else if(USB_Buff[2]==0x01 && USB_Buff[3]==0x00)
            {
               Config=1;
               USB_Write_EndPoint_Buff(1,0,0);
               USB_SetEndPoint_Enable(1);
            }
            else   //使端点0处于停止状态
               USB_Stall();
         }
         else      //使端点0处于停止状态
            USB_Stall();
      }
      else if(USB_Buff[0]==0x80)
      {
         if(USB_Buff[1]==0x06)    //获取描述符
         {
            if(USB_Buff[3]==0x01)   //设备描述符
            {  
              // printf("get_device_discriptor\n");
               USB_Write_EndPoint_Buff(1,16,DEVICE_DISCRIPTOR);
               if(Data_Len==18)                       //?????
                  Setup_Step=USB_Device_Setup_Flag;
            }
            else if(USB_Buff[3]==0x02)   //获取配置描述符
            {
               //printf("get_config_discriptor\n");
               if(Data_Len==9)
                  USB_Write_EndPoint_Buff(1,9,CONFIG_DISCRIPTOR);
               else if(Data_Len>16)
               {
                  USB_Write_EndPoint_Buff(1,16,CONFIG_DISCRIPTOR);
                  Setup_Step=USB_Interface_Setup_Flag;
               }
            }
            else    //使端点0处于停止状态
               USB_Stall();              
         }
         else if(USB_Buff[1]==0x08)   //读取配置状态
            USB_Write_EndPoint_Buff(1,1,&Config);
         else    //使端点0处于停止状态
            USB_Stall();
      }
      else if(USB_Buff[0]==0x81)
      {
         if(USB_Buff[1]==0x0a)      //获取接口状态
         { 
            //printf("get_interface_discriptor\n");
            USB_Buff[7]=0x00;
            USB_Write_EndPoint_Buff(1,1,USB_Buff+7);                  
         }
         else   //使端点0处于停止状态
            USB_Stall();            
      }
      else    //使端点0处于停止状态
         USB_Stall();
   }  
}
void USB_EndPoint1_IN(void)      //端点1 IN中断服务子程序
{

}
void USB_EndPoint1_OUT(void)     //端点1 OUT中断服务子程序
{ 

}
void USB_EndPoint2_IN(void)      //端点02 IN中断服务子程序
{

}
void USB_EndPoint2_OUT(void)     //端点2 OUT中断服务子程序
{

}



 

⌨️ 快捷键说明

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