?? usbcore.c
字號:
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: USBCORE.C
* Purpose: USB Core Module
* Version: V1.10
*----------------------------------------------------------------------------
* This file is part of the uVision/ARM development tools.
* This software may only be used under the terms of a valid, current,
* end user licence from KEIL for a compatible version of KEIL software
* development tools. Nothing else gives you the right to use it.
*
* Copyright (c) 2005-2006 Keil Software.
*---------------------------------------------------------------------------*/
#include "type.h"
#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "usbdesc.h"
#include "usbuser.h"
#include "lcd.h"
#if (USB_AUDIO)
#include "audio.h"
#include "adcuser.h"
#endif
#if (USB_HID)
#include "hid.h"
#include "hiduser.h"
#endif
#if (USB_MSC)
#include "msc.h"
#include "mscuser.h"
#endif
#pragma diag_suppress 111,1441
WORD USB_DeviceStatus;
BYTE USB_DeviceAddress;
BYTE USB_Configuration;
DWORD USB_EndPointMask;
DWORD USB_EndPointHalt;
BYTE USB_NumInterfaces;
BYTE USB_AltSetting[USB_IF_NUM];
BYTE EP0Buf[USB_MAX_PACKET0];
BYTE USB_MouseSuccessFlag;//lakin add
USB_EP_DATA EP0Data;
USB_SETUP_PACKET SetupPacket;
/*
* Reset USB Core
* Parameters: None
* Return Value: None
*/
void USB_ResetCore (void) {
USB_DeviceStatus = USB_POWER;
USB_DeviceAddress = 0;
USB_Configuration = 0;
USB_EndPointMask = 0x00010001;
USB_EndPointHalt = 0x00000000;
}
/*
* USB Request - Setup Stage
* Parameters: None (global SetupPacket)
* Return Value: None
*/
void USB_SetupStage (void) {
USB_ReadEP(0x00, (BYTE *)&SetupPacket);
}
/*
* USB Request - Data In Stage
* Parameters: None (global EP0Data)
* Return Value: None
*/
void USB_DataInStage (void) {
DWORD 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 Request - Data Out Stage
* Parameters: None (global EP0Data)
* Return Value: None
*/
void USB_DataOutStage (void) {
DWORD cnt;
cnt = USB_ReadEP(0x00, EP0Data.pData);
EP0Data.pData += cnt;
EP0Data.Count -= cnt;
}
/*
* USB Request - Status In Stage
* Parameters: None
* Return Value: None
*/
void USB_StatusInStage (void) {
USB_WriteEP(0x80, NULL, 0);
}
/*
* USB Request - Status Out Stage
* Parameters: None
* Return Value: None
*/
void USB_StatusOutStage (void) {
USB_ReadEP(0x00, EP0Buf);
}
/*
* Get Status USB Request
* Parameters: None (global SetupPacket)
* Return Value: TRUE - Success, FALSE - Error
*/
__inline BOOL USB_GetStatus (void) {
DWORD n, m;
display_num++; LCD_print("GetStatus",display_num*10,10);
switch (SetupPacket.bmRequestType.BM.Recipient) {
case REQUEST_TO_DEVICE:
EP0Data.pData = (BYTE *)&USB_DeviceStatus;
USB_DataInStage();
break;
case REQUEST_TO_INTERFACE:
if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) {
*((__packed WORD *)EP0Buf) = 0;
EP0Data.pData = EP0Buf;
USB_DataInStage();
} else {
return (FALSE);
}
break;
case REQUEST_TO_ENDPOINT:
n = SetupPacket.wIndex.WB.L & 0x8F;
m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) && (USB_EndPointMask & m)) {
*((__packed WORD *)EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0;
EP0Data.pData = EP0Buf;
USB_DataInStage();
} else {
return (FALSE);
}
break;
default:
return (FALSE);
}
return (TRUE);
}
/*
* Set/Clear Feature USB Request
* Parameters: sc: 0 - Clear, 1 - Set
* None (global SetupPacket)
* Return Value: TRUE - Success, FALSE - Error
*/
__inline BOOL USB_SetClrFeature (DWORD sc) {
DWORD n, m;
switch (SetupPacket.bmRequestType.BM.Recipient) {
case REQUEST_TO_DEVICE:
if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) {
if (sc) {
USB_WakeUpCfg(TRUE);
USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP;
} else {
USB_WakeUpCfg(FALSE);
USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP;
}
} else {
return (FALSE);
}
break;
case REQUEST_TO_INTERFACE:
return (FALSE);
case REQUEST_TO_ENDPOINT:
n = SetupPacket.wIndex.WB.L & 0x8F;
m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
if ((USB_Configuration != 0) && ((n & 0x0F) != 0) && (USB_EndPointMask & m)) {
if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL) {
if (sc) {
USB_SetStallEP(n);
USB_EndPointHalt |= m;
} else {
USB_ClrStallEP(n);
USB_EndPointHalt &= ~m;
}
} else {
return (FALSE);
}
} else {
return (FALSE);
}
break;
default:
return (FALSE);
}
return (TRUE);
}
/*
* Get Descriptor USB Request
* Parameters: None (global SetupPacket)
* Return Value: TRUE - Success, FALSE - Error
*/
//進入getdescriptor后是通過WValue的高位來判斷獲得什么描述符
/*
//下面的bmRequestType 接收者是屬于設備
#define DEVICE_DESCRIPTOR 0x01 //設備描述符
#define CONFIGURATION_DESCRIPTOR 0x02 //配置描述符
#define STRING_DESCRIPTOR 0x03 //字符串描述符
#define INTERFACE_DESCRIPTOR 0x04 //接口描述符
#define ENDPOINT_DESCRIPTOR 0x05 //端點描述符
//下面的bmRequestType 接收者是屬于接口
#define HID_DESCRIPTOR 0x21 //HID描述符
#define REPORT_DESCRIPTOR 0x22 //報告描述符
#define PHYSICAL_DESCRIPTOR 0x23 //物理描述符
*/
__inline BOOL USB_GetDescriptor (void) {
BYTE *pD;
DWORD len, n;
switch (SetupPacket.bmRequestType.BM.Recipient) {
case REQUEST_TO_DEVICE:
switch (SetupPacket.wValue.WB.H) {
case USB_DEVICE_DESCRIPTOR_TYPE:
EP0Data.pData = (BYTE *)USB_DeviceDescriptor;
len = USB_DEVICE_DESC_SIZE;
display_num++; LCD_print("USB DEVICE",display_num*10,10);
break;
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
display_num++; LCD_print("USB CONFIGURATION",display_num*10,10);
pD = (BYTE *)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) {
return (FALSE);
}
EP0Data.pData = pD;
len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength;
break;
case USB_STRING_DESCRIPTOR_TYPE:
EP0Data.pData = (BYTE *)USB_StringDescriptor + SetupPacket.wValue.WB.L;
len = ((USB_STRING_DESCRIPTOR *)EP0Data.pData)->bLength;
break;
default:
return (FALSE);
}
break;
case REQUEST_TO_INTERFACE:
//display_num++; LCD_print("INTERFACE",display_num*10,10);
switch (SetupPacket.wValue.WB.H) {
#if USB_HID
case HID_HID_DESCRIPTOR_TYPE:
if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) {
return (FALSE); /* Only Single HID Interface is supported */
}
EP0Data.pData = (BYTE *)USB_ConfigDescriptor + HID_DESC_OFFSET;
len = HID_DESC_SIZE;
break;
case HID_REPORT_DESCRIPTOR_TYPE:
display_num++; LCD_print("REPORT",display_num*10,10);
if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) {
return (FALSE); /* Only Single HID Interface is supported */
}
// EP0Data.pData = (BYTE *)HID_ReportDescriptor;
#ifdef MOUSE_HID
EP0Data.pData = (BYTE *)MouseReportDescriptor;
#else
EP0Data.pData = (BYTE *)KeyBoardReportDescriptor;
#endif
len = HID_ReportDescSize;
USB_MouseSuccessFlag = 1; //lakin add
break;
case HID_PHYSICAL_DESCRIPTOR_TYPE:
return (FALSE); /* HID Physical Descriptor is not supported */
#endif
default:
return (FALSE);
}
break;
default:
return (FALSE);
}
if (EP0Data.Count > len) {
EP0Data.Count = len;
}
USB_DataInStage();
return (TRUE);
}
/*
* Set Configuration USB Request
* Parameters: None (global SetupPacket)
* Return Value: TRUE - Success, FALSE - Error
*/
__inline BOOL USB_SetConfiguration (void) {
USB_COMMON_DESCRIPTOR *pD;
DWORD alt, n, m;
if (SetupPacket.wValue.WB.L) {
pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor;
while (pD->bLength) {
switch (pD->bDescriptorType) {
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue == SetupPacket.wValue.WB.L) {
USB_Configuration = SetupPacket.wValue.WB.L;
USB_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bNumInterfaces;
for (n = 0; n < USB_IF_NUM; n++) {
USB_AltSetting[n] = 0;
}
for (n = 1; n < 16; n++) {
if (USB_EndPointMask & (1 << n)) {
USB_DisableEP(n);
}
if (USB_EndPointMask & ((1 << 16) << n)) {
USB_DisableEP(n | 0x80);
}
}
USB_EndPointMask = 0x00010001;
USB_EndPointHalt = 0x00000000;
USB_Configure(TRUE);
if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bmAttributes & USB_CONFIG_SELF_POWERED) {
USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED;
} else {
USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED;
}
} else {
(BYTE *)pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength;
continue;
}
break;
case USB_INTERFACE_DESCRIPTOR_TYPE:
alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting;
break;
case USB_ENDPOINT_DESCRIPTOR_TYPE:
if (alt == 0) {
n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F;
m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
USB_EndPointMask |= m;
USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD);
USB_EnableEP(n);
USB_ResetEP(n);
}
break;
}
(BYTE *)pD += pD->bLength;
}
}
else {
USB_Configuration = 0;
for (n = 1; n < 16; n++) {
if (USB_EndPointMask & (1 << n)) {
USB_DisableEP(n);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -