⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbiox.c

📁 USB2I2C USB2SPI USB2ISP资料开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <string.h>#include <usb.h>#include "USBIOX.h"#define vid_old 	0x4348#define vid_new 	0x1a86#define pid 		0x5512//调试#define debug 1#undef dbg#define dbg(format, arg...) do { if(debug)printf(format "\n" , ## arg); } while (0)#define VERSION "0.1"struct sUSBIO_context{	struct usb_device *dev; //设备指针	int write_timeout; //写超时	int read_timeout; //读超时	int out_ep; //下传端点	int in_ep; //上传端点	int index;	 //设备号		unsigned char	USBIO_ver_ic;	//USB2XXX的芯片版本号	unsigned char	USBIO_stream_mode;	// USB2XXX的串口流模式};struct sUSBIO_context sUSBIO[ mUSBIO_MAX_NUMBER ]; //结构体数组usb_dev_handle *usb_dev[ mUSBIO_MAX_NUMBER ];const unsigned char msb_table[256] = { 	0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,		// 0XH								   	0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,		// 1XH								   	0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,		// 2XH								   	0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,	// 3XH								   	0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,		// 4XH								   	0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,	// 5XH								   	0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,		// 6XH								   	0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,		// 7XH								   	0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,		// 8XH								   	0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,		// 9XH								   	0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,		// AXH								   	0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,	// BXH								   	0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,		// CXH								   	0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,	// DXH								0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,		// EXH		0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF };		// FXH//查找所有USB2XXX设备,最多支持16个设备//操作成功返回找到的设备个数,失败返回0int USB2XXX_init( void ){	int i=0;	struct usb_bus *bus;	struct usb_device *dev;	usb_init();	if(usb_find_busses()<0)return i;	if(usb_find_devices()<0)return i;	for(bus=usb_busses; bus; bus=bus->next)	{		for(dev=bus->devices; dev; dev=dev->next)		{			if((dev->descriptor.idVendor == vid_old | dev->descriptor.idVendor == vid_new) && dev->descriptor.idProduct==pid)			{				sUSBIO[ i ].dev=dev;				sUSBIO[ i ].write_timeout=5000;				sUSBIO[ i ].read_timeout=5000;				sUSBIO[ i ].out_ep=0x02;				sUSBIO[ i ].in_ep=0x82;				sUSBIO[ i ].index=i;				sUSBIO[ i ].USBIO_ver_ic=0;				sUSBIO[ i ].USBIO_stream_mode=1;				i++;				if( i==mUSBIO_MAX_NUMBER )goto out;			}		}	}	out:	return i;	}//打开设备,成功返回指向设备的指针,失败返回NULL//index: 打开设备序号,打开第一个设备index=0,打开第二个设备index=1,依此类推,最多支持16个设备usb_dev_handle *USB2XXX_open(int index){	if( usb_dev[ index ] = usb_open( sUSBIO[ index ].dev ))	{		return usb_dev[ index ];	}	else 	{			return NULL;	}}//关闭设备,关闭成功返回1,失败返回0//usb_dev: 打开设备成功后返回的指针unsigned char USB2XXX_close( usb_dev_handle *usb_dev ){	if( ! usb_close( usb_dev ) )		return TRUE;	else return FALSE;}//批量数据下传,成功返回写出的数据长度,失败返回0// index: 指定USB2XXX设备序号// buf: 指向一个缓冲区,放置准备写出的数据// size: 指向长度单元,输入时为准备写出的长度int USB2XXX_write_data( unsigned char index, unsigned char *buf, unsigned long size ){    int ret;    int offset = 0;    int total_written = 0;	while (offset < size) 	{        int write_size = mMAX_BUFFER_LENGTH;		if (offset+write_size > size)            write_size = size-offset;		ret = usb_bulk_write( usb_dev[ index ], sUSBIO[ index ].out_ep, (char *)buf+offset, write_size, sUSBIO[ index ].write_timeout);		if (ret < 0)			return FALSE;        total_written += ret;        offset += write_size;    }	return total_written;}// 设置硬件异步延时,调用后很快返回,而在下一个流操作之前延时指定毫秒数// index: 指定USB2XXX设备序号// delay: 指定延时的毫秒数unsigned char USB2XXX_set_delays( unsigned char index, unsigned long delay ){	unsigned char buffer_delay[ mUSBIO_PACKET_LENGTH ];	unsigned long length_delay;	while ( delay ) 	{		length_delay = delay >= mUSBIOA_CMD_I2C_STM_DLY ? mUSBIOA_CMD_I2C_STM_DLY : delay;		delay -= length_delay;		buffer_delay[0] = mUSBIOA_CMD_I2C_STREAM;		buffer_delay[1] = ( unsigned char )mUSBIOA_CMD_I2C_STM_MS | length_delay;  // 以亳秒为单位延时,位3-位0为延时值		buffer_delay[2] = 	mUSBIOA_CMD_I2C_STM_END;		length_delay = 3;		if ( USB2XXX_write_data( index, buffer_delay, length_delay ) == FALSE ) return( FALSE );  // 写出数据块	}	return( TRUE );}// 执行数据流命令,先输出再输入// index: 指定USB2XXX设备序号// write_length: 写长度,准备写出的长度// write_buffer: 指向一个缓冲区,放置准备写出的数据// read_step: 准备读取的单个块的长度// read_times: 准备读取的次数// read_length: 指向长度单元,返回后为实际读取的长度// read_buffer: 指向一个足够大的缓冲区,用于保存读取的数据unsigned char USB2XXX_write_read ( unsigned char index, unsigned long write_length, unsigned char * write_buffer, unsigned long read_step,	 unsigned long read_times, unsigned long *read_length, unsigned char *read_buffer )	{	unsigned char read[mUSBIO_PACKET_LENGTH];	unsigned long j=0,k=0,s=0;	unsigned long 	m_length, m_rdlen;	m_rdlen = read_step * read_times;	if ( m_rdlen == 0 ) return( FALSE );	m_length = max( write_length, m_rdlen );	j = USB2XXX_write_data( index, write_buffer, write_length );	do	{		s = usb_bulk_read( usb_dev[ index ], sUSBIO[ index ].in_ep, read, read_step, sUSBIO[ index ].read_timeout );		memcpy( read_buffer, read, s );		read_buffer+=s;		k+=s;	}while(--read_times);	*read_length=k;	return k;	}//设置串口流模式,成功返回1,失败返回0// index: 指定USB2XXX设备序号// mode: 指定模式,见下行// 位1-位0:	I2C接口速度/SCL频率, 00=低速/20KHz,01=标准/100KHz(默认值),10=快速/400KHz,11=高速/750KHz// 位2:	SPI的I/O数/IO引脚, 0=单入单出(D3时钟/D5出/D7入)(默认值),1=双入双出(D3时钟/D5出D4出/D7入D6入)// 位7:	SPI字节中的位顺序, 0=低位在前, 1=高位在前// 其它保留,必须为0unsigned char USB2XXX_set_stream( unsigned char index, unsigned char mode ){	unsigned char buffer[ mUSBIO_PACKET_LENGTH ];	int length, write_length;	sUSBIO[ index ].USBIO_stream_mode = mode & 0x8F;	//保存当前模式	buffer[0] = mUSBIOA_CMD_I2C_STREAM;	buffer[1] = ( mUSBIOA_CMD_I2C_STM_SET | sUSBIO[ index ].USBIO_stream_mode & 0x0F ); //设置参数		buffer[2] = mUSBIOA_CMD_I2C_STM_END;	length = 3;	if( write_length = USB2XXX_write_data( index, buffer, length) )	{		if( write_length >= 2 ) return( TRUE );	}	return( FALSE ); }// 处理I2C数据流,2线接口,时钟线为SCL引脚,数据线为SDA引脚(准双向I/O),速度约56K字节// index: 指定USB2XXX设备序号// write_len: 准备写出的数据字节数// write_buf: 指向一个缓冲区,放置准备写出的数据,首字节通常是I2C设备地址及读写方向位// read_len: 准备读取的数据字节数// read_buf: 指向一个缓冲区,返回后是读入的数据unsigned char USB2XXX_stream_i2c(	unsigned char index, unsigned long write_len, unsigned char *write_buf, unsigned long read_len, unsigned char *read_buf ){	unsigned char buffer[mDEFAULT_BUFFER_LEN];	unsigned long i, j, length;	unsigned char *wr_buffer;	length=max( write_len, read_len );	if( length > mMAX_BUFFER_LENGTH ) return(FALSE);	length = write_len;	if ( length > mMAX_BUFFER_LENGTH ) return( FALSE );	if ( length <= mDEFAULT_BUFFER_LEN ) wr_buffer = (unsigned char *)buffer;  // 不超过默认缓冲区长度	else 	{  // 超过则需要另外分配内存		wr_buffer = malloc( mDEFAULT_BUFFER_LEN );  // 分配内存		if ( wr_buffer == NULL ) return( FALSE );  // 分配内存失败	}	i = 0;	wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STREAM;  // 命令码	if ( ( sUSBIO[ index ].USBIO_stream_mode & 0x03 ) == 0 ) 	{		wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_US | 10;  // 延时10微秒		wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_US | 10;  // 延时10微秒	}	wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_STA;  // 产生起始位	if ( write_len )	{		for ( j = 0; j < write_len; ) 		{			length = mUSBIO_PACKET_LENGTH - i % mUSBIO_PACKET_LENGTH;  // 当前包剩余长度,<mUSBIOA_CMD_I2C_STM_MAX			if ( length <= 2 ) 			{				while ( length-- ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_END;  // 当前包提前结束				length = mUSBIO_PACKET_LENGTH;			}			if ( length >= mUSBIO_PACKET_LENGTH ) 			{				wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STREAM;  // 新包的命令码				length = mUSBIO_PACKET_LENGTH - 1;			}			length--;  // 去掉尾部的提前结束码			length--;  // 去掉输出数据的命令码			if ( length > write_len - j ) length = write_len - j;  // 本次输出有效数据长度			wr_buffer[ i++ ] = (unsigned char)( mUSBIOA_CMD_I2C_STM_OUT | length );  // 输出数据,位5-位0为长度			while ( length-- ) wr_buffer[ i++ ] = *( (unsigned char *)write_buf + j++ );  // 复制数据		}	}	if ( read_len )	{		length = mUSBIO_PACKET_LENGTH - i % mUSBIO_PACKET_LENGTH;  // 当前包剩余长度,<mUSBIOA_CMD_I2C_STM_MAX		if ( length <= 3 )		{			while ( length-- ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_END;  // 当前包提前结束			length = mUSBIO_PACKET_LENGTH;		}		if ( length >= mUSBIO_PACKET_LENGTH ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STREAM;  // 新包的命令码		if ( write_len > 1 )		{  // 先输出			wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_STA;  // 产生起始位			wr_buffer[ i++ ] = (unsigned char)( mUSBIOA_CMD_I2C_STM_OUT | 1 );  // 输出数据,位5-位0为长度			wr_buffer[ i++ ] = *(unsigned char *)write_buf | 0x01;  // I2C目标设备地址,最低位为1则进行读操作		}		else if ( write_len )		{  // 输出一字节后直接输入			i--;			wr_buffer[ i++ ] = *(unsigned char *)write_buf | 0x01;  // I2C目标设备地址,最低位为1则进行读操作		}		for ( j = 1; j < read_len; ) 		{			length = mUSBIO_PACKET_LENGTH - i % mUSBIO_PACKET_LENGTH;  // 当前包剩余长度,<mUSBIOA_CMD_I2C_STM_MAX			if ( length <= 1 ) 			{				if ( length ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_END;  // 当前包提前结束				length = mUSBIO_PACKET_LENGTH;			}			if ( length >= mUSBIO_PACKET_LENGTH ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STREAM;  // 新包的命令码			length = read_len - j >= mUSBIOA_CMD_I2C_STM_MAX ? mUSBIOA_CMD_I2C_STM_MAX : read_len - j;  // 本次输入有效数据长度			wr_buffer[ i++ ] = (unsigned char)( mUSBIOA_CMD_I2C_STM_IN | length );  // 输入数据,位5-位0为长度			j += length;			if ( length >= mUSBIOA_CMD_I2C_STM_MAX )			{  // 当前包将满				wr_buffer[ i ] = mUSBIOA_CMD_I2C_STM_END;  // 当前包提前结束				i += mUSBIO_PACKET_LENGTH - i % mUSBIO_PACKET_LENGTH;  // 跳过当前包剩余部分			}		}		length = mUSBIO_PACKET_LENGTH - i % mUSBIO_PACKET_LENGTH;  // 当前包剩余长度,<mUSBIOA_CMD_I2C_STM_MAX		if ( length <= 1 ) 		{			if ( length ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_END;  // 当前包提前结束			length = mUSBIO_PACKET_LENGTH;		}		if ( length >= mUSBIO_PACKET_LENGTH ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STREAM;  // 新包的命令码		wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_IN;  // 输入数据,只接收一个字节并发送无应答	}	length = mUSBIO_PACKET_LENGTH - i % mUSBIO_PACKET_LENGTH;  // 当前包剩余长度,<mUSBIOA_CMD_I2C_STM_MAX	if ( length <= 1 ) 	{		if ( length ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_END;  // 当前包提前结束		length = mUSBIO_PACKET_LENGTH;	}	if ( length >= mUSBIO_PACKET_LENGTH ) wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STREAM;  // 新包的命令码	wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_STO;  // 产生停止位	wr_buffer[ i++ ] = mUSBIOA_CMD_I2C_STM_END;  // 当前包提前结束	length = 0;		if( read_len ) j = USB2XXX_write_read( index, i, wr_buffer, mUSBIOA_CMD_I2C_STM_MAX, 						(read_len+mUSBIOA_CMD_I2C_STM_MAX-1)/mUSBIOA_CMD_I2C_STM_MAX,						&length, read_buf);	else j = USB2XXX_write_data( index, wr_buffer, i );  // 写出数据块

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -