9790|14

238

帖子

2

TA的资源

纯净的硅(高级)

楼主
 

第七章Bulk设备 [复制链接]

小川工作室编写,本书为LM3S的USB芯片编写,上传的均为草稿还有没修改,可能还有很多地方不足,希望各位网友原谅!

QQ:2609828265

TEL:15882446438

E-mail:paulhyde@126.com

第七章Bulk设备

7.1 bulk设备介绍

USB通道的数据传输格式有两种,而且这两种格式还是互斥的。有消息和流两种对于流状态,不具有usb数据的格式,遵循的规则就是先进先出。对于消息通道,它的通信模式符合usb的数据格式,一般有三个阶段组成首先是建立阶段,数据阶段,确认阶段。所有的通信的开始都是由主机方面发起的。

USB协议制定时,为了方便不同设备的开发商基于USB进行设计,定义了不同的设备类来支持不同类型的设备。Bulk也是其中一种,Bulk设备使用端点Bulk传输模式,可以快速传输大量数据

批量传输(BULK)采用的是流状态传输,批量传送的一个特点就是支持不确定时间内进行大量数据传输,能够保证数据一定可以传输,但是不能保证传输的带宽和传输的延迟。而且批量传输是一种单向的传输,要进行双向传输必须要使用两个通道。本章将介绍双向BULK的批量传输。

7.2 bulk数据类型

usbdbulk.h、usblib.h中已经定义好Bulk设备类中使用的所有数据类型和函数,下面介绍Bulk设备类使用的数据类型。

typedef struct

{

    //定义本Buffer是用于传输还是接收,True为接收,False为发送。

    tBoolean bTransmitBuffer;

    //Callback函数,用于Buffer数据处理完成后

    tUSBCallback pfnCallback;

    //Callback第一个输入参数

    void *pvCBData;

    //数据传输或者接收时调用的函数,用于完成发送或者接收的函数。

    tUSBPacketTransfer pfnTransfer;

    //数据传输或者接收时调用的函数。

//发送时,用于检查是否有足够空间;接收时,用于检查可以接收的数量。

    tUSBPacketAvailable pfnAvailable;

    //在设备模式下,设备类指针

    void *pvHandle;

    //用于存放发送或者接收的数据.

    unsigned char *pcBuffer;

    //发送或者接收数据大小

    unsigned long ulBufferSize;

    //RAM Buffer 

    void *pvWorkspace;

}

tUSBBuffer;

tUSBBuffer,数据缓存控制结构体,定义在usblib.h中,用于在Bulk传输过程中,发送数据或者接收数据。是Bulk设备传输的主要载体,结构体内部包含数据发送、接收、处理函数等。

typedef enum

{

    //Bulk 状态没定义

    BULK_STATE_UNCONFIGURED,

    //空闲状态

    BULK_STATE_IDLE,

    //等待数据发送或者结束

    BULK_STATE_WAIT_DATA,

    //等待数据处理.

    BULK_STATE_WAIT_CLIENT

} tBulkState;

tBulkState,定义Bulk端点状态。定义在usbdbulk.h。用于端点状态标记与控制,可以保证数据传输不相互冲突。

typedef struct

{

//USB基地址

    unsigned long ulUSBBase;

//设备信息

    tDeviceInfo *psDevInfo;

//配置信息

    tConfigDescriptor *psConfDescriptor;

//Bulk 接收端点状态

    volatile tBulkState eBulkRxState;

//Bulk 发送端点状态

    volatile tBulkState eBulkTxState;

//标志位

    volatile unsigned short usDeferredOpFlags;

    //最后一次发送数据大小

    unsigned short usLastTxSize;

//连接是否成功

    volatile tBoolean bConnected;

//IN端点号

    unsigned char ucINEndpoint;

//OUT端点号

    unsigned char ucOUTEndpoint;

//接口号

    unsigned char ucInterface;

}

tBulkInstance;

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

typedef struct

{

    //VID

    unsigned short usVID;

    //PID

    unsigned short usPID;

    //最大耗电量

    unsigned short usMaxPowermA;

    //电源属性

    unsigned char ucPwrAttributes;

    //接收回调函数,主要用于接收数据处理

    tUSBCallback pfnRxCallback;

    //接收回调函数的第一个参数。

    void *pvRxCBData;

    //发送回调函数,主要用于发送数据处理

    tUSBCallback pfnTxCallback;

    //发送回调函数的第一个参数。

    void *pvTxCBData;

    //字符串描述符集合

    const unsigned char * const *ppStringDescriptors;

    //字符串描述符个数

    unsigned long ulNumStringDescriptors;

    //Bulk设备实例

    tBulkInstance *psPrivateBulkData;

}

tUSBDBulkDevice;

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

7.3 API函数

在Bulk设备类API库中定义了11个函数,完成USB Bulk设备初始化、配置及数据处理。以及 11个Buffer操作函数,下面为usbdbulk.h中定义的API函数:

void *USBDBulkInit(unsigned long ulIndex,

                         const tUSBDBulkDevice *psDevice);

void *USBDBulkCompositeInit(unsigned long ulIndex,

                                   const tUSBDBulkDevice *psDevice);

unsigned long USBDBulkPacketWrite(void *pvInstance,

                                         unsigned char *pcData,

                                         unsigned long ulLength,

                                         tBoolean bLast);

unsigned long USBDBulkPacketRead(void *pvInstance,

                                        unsigned char *pcData,

                                        unsigned long ulLength,

                                        tBoolean bLast);

unsigned long USBDBulkTxPacketAvailable(void *pvInstance);

unsigned long USBDBulkRxPacketAvailable(void *pvInstance);

void USBDBulkTerm(void *pvInstance);

void *USBDBulkSetRxCBData(void *pvInstance, void *pvCBData);

void *USBDBulkSetTxCBData(void *pvInstance, void *pvCBData);

void USBDBulkPowerStatusSet(void *pvInstance, unsigned char ucPower);

tBoolean USBDBulkRemoteWakeupRequest(void *pvInstance); 

void *USBDBulkInit(unsigned long ulIndex,

                         const tUSBDBulkDevice *psDevice);

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

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

返回:指向配置后的tUSBDBulkDevice

void *USBDBulkCompositeInit(unsigned long ulIndex,

                                   const tUSBDBulkDevice *psDevice);

作用:初始化Bulk设备协议,本函数在USBDBulkInit中已经调用。

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

返回:指向配置后的tUSBDBulkDevice

unsigned long USBDBulkPacketWrite(void *pvInstance,

                                         unsigned char *pcData,

                                         unsigned long ulLength,

                                         tBoolean bLast);

作用:通过Bulk传输发送一个包数据,底层驱动,在Buffer中使用。

参数:pvInstancetUSBDBulkDevice设备指针。pcData,待写入的数据指针。ulLength,待写入数据的长度。bLast,是否传输结束包。

返回:成功发送长度,可能与ulLength长度不一样。

unsigned long USBDBulkPacketRead(void *pvInstance,

                                        unsigned char *pcData,

                                        unsigned long ulLength,

                                        tBoolean bLast);

作用:通过Bulk传输接收一个包数据,底层驱动,在Buffer中使用。

参数:pvInstancetUSBDBulkDevice设备指针。pcData,读出数据指针。ulLength,读出数据的长度。bLast,是否是束包。

返回:成功接收长度,可能与ulLength长度不一样。

unsigned long USBDBulkTxPacketAvailable(void *pvInstance);

作用:获取可用发送数据长度。

参数:pvInstancetUSBDBulkDevice设备指针。

返回:发送包大小,用发送数据长度。

unsigned long USBDBulkRxPacketAvailable(void *pvInstance);

作用:获取接收数据长度。

参数:pvInstancetUSBDBulkDevice设备指针。

返回:可用接收数据个数,可读取的有效数据。

void USBDBulkTerm(void *pvInstance);

作用:结束Bulk设备。

参数:pvInstance,指向tUSBDBulkDevice

返回:无。

void *USBDBulkSetRxCBData(void *pvInstance, void *pvCBData);

作用:改变接收回调函数的第一个参数。

参数:pvInstance,指向tUSBDBulkDevicepvCBData,用于替换的参数

返回:旧参数指针。

void *USBDBulkSetTxCBData(void *pvInstance, void *pvCBData);

作用:改变发送回调函数的第一个参数。

参数:pvInstance,指向tUSBDBulkDevicepvCBData,用于替换的参数

返回:旧参数指针。

void USBDBulkPowerStatusSet(void *pvInstance, unsigned char ucPower);

作用:修改电源属性、状态。

参数:pvInstance,指向tUSBDBulkDeviceucPower,电源属性。

返回:无。

tBoolean USBDBulkRemoteWakeupRequest(void *pvInstance); 

作用:唤醒请求。

参数:pvInstance,指向tUSBDBulkDevice

返回:无。

在这些函数中USBDBulkInitUSBDBulkPacketWriteUSBDBulkPacketReadUSBDBulkTxPacketAvailableUSBDBulkRxPacketAvailable函数最重要并且使用最多,USBDBulkInit第一次使用Bulk设备时,用于初始化Bulk设备的配置与控制。USBDBulkPacketReadUSBDBulkPacketWriteUSBDBulkTxPacketAvailableUSBDBulkRxPacketAvailable为Bulk传输数据的底层驱动函数用于驱动Buffer。

usblib.h中定义为11个Buffer操作函数,用于数据发送、接收、以及回调其它函数,下面介绍11个Buffer操作函数:

const tUSBBuffer *USBBufferInit(const tUSBBuffer *psBuffer);

void USBBufferInfoGet(const tUSBBuffer *psBuffer,

                             tUSBRingBufObject *psRingBuf);

unsigned long USBBufferWrite(const tUSBBuffer *psBuffer,

                                    const unsigned char *pucData,

                                    unsigned long ulLength);

void USBBufferDataWritten(const tUSBBuffer *psBuffer,

                                 unsigned long ulLength);

void USBBufferDataRemoved(const tUSBBuffer *psBuffer,

                                 unsigned long ulLength);

void USBBufferFlush(const tUSBBuffer *psBuffer);

unsigned long USBBufferRead(const tUSBBuffer *psBuffer,

                                   unsigned char *pucData,

                                   unsigned long ulLength);

unsigned long USBBufferDataAvailable(const tUSBBuffer *psBuffer);

unsigned long USBBufferSpaceAvailable(const tUSBBuffer *psBuffer);

void *USBBufferCallbackDataSet(tUSBBuffer *psBuffer, void *pvCBData);

unsigned long USBBufferEventCallback(void *pvCBData,

                                            unsigned long ulEvent,

                                            unsigned long ulMsgValue,

                                            void *pvMsgData);

const tUSBBuffer *USBBufferInit(const tUSBBuffer *psBuffer);

作用:初始化Buffer,把它加入到当前设备中。首次使用Buffer必须使用此函数。

参数:psBuffer,待初始化的Buffer。

返回:指向配置后的Buffer。

void USBBufferInfoGet(const tUSBBuffer *psBuffer,

                             tUSBRingBufObject *psRingBuf);

作用:获取Buffer信息。psRingBufpsBuffer建立关系。

参数:psBuffer,操作的目标Buffer。psRingBuf,申明一个tUSBRingBufObject 变量。

返回:无。

unsigned long USBBufferWrite(const tUSBBuffer *psBuffer,

                                    const unsigned char *pucData,

                                    unsigned long ulLength);

作用:写入一组数据。直接写入。

参数:psBuffer,目标Buffer。pucData,待写入数据指针。ulLength,写入长度。

返回:写入的数据长度。

void USBBufferDataWritten(const tUSBBuffer *psBuffer,

                                 unsigned long ulLength);

作用:写入一组数据。使用前要调用USBBufferInfoGet

参数:psBuffer,目标Buffer。ulLength,写入长度。

返回:写入的数据长度。

void USBBufferDataRemoved(const tUSBBuffer *psBuffer,

                                 unsigned long ulLength);

作用:从Buffer中移出数据。

参数:psBuffer,目标Buffer。ulLength,移出数据个数。

返回:无。

void USBBufferFlush(const tUSBBuffer *psBuffer);

作用:清除Buffer中数据。

参数:psBuffer,目标Buffer。

返回:无。

unsigned long USBBufferRead(const tUSBBuffer *psBuffer,

                                   unsigned char *pucData,

                                   unsigned long ulLength);

作用:读取数据。

参数:psBuffer,目标Buffer。pucData,数据存放指针。ulLength,读取个数。

返回:读取数据个数。

unsigned long USBBufferDataAvailable(const tUSBBuffer *psBuffer);

作用:可读取数据个数。

参数:psBuffer,目标Buffer。

返回:可读取数据个数。

unsigned long USBBufferSpaceAvailable(const tUSBBuffer *psBuffer);

作用:可用数据空间大小。

参数:psBuffer,目标Buffer。

返回:数据空间大小。

void *USBBufferCallbackDataSet(tUSBBuffer *psBuffer, void *pvCBData);

作用:修改设备Buffer。

参数:psBuffer,用于替换的新Buffer指针。

返回:旧Buffer指针。

unsigned long USBBufferEventCallback(void *pvCBData,

                                            unsigned long ulEvent,

                                            unsigned long ulMsgValue,

                                            void *pvMsgData);

作用:Buffer事件调用函数。

参数:pvCBData,设备指针。ulEvent,Buffer事务。ulMsgValue,数据长度。pvMsgData数据指针。

返回:函数是否成功执行。

以上是11个Buffer处理函数,用于Buffer数据接收、发送及处理。在Bulk传输中大量使用。

7.4 Bulk设备开发

Bulk设备开发只需要4步就能完成。如图2所示,Bulk设备配置(主要是字符串描述符)、callback函数编写、USB处理器初始化、数据处理。


图2

第一步:Bulk设备配置(主要是字符串描述符),按字符串描述符标准完成串描述符配置,进而完成Bulk设备配置。

#include "inc/hw_ints.h"

#include "inc/hw_memmap.h"

#include "inc/hw_types.h"

#include "inc/hw_sysctl.h"

#include "inc/hw_udma.h"

#include "inc/hw_gpio.h"

#include "driverlib/gpio.h"

#include "driverlib/interrupt.h"

#include "driverlib/sysctl.h"

#include "driverlib/usb.h"

#include "usblib/usblib.h"

#include "usblib/usb-ids.h"

#include "usblib/device/usbdevice.h"

#include "usblib/device/usbdbulk.h"

#include "uartstdio.h"

#include "ustdlib.h"

//每次传输数据大小

#define BULK_BUFFER_SIZE 256

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

                               unsigned long ulMsgValue, void *pvMsgData);

unsigned long TxHandler(void *pvlCBData, unsigned long ulEvent,

                               unsigned long ulMsgValue, void *pvMsgData);

unsigned long EchoNewDataToHost(tUSBDBulkDevice *psDevice, unsigned char *pcData,

                  unsigned long ulNumBytes);

#define COMMAND_PACKET_RECEIVED 0x00000001

#define COMMAND_STATUS_UPDATE   0x00000002

volatile unsigned long g_ulFlags = 0;

char *g_pcStatus;

static volatile tBoolean g_bUSBConfigured = false;

volatile unsigned long g_ulTxCount = 0;

volatile unsigned long g_ulRxCount = 0;

const tUSBBuffer g_sRxBuffer;

const tUSBBuffer g_sTxBuffer;

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

// 设备语言描述符.

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

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,

    'G', 0, 'e', 0, 'n', 0, 'e', 0, 'r', 0, 'i', 0, 'c', 0, ' ', 0, 'B', 0,

    'u', 0, 'l', 0, 'k', 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 g_pDataInterfaceString[] =

{

    (19 + 1) * 2,

    USB_DTYPE_STRING,

    'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,

    'a', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0,

    'a', 0, 'c', 0, 'e', 0

};

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

//  设备配置字符串描述符

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

const unsigned char g_pConfigString[] =

{

    (23 + 1) * 2,

    USB_DTYPE_STRING,

    'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,

    'a', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 'f', 0, 'i', 0, 'g', 0,

    'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0, 'o', 0, 'n', 0

};

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

// 字符串描述符集合

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

const unsigned char * const g_pStringDescriptors[] =

{

    g_pLangDescriptor,

    g_pManufacturerString,

    g_pProductString,

    g_pSerialNumberString,

    g_pDataInterfaceString,

    g_pConfigString

};

#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) /                \

                                sizeof(unsigned char *))

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

// 定义Bulk设备实例

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

tBulkInstance g_sBulkInstance;

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

// 定义Bulk设备

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

const tUSBDBulkDevice g_sBulkDevice =

{

    0x1234,

    USB_PID_BULK,

    500,

    USB_CONF_ATTR_SELF_PWR,

    USBBufferEventCallback,

    (void *)&g_sRxBuffer,

    USBBufferEventCallback,

    (void *)&g_sTxBuffer,

    g_pStringDescriptors,

    NUM_STRING_DESCRIPTORS,

    &g_sBulkInstance

};

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

// 定义Buffer

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

unsigned char g_pucUSBRxBuffer[BULK_BUFFER_SIZE];

unsigned char g_pucUSBTxBuffer[BULK_BUFFER_SIZE];

unsigned char g_pucTxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

unsigned char g_pucRxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

const tUSBBuffer g_sRxBuffer =

{

    false,                           // This is a receive buffer.

    RxHandler,                       // pfnCallback

    (void *)&g_sBulkDevice,          // Callback data is our device pointer.

    USBDBulkPacketRead,              // pfnTransfer

    USBDBulkRxPacketAvailable,       // pfnAvailable

    (void *)&g_sBulkDevice,          // pvHandle

    g_pucUSBRxBuffer,                // pcBuffer

    BULK_BUFFER_SIZE,                // ulBufferSize

    g_pucRxBufferWorkspace           // pvWorkspace

};

const tUSBBuffer g_sTxBuffer =

{

    true,                            // This is a transmit buffer.

    TxHandler,                       // pfnCallback

    (void *)&g_sBulkDevice,          // Callback data is our device pointer.

    USBDBulkPacketWrite,             // pfnTransfer

    USBDBulkTxPacketAvailable,       // pfnAvailable

    (void *)&g_sBulkDevice,          // pvHandle

    g_pucUSBTxBuffer,                // pcBuffer

    BULK_BUFFER_SIZE,                // ulBufferSize

    g_pucTxBufferWorkspace           // pvWorkspace

};

tUSBDBulkDevice g_sBulkDevicetUSBBuffer g_sTxBuffertUSBBuffer g_sRxBuffer是管理Bulk设备的主要结构体,它们三者关系如下图:


tUSBDBulkDevice g_sBulkDevice主要进行上层协议与通信管理控制,通过USBBufferEventCallback函数处理Buffer数据:数据发送、接收、控制事件,通过g_sTxBuffer中的USBDBulkPacketWriteUSBDBulkTxPacketAvailable实现底层数据发送,并通过TxHandler返回处理结果;通过g_sRxBuffer中的USBDBulkPacketReadUSBDBulkRxPacketAvailable实现底层数据接收,并通过RxHandler返回处理结果。在g_sBulkDevice层可以直接使用Buffer函数对Buffer层操作,并通过TxHandlerRxHandler返回处理结果。所有处理过程中的数据都保存在Buffer层的g_pucUSBTxBuffer或者g_pucUSBRxBuffer,隶属于g_sBulkDevice的一部分。注意:USBDBulkPacketWriteUSBDBulkTxPacketAvailableUSBDBulkPacketReadUSBDBulkRxPacketAvailable由Bulk设备类API定义,可以直接使用。USBBufferEventCallback为Buffer层定义的标准API,用于处理、调用USBDBulkPacketWriteUSBDBulkTxPacketAvailableUSBDBulkPacketReadUSBDBulkRxPacketAvailableTxHandlerRxHandler完成g_sBulkDevice层发送的数据接收与发送命令。

第二步:完成Callback函数。Callback函数用于处理输出端点、输入端点数据事务。Bulk设备接收回调函数包含以下事务:USB_EVENT_CONNECTEDUSB_EVENT_DISCONNECTEDUSB_EVENT_RX_AVAILABLEUSB_EVENT_SUSPENDUSB_EVENT_RESUMEUSB_EVENT_ERROR。Bulk设备发送回调函数包含了以下事务:USB_EVENT_TX_COMPLETE。如下表:

名称

属性

说明

USB_EVENT_CONNECTED

接收

USB设备已经连接到主机

USB_EVENT_DISCONNECTED

接收

USB设备已经与主机断开

USB_EVENT_RX_AVAILABLE

接收

有接受数据

USB_EVENT_SUSPEND

接收

挂起

USB_EVENT_RESUME

接收

唤醒

USB_EVENT_ERROR

接收

错误

USB_EVENT_TX_COMPLETE

发送

发送完成

2. Bulk事务

根据以上事务编写Callback函数:

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

//USB Bulk设备类返回事件处理函数(callback).

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

unsigned long  TxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,

          void *pvMsgData)

{

    //发送完成事件

    if(ulEvent == USB_EVENT_TX_COMPLETE)

    {

        g_ulTxCount += ulMsgValue;

    }

    return(0);

}

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

               unsigned long ulMsgValue, void *pvMsgData)

{

    // 接收事件

    switch(ulEvent)

    {

        //连接成功

        case USB_EVENT_CONNECTED:

        {

GPIOPinWrite(GPIO_PORTF_BASE,0x40,0x40); 

            g_bUSBConfigured = true;

            g_pcStatus = "Host connected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            // Flush our buffers.

            USBBufferFlush(&g_sTxBuffer);

            USBBufferFlush(&g_sRxBuffer);

            break;

        }

        // 断开连接.

        case USB_EVENT_DISCONNECTED:

        {

GPIOPinWrite(GPIO_PORTF_BASE,0x40,0x00);

            g_bUSBConfigured = false;

            g_pcStatus = "Host disconnected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            break;

        }

        // 有可能数据接收.

        case USB_EVENT_RX_AVAILABLE:

        {

            tUSBDBulkDevice *psDevice;

            psDevice = (tUSBDBulkDevice *)pvCBData;

            // 把接收到的数据发送回去。

            return(EchoNewDataToHost(psDevice, pvMsgData, ulMsgValue));

        }

        //挂起,唤醒

        case USB_EVENT_SUSPEND:

        case USB_EVENT_RESUME:break;

        default:break;

    }

    return(0);

}

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

//EchoNewDataToHost函数

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

unsigned long EchoNewDataToHost(tUSBDBulkDevice *psDevice, unsigned char *pcData,

                  unsigned long ulNumBytes)

{

    unsigned long ulLoop, ulSpace, ulCount;

    unsigned long ulReadIndex;

    unsigned long ulWriteIndex;

    tUSBRingBufObject sTxRing;

    // 获取Buffer信息.

    USBBufferInfoGet(&g_sTxBuffer, &sTxRing);

    // 有多少可能空间

    ulSpace = USBBufferSpaceAvailable(&g_sTxBuffer);

    // 改变数据

    ulLoop = (ulSpace < ulNumBytes) ? ulSpace : ulNumBytes;

    ulCount = ulLoop;

    // 更新接收到的数据个数

    g_ulRxCount += ulNumBytes;

    ulReadIndex = (unsigned long)(pcData - g_pucUSBRxBuffer);

    ulWriteIndex = sTxRing.ulWriteIndex;

    while(ulLoop)

    {

        //更新接收的数据

        if((g_pucUSBRxBuffer[ulReadIndex] >= 'a') &&

           (g_pucUSBRxBuffer[ulReadIndex] <= 'z'))

        {

            //转换

            g_pucUSBTxBuffer[ulWriteIndex] =

                (g_pucUSBRxBuffer[ulReadIndex] - 'a') + 'A';

        }

        else

        {

             //转换

            if((g_pucUSBRxBuffer[ulReadIndex] >= 'A') &&

               (g_pucUSBRxBuffer[ulReadIndex] <= 'Z'))

            {

                 //转换

                g_pucUSBTxBuffer[ulWriteIndex] =

                    (g_pucUSBRxBuffer[ulReadIndex] - 'Z') + 'z';

            }

            else

            {

                 //转换

                g_pucUSBTxBuffer[ulWriteIndex] = g_pucUSBRxBuffer[ulReadIndex];

            }

        }

        // 更新指针

        ulWriteIndex++;

        ulWriteIndex = (ulWriteIndex == BULK_BUFFER_SIZE) ? 0 : ulWriteIndex;

        ulReadIndex++;

        ulReadIndex = (ulReadIndex == BULK_BUFFER_SIZE) ? 0 : ulReadIndex;

        ulLoop--;

    }

    // 发送数据

    USBBufferDataWritten(&g_sTxBuffer, ulCount);

    return(ulCount);

}

