10.1 Composite设备介绍

USB的Composite类是USB 复合设备类,一个USB设备具有多种设备功能,比如一个USB设备同时具有鼠标和键盘功能。单一的USB设备开发相对简单,但在很多时候使用的USB设备具有多种功能。Composite类可以满足这种要求。

10.2 Composite数据类型

usbdcomp.h中已经定义好composite设备类中使用的所有数据类型和函数。下面介绍composite设备类使用的数据类型。

typedef struct

{

const tDeviceInfo *pDeviceInfo;

const tConfigHeader *psConfigHeader;

unsigned char ucIfaceOffset;

} tUSBDCompositeEntry;

tUSBDCompositeEntry,定义composite设备信息。定义在usbdcomp.h。

typedef struct

{

unsigned long ulUSBBase;

tDeviceInfo *psDevInfo;

tConfigDescriptor sConfigDescriptor;

tDeviceDescriptor sDeviceDescriptor;

tConfigHeader sCompConfigHeader;

tConfigSection psCompSections[2];

tConfigSection *ppsCompSections[2];

unsigned long ulDataSize;

unsigned char *pucData;

}

tCompositeInstance;

tCompositeInstance,设备类实例。定义了Composite设备类的USB基地址、设备信息、IN端点、OUT端点等信息。

typedef struct

{

const tDeviceInfo *psDevice;

void *pvInstance;

}

tCompositeEntry;

tCompositeEntry,Composite各设备的设备信息。

typedef struct

{

unsigned short usVID;

unsigned short usPID;

unsigned short usMaxPowermA;

unsigned char ucPwrAttributes;

tUSBCallback pfnCallback;

const unsigned char * const *ppStringDescriptors;

unsigned long ulNumStringDescriptors;

unsigned long ulNumDevices;

tCompositeEntry *psDevices;

tCompositeInstance *psPrivateData;

}

tUSBDCompositeDevice;

tUSBDCompositeDevice,Composite设备类,定义了VID、PID、电源属性、字符串描述符等,还包括了Composite设备类实例。其它设备描述符、配置信息通过API函数储入tCompositeInstance定义的Composite设备实例中。

10.3 API函数

在Composite设备类API库中定义了2个函数,完成USB Composite设备初始化、配置及数据处理。下面为usbdcomp.h中定义的API函数:

void *USBDCompositeInit(unsigned long ulIndex,

tUSBDCompositeDevice *psCompDevice,

unsigned long ulSize,

unsigned char *pucData);

void USBDCompositeTerm(void *pvInstance);

void *USBDCompositeInit(unsigned long ulIndex,

tUSBDCompositeDevice *psCompDevice,

unsigned long ulSize,

unsigned char *pucData);

作用:初始化Composite设备硬件、协议,把其它配置参数填入psCompDevice实例中。

参数:ulIndex,USB模块代码,固定值:USB_BASE0。psMSCDevice,MSC设备类。

返回:指向配置后的tUSBDCompositeDevice。

void USBDCompositeTerm(void *pvInstance);

作用:结束Composite设备。

参数:pvInstance,指向tUSBDCompositeDevice。

返回:无。

在这些函数中USBDCompositeInit函数最重要,用于处理各子设备信息,保存所有子设备配置及其它数据。

9.4 Composite设备开发

Composite设备开发只需要3步就能完成:各子设备配置、完善接口函数;Composite设备配置、协调;各子设备数据处理。如图2所示,

<ignore_js_op>

图2

下面以“电子教鞭”实例说明使用USB库开发USB Composite设备过程,电子教鞭有两个重要功能,U盘功能和控制功能。所以要做两个子类:大容量存储类与键盘类:

第一步:各子设备配置、完善接口函数:

#define DESCRIPTOR_DATA_SIZE    (COMPOSITE_DHID_SIZE + COMPOSITE_DMSC_SIZE)

unsigned char g_pucDescriptorData[DESCRIPTOR_DATA_SIZE];

//声明函数原型

unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgParam,

void *pvMsgData);

//声明函数原型

unsigned long KeyboardHandler(void *pvCBData,

unsigned long ulEvent,

unsigned long ulMsgData,

void *pvMsgData);

unsigned long EventHandler(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgData, void *pvMsgData);

const tUSBDMSCDevice g_sMSCDevice;

//msc状态

volatile enum

{

MSC_DEV_DISCONNECTED,

MSC_DEV_CONNECTED,

MSC_DEV_IDLE,

MSC_DEV_READ,

MSC_DEV_WRITE,

}

g_eMSCState;

//全局标志

#define FLAG_UPDATE_STATUS      1

static unsigned long g_ulFlags;

//DMA

tDMAControlTable sDMAControlTable[64] __attribute__ ((aligned(1024)));

//****************************************************************************

// 语言描述符

//****************************************************************************

const unsigned char g_pLangDescriptor[] =

{

4,

USB_DTYPE_STRING,

USBShort(USB_LANG_EN_US)

};

//****************************************************************************

// 制造商 字符串 描述符

//****************************************************************************

const unsigned char g_pManufacturerString[] =

{

(17 + 1) * 2,

USB_DTYPE_STRING,

'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0,

't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0,

};

//****************************************************************************

//产品 字符串 描述符

//****************************************************************************

const unsigned char g_pProductString[] =

{

(19 + 1) * 2,

USB_DTYPE_STRING,

'M', 0, 'a', 0, 's', 0, 's', 0, ' ', 0, 'S', 0, 't', 0, 'o', 0, 'r', 0,

'a', 0, 'g', 0, 'e', 0, ' ', 0, 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0,

'e', 0

};

//****************************************************************************

//  产品 序列号 描述符

//****************************************************************************

const unsigned char g_pSerialNumberString[] =

{

(8 + 1) * 2,

USB_DTYPE_STRING,

'1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0

};

//*****************************************************************************

// 字符串描述符集合

//*****************************************************************************

const unsigned char * const g_pStringDescriptors[] =

{

g_pLangDescriptor,

g_pManufacturerString,

g_pProductString,

g_pSerialNumberString,

};

#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) /                \

sizeof(unsigned char *))

//*****************************************************************************

//MSC实例,配置并为设备信息提供空间

//*****************************************************************************

tMSCInstance g_sMSCInstance;

//*****************************************************************************

//msc设备配置

//*****************************************************************************

const tUSBDMSCDevice g_sMSCDevice =

{

USB_VID_STELLARIS,

USB_PID_MSC,

"TI      ",

"Mass Storage    ",

"1.00",

200,

USB_CONF_ATTR_SELF_PWR,

g_pStringDescriptors,

NUM_STRING_DESCRIPTORS,

{

USBDMSCStorageOpen,

USBDMSCStorageClose,

USBDMSCStorageRead,

USBDMSCStorageWrite,

USBDMSCStorageNumBlocks

},

USBDMSCEventCallback,

&g_sMSCInstance

};

#define MSC_BUFFER_SIZE 512

//*****************************************************************************

//键盘实例,配置并为设备信息提供空间

//*****************************************************************************

tHIDKeyboardInstance g_KeyboardInstance;

//*****************************************************************************

//键盘设备配置

//*****************************************************************************

const tUSBDHIDKeyboardDevice g_sKeyboardDevice =

{

USB_VID_STELLARIS,

USB_VID_STELLARIS,

200,

USB_CONF_ATTR_SELF_PWR | USB_CONF_ATTR_RWAKE,

KeyboardHandler,

(void *)&g_sKeyboardDevice,

0,

0,

&g_KeyboardInstance

};

//*****************************************************************************

//callback函数

//*****************************************************************************

unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgParam, void *pvMsgData)

{

switch(ulEvent)

{

// 正在写数据到存储设备.

case USBD_MSC_EVENT_WRITING:

{

break;

}

//读取数据.

case USBD_MSC_EVENT_READING:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x10);

break;

}

//空闲

case USBD_MSC_EVENT_IDLE:

default:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x00);

break;

}

}

return(0);

}

//*****************************************************************************

//键盘callback函数

//*****************************************************************************

unsigned long KeyboardHandler(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgData, void *pvMsgData)

{

switch (ulEvent)

{

case USB_EVENT_CONNECTED:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);

break;

}

case USB_EVENT_DISCONNECTED:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x00);

break;

}

case USB_EVENT_TX_COMPLETE:

{

break;

}

case USB_EVENT_SUSPEND:

{

break;

}

case USB_EVENT_RESUME:

{

break;

}

case USBD_HID_KEYB_EVENT_SET_LEDS:

