NUC980_Non-OS_BSP_v1.03.000 SDK中没有提供USB bulk传输的例程,基于USBD_HID_Mouse例程进行修改。大体思路参考这个文章,先修改设备、配置、接口、端点等描述符,再安装驱动,最后编写下位机和上位机程序进行验证。
USB Device Controller的框图如下:

特性:
关于描述符的详细说明参考博客。
各种描述符之间的关系:

修改descriptors.c中DeviceDescriptor:
- uint8_t gu8DeviceDescriptor[] __attribute__((aligned(4))) =
- {
- #endif
- LEN_DEVICE, /* bLength */
- DESC_DEVICE, /* bDescriptorType */
- 0x00, 0x02, /* bcdUSB */ //0x10,0x01->0x00,0x20
- 0xFF, /* bDeviceClass */ //0x00->0xFF
- 0x00, /* bDeviceSubClass */
- 0x00, /* bDeviceProtocol */
- CEP_MAX_PKT_SIZE, /* bMaxPacketSize0 */
- /* idVendor */
- USBD_VID & 0x00FF,
- ((USBD_VID & 0xFF00) >> 8),
- /* idProduct */
- USBD_PID & 0x00FF,
- ((USBD_PID & 0xFF00) >> 8),
- 0x00, 0x00, /* bcdDevice */
- 0x01, /* iManufacture */
- 0x02, /* iProduct */
- 0x00, /* iSerialNumber - no serial */
- 0x01 /* bNumConfigurations */
- };
修改hid_mouse.h中VID和PID的值(不是必须要修改的):
- #define USBD_VID 0x303A //0x0416->0x303A
- #define USBD_PID 0x3002 //0x8249->0x3001
在hid_mouse.h中增加OUT节点的定义:
- /* Define EP maximum packet size */
- #define CEP_MAX_PKT_SIZE 64
- #define CEP_OTHER_MAX_PKT_SIZE 64
- #define EPA_MAX_PKT_SIZE 512 //修改,由64改为512
- #define EPA_OTHER_MAX_PKT_SIZE 64
- #define EPB_MAX_PKT_SIZE 512 //新增
- #define EPB_OTHER_MAX_PKT_SIZE 64
-
- #define CEP_BUF_BASE 0
- #define CEP_BUF_LEN CEP_MAX_PKT_SIZE
-
- #define EPA_BUF_BASE 0x200 //新增
- #define EPA_BUF_LEN EPA_MAX_PKT_SIZE
-
- #define EPB_BUF_BASE 0x400 //新增
- #define EPB_BUF_LEN EPB_MAX_PKT_SIZE //新增
-
- /* Define the interrupt In EP number */
- #define INT_IN_EP_NUM 0x01
-
- #define INT_OUT_EP_NUM 0x01 //新增
修改descriptors.c中ConfigDescriptor :
- uint8_t gu8ConfigDescriptor[] __attribute__((aligned(4))) =
- {
- #endif
- LEN_CONFIG, /* bLength */
- DESC_CONFIG, /* bDescriptorType */
- /* wTotalLength */
- LEN_CONFIG_AND_SUBORDINATE & 0x00FF,
- ((LEN_CONFIG_AND_SUBORDINATE & 0xFF00) >> 8),
- 0x01, /* bNumInterfaces */
- 0x01, /* bConfigurationValue */
- 0x00, /* iConfiguration */
- 0x80 | (USBD_SELF_POWERED << 6) | (USBD_REMOTE_WAKEUP << 5),/* bmAttributes */
- USBD_MAX_POWER, /* MaxPower */
-
- /* I/F descr: HID */
- LEN_INTERFACE, /* bLength */
- DESC_INTERFACE, /* bDescriptorType */
- 0x00, /* bInterfaceNumber */
- 0x00, /* bAlternateSetting */
- 0x02, /* bNumEndpoints */ //0x01->0x02
- 0xFF, /* bInterfaceClass */ //0x03->0xFF
- 0x01, /* bInterfaceSubClass */
- 0x00, /* bInterfaceProtocol */ //HID_MOUSE->0x00
- 0x00, /* iInterface */
-
- /* HID Descriptor */ //不使用报告描述符,将此段配置注释。
- // LEN_HID, /* Size of this descriptor in UINT8s. */
- // DESC_HID, /* HID descriptor type. */
- // 0x10, 0x01, /* HID Class Spec. release number. */
- // 0x00, /* H/W target country. */
- // 0x01, /* Number of HID class descriptors to follow. */
- // DESC_HID_RPT, /* Descriptor type. */
- /* Total length of report descriptor. */
- // sizeof(HID_MouseReportDescriptor) & 0x00FF,
- // ((sizeof(HID_MouseReportDescriptor) & 0xFF00) >> 8),
- /* EP Descriptor: bulk in. */
- LEN_ENDPOINT, /* bLength */
- DESC_ENDPOINT, /* bDescriptorType */
- (INT_IN_EP_NUM | EP_INPUT), /* bEndpointAddress */
- EP_BULK, /* bmAttributes */ //EP_INT->EP_BULK
- /* wMaxPacketSize */
- EPA_MAX_PKT_SIZE & 0x00FF,
- ((EPA_MAX_PKT_SIZE & 0xFF00) >> 8),
- 0x00, /* bInterval */ //HID_DEFAULT_INT_IN_INTERVAL->0x00
-
- /* EP Descriptor: bulk out. */ //新增一个输出端点。
- LEN_ENDPOINT, /* bLength */
- DESC_ENDPOINT, /* bDescriptorType */
- (INT_OUT_EP_NUM | EP_OUTPUT), /* bEndpointAddress */
- EP_BULK, /* bmAttributes */
- /* wMaxPacketSize */
- EPB_MAX_PKT_SIZE & 0x00FF,
- ((EPB_MAX_PKT_SIZE & 0xFF00) >> 8),
- 0x00 /* bInterval */
- };
修改LEN_CONFIG_AND_SUBORDINATE的值(减去了一个REPORT,增加了一个END):
#define LEN_CONFIG_AND_SUBORDINATE (LEN_CONFIG+LEN_INTERFACE+LEN_ENDPOINT+LEN_ENDPOINT)
修改hid_mouse.c中的HID_InitForHighSpeed()、HID_InitForFullSpeed(),增加OUT端点配置:
- /**
- * @brief USBD Endpoint Config.
- * @param None.
- * @retval None.
- */
- void HID_InitForHighSpeed(void)
- {
- /* EPA ==> Interrupt IN endpoint, address 1 */
- USBD_SetEpBufAddr(EPA, EPA_BUF_BASE, EPA_BUF_LEN);
- USBD_SET_MAX_PAYLOAD(EPA, EPA_MAX_PKT_SIZE);
- USBD_ConfigEp(EPA, INT_IN_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_IN);
-
- /* EPB ==> Interrupt OUT endpoint, address 1 */
- USBD_SetEpBufAddr(EPB, EPB_BUF_BASE, EPB_BUF_LEN);
- USBD_SET_MAX_PAYLOAD(EPB, EPA_MAX_PKT_SIZE);
- USBD_ConfigEp(EPB, INT_OUT_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_OUT);
-
- USBD_ENABLE_EP_INT(EPB, USBD_EPINTEN_RXPKIEN_Msk);
- }
-
- void HID_InitForFullSpeed(void)
- {
- /* EPA ==> Interrupt IN endpoint, address 1 */
- USBD_SetEpBufAddr(EPA, EPA_BUF_BASE, EPA_BUF_LEN);
- USBD_SET_MAX_PAYLOAD(EPA, EPA_OTHER_MAX_PKT_SIZE);
- USBD_ConfigEp(EPA, INT_IN_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_IN);
-
- /* EPB ==> Interrupt OUT endpoint, address 1 */
- USBD_SetEpBufAddr(EPB, EPB_BUF_BASE, EPB_BUF_LEN);
- USBD_SET_MAX_PAYLOAD(EPB, EPB_OTHER_MAX_PKT_SIZE);
- USBD_ConfigEp(EPB, INT_OUT_EP_NUM, USB_EP_CFG_TYPE_BULK, USB_EP_CFG_DIR_IN);
-
- USBD_ENABLE_EP_INT(EPB, USBD_EPINTEN_RXPKIEN_Msk);
- }
修改UsbString:
- uint8_t gu8ProductStringDesc[] __attribute__((aligned(4))) =
- {
- #endif
- 34,
- DESC_STRING,
- 'B', 0, 'U', 0, 'L', 0, 'K', 0,' ', 0, 'T', 0, 'r', 0, 'a', 0, 'n', 0, 's', 0, 'a', 0, 'c', 0, 't', 0, 'i', 0, 'o', 0, 'n', 0
- };
编译程序,重新烧录。电脑->设备管理器>其它设备 下多了一个名称为BULK Transaction的设备:
![]()
运行inf-wizard.exe应用,点击 Next:

