NK-RTU980 USB bulk传输

发布于:2023-01-10 ⋅ 阅读:(459) ⋅ 点赞:(0)

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

USB Device Controller的框图如下:

特性: 

  • USB Specification reversion 2.0 compliant
  • Supports 12 configurable endpoints in addition to Control Endpoint
  • Each of the endpoints can be Isochronous, Bulk or Interrupt and either IN or OUT direction
  • Three different operation modes of an in-endpoint - Auto Validation mode, Manual Validation mode, Fly mode
  • Supports DMA operation
  • 4096 Bytes Configurable RAM used as endpoint buffer
  • Supports Endpoint Maximum Packet Size up to 1024 bytes

1.修改描述符

关于描述符的详细说明参考博客

各种描述符之间的关系:

修改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的设备:

 2.生成USB 驱动

运行inf-wizard.exe应用,点击 Next:

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

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

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

 点击Done完成并退出。

3.安装驱动

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

 点击 下一页。

 一般会遇到以上问题,这是因为驱动没有包含数字签名,解决办法

驱动安装成功之后,设备管理器展示如下:

 4.使用工具查看设备描述符

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

5.编写NUC980 bulk读写函数及测试程序

在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。

6.编写windows应用程序测试数据通信

基于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

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到