{

break;

}

default:

{

break;

}

}

return (0);

}

第二步:完成Composite设备配置、协调:

//*****************************************************************************

//复合设备配置

//*****************************************************************************

tCompositeEntry g_psCompDevices[]=

{

{

&g_sMSCDeviceInfo,

(void  *)&g_sMSCDeviceInfo

},

{

&g_sHIDDeviceInfo,

(void  *)&g_sHIDDeviceInfo

}

};

#define NUM_DEVICES          (sizeof(g_psCompDevices)/sizeof(tCompositeEntry))

tCompositeInstance g_CompInstance;

unsigned long xxx[10];

tUSBDCompositeDevice g_sCompDevice =

{

USB_VID_STELLARIS,

0x0123,

500,

USB_CONF_ATTR_BUS_PWR,

EventHandler,

g_pStringDescriptors,

NUM_STRING_DESCRIPTORS,

2,

g_psCompDevices,

xxx,

&g_CompInstance

};

//*****************************************************************************

//复合设备callback函数

//*****************************************************************************

unsigned long EventHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgData,

void *pvMsgData)

{

unsigned long ulNewEvent;

ulNewEvent = 1;

switch(ulEvent)

{

case USB_EVENT_CONNECTED:

{

break;

}

case USB_EVENT_DISCONNECTED:

{

break;

}

case USB_EVENT_SUSPEND:

{

break;

}

case USB_EVENT_RESUME:

{

break;

}

default:

{

ulNewEvent = 0;

break;

}

}

if(ulNewEvent)

{

}

return(0);

}

第三步:各子设备数据处理,主要是按键处理,U盘功能自动调用底层驱动自动完成:

//系统初始化。

SysCtlLDOSet(SYSCTL_LDO_2_75V);

SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL  | SYSCTL_OSC_MAIN );

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,0xf0);

GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,0x0f);

HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= 0x0f;

// ucDMA配置

SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

SysCtlDelay(10);

uDMAControlBaseSet(&sDMAControlTable[0]);

uDMAEnable();

g_ulFlags = 0;

g_eMSCState = MSC_DEV_IDLE;

//复合设备初始化

g_sCompDevice.psDevices[0].pvInstance =

USBDMSCCompositeInit(0, &g_sMSCDevice);

g_sCompDevice.psDevices[1].pvInstance =

USBDHIDKeyboardInit(0, &g_sKeyboardDevice);

USBDCompositeInit(0, &g_sCompDevice, DESCRIPTOR_DATA_SIZE,

g_pucDescriptorData);

//初始化存储设备

disk_initialize(0);

while(1)

{

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, HID_KEYB_CAPS_LOCK,

HID_KEYB_USAGE_A,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_0)

? false : true);

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,

HID_KEYB_USAGE_DOWN_ARROW,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_1)

? false : true);

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,

HID_KEYB_USAGE_UP_ARROW,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_2)

? false : true);

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,

HID_KEYB_USAGE_ESCAPE,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_3)

? false : true);

SysCtlDelay(SysCtlClockGet()/3000);

}

使用上面三步就完成Composite设备开发。Composite设备开发时要加入两个lib库函数: usblib.lib和DriverLib.lib,在启动代码中加入USB0DeviceIntHandler中断服务函数。以上Composite备开发完成,在Win xp下运行效果如下图所示:

<ignore_js_op>

在电脑中可以发现多了USB MSC设备和HID设备,同时还多了一个Composite设备。

Composite设备开发源码较多,下面只列出一部分如下:

#include "inc/hw_ints.h"

#include "inc/hw_memmap.h"

#include "inc/hw_gpio.h"

#include "inc/hw_types.h"

#include "inc/hw_ints.h"

#include "driverlib/sysctl.h"

#include "driverlib/gpio.h"

#include "driverlib/interrupt.h"

#include "driverlib/rom.h"

#include "driverlib/systick.h"

#include "driverlib/usb.h"

#include "driverlib/udma.h"

#include "usblib/usblib.h"

#include "usblib/usb-ids.h"

#include "usblib/device/usbdevice.h"

#include "usblib/device/usbdmsc.h"

#include "diskio.h"

#include "usbdsdcard.h"

#include "usblib/usblib.h"

#include "usblib/usbhid.h"

#include "usblib/device/usbdhid.h"