第三步:系统初始化,配置内核电压、系统主频、使能端口、LED控制等,本例中使用4个LED进行指示数据传输。在这个例子中,Bulk传输接收的数据发送给主机。原理图如图3所示:

图3

系统初始化:

    unsigned long ulTxCount = 0;

    unsigned long ulRxCount = 0;

// char pcBuffer[16];

    //设置内核电压、主频 50Mhz

SysCtlLDOSet(SYSCTL_LDO_2_75V);

SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_4 | 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;

// 初始化发送与接收Buffer.

    USBBufferInit((tUSBBuffer *)&g_sTxBuffer);

    USBBufferInit((tUSBBuffer *)&g_sRxBuffer);

// 初始化Bulk设备

USBDBulkInit(0, (tUSBDBulkDevice *)&g_sBulkDevice);   

第四步:数据处理。主要使用11个Buffer处理函数,用于Buffer数据接收、发送及处理。在Bulk传输中大量使用。

while(1)

    {

        //等待连接结束.

        while((g_ulFlags & FLAG_CONNECTED) == 0)

        {

        }

//初始化Buffer

        g_sBuffer.pucFill = g_sBuffer.pucBuffer;

        g_sBuffer.pucPlay = g_sBuffer.pucBuffer;

        g_sBuffer.ulFlags = 0;

//从Bulk设备类中获取数据

        if(USBBulkBufferOut(g_pvBulkDevice,

                             (unsigned char *)g_sBuffer.pucFill,

                             BULK_PACKET_SIZE, USBBufferCallback) == 0)

        {

            //标记数据放入buffer中.

            g_sBuffer.ulFlags |= SBUFFER_FLAGS_FILLING;

        }

        //设备连接到主机.

        while(g_ulFlags & FLAG_CONNECTED)

        {

            // 检查音量是否有改变.

            if(g_ulFlags & FLAG_VOLUME_UPDATE)

            {

                // 清除更新音量标志.

                g_ulFlags &= ~FLAG_VOLUME_UPDATE;    

                // 修改音量,自行添加代码.在此以LED灯做指示。

                //UpdateVolume();

GPIOPinWrite(GPIO_PORTF_BASE,0x40,~GPIOPinRead(GPIO_PORTF_BASE,0x40));

            }

            //是否静音

            if(g_ulFlags & FLAG_MUTE_UPDATE)

            {

                //修改静音状态,自行添加函数.在此以LED灯做指示。

                //UpdateMute();

if(g_ulFlags & FLAG_MUTED)

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);

else

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x00);

                // 清除静音标志

                g_ulFlags &= ~FLAG_MUTE_UPDATE;

            }

        }

}

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

//USBBulkBufferOut 的Callback入口参数

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

void USBBufferCallback(void *pvBuffer, unsigned long ulParam, unsigned long ulEvent)

{

//数据处理,自行加入代码。

// Your Codes .........

    //再一次获取数据.

    USBBulkBufferOut(g_pvBulkDevice, (unsigned char *)g_sBuffer.pucFill,

                      BULK_PACKET_SIZE, USBBufferCallback);

}

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



驱动安装完成

在枚举过程中可以看出,在电脑右下脚可以看到“Generic Bulk Device”字样,标示正在进行枚举,并手手动安装驱动。枚举成功后,在“设备管理器”的“Stellaris Bulk Device”中看到“Generic Bulk Device”设备,如下图。现在Bulk设备可以正式使用。

Bulk设备要配合上位机使用,上位机发送字符串通过USB Bulk设备转换后发送给主机。运行图如下:

上位机源码如下:

#include <windows.h>

#include <strsafe.h>

#include <initguid.h>

#include "lmusbdll.h"

#include "luminary_guids.h"

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

// Buffer size definitions.

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

#define MAX_STRING_LEN 256

#define MAX_ENTRY_LEN 256

#define USB_BUFFER_LEN 1216

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

// The build version number

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

#define BLDVER "6075"

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

// The number of bytes we read and write per transaction if in echo mode.

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

#define ECHO_PACKET_SIZE 1216

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

// Buffer into which error messages are written.

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

TCHAR g_pcErrorString[MAX_STRING_LEN];

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

// The number of bytes transfered in the last measurement interval.

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

ULONG g_ulByteCount = 0;

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

// The total number of packets transfered.

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

ULONG g_ulPacketCount = 0;

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

LPTSTR GetSystemErrorString(DWORD dwError)

{

    DWORD dwRetcode;

    // Ask Windows for the error message description.

    dwRetcode = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, "%0", dwError, 0,

                              g_pcErrorString, MAX_STRING_LEN, NULL);

    if(dwRetcode == 0)

    {

        return((LPTSTR)L"Unknown");

    }

    else

    {

        // Remove the trailing "\n\r" if present.

        if(dwRetcode >= 2)

        {

            if(g_pcErrorString[dwRetcode - 2] == '\r')

            {

                g_pcErrorString[dwRetcode - 2] = '\0';

            }

        }

        return(g_pcErrorString);

    }

}

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

// Print the throughput in terms of Kbps once per second.

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

void UpdateThroughput(void)

{

    static ULONG ulStartTime = 0;

    static ULONG ulLast = 0;

    ULONG ulNow;

    ULONG ulElapsed;

    SYSTEMTIME sSysTime;

    // Get the current system time.

    GetSystemTime(&sSysTime);

    ulNow = (((((sSysTime.wHour * 60) +

               sSysTime.wMinute) * 60) +

              sSysTime.wSecond) * 1000) + sSysTime.wMilliseconds;

    // If this is the first call, set the start time.

    if(ulStartTime == 0)

    {

        ulStartTime = ulNow;

        ulLast = ulNow;

        return;

    }

    // How much time has elapsed since the last measurement?

    ulElapsed = (ulNow > ulStartTime) ? (ulNow - ulStartTime) : (ulStartTime - ulNow);

    // We dump a new measurement every second.

    if(ulElapsed > 1000)

    {

        printf("\r%6dKbps Packets: %10d ", ((g_ulByteCount * 8) / ulElapsed), g_ulPacketCount);

        g_ulByteCount = 0;

        ulStartTime = ulNow;

    }

}

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

// The main application entry function.

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

int main(int argc, char *argv[])

{

    BOOL bResult;

    BOOL bDriverInstalled;

    BOOL bEcho;

    char szBuffer[USB_BUFFER_LEN];

    ULONG ulWritten;

    ULONG ulRead;

    ULONG ulLength;

    DWORD dwError;

    LMUSB_HANDLE hUSB;

    // Are we operating in echo mode or not? The "-e" parameter tells the

    // app to echo everything it receives back to the device unchanged.

    bEcho = ((argc > 1) && (argv[1][1] == 'e')) ? TRUE : FALSE;

    // Print a cheerful welcome.

    printf("\nStellaris Bulk USB Device Example\n");

    printf( "---------------------------------\n\n");

    printf("Version %s\n\n", BLDVER);

    if(!bEcho)

    {

        printf("This is a partner application to the usb_dev_bulk example\n");

        printf("shipped with StellarisWare software releases for USB-enabled\n");

        printf("boards. Strings entered here are sent to the board which\n");

        printf("inverts the case of the characters in the string and returns\n");

        printf("them to the host.\n\n");

    }

    else

    {

        printf("If run with the \"-e\" command line switch, this application\n");

        printf("echoes all data received on the bulk IN endpoint to the bulk\n");

        printf("OUT endpoint.  This feature may be helpful during development\n");

        printf("and debug of your own USB devices.  Note that this will not\n");

        printf("do anything exciting if run with the usb_dev_bulk example\n");

        printf("device attached since it expects the host to initiate transfers.\n\n");

    }

    // Find our USB device and prepare it for communication.

    hUSB = InitializeDevice(BULK_VID, BULK_PID,

                            (LPGUID)&(GUID_DEVINTERFACE_STELLARIS_BULK),

                            &bDriverInstalled);

    if(hUSB)

    {

        // Are we operating in echo mode or not? The "-e" parameter tells the

        // app to echo everything it receives back to the device unchanged.

        if(bEcho)

        {

            printf("Running in echo mode. Press Ctrl+C to exit.\n\n"

                "Throughput:      0Kbps Packets:           0");

            while(1)

            {

                // Read a block of data from the device.

                dwError = ReadUSBPacket(hUSB, szBuffer, USB_BUFFER_LEN, &ulRead,

                                        INFINITE, NULL);

                if(dwError != ERROR_SUCCESS)

                {

                    // We failed to read from the device.

                    printf("\n\nError %d (%S) reading from bulk IN pipe.\n", dwError,

                           GetSystemErrorString(dwError));

                    break;

                }

                else

                {

                    // Update our byte and packet counters.

                    g_ulByteCount += ulRead;

                    g_ulPacketCount++;

                    // Write the data back out to the device.

                    bResult = WriteUSBPacket(hUSB, szBuffer, ulRead, &ulWritten);

                    if(!bResult)

                    {

                        // We failed to write the data for some reason.

                        dwError = GetLastError();

                        printf("\n\nError %d (%S) writing to bulk OUT pipe.\n", dwError,

                               GetSystemErrorString(dwError));

                        break;

                    }

                    // Display the throughput.

                   UpdateThroughput();

                }

            }

        }

        else

        {

            // We are running in normal mode.  Keep sending and receiving

            // strings until the user indicates that it is time to exit.

            while(1)

            {

                // The device was found and successfully configured. Now get a string from

                // the user...

                do

                {

                    printf("\nEnter a string (EXIT to exit): ");

                    fgets(szBuffer, MAX_ENTRY_LEN, stdin);

                    printf("\n");

                    // How many characters were entered (including the trailing '\n')?

                    ulLength = (ULONG)strlen(szBuffer);                    

if(ulLength <= 1)

                    {

                        printf("\nPlease enter some text.\n");

                        ulLength = 0;

                    }

                    else

                    {

                        // Get rid of the trailing '\n' if there is one there.

                         if(szBuffer[ulLength - 1] == '\n')

                        {

                            szBuffer[ulLength - 1] = '\0';

                            ulLength--;

                        }

                    }

                }

                while(ulLength == 0);

                if(!(strcmp("EXIT", szBuffer)))

                {               

                    printf("Exiting on user request.\n");

                    break;

                }

                // Write the user's string to the device.

                bResult = WriteUSBPacket(hUSB, szBuffer, ulLength, &ulWritten);

                if(!bResult)

                {

                    dwError = GetLastError();

                    printf("Error %d (%S) writing to bulk OUT pipe.\n", dwError,

                           GetSystemErrorString(dwError));

                }

                else

                {

                    // We wrote data successfully so now read it back.

                    printf("Wrote %d bytes to the device. Expected %d\n",

                           ulWritten, ulLength);

                    // We expect the same number of bytes as we just sent.

                    dwError = ReadUSBPacket(hUSB, szBuffer, ulWritten, &ulRead,

                                            INFINITE, NULL);

                    if(dwError != ERROR_SUCCESS)

                    {

                        // We failed to read from the device.

                        printf("Error %d (%S) reading from bulk IN pipe.\n", dwError,

                               GetSystemErrorString(dwError));

                    }

                    else

                    {                      

                        szBuffer[ulRead] = '\0';

                        printf("Read %d bytes from device. Expected %d\n",

                               ulRead, ulWritten);

                        printf("\nReturned string: \"%s\"\n", szBuffer);

                    }

                }

            }

        }

    }

    else

    {

        // An error was reported while trying to connect to the device.

        dwError = GetLastError();        

printf("\nUnable to initialize the Stellaris Bulk USB Device.\n");

        printf("Error code is %d (%S)\n\n", dwError, GetSystemErrorString(dwError));

        printf("Please make sure you have a Stellaris USB-enabled evaluation\n");

        printf("or development kit running the usb_dev_bulk example\n");

        printf("application connected to this system via the \"USB OTG\" or\n");

        printf("\"USB DEVICE\" connectors. Once the device is connected, run\n");

        printf("this application again.\n\n");

        printf("\nPress \"Enter\" to exit: ");

        fgets(szBuffer, MAX_STRING_LEN, stdin);

        printf("\n");

        return(2);

    }

    TerminateDevice(hUSB);

    return(0);

}

