📄 usbiox.c
字号:
#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 + -