#include "usblib/device/usbdcomp.h"

#include "usblib/device/usbdhidkeyb.h"

#define DESCRIPTOR_DATA_SIZE    (COMPOSITE_DHID_SIZE + COMPOSITE_DMSC_SIZE)

unsigned char g_pucDescriptorData[DESCRIPTOR_DATA_SIZE];

//声明函数原型

unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgParam,

void *pvMsgData);

//声明函数原型

unsigned long KeyboardHandler(void *pvCBData,

unsigned long ulEvent,

unsigned long ulMsgData,

void *pvMsgData);

unsigned long EventHandler(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgData, void *pvMsgData);

const tUSBDMSCDevice g_sMSCDevice;

//msc状态

volatile enum

{

MSC_DEV_DISCONNECTED,

MSC_DEV_CONNECTED,

MSC_DEV_IDLE,

MSC_DEV_READ,

MSC_DEV_WRITE,

}

g_eMSCState;

//全局标志

#define FLAG_UPDATE_STATUS      1

static unsigned long g_ulFlags;

//DMA

tDMAControlTable sDMAControlTable[64] __attribute__ ((aligned(1024)));

//****************************************************************************

// 语言描述符

//****************************************************************************

const unsigned char g_pLangDescriptor[] =

{

4,

USB_DTYPE_STRING,

USBShort(USB_LANG_EN_US)

};

//****************************************************************************

// 制造商 字符串 描述符

//****************************************************************************

const unsigned char g_pManufacturerString[] =

{

(17 + 1) * 2,

USB_DTYPE_STRING,

'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0,

't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0,

};

//****************************************************************************

//产品 字符串 描述符

//****************************************************************************

const unsigned char g_pProductString[] =

{

(19 + 1) * 2,

USB_DTYPE_STRING,

'M', 0, 'a', 0, 's', 0, 's', 0, ' ', 0, 'S', 0, 't', 0, 'o', 0, 'r', 0,

'a', 0, 'g', 0, 'e', 0, ' ', 0, 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0,

'e', 0

};

//****************************************************************************

//  产品 序列号 描述符

//****************************************************************************

const unsigned char g_pSerialNumberString[] =

{

(8 + 1) * 2,

USB_DTYPE_STRING,

'1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0

};

//*****************************************************************************

// 字符串描述符集合

//*****************************************************************************

const unsigned char * const g_pStringDescriptors[] =

{

g_pLangDescriptor,

g_pManufacturerString,

g_pProductString,

g_pSerialNumberString,

};

#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) /                \

sizeof(unsigned char *))

//*****************************************************************************

//MSC实例,配置并为设备信息提供空间

//*****************************************************************************

tMSCInstance g_sMSCInstance;

//*****************************************************************************

//msc设备配置

//*****************************************************************************

const tUSBDMSCDevice g_sMSCDevice =

{

USB_VID_STELLARIS,

USB_PID_MSC,

"TI      ",

"Mass Storage    ",

"1.00",

200,

USB_CONF_ATTR_SELF_PWR,

g_pStringDescriptors,

NUM_STRING_DESCRIPTORS,

{

USBDMSCStorageOpen,

USBDMSCStorageClose,

USBDMSCStorageRead,

USBDMSCStorageWrite,

USBDMSCStorageNumBlocks

},

USBDMSCEventCallback,

&g_sMSCInstance

};

#define MSC_BUFFER_SIZE 512

//*****************************************************************************

//键盘实例,配置并为设备信息提供空间

//*****************************************************************************

tHIDKeyboardInstance g_KeyboardInstance;

//*****************************************************************************

//键盘设备配置

//*****************************************************************************

const tUSBDHIDKeyboardDevice g_sKeyboardDevice =

{

USB_VID_STELLARIS,

USB_VID_STELLARIS,

200,

USB_CONF_ATTR_SELF_PWR | USB_CONF_ATTR_RWAKE,

KeyboardHandler,

(void *)&g_sKeyboardDevice,

0,

0,

&g_KeyboardInstance

};

//*****************************************************************************

//复合设备配置

//*****************************************************************************

tCompositeEntry g_psCompDevices[]=

{

{

&g_sMSCDeviceInfo,

(void  *)&g_sMSCDeviceInfo

},

{

&g_sHIDDeviceInfo,

(void  *)&g_sHIDDeviceInfo

}

};

#define NUM_DEVICES          (sizeof(g_psCompDevices)/sizeof(tCompositeEntry))

tCompositeInstance g_CompInstance;

unsigned long xxx[10];

tUSBDCompositeDevice g_sCompDevice =

{

USB_VID_STELLARIS,

0x0124,

500,

USB_CONF_ATTR_BUS_PWR,

EventHandler,

g_pStringDescriptors,

NUM_STRING_DESCRIPTORS,

2,

g_psCompDevices,

xxx,

&g_CompInstance

};

//*****************************************************************************

//callback函数

//*****************************************************************************

unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgParam, void *pvMsgData)

{

switch(ulEvent)

{

// 正在写数据到存储设备.

case USBD_MSC_EVENT_WRITING:

{

break;

}

//读取数据.

case USBD_MSC_EVENT_READING:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x10);

break;

}

//空闲

case USBD_MSC_EVENT_IDLE:

default:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x00);

break;

}

}

return(0);

}

//*****************************************************************************

//键盘callback函数

//*****************************************************************************

unsigned long KeyboardHandler(void *pvCBData, unsigned long ulEvent,

unsigned long ulMsgData, void *pvMsgData)

{

switch (ulEvent)

{

case USB_EVENT_CONNECTED:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);

break;

}

case USB_EVENT_DISCONNECTED:

{

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x00);

break;

}

case USB_EVENT_TX_COMPLETE:

{

break;

}

case USB_EVENT_SUSPEND:

{

break;

}

case USB_EVENT_RESUME:

{

break;

}

case USBD_HID_KEYB_EVENT_SET_LEDS:

{

break;

}

default:

{

break;

}

}

return (0);

}

//*****************************************************************************

//复合设备callback函数

//*****************************************************************************

unsigned long EventHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgData,

void *pvMsgData)

{

unsigned long ulNewEvent;

ulNewEvent = 1;

switch(ulEvent)

{

case USB_EVENT_CONNECTED:

{

break;

}

case USB_EVENT_DISCONNECTED:

{

break;

}

case USB_EVENT_SUSPEND:

{

break;

}

case USB_EVENT_RESUME:

{

break;

}

default:

{

ulNewEvent = 0;

break;

}

}

if(ulNewEvent)

{

}

return(0);

}

//*****************************************************************************

//主函数

//*****************************************************************************

int main(void)

{

//系统初始化。

SysCtlLDOSet(SYSCTL_LDO_2_75V);

SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL  | SYSCTL_OSC_MAIN );

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,0xf0);

GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,0x0f);

HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= 0x0f;

// ucDMA配置

SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

SysCtlDelay(10);

uDMAControlBaseSet(&sDMAControlTable[0]);

uDMAEnable();

g_ulFlags = 0;

g_eMSCState = MSC_DEV_IDLE;

//复合设备初始化

g_sCompDevice.psDevices[0].pvInstance =

USBDMSCCompositeInit(0, &g_sMSCDevice);

g_sCompDevice.psDevices[1].pvInstance =

USBDHIDKeyboardInit(0, &g_sKeyboardDevice);

USBDCompositeInit(0, &g_sCompDevice, DESCRIPTOR_DATA_SIZE,

g_pucDescriptorData);

//初始化存储设备

disk_initialize(0);

while(1)

{

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, HID_KEYB_CAPS_LOCK,

HID_KEYB_USAGE_A,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_0)

? false : true);

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,

HID_KEYB_USAGE_DOWN_ARROW,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_1)

? false : true);

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,

HID_KEYB_USAGE_UP_ARROW,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_2)

? false : true);

USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,

HID_KEYB_USAGE_ESCAPE,

(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_3)

? false : true);

SysCtlDelay(SysCtlClockGet()/3000);

}

}

第十章Composite设备的更多相关文章

  1. USB组合设备 Interface Association Descriptor (IAD)

    Communication Device Class,简称CDCUSB Compound Device,USB复合设备USB Composite Device,USB组合设备 摘要USB复合设备 Co ...

  2. Linux下时钟框架实践---一款芯片的时钟树配置

    关键词:时钟.PLL.Mux.Divider.Gate.clk_summary等. 时钟和电源是各种设备的基础设施,整个时钟框架可以抽象为几种基本的元器件:负责提供晶振 Linux内核提供了良好的CC ...

  3. Linux usb gadget框架概述

    很幸运,在公司开发了gadget相关驱动,总结下来,大大小小开发了四个与gadget相关的驱动,字符驱动.g_multi.g_ether.g_zero,在这里把自己对gadget的开发中自己的感悟记录 ...

  4. USB Compound Device,USB复合设备 ; USB Composite Device,USB组合设备【转】

    本文转载自:https://blog.csdn.net/autumn20080101/article/details/52776863 科普下USB复合设备和USB组合设备的区别. 关键字 Commu ...

  5. windows无法停用“Android Composite Interface”设备的解决方法

    遇到这个问题时,解决方法如下: 打开设备管理器 -> 进程 -> 找到 adb.exe -> 右击选择结束进程 -> 然后重新弹出Android设备

  6. Android composite adb interface

    我的平板连上电脑后,在eclipse的DDMS中查看不到.很奇怪以前不会,我以为在进程中有其他的adb.exe冲突.查看任务管理器没有看到其他adb.exe进程.然后重启eclipse也不用,重启电脑 ...

  7. 20135306黄韧 附录A及第十章学习总结

    附录A  错误处理 A.1 Unix系统中的错误处理 1.Unix风格的错误处理 if ((pid = wait(NULL)) < 0) { fprintf(stderr,”wait error ...

  8. [platform]新旧内核的device设备注册对比

    转自:http://blog.chinaunix.net/uid-7332782-id-3268801.html 1. Version2.6内核启动过程 start_kernel( ) //板子上电启 ...

  9. android 与usb 设备通信(二)

    再次遇到android  mUsbManager.getDevicelist() 得不到usb 设备的问题.于是深入去探讨android 与usb 外围设备通信的问题.第一篇文章写的有点乱,本质就是需 ...

随机推荐

  1. SDK 组件 Qupaisdk 启动出错,错误消息为 [Qupaisdk], the android stack error message is Fail to start the plugin, which is caused by Failed resolution of: Lcom/duanqu/qupai/recorder/R$array;

    紧急解决办法: 将你的oneSDK(qupaiSDK)里面的manifest的pageckage改为:com.duanqu.qupai.recorder

  2. js获取jsp中的变量值

    js获取jsp中的变量值,有两种方式: 1.jsp标签获取属性 var message = '<%=request.getAttribute("message")%>' ...

  3. redis 实践—— sorted set, hash set

    在这里就不谈redis的安装与启动啦,网上太多人写这个了. 从最近的一个项目[钻石夺宝]说起,如果大家有玩过一元夺宝或者全名夺宝的话,大概会知道如果参与人数多的话,每隔几秒.快的话每隔一秒都会新生成一 ...

  4. 用函数的地址调用函数 C++ MFC

    先说一段废话,幸亏我汇编基础(基础 基础 基础)扎实,否则这个问题真的恶心到我了正题  因为有特殊需求, 需要写一个类似于接口的功能,但是因为用到的次数不多再加上C++写接口各种麻烦所以想通过函数的地 ...

  5. [Effective Java读书笔记] 第二章 创建和销毁对象(1~7)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537576.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  6. remastersys修改默认选项

    1.vim /etc/remastersys/isolinux/isolinux.cfg.vesamenu default vesamenu.c32prompt 0timeout 100 menu t ...

  7. ASP.NET MVC Web API使用示例

    上篇博客讲解rest服务开发时,曾经提到过asp.net mvc中的rest api,由于篇幅原因,没有在上篇博客中进行讲解,这里专门拿出来进行讨论.还是一样引用上次的案例,用asp.net mvc提 ...

  8. sae-多个file_put_contents('saestor://public/text.txt',$data);只写第一次

    多个file_put_contents('saestor://public/text.txt',$data); 只执行第一个文件的写入,永久存储也只需要一次写入 如果需要用户中间缓存文件,用tmpfs ...

  9. Your branch and 'origin/master' have diverged

    git fetch origin git reset --hard origin/master

  10. 使用Github总结

    1. 使用Git GUI 首先熟悉一下GUI,如下: 第一步,首先将代码fork到自己的版本库下面,如下: 并获取clone URL,如下图: 然后点击GUI克隆已有版本库,如下图: 点击克隆就可以得 ...