选择Vendor ID为0x303A、Product ID为0x3002的设备,点击Next:

Manufacturer Name、Device Name可修改为其它类容,点击Next:

选择一个路径存放驱动文件。

点击Done完成并退出。

右键 ->更新驱动程序->浏览我的电脑以查找驱动程序(R),选择刚才存放驱动的文件夹:

点击 下一页。

一般会遇到以上问题,这是因为驱动没有包含数字签名,解决办法。
驱动安装成功之后,设备管理器展示如下:

运行testlibusb-win.exe,设备描述符如下:

在hid_mouse.c中增加bulk读写函数:
- /**
- * @brief USBD Endpoint Write.
- * @param None.
- * @retval None.
- */
- void BulkWriteData( uint8_t *Datas, uint16_t Len )
- {
- uint16_t i;
-
- for ( i=0; i<Len; i++)
- {
- USBD->EP[EPA].ep.EPDAT_BYTE = Datas[i];
- }
-
- USBD->EP[EPA].EPRSPCTL = USB_EP_RSPCTL_SHORTTXEN;
- USBD_ENABLE_EP_INT(EPA, USBD_EPINTEN_INTKIEN_Msk);
- }
- /**
- * @brief USBD Endpoint Read.
- * @param None.
- * @retval None.
- */
- uint16_t BulkReadData( uint8_t *Datas, uint16_t Len )
- {
- uint16_t i;
- uint16_t DataCnt = USBD->EP[EPB].EPDATCNT;
- if( DataCnt > 0 )
- {
- for( i = 0; i < DataCnt; i++ )
- {
- Datas[i] = USBD->EP[EPB].ep.EPDAT_BYTE;
- }
- }
-
- return DataCnt;
- }
main.c中增加接收和发送数据的逻辑,main()函数如下:
- int32_t main (void)
- {
- uint8_t i, Cnt = 0;
- uint8_t DataBuf[EPB_MAX_PKT_SIZE];
- uint16_t RxLen;
-
- sysDisableCache();
- sysFlushCache(I_D_CACHE);
- sysEnableCache(CACHE_WRITE_BACK);
- UART_Init();
- printf("\n");
- printf("=======================\n");
- printf(" USB HID Mouse \n");
- printf("=======================\n");
-
- sysInstallISR(IRQ_LEVEL_1, IRQ_UDC, (PVOID)USBD_IRQHandler);
- /* enable CPSR I bit */
- sysSetLocalInterrupt(ENABLE_IRQ);
- sysEnableInterrupt(IRQ_UDC);
-
- USBD_Open(&gsInfo, HID_ClassRequest, NULL);
-
- /* Endpoint configuration */
- HID_Init();
-
- /* Start transaction */
- while(1)
- {
- if (USBD_IS_ATTACHED())
- {
- USBD_Start();
- break;
- }
- }
-
-
-
- while(1)
- {
- RxLen = BulkReadData(DataBuf, EPB_MAX_PKT_SIZE );
-
- if( RxLen > 0 )
- {
- BulkWriteData( DataBuf, EPA_MAX_PKT_SIZE );
- }
-
- }
- }
编译之后烧写到NUC980。
基于libusb.lib编写一个测试应用,进行简单的数据的发送和接收。代码如下:
- #include "lusb0_usb.h"
- #include <stdio.h>
- #include "stdint.h"
- #include <iostream>
- #include <sys/timeb.h>
- #include "windows.h"
-
- using namespace std;
-
- // Enables this example to work with a device running the
- // libusb-win32 PIC Benchmark Firmware.
- //#define BENCHMARK_DEVICE
-
- //
- // TEST SETUP (User configurable)
-
- // Issues a Set configuration request
- #define TEST_SET_CONFIGURATION
-
- // Issues a claim interface request
- #define TEST_CLAIM_INTERFACE
-
- // Use the libusb-win32 async transfer functions. see
- // transfer_bulk_async() below.
- #define TEST_ASYNC
-
- // Attempts one bulk read.
- #define TEST_BULK_READ
-
- // Attempts one bulk write.
- #define TEST_BULK_WRITE
-
- // Device vendor and product id.
- //#define MY_VID 0x05AC
- //#define MY_PID 0x12A0
-
- #define MY_VID 0x303A
- #define MY_PID 0x3002
-
- // Device configuration and interface id.
- #define MY_CONFIG 1 //bConfigurationValue --lwz
- #define MY_INTF 0 //bInterfaceNumber --lwz
-
- // Device endpoint(s)
- #define EP_IN 0x81 //0x81
- #define EP_OUT 0x01
- // Device of bytes to transfer.
- #define RX_BUF_SIZE 512
- #define TX_BUF_SIZE 512
-
- #define TEST_BULK_SPEED
-
- usb_dev_handle *dev = NULL; /* the device handle */
-
- //
- usb_dev_handle *open_dev(void);
- uint16_t usb_dev_read_sync( uint8_t *Buf, uint16_t bufsz );
- bool usb_dev_write_async( uint8_t *Datas, uint16_t DataLen, int timeout );
- int usb_dev_read_async( uint8_t *Buf, uint16_t bufsz, int timeout );
-
- static int transfer_bulk_async(usb_dev_handle *dev,
- int ep,
- char *bytes,
- int size,
- int timeout);
-
- usb_dev_handle *open_dev(void)
- {
- struct usb_bus *bus;
- struct usb_device *dev;
-
- for (bus = usb_get_busses(); bus; bus = bus->next)
- {
- for (dev = bus->devices; dev; dev = dev->next)
- {
- if (dev->descriptor.idVendor == MY_VID
- && dev->descriptor.idProduct == MY_PID)
- {
- return usb_open(dev);
- }
- }
- }
- return NULL;
- }
-
- //
- // usb_dev_init.
- //
- void usb_dev_init( void )
- {
- usb_init(); /* initialize the library */
- }
- //
- // usb_dev_open.
- //
- bool usb_dev_open( void )
- {
- usb_find_busses(); /* find all busses */
- usb_find_devices(); /* find all connected devices */
-
- if (!(dev = open_dev()))
- {
- printf("error opening device: \n%s\n", usb_strerror());
- return false;
- }
-
- if (usb_set_configuration(dev, MY_CONFIG) < 0) //MY_CONFIG是配置描述符中的bConfigurationValue
- {
- printf("error setting config #%d: %s\n", MY_CONFIG, usb_strerror());
- usb_close(dev);
- return false;
- }
-
- if (usb_claim_interface(dev, MY_INTF) < 0) //注册与操作系统通信的接口 --lwz
- {
- printf("error claiming interface #%d:\n%s\n", MY_INTF, usb_strerror());
- usb_close(dev);
- return false;
- }
-
- return true;
- }
- //
- // usb_dev_close.
- //
- void usb_dev_close( void )
- {
- if (dev)
- {
- usb_release_interface(dev, MY_INTF); //注销被usb_claim_interface函数调用后的接口,释放资源 --lwz
- usb_close(dev);
- }
- }
-
- bool usb_dev_isopen( void )
- {
- if( dev != NULL )
- {
- return true;
- }
-
- return false;
- }
-
- void usb_dev_reset_epin( void )
- {
- usb_clear_halt( dev, EP_IN );
- }
-
- void usb_dev_reset_epout( void )
- {
- usb_clear_halt( dev, EP_OUT );
- }
-
- int main(char argc,char **argv)
- {
- usb_dev_handle *dev = NULL; /* the device handle */
- char tmp[RX_BUF_SIZE];
- int ret;
- void* async_read_context = NULL;
- void* async_write_context = NULL;
-
- usb_init(); /* initialize the library */
- usb_find_busses(); /* find all busses */
- usb_find_devices(); /* find all connected devices */
-
- if (!(dev = open_dev()))
- {
- printf("error opening device: \n%s\n", usb_strerror());
- return 0;
- }
- else
- {
- printf("success: device %04X:%04X opened\n", MY_VID, MY_PID);
- }
-
- #ifdef TEST_SET_CONFIGURATION
- if (usb_set_configuration(dev, MY_CONFIG) < 0) //MY_CONFIG是配置描述符中的bConfigurationValue
- {
- printf("error setting config #%d: %s\n", MY_CONFIG, usb_strerror());
- usb_close(dev);
- return 0;
- }
- else
- {
- printf("success: set configuration #%d\n", MY_CONFIG);
- }
- #endif
-
- #ifdef TEST_CLAIM_INTERFACE
- if (usb_claim_interface(dev, 0) < 0) //注册与操作系统通信的接口 --lwz
- {
- printf("error claiming interface #%d:\n%s\n", MY_INTF, usb_strerror());
- usb_close(dev);
- return 0;
- }
- else
- {
- printf("success: claim_interface #%d\n", MY_INTF);
- }
- #endif
-
- #ifdef TEST_BULK_SPEED
-
- char tmpOut[TX_BUF_SIZE];
- char tmpIn[RX_BUF_SIZE];
-
- uint8_t Count = 0;
- uint64_t ComCnt = 0;
- uint64_t errCnt = 0;
-
- struct timeb rawtime;
-
- ftime(&rawtime);
- uint64_t StartTime = rawtime.time;
-
- for( ;; )
- {
- for( uint16_t i = 0; i < sizeof(tmpOut); i++ )
- {
- tmpOut[i] = Count++;
- }
-
- ComCnt ++;
-
- ret = transfer_bulk_async(dev, EP_OUT, tmpOut, sizeof(tmpOut), 5000);
- if (ret < 0)
- {
- // printf("error writing:\n%s\n", usb_strerror());
- }
- else
- {
- // printf("success: bulk write %d bytes\n", ret);
- }
-
- // Running an async read test
- ret = transfer_bulk_async(dev, EP_IN, tmpIn, sizeof(tmpIn), 5000);
-
- if (ret < 0)
- {
- printf("error reading:\n%s\n", usb_strerror());
- }
- else
- {
- printf("success: bulk read %d bytes\n", ret);
- }
-
-
- //if( memcmp( tmpOut, tmpIn, BUF_SIZE ) != 0 )
- //{
- // errCnt ++;
- //}
-
- for( int j = 0; j < TX_BUF_SIZE; j++ )
- {
- if( tmpOut[j] != tmpIn[j] )
- {
- errCnt ++;
- break;
- }
- }
-
- if( (ComCnt % 2000) == 0 )
- {
- printf("ComCnt:%d ",ComCnt );
- printf("errCnt:%d \n",errCnt );
-
- struct timeb rawtime1;
-
- ftime(&rawtime1);
-
- uint64_t endTime = rawtime1.time;
-
- printf("transfer speed:%0.2f bps\n", ((float)(ComCnt * TX_BUF_SIZE * 2 * 8) / (endTime - StartTime)) );
- }
-
- // Sleep(3);
- }
- #endif
-
- #ifdef TEST_BULK_WRITE
- #ifdef BENCHMARK_DEVICE
- ret = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- 14, /* set/get test */
- 2, /* test type */
- MY_INTF, /* interface id */
- tmp, 1, 1000); //从默认的管道发送和接受控制数据--lwz
- #endif
-
- #ifdef TEST_ASYNC
- // Running an async write test
- for( int i = 0; i < sizeof(tmp); i++ )
- {
- tmp[i] = i;
- }
- ret = transfer_bulk_async(dev, EP_OUT, tmp, sizeof(tmp), 5000);
- #else
- // Running a sync write test
- ret = usb_bulk_write(dev, EP_OUT, tmp, sizeof(tmp), 5000);
- #endif
- if (ret < 0)
- {
- printf("error writing:\n%s\n", usb_strerror());
- }
- else
- {
- printf("success: bulk write %d bytes\n", ret);
- }
- #endif
- memset(tmp, 0 , TX_BUF_SIZE );
- #ifdef TEST_BULK_READ
- #ifdef BENCHMARK_DEVICE
- ret = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- 14, /* set/get test */
- 1, /* test type */
- MY_INTF, /* interface id */
- tmp, 1, 1000);
- #endif
-
- #ifdef TEST_ASYNC //有声明--lwz
- // Running an async read test
- ret = transfer_bulk_async(dev, EP_IN, tmp, sizeof(tmp), 5000);
- #else
- // Running a sync read test
- ret = usb_bulk_read(dev, EP_IN, tmp, sizeof(tmp), 5000);
- #endif
- if (ret < 0)
- {
- printf("error reading:\n%s\n", usb_strerror());
- }
- else
- {
- printf("success: bulk read %d bytes\n", ret);
-
- for(int i = 0; i < ret; i++ )
- {
- printf( "%02X ", tmp[i]);
- }
-
- printf("\n");
- }
- #endif
-
- #ifdef TEST_BULK_READ
- #ifdef BENCHMARK_DEVICE
- ret = usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- 14, /* set/get test */
- 1, /* test type */
- MY_INTF, /* interface id */
- tmp, 1, 1000);
- #endif
-
- #ifdef TEST_ASYNC
- // Running an async read test
- ret = transfer_bulk_async(dev, EP_IN, tmp, sizeof(tmp), 5000);
- #else
- // Running a sync read test
- ret = usb_bulk_read(dev, EP_IN, tmp, sizeof(tmp), 5000);
- #endif
- if (ret < 0)
- {
- printf("error reading:\n%s\n", usb_strerror());
- }
- else
- {
- printf("success: bulk read %d bytes\n", ret);
- }
- #endif
-
- #ifdef TEST_CLAIM_INTERFACE
- usb_release_interface(dev, 0); //注销被usb_claim_interface函数调用后的接口,释放资源 --lwz
- #endif
-
- if (dev)
- {
- usb_close(dev);
- }
- printf("Done.\n");
-
- return 0;
-
- }
-
- /*
- * Read/Write using async transfer functions.
- *
- * NOTE: This function waits for the transfer to complete essentially making
- * it a sync transfer function so it only serves as an example of how one might
- * implement async transfers into thier own code.
- */
- static int transfer_bulk_async(usb_dev_handle *dev,
- int ep,
- char *bytes,
- int size,
- int timeout)
- {
- // Each async transfer requires it's own context. A transfer
- // context can be re-used. When no longer needed they must be
- // freed with usb_free_async().
- //
- void* async_context = NULL;
- int ret;
- // Setup the async transfer. This only needs to be done once
- // for multiple submit/reaps. (more below)
- //
- ret = usb_bulk_setup_async(dev, &async_context, ep);
- if (ret < 0)
- {
- printf("error usb_bulk_setup_async:\n%s\n", usb_strerror());
- goto Done;
- }
- // Submit this transfer. This function returns immediately and the
- // transfer is on it's way to the device.
- //
- ret = usb_submit_async(async_context, bytes, size);
- if (ret < 0)
- {
- printf("error usb_submit_async:\n%s\n", usb_strerror());
- usb_free_async(&async_context);
- goto Done;
- }
-
- // Wait for the transfer to complete. If it doesn't complete in the
- // specified time it is cancelled. see also usb_reap_async_nocancel().
- //
- ret = usb_reap_async(async_context, timeout);
- // Free the context.
- usb_free_async(&async_context);
- Done:
- return ret;
- }
- //
- // usb_dev_read_async.
- //
- int usb_dev_read_async( uint8_t *Buf, uint16_t bufsz, int timeout )
- {
- if( dev == NULL )
- {
- return 0;
- }
- int ret;
- char tmp[RX_BUF_SIZE];
-
- ret = transfer_bulk_async(dev, EP_IN, tmp, RX_BUF_SIZE, timeout );
- if( ret > 0 )
- {
- if( bufsz >= ret )
- {
- memcpy(Buf, tmp, ret );
- }
- }
- return ret;
- }
- //
- // usb_dev_write_async.
- //
- bool usb_dev_write_async( uint8_t *Datas, uint16_t DataLen, int timeout )
- {
- if( dev == NULL )
- {
- return false;
- }
- int ret;
- ret = transfer_bulk_async(dev, EP_OUT, (char *)Datas, DataLen , timeout);
- if( ret < 0 )
- {
- return false;
- }
- return true;
- }
- //
- // usb_dev_read_sync.
- //
- uint16_t usb_dev_read_sync( uint8_t *Buf, uint16_t bufsz )
- {
- if( dev == NULL )
- {
- return 0;
- }
- int ret;
- char tmp[RX_BUF_SIZE];
-
- ret = usb_bulk_read(dev, EP_IN, tmp, RX_BUF_SIZE,5000);
- if( ret > 0 )
- {
- if( bufsz >= ret )
- {
- memcpy(Buf, tmp, ret );
- }
- }
- return ret;
- }
上位机运行日志如下:

计算出的速率大约2.7MB/s,比全速高一点,这个速度还有待提升。
NUC980技术交流QQ群:912184327