Bulk设备开发源码如下:

#include "inc/hw_ints.h"

#include "inc/hw_memmap.h"

#include "inc/hw_types.h"

#include "inc/hw_sysctl.h"

#include "inc/hw_udma.h"

#include "inc/hw_gpio.h"

#include "driverlib/gpio.h"

#include "driverlib/interrupt.h"

#include "driverlib/sysctl.h"

#include "driverlib/usb.h"

#include "usblib/usblib.h"

#include "usblib/usb-ids.h"

#include "usblib/device/usbdevice.h"

#include "usblib/device/usbdbulk.h"

#include "uartstdio.h"

#include "ustdlib.h"

//每次传输数据大小

#define BULK_BUFFER_SIZE 256

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

                               unsigned long ulMsgValue, void *pvMsgData);

unsigned long TxHandler(void *pvlCBData, unsigned long ulEvent,

                               unsigned long ulMsgValue, void *pvMsgData);

unsigned long EchoNewDataToHost(tUSBDBulkDevice *psDevice, unsigned char *pcData,

                  unsigned long ulNumBytes);

#define COMMAND_PACKET_RECEIVED 0x00000001

#define COMMAND_STATUS_UPDATE   0x00000002

volatile unsigned long g_ulFlags = 0;

char *g_pcStatus;

static volatile tBoolean g_bUSBConfigured = false;

volatile unsigned long g_ulTxCount = 0;

volatile unsigned long g_ulRxCount = 0;

const tUSBBuffer g_sRxBuffer;

const tUSBBuffer g_sTxBuffer;

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

// 设备语言描述符.

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

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,

    'G', 0, 'e', 0, 'n', 0, 'e', 0, 'r', 0, 'i', 0, 'c', 0, ' ', 0, 'B', 0,

    'u', 0, 'l', 0, 'k', 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 g_pDataInterfaceString[] =

{

    (19 + 1) * 2,

    USB_DTYPE_STRING,

    'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,

    'a', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0,

    'a', 0, 'c', 0, 'e', 0

};

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

//  设备配置字符串描述符

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

const unsigned char g_pConfigString[] =

{

    (23 + 1) * 2,

    USB_DTYPE_STRING,

    'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,

    'a', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 'f', 0, 'i', 0, 'g', 0,

    'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0, 'o', 0, 'n', 0

};

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

// 字符串描述符集合

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

const unsigned char * const g_pStringDescriptors[] =

{

    g_pLangDescriptor,

    g_pManufacturerString,

    g_pProductString,

    g_pSerialNumberString,

    g_pDataInterfaceString,

    g_pConfigString

};

#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) /                \

                                sizeof(unsigned char *))

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

// 定义Bulk设备实例

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

tBulkInstance g_sBulkInstance;

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

// 定义Bulk设备

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

const tUSBDBulkDevice g_sBulkDevice =

{

    0x1234,

    USB_PID_BULK,

    500,

    USB_CONF_ATTR_SELF_PWR,

    USBBufferEventCallback,

    (void *)&g_sRxBuffer,

    USBBufferEventCallback,

    (void *)&g_sTxBuffer,

    g_pStringDescriptors,

    NUM_STRING_DESCRIPTORS,

    &g_sBulkInstance

};

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

// 定义Buffer

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

unsigned char g_pucUSBRxBuffer[BULK_BUFFER_SIZE];

unsigned char g_pucUSBTxBuffer[BULK_BUFFER_SIZE];

unsigned char g_pucTxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

unsigned char g_pucRxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

const tUSBBuffer g_sRxBuffer =

{

    false,                           // This is a receive buffer.

    RxHandler,                       // pfnCallback

    (void *)&g_sBulkDevice,          // Callback data is our device pointer.

    USBDBulkPacketRead,              // pfnTransfer

    USBDBulkRxPacketAvailable,       // pfnAvailable

    (void *)&g_sBulkDevice,          // pvHandle

    g_pucUSBRxBuffer,                // pcBuffer

    BULK_BUFFER_SIZE,                // ulBufferSize

    g_pucRxBufferWorkspace           // pvWorkspace

};

const tUSBBuffer g_sTxBuffer =

{

    true,                            // This is a transmit buffer.

    TxHandler,                       // pfnCallback

    (void *)&g_sBulkDevice,          // Callback data is our device pointer.

    USBDBulkPacketWrite,             // pfnTransfer

    USBDBulkTxPacketAvailable,       // pfnAvailable

    (void *)&g_sBulkDevice,          // pvHandle

    g_pucUSBTxBuffer,                // pcBuffer

    BULK_BUFFER_SIZE,                // ulBufferSize

    g_pucTxBufferWorkspace           // pvWorkspace

};

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

//USB Bulk设备类返回事件处理函数(callback).

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

unsigned long  TxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,

          void *pvMsgData)

{

    //发送完成事件

    if(ulEvent == USB_EVENT_TX_COMPLETE)

    {

        g_ulTxCount += ulMsgValue;

    }

    return(0);

}

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

               unsigned long ulMsgValue, void *pvMsgData)

{

    // 接收事件

    switch(ulEvent)

    {

        //连接成功

        case USB_EVENT_CONNECTED:

        {

GPIOPinWrite(GPIO_PORTF_BASE,0x40,0x40); 

            g_bUSBConfigured = true;

            g_pcStatus = "Host connected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            // Flush our buffers.

            USBBufferFlush(&g_sTxBuffer);

            USBBufferFlush(&g_sRxBuffer);

            break;

        }

        // 断开连接.

        case USB_EVENT_DISCONNECTED:

        {

GPIOPinWrite(GPIO_PORTF_BASE,0x40,0x00);

            g_bUSBConfigured = false;

            g_pcStatus = "Host disconnected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            break;

        }

        // 有可能数据接收.

        case USB_EVENT_RX_AVAILABLE:

        {

            tUSBDBulkDevice *psDevice;

            psDevice = (tUSBDBulkDevice *)pvCBData;

            // 把接收到的数据发送回去。

            return(EchoNewDataToHost(psDevice, pvMsgData, ulMsgValue));

        }

        //挂起,唤醒

        case USB_EVENT_SUSPEND:

        case USB_EVENT_RESUME:break;

        default:break;

    }

    return(0);

}

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

