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

📄 usbcore.c

📁 基于AT91SAM7S64单片机的USB口转Uart串行口的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
             Prints("(未知的索引值)。\r\n");
            #endif
            //对于未知索引值的请求,返回一个0长度的包
            SendLength=0;
            NeedZeroPacket=1;
           break;
          }
          //判断请求的字节数是否比实际需要发送的字节数多
          //如果请求的比实际的长,那么只返回实际长度的数据
          if(wLength>SendLength)
          {
           if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
           {
            NeedZeroPacket=1; //需要返回0长度的数据包
           }
          }
          else
          {
           SendLength=wLength;
          }
          //将数据通过EP0返回
          UsbEp0SendData();         
         break;

         case REPORT_DESCRIPTOR:  //报告描述符
          #ifdef DEBUG0
           Prints("报告描述符。\r\n");
          #endif
          pSendData=0;
          SendLength=0; //需要返回的数据长度         
          //判断请求的字节数是否比实际需要发送的字节数多
          //如果请求的比实际的长,那么只返回实际长度的数据
          if(wLength>SendLength)
          {
           if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
           {
            NeedZeroPacket=1; //需要返回0长度的数据包
           }
          }
          else
          {
           SendLength=wLength;
          }
          //将数据通过EP0返回
          UsbEp0SendData();
         break;
                 
         default:  //其它描述符
          #ifdef DEBUG0
           Prints("其他描述符,描述符代码:");
           PrintHex((wValue>>8)&0xFF);
           Prints("\r\n");
          #endif
         break;
        }
       break;
      
      case GET_INTERFACE: //获取接口
       #ifdef DEBUG0
        Prints("获取接口。\r\n");
       #endif
      break;
      
      case GET_STATUS: //获取状态
       #ifdef DEBUG0
        Prints("获取状态。\r\n");
       #endif
      break;
      
      case SYNCH_FRAME: //同步帧
       #ifdef DEBUG0
        Prints("同步帧。\r\n");
       #endif
      break;
      
      default:  //未定义的标准请求
       #ifdef DEBUG0
        Prints("错误:未定义的标准输入请求。\r\n");
       #endif       
      break;
     }
    break;
    
    case 1:  //类请求
     #ifdef DEBUG0
      Prints("USB类输入请求:\r\n");
     #endif
     switch(bRequest)
     {
      case GET_LINE_CODING: //GET_LINE_CODING请求
       #ifdef DEBUG0
        Prints("GET_LINE_CODING。\r\n");
       #endif
       SendLength=0x07; //7字节的LineCoding
       pSendData=LineCoding;
      break;
      
      case SERIAL_STATE: //获取SERIAL_STATE请求
       //本来该请求是获取串口状态的,但是圈圈在实际使用中,
       //发现主机从来未发送过该请求,因而这里并不对它进行处理,
       //只是简单地发送一个0长度的数据包。
       #ifdef DEBUG0
        Prints("SERIAL_STATE。\r\n");
       #endif       
       SendLength=0;
       NeedZeroPacket=1;
      break;
      
      default:
       #ifdef DEBUG0
        Prints("未知类请求。\r\n");
       #endif
       SendLength=0;
       NeedZeroPacket=1;
      break;
     }
    //判断请求的字节数是否比实际需要发送的字节数多
    //如果请求的比实际的长,那么只返回实际长度的数据
    if(wLength>SendLength)
    {
     if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
     {
      NeedZeroPacket=1; //需要返回0长度的数据包
     }
    }
    else
    {
     SendLength=wLength;
    }
    //将数据通过EP0返回
    UsbEp0SendData();
    break;
    
    case 2:  //厂商请求
     #ifdef DEBUG0
      Prints("USB厂商输入请求:\r\n");
     #endif
    break;
    
    default: //未定义的请求。这里只显示一个报错信息。
     #ifdef DEBUG0
      Prints("错误:未定义的输入请求。\r\n");
     #endif
    break;
   }
  }
  //否则说明是输出请求
  else //if(bmRequestType&0x80==0x80)之else
  {
   //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
   //0为标准请求,1为类请求,2为厂商请求。
   switch((bmRequestType>>5)&0x03)
   {
    case 0:  //标准请求
     #ifdef DEBUG0
      Prints("USB标准输出请求:");
     #endif
     //USB协议定义了几个标准输出请求,我们实现这些标准请求即可
     //请求的代码在bRequest中,对不同的请求代码进行散转
     switch(bRequest)
     {
      case CLEAR_FEATURE: //清除特性
       #ifdef DEBUG0
        Prints("清除特性。\r\n");
       #endif
      break;
      
      case SET_ADDRESS:  //设置地址
       #ifdef DEBUG0
        Prints("设置地址。地址为:");
        PrintHex(wValue&0xFF); //显示所设置的地址
        Prints("\r\n");
       #endif
       //设置地址没有数据过程,直接进入到状态过程,返回一个0长度的数据包
       SendLength=0;
       NeedZeroPacket=1;
       //将数据通过EP0返回
       UsbEp0SendData();
       UsbChipWriteAddress(wValue&0xFF); //wValue中的低字节是设置的地址值
      break;
      
      case SET_CONFIGURATION: //设置配置
       #ifdef DEBUG0
        Prints("设置配置。\r\n");
       #endif
       //wValue的低字节为配置的值,如果该值为非0,才能使能非0端点。        
       //保存当前配置值
       ConfigValue=wValue&0xFF;
       //设置芯片的config值     
       UsbChipSetConfig(ConfigValue); 
         
       //使能非0端点。非0端点只有在设置为非0的配置后才能使能。
       UsbChipSetEndpointEnable(ConfigValue);
      
       //返回一个0长度的状态数据包
       SendLength=0;
       NeedZeroPacket=1;
       //将数据通过EP0返回
       UsbEp0SendData();
      break;
      
      case SET_DESCRIPTOR: //设置描述符
       #ifdef DEBUG0
        Prints("设置描述符。\r\n");
       #endif
      break;
      
      case SET_FEATURE: //设置特性
       #ifdef DEBUG0
        Prints("设置特性。\r\n");
       #endif
      break;

      case SET_INTERFACE: //设置接口
       #ifdef DEBUG0
        Prints("设置接口。\r\n");
       #endif
      break;      
      
      default:  //未定义的标准请求
       #ifdef DEBUG0
        Prints("错误:未定义的标准输出请求。\r\n");
        Prints("未知请求。\r\n");        
       #endif
        //只需要返回一个0长度的数据包即可
        SendLength=0;
        NeedZeroPacket=1;
        //将数据通过EP0返回
        UsbEp0SendData();
      break;
     }
    break;
    
    case 1:  //类请求
     #ifdef DEBUG0
      Prints("USB类输出请求:");
     #endif
     switch(bRequest)
     {
      case SET_CONTROL_LINE_STATE:
       #ifdef DEBUG0
        Prints("SET_CONTROL_LINE_STATE。\r\n");
       #endif
       //该请求没有数据输出阶段,其中wValue字段的D0位表示DTR,
       //D1位表示RTS。但是我们的板上的串口并没有这两引脚,因而
       //对该请求我们仅是简单地返回一个0长度的状态过程数据包即可
       SendLength=0;
       NeedZeroPacket=1;
       //将数据通过EP0返回
       UsbEp0SendData();
      break;
      
      case SET_LINE_CODING:
      //该请求设置串口的属性,但是实际的数据并不在设置过程发出,
      //而是在之后的数据过程发出。这里不用做任何处理,在数据过程
      //完成后返回0长度的状态包。
       #ifdef DEBUG0
        Prints("SET_LINE_CODING。\r\n");
       #endif
       break;
      
      default:
       #ifdef DEBUG0
        Prints("未知请求。\r\n");
       #endif        
        //只需要返回一个0长度的数据包即可
        SendLength=0;
        NeedZeroPacket=1;
        //将数据通过EP0返回
        UsbEp0SendData();
      break;
     }
    break;
    
    case 2:  //厂商请求
     #ifdef DEBUG0
      Prints("USB厂商输出请求:\r\n");
     #endif
    break;
    
    default: //未定义的请求。这里只显示一个报错信息。
     #ifdef DEBUG0
      Prints("错误:未定义的输出请求。\r\n");
     #endif
    break;
   }
  }
 }
 //普通数据输出
 else //判断setup包之else
 {
  ClrCsr(0,1<<7);  //设置DIR为0
  UsbEp0DataOut(); //处理标准请求的数据部分
 }
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:端点0输入中断处理函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbEp0In(void)
{
#ifdef DEBUG0
 Prints("USB端点0输入中断。\r\n");
#endif
 //清除端点0的输入完成中断标志位
 ClrCsr(0,1<<0);
 
 //发送剩余的字节数
 UsbEp0SendData();
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:端点1输入中断处理函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbEp1In(void)
{
#ifdef DEBUG0
 Prints("USB端点1输入中断。\r\n");
#endif
 //清除端点1的输入完成中断标志位
 ClrCsr(1,1<<0);
 //端点1输入处于空闲状态
 Ep1InIsBusy=0;
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:端点2输出中断处理函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbEp2Out(void)
{
#ifdef DEBUG0
 Prints("USB端点2输出中断。\r\n");
#endif

 //如果缓冲区中的数据还未通过串口发送完毕,则暂时不处理该中断,直接返回。
 if(UsbEp2ByteCount!=0) return;
 
 //清除端点2输出的中断标志位
 //无操作
  
 //读取端点2的数据。返回值为实际读到的数据字节数
 UsbEp2ByteCount=UsbChipReadEndpointBuffer(2,BUF_LEN,UsbEp2Buffer);
 //清除端点缓冲区
 UsbChipClearBuffer(2); 
 //输出位置设为0
 UsbEp2BufferOutputPoint=0; 
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:端点3输入中断处理函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbEp3In(void)
{
#ifdef DEBUG0
 Prints("USB端点3输入中断。\r\n");
#endif
 //清除端点3的输入完成中断标志位
 ClrCsr(3,1<<0);
 //端点3输入处于空闲状态
 Ep3InIsBusy=0;
}
////////////////////////End of function//////////////////////////////

⌨️ 快捷键说明

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