LPC1768的USB使用-枚举过程
扫描二维码
随时随地手机看文章
枚举过程如下
#ifndef __USBCORE_H__
#define __USBCORE_H__
/* USB端点0 发送数据结构体*/
typedefstruct _USB_EP_DATA
{
U8*pData;
U16 Count;
}USB_EP_DATA;
/* USB全局变量 */
extern U16 USB_DeviceStatus;
extern U8 USB_DeviceAddress;
extern U8 USB_Configuration;
/* 端点0输出数据缓冲区 */
extern U8 EP0Buf[USB_MAX_PACKET0];
/* 端点输入信息暂存 */
extern USB_EP_DATA EP0Data;
/* usb setup包数据暂存 */
extern USB_SETUP_PACKET SetupPacket;
/* usb初始化类内核变量 */
extern void USB_ResetCore(void);
#endif
#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "usbdesc.h"
#include "usbuser.h"
#include "hid.h"
#pragma diag_suppress 111,1441
U16 USB_DeviceStatus;//usb的设备状态,比如唤醒之类的
U8 USB_DeviceAddress;//usb设备的地址,在枚举阶段主机会设置地址
U8 USB_Configuration;//usb设备的当前配置(usb可以有几套配置)
U8 EP0Buf[USB_MAX_PACKET0];
USB_EP_DATA EP0Data;
USB_SETUP_PACKET SetupPacket;//usb setup包
//usb设备复位
void USB_ResetCore(void)
{
USB_DeviceStatus=0;//设备上电初始状态
USB_DeviceAddress=0;
USB_Configuration=0;
}
//usbsetup包的获取
void USB_SetupStage(void)
{
USB_ReadEP(0x00,(U8*)&SetupPacket);
}
//usb写入数据 端点0 in
void USB_DataInStage(void)
{
U32 cnt;
if(EP0Data.Count>USB_MAX_PACKET0)
{
cnt=USB_MAX_PACKET0;
}else
{
cnt=EP0Data.Count;
}
cnt=USB_WriteEP(0x80,EP0Data.pData,cnt);
EP0Data.pData+=cnt;
EP0Data.Count-=cnt;
}
//usb输出数据 out
void USB_DataOutStage(void)
{
U32 cnt;
cnt=USB_ReadEP(0x00,EP0Data.pData);
EP0Data.pData+=cnt;
EP0Data.Count-=cnt;
}
//usb发送0状态包
void USB_StatusInStage(void)
{
USB_WriteEP(0x80,NULL,0);
}
//usb读取状态包
void USB_StatusOutStage(void)
{
USB_ReadEP(0x00,EP0Buf);
}
//usb请求描述符(标准请求)
__inline BOOL USB_ReqGetDescriptor(void)
{
U8*pD;
U32 len,n;
switch(SetupPacket.bmRequestType.BM.Recipient)
{
caseREQUEST_TO_DEVICE://设备请求
switch(SetupPacket.wValue.WB.H)
{
caseUSB_DEVICE_DESCRIPTOR_TYPE://设备描述符
EP0Data.pData=(U8*)USB_DeviceDescriptor;
len=USB_DEVICE_DESC_SIZE;
usb_debug_printf("获取设备描述符rn");
break;
caseUSB_CONFIGURATION_DESCRIPTOR_TYPE://配置描述符
pD=(U8*)USB_ConfigDescriptor;
for(n=0;n!=SetupPacket.wValue.WB.L;n++)//可能有多个配置,选择指定的配置
{
if(((USB_CONFIGURATION_DESCRIPTOR*)pD)->bLength!=0)
{
pD+=((USB_CONFIGURATION_DESCRIPTOR*)pD)->wTotalLength;
}
}
if(((USB_CONFIGURATION_DESCRIPTOR*)pD)->bLength==0)
{
usb_debug_printf("没有指定的配置描述符rn");
return(__FALSE);
}
EP0Data.pData=pD;
len=((USB_CONFIGURATION_DESCRIPTOR*)pD)->wTotalLength;
usb_debug_printf("获取配置描述符rn");
break;
caseUSB_STRING_DESCRIPTOR_TYPE://字符串描述符
pD=(U8*)USB_StringDescriptor;
for(n=0;n!=SetupPacket.wValue.WB.L;n++)//根据字符串描述符的ID选择相应的字符串,这一项和设备描述符中的字符串ID相关
{
if(((USB_STRING_DESCRIPTOR*)pD)->bLength!=0)
{
pD+=((USB_STRING_DESCRIPTOR*)pD)->bLength;
}
}
if(((USB_STRING_DESCRIPTOR*)pD)->bLength==0)
{
usb_debug_printf("获取字符串描述符不支持rn");
return(__FALSE);
}
EP0Data.pData=pD;
len=((USB_STRING_DESCRIPTOR*)pD)->bLength;
usb_debug_printf("获取字符串描述符 %drn",n);
break;
default:
usb_debug_printf("不支持的请求对象rn");
return(__FALSE);
}
break;
caseREQUEST_TO_INTERFACE://请求接口
switch(SetupPacket.wValue.WB.H)//接口请求类型
{
caseHID_REPORT_DESCRIPTOR_TYPE://报告描述符
if(SetupPacket.wIndex.WB.L!=USB_HID_IF_NUM)
{
return(__FALSE);/* Only Single HID Interface is supported */
}
EP0Data.pData=(U8*)HID_ReportDescriptor;
len=HID_ReportDescSize;
usb_debug_printf("请求报告描述符rn");
break;
caseHID_PHYSICAL_DESCRIPTOR_TYPE://端点物理特性描述符
usb_debug_printf("不支持的