//EchoNewDataToHost函数

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

unsigned long EchoNewDataToHost(tUSBDBulkDevice *psDevice, unsigned char *pcData,

                  unsigned long ulNumBytes)

{

    unsigned long ulLoop, ulSpace, ulCount;

    unsigned long ulReadIndex;

    unsigned long ulWriteIndex;

    tUSBRingBufObject sTxRing;

    // 获取Buffer信息.

    USBBufferInfoGet(&g_sTxBuffer, &sTxRing);

    // 有多少可能空间

    ulSpace = USBBufferSpaceAvailable(&g_sTxBuffer);

    // 改变数据

    ulLoop = (ulSpace < ulNumBytes) ? ulSpace : ulNumBytes;

    ulCount = ulLoop;

    // 更新接收到的数据个数

    g_ulRxCount += ulNumBytes;

    ulReadIndex = (unsigned long)(pcData - g_pucUSBRxBuffer);

    ulWriteIndex = sTxRing.ulWriteIndex;

    while(ulLoop)

    {

        //更新接收的数据

        if((g_pucUSBRxBuffer[ulReadIndex] >= 'a') &&

           (g_pucUSBRxBuffer[ulReadIndex] <= 'z'))

        {

            //转换

            g_pucUSBTxBuffer[ulWriteIndex] =

                (g_pucUSBRxBuffer[ulReadIndex] - 'a') + 'A';

        }

        else

        {

             //转换

            if((g_pucUSBRxBuffer[ulReadIndex] >= 'A') &&

               (g_pucUSBRxBuffer[ulReadIndex] <= 'Z'))

            {

                 //转换

                g_pucUSBTxBuffer[ulWriteIndex] =

                    (g_pucUSBRxBuffer[ulReadIndex] - 'Z') + 'z';

            }

            else

            {

                 //转换

                g_pucUSBTxBuffer[ulWriteIndex] = g_pucUSBRxBuffer[ulReadIndex];

            }

        }

        // 更新指针

        ulWriteIndex++;

        ulWriteIndex = (ulWriteIndex == BULK_BUFFER_SIZE) ? 0 : ulWriteIndex;

        ulReadIndex++;

        ulReadIndex = (ulReadIndex == BULK_BUFFER_SIZE) ? 0 : ulReadIndex;

        ulLoop--;

    }

    // 发送数据

    USBBufferDataWritten(&g_sTxBuffer, ulCount);

    return(ulCount);

}

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

// 应用主函数.

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

int  main(void)

{

unsigned long ulTxCount = 0;

    unsigned long ulRxCount = 0;

// char pcBuffer[16];

    //设置内核电压、主频 50Mhz

SysCtlLDOSet(SYSCTL_LDO_2_75V);

SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_4 | 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;

// 初始化发送与接收Buffer.

    USBBufferInit((tUSBBuffer *)&g_sTxBuffer);

    USBBufferInit((tUSBBuffer *)&g_sRxBuffer);

// 初始化Bulk设备

    USBDBulkInit(0, (tUSBDBulkDevice *)&g_sBulkDevice);   

    while(1)

    {

        if(g_ulFlags & COMMAND_STATUS_UPDATE)

        {

            //清除更新标志

            g_ulFlags &= ~COMMAND_STATUS_UPDATE;

GPIOPinWrite(GPIO_PORTF_BASE,0x30,0x30);          

        }

// 发送完成

        if(ulTxCount != g_ulTxCount)

        {

            ulTxCount = g_ulTxCount;

GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x10);

//usnprintf(pcBuffer, 16, " %d ", ulTxCount);

        }

        // 接收完成

        if(ulRxCount != g_ulRxCount)

        {

            ulRxCount = g_ulRxCount;

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);

        }

    }

}

07 Bulk设备.pdf (232.94 KB, 下载次数: 445)


最新回复

非常有用,谢谢  详情 回复 发表于 2017-7-28 20:39
 
点赞 关注
个人签名QQ:1795100002
E-mail:paulhyde@qq.com

回复
举报

1729

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
MARK 下,回去慢慢看!
 
 

回复

242

帖子

0

TA的资源

纯净的硅(中级)

板凳
 
如此强大的分享,岂能如此低调。

[ 本帖最后由 guguo2010 于 2011-10-26 10:17 编辑 ]
 
个人签名以摆脱无知为起点,以力求专业为目标
 
 

回复

1803

帖子

0

TA的资源

五彩晶圆(高级)

4
 
这真的是好帖子!
 
 
 

回复

400

帖子

0

TA的资源

五彩晶圆(中级)

5
 
非常好的帖
 
 
 

回复

232

帖子

0

TA的资源

一粒金砂(中级)

6
 
好贴,谢谢分享
 
 
 

回复

37

帖子

0

TA的资源

一粒金砂(中级)

7
 
...好强大。。谢谢分享
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

8
 

谢谢

 谢谢分享
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

9
 
这个贴 解决了手头上问题 谢谢!
 
 
 

回复

1万

帖子

28

TA的资源

裸片初长成(高级)

10
 
好帖
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

11
 
楼主,请问一下USB0有两个中断处理函数RxHandler和TxHandle,那在startup_ccs.c中该怎么写啊

点评

问错了。。。无视这个问题吧  详情 回复 发表于 2014-8-11 13:06
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

12
 
longrejoy 发表于 2014-8-11 12:55
楼主,请问一下USB0有两个中断处理函数RxHandler和TxHandle,那在startup_ccs.c中该怎么写啊

问错了。。。无视这个问题吧



 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

13
 
问一下上位机的程序环境是什么啊
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

14
 
问一下程序里为什么没有SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);这句话,一般不都要使能一下外设吗?还是在其他函数里已经使能了?
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

15
 
非常有用,谢谢
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表