LPC1768的USB使用-枚舉過程
枚舉過程如下
#ifndef __USBCORE_H__
#define __USBCORE_H__
/* USB端點(diǎn)0 發(fā)送數(shù)據(jù)結(jié)構(gòu)體*/
typedefstruct _USB_EP_DATA
{
U8*pData;
U16 Count;
}USB_EP_DATA;
/* USB全局變量 */
extern U16 USB_DeviceStatus;
extern U8 USB_DeviceAddress;
extern U8 USB_Configuration;
/* 端點(diǎn)0輸出數(shù)據(jù)緩沖區(qū) */
extern U8 EP0Buf[USB_MAX_PACKET0];
/* 端點(diǎn)輸入信息暫存 */
extern USB_EP_DATA EP0Data;
/* usb setup包數(shù)據(jù)暫存 */
extern USB_SETUP_PACKET SetupPacket;
/* usb初始化類內(nèi)核變量 */
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的設(shè)備狀態(tài),比如喚醒之類的
U8 USB_DeviceAddress;//usb設(shè)備的地址,在枚舉階段主機(jī)會(huì)設(shè)置地址
U8 USB_Configuration;//usb設(shè)備的當(dāng)前配置(usb可以有幾套配置)
U8 EP0Buf[USB_MAX_PACKET0];
USB_EP_DATA EP0Data;
USB_SETUP_PACKET SetupPacket;//usb setup包
//usb設(shè)備復(fù)位
void USB_ResetCore(void)
{
USB_DeviceStatus=0;//設(shè)備上電初始狀態(tài)
USB_DeviceAddress=0;
USB_Configuration=0;
}
//usbsetup包的獲取
void USB_SetupStage(void)
{
USB_ReadEP(0x00,(U8*)&SetupPacket);
}
//usb寫入數(shù)據(jù) 端點(diǎn)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輸出數(shù)據(jù) out
void USB_DataOutStage(void)
{
U32 cnt;
cnt=USB_ReadEP(0x00,EP0Data.pData);
EP0Data.pData+=cnt;
EP0Data.Count-=cnt;
}
//usb發(fā)送0狀態(tài)包
void USB_StatusInStage(void)
{
USB_WriteEP(0x80,NULL,0);
}
//usb讀取狀態(tài)包
void USB_StatusOutStage(void)
{
USB_ReadEP(0x00,EP0Buf);
}
//usb請(qǐng)求描述符(標(biāo)準(zhǔn)請(qǐng)求)
__inline BOOL USB_ReqGetDescriptor(void)
{
U8*pD;
U32 len,n;
switch(SetupPacket.bmRequestType.BM.Recipient)
{
caseREQUEST_TO_DEVICE://設(shè)備請(qǐng)求
switch(SetupPacket.wValue.WB.H)
{
caseUSB_DEVICE_DESCRIPTOR_TYPE://設(shè)備描述符
EP0Data.pData=(U8*)USB_DeviceDescriptor;
len=USB_DEVICE_DESC_SIZE;
usb_debug_printf("獲取設(shè)備描述符rn");
break;
caseUSB_CONFIGURATION_DESCRIPTOR_TYPE://配置描述符
pD=(U8*)USB_ConfigDescriptor;
for(n=0;n!=SetupPacket.wValue.WB.L;n++)//可能有多個(gè)配置,選擇指定的配置
{
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++)//根據(jù)字符串描述符的ID選擇相應(yīng)的字符串,這一項(xiàng)和設(shè)備描述符中的字符串ID相關(guān)
{
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("不支持的請(qǐng)求對(duì)象rn");
return(__FALSE);
}
break;
caseREQUEST_TO_INTERFACE://請(qǐng)求接口
switch(SetupPacket.wValue.WB.H)//接口請(qǐng)求類型
{
caseHID_REPORT_DESCRIPTOR_TYPE://報(bào)告描述符
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("請(qǐng)求報(bào)告描述符rn");
break;
caseHID_PHYSICAL_DESCRIPTOR_TYPE://端點(diǎn)物理特性描述符
usb_debug_printf("不支持的