CH374成功枚舉USB鍵盤(pán),獲取按鍵值失敗

#include "include.h"

#include "bsp_ch374.h"




const u8 SetupGetDevDescr[] = {0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00};/* 獲取設(shè)備描述符 */

constu8 SetupGetCfgDescr[] = {0x80,0x06,0x00,0x02,0x00,0x00,0x04,0x00};/* 獲取配置描述符 */

constu8 SetupSetUsbAddr[] = {0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00};/* 設(shè)置USB地址 */

const u8 SetupSetUsbConfig[] = {0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00};/* 設(shè)置USB配置 */

u8 SetupSetidle[]={0x21,0x0a,0x00,0x00,0x00,0x00,0x00,0x00}; /* SET IDLE */

u8 SetupGetHidDes[]={0x81,0x06,0x00,0x22,0x00,0x00,0x81,0x00};/* 獲取HID 報(bào)告描述符 */

u8 SetupSetReport[]={0x21,0x09,0x00,0x02,0x00,0x00,0x01,0x00};/* SET REPORT */ ?


u8 endp_out_addr;//輸出地址(端口)

u8 endp_in_addr;//輸入地址(端口)

u8 endp_in_addr;// in 端點(diǎn)地址?

u8 ReadDataFlag;//讀取數(shù)據(jù)的同步標(biāo)志

u8 hid_des_leng;// HID類(lèi)報(bào)告描述符的長(zhǎng)度

u8 FlagDeviceStatus;// 當(dāng)前USB設(shè)備狀態(tài),通常用于中斷方式的全局變量,本程序中未使用?

u8 UsbDevEndpSize = DEFAULT_ENDP0_SIZE;

/**

? *@Name:SetHostLeisure

*@Describe:設(shè)定USB主機(jī)空閑

*@Output:Not

*@Input:Not

*@Date:2017-02-19

**/

void SetHostLeisure(void)

{

//CH374_WRITE_REGISTER( REG_USB_SETUP, M_SET_USB_BUS_FREE( Read374Byte( REG_USB_SETUP ) ) ); ? ?// USB總線空閑

CH374_WRITE_REGISTER( REG_USB_SETUP, BIT_SETP_HOST_MODE| BIT_SETP_AUTO_SOF ); ? ? ? ? ? ? ? ? // USB總線復(fù)位

}

/**

? *@Name:SetHostUsbAddr

*@Describe:設(shè)置USB主機(jī)當(dāng)前操作的USB設(shè)備地址

*@Output:Not

*@Input:Not

*@Date:2017-02-19

**/

void SetHostUsbAddr( u8 addr ) ?

{

CH374_WRITE_REGISTER(REG_USB_ADDR,addr);

}


/**

? *@Name:Init374Host

*@Describe:初始化USB主機(jī)

*@Output:Not

*@Input:Not

*@Date:2017-02-19

**/

void Init374Host(void)

{

CH374_WRITE_REGISTER( REG_USB_SETUP,0x00);

SetHostUsbAddr(0x00);

CH374_WRITE_REGISTER( REG_USB_H_CTRL,0x00);

CH374_WRITE_REGISTER( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); ?// 清所有中斷標(biāo)志

//CH374_WRITE_REGISTER( REG_INTER_EN, BIT_IE_TRANSFER ); ? ? ? ? ? ? ? ? ? ? ? ? // 允許傳輸完成中斷,因?yàn)楸境绦蚴褂貌樵?xún)方式檢測(cè)USB設(shè)備插拔,所以無(wú)需USB設(shè)備檢測(cè)中斷

CH374_WRITE_REGISTER( REG_INTER_EN, BIT_IE_TRANSFER | BIT_IE_DEV_DETECT ); ? ? // 允許傳輸完成中斷和USB設(shè)備檢測(cè)中斷

CH374_WRITE_REGISTER( REG_SYS_CTRL, BIT_CTRL_OE_POLAR ); ? ? ? ? ? ? ? ? ? ? ? // 對(duì)于CH374T或者UEN引腳懸空的CH374S必須置BIT_CTRL_OE_POLAR為1

SetHostLeisure(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // USB總線空閑

}

/**

? *@Name:HostSetReset

*@Describe:USB總線復(fù)位

*@Output:Not

*@Input:Not

*@Date:2017-02-20

**/

void HostSetReset(void)

{

UsbDevEndpSize = DEFAULT_ENDP0_SIZE; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// USB設(shè)備的端點(diǎn)0的最大包尺寸?

SetHostUsbAddr(0x00);

CH374_WRITE_REGISTER(REG_USB_H_CTRL,0x00);

//Write374Byte( REG_USB_SETUP, M_SET_USB_BUS_RESET( Read374Byte( REG_USB_SETUP ) & ~ BIT_SETP_AUTO_SOF ) ); ?// USB總線復(fù)位

CH374_WRITE_REGISTER( REG_USB_SETUP, M_SET_USB_BUS_RESET( BIT_SETP_HOST_MODE ) ); ? ? ? ? ? // USB總線復(fù)位

? OSTimeDly(1); //延時(shí)1*20ms = 20ms ?// USB總線復(fù)位期間

//Write374Byte( REG_USB_SETUP, M_SET_USB_BUS_FREE( Read374Byte( REG_USB_SETUP ) ) ); ?// USB總線空閑

SetHostLeisure(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// USB總線空閑

delay_us(1000);

CH374_WRITE_REGISTER( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_DEV_DETECT | BIT_IF_USB_SUSPEND ); ?// 清中斷標(biāo)志

}



/**

? *@Name:Query374DevFullSpeed

*@Describe:查詢(xún)當(dāng)前的USB設(shè)備是全速還是低速, 返回TRUE為全速?

*@Output:返回1則全速,返回0則低速

*@Input:Not

*@Date:2017-02-20

**/

u8 Query374DevFullSpeed(void)

{

if((CH374_READ_REGISTER(REG_SYS_INFO) & BIT_INFO_USB_DP))

return 1;

else

return 0;

}


/**

? *@Name:HostSetFullSpeed

*@Describe:設(shè)定全速USB設(shè)備運(yùn)行環(huán)境?

*@Output:Not

*@Input:Not

*@Date:2017-02-20

**/

void HostSetFullSpeed( void ) ?

{

CH374_WRITE_REGISTER(REG_USB_SETUP, (CH374_READ_REGISTER(REG_USB_SETUP) & (~BIT_SETP_USB_SPEED)) | BIT_SETP_AUTO_SOF );// 全速且發(fā)SOF

delay_us(1000);

}


/**

? *@Name:HostSetLowSpeed

*@Describe:設(shè)定低速USB設(shè)備運(yùn)行環(huán)境?

*@Output:Not

*@Input:Not

*@Date:2017-02-20

**/

void HostSetLowSpeed( void ) ?

{

CH374_WRITE_REGISTER(REG_USB_SETUP, CH374_READ_REGISTER(REG_USB_SETUP) | BIT_SETP_USB_SPEED | BIT_SETP_AUTO_SOF );// 低速且發(fā)SOF

delay_us(1000);

}


/**

? *@Name:Query374Interrupt

*@Describe:查詢(xún)CH374的中斷

*@Output:Not

*@Input:Not

*@Date:2017-02-19

**/

u8 Query374Interrupt(void)

{

#ifdef CH374_INT_WIRE ??

?if(CH374_INT_WIRE) return 0;

?else return 1;

? ? //return( CH374_INT_WIRE ? FALSE : TRUE ); ?/* 如果連接了CH374的中斷引腳則直接查詢(xún)中斷引腳 */ ??

? #else ?

?if(CH374_READ_REGISTER( REG_INTER_FLAG ) & ( BIT_IF_DEV_DETECT | BIT_IF_TRANSFER )) return 1;

?else return 0;

? ?// return( Read374Byte( REG_INTER_FLAG ) & BIT_IF_INTER_FLAG ? TRUE : FALSE );/* 如果未連接CH374的中斷引腳則查詢(xún)中斷標(biāo)志寄存器 */ ??

? #endif ?

}

/**

? *@Name:Query374DeviceIn

*@Describe:檢測(cè)是否有USB設(shè)備插入

*@Output:Not

*@Input:Not

*@Date:2017-02-19

**/

u8 Query374DeviceIn(void)

{

if(CH374_READ_REGISTER( REG_INTER_FLAG ) & BIT_IF_DEV_ATTACH ) ?

return 1;

else?

return 0;

}

/**

? *@Name:HostDetectInterrupt

*@Describe:處理USB設(shè)備插拔事件中斷

*@Output:Not

*@Input:Not

*@Date:2017-02-19

**/

void HostDetectInterrupt( void ) ? ? ?

{

u8s,u;

? ?

s = CH374_READ_REGISTER( REG_INTER_FLAG );// 獲取中斷狀態(tài)

if( s & BIT_IF_DEV_DETECT )// USB設(shè)備插拔事件

? {

CH374_WRITE_REGISTER( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_DEV_DETECT );// 清中斷標(biāo)志

if ( s & BIT_IF_DEV_ATTACH ) ? ? ? ? ? // USB設(shè)備連接事件

? ? {

u = CH374_READ_REGISTER( REG_USB_SETUP );

if ( s & BIT_IF_USB_DX_IN )// 速度匹配,不需要切換速度

? ? ? {

if ( u & BIT_SETP_USB_SPEED ) FlagDeviceStatus = USB_INT_CONNECT_LS;// 低速USB設(shè)備

else FlagDeviceStatus = USB_INT_CONNECT;// 全速USB設(shè)備

}

else// 速度失配,需要切換速度

? ? ? {

if ( u & BIT_SETP_USB_SPEED ) FlagDeviceStatus = USB_INT_CONNECT;// 全速USB設(shè)備

else FlagDeviceStatus = USB_INT_CONNECT_LS;// 低速USB設(shè)備

}

}

else FlagDeviceStatus = USB_INT_DISCONNECT;// USB設(shè)備斷開(kāi)事件

}

else // 意外的中斷

? {?

CH374_WRITE_REGISTER( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER | BIT_IF_USB_SUSPEND | BIT_IF_WAKE_UP );// 清中斷標(biāo)志

}

}

/**

? *@Name:Wait374Interrupt

*@Describe:等待CH374中斷(INT#低電平),超時(shí)則返回ERR_USB_UNKNOWN?

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-21

**/

u8 Wait374Interrupt(void) ??

{ ??

u16 i;?

??

for(i = 0; i < 10000; i++ ) // 計(jì)數(shù)防止超時(shí)?

{ ? ?

if(Query374Interrupt())?

return 0; ??

} ??

return ERR_USB_UNKNOWN; // 不應(yīng)該發(fā)生的情況 ??

}?

/**

? *@Name:HostTransact374

*@Describe: CH374傳輸事務(wù)

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-21

**/

/* CH374傳輸事務(wù),輸入目的端點(diǎn)地址/PID令牌/同步標(biāo)志,返回同CH375,NAK不重試,超時(shí)/出錯(cuò)重試 */

u8HostTransact374(u8 endp_addr,u8 pid,u8 tog )

{ ?// 本子程序著重于易理解,而在實(shí)際應(yīng)用中,為了提供運(yùn)行速度,應(yīng)該對(duì)本子程序代碼進(jìn)行優(yōu)化

u8retry;

u8s,r,u;

for(retry = 0;retry < 3;retry++)

{

CH374_WRITE_REGISTER( REG_USB_H_PID,M_MK_HOST_PID_ENDP(pid,endp_addr) ); // 指定令牌PID和目的端點(diǎn)號(hào)

//Write374Byte( REG_USB_H_CTRL, BIT_HOST_START | ( tog ? ( BIT_HOST_TRAN_TOG | BIT_HOST_RECV_TOG ) : 0x00 ) ); ?// 設(shè)置同步標(biāo)志并啟動(dòng)傳輸

CH374_WRITE_REGISTER( REG_USB_H_CTRL, ( tog ? ( BIT_HOST_START | BIT_HOST_TRAN_TOG | BIT_HOST_RECV_TOG ) : BIT_HOST_START ) );// 設(shè)置同步標(biāo)志并啟動(dòng)傳輸

/*

if(tog)

?CH374_WRITE_REGISTER( REG_USB_H_CTRL, ( BIT_HOST_START | BIT_HOST_TRAN_TOG | BIT_HOST_RECV_TOG ) );// 設(shè)置同步標(biāo)志并啟動(dòng)傳輸

else

?CH374_WRITE_REGISTER( REG_USB_H_CTRL, BIT_HOST_START ); ?// 設(shè)置同步標(biāo)志并啟動(dòng)傳輸

*/

s = Wait374Interrupt();

if(s == ERR_USB_UNKNOWN ) return( s ); // 中斷超時(shí),可能是硬件異常

s = CH374_READ_REGISTER(REG_INTER_FLAG);// 獲取中斷狀態(tài)

if( s & BIT_IF_DEV_DETECT ) // USB設(shè)備插拔事件

{ ? ? ? ? ? ? ? ? ?

//delay_us( 250 ); // 等待傳輸完成

OSTimeDly(1);//1*20ms

CH374_WRITE_REGISTER( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_DEV_DETECT | BIT_IF_TRANSFER );// 清中斷標(biāo)志

if ( s & BIT_IF_DEV_ATTACH )// USB設(shè)備連接事件

{ ? ? ? ? ? ??

//delay_us( 200 ); ?// 等待傳輸完成

OSTimeDly(1);//1*20ms

u = CH374_READ_REGISTER( REG_USB_SETUP );

if( s & BIT_IF_USB_DX_IN )// 速度匹配,不需要切換速度

{ ? ? ? ? ??

if( u & BIT_SETP_USB_SPEED )?

return( USB_INT_CONNECT_LS );// 低速USB設(shè)備

return( USB_INT_CONNECT );// 全速USB設(shè)備

}

else // 速度失配,需要切換速度

{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

if( u & BIT_SETP_USB_SPEED )?

return( USB_INT_CONNECT );// 全速USB設(shè)備

return( USB_INT_CONNECT_LS );// 低速USB設(shè)備

}

}

else return( USB_INT_DISCONNECT );// USB設(shè)備斷開(kāi)事件

}

else if( s & BIT_IF_TRANSFER ) // 傳輸完成

{ ? ? ? ? ? ? ?

CH374_WRITE_REGISTER( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); ?// 清中斷標(biāo)志

s = CH374_READ_REGISTER(REG_USB_STATUS);// USB狀態(tài)

r = s & BIT_STAT_DEV_RESP;// USB設(shè)備應(yīng)答狀態(tài)

switch( pid )?

{

case DEF_USB_PID_SETUP:

case DEF_USB_PID_OUT:

if ( r == DEF_USB_PID_ACK )

return( USB_INT_SUCCESS );

else if ((r == DEF_USB_PID_STALL) || (r == DEF_USB_PID_NAK) )?

return( r | 0x20 );

else if ( ! M_IS_HOST_TIMEOUT( s ) )?

return( r | 0x20 ); ?// 不是超時(shí)/出錯(cuò),意外應(yīng)答

break;

case DEF_USB_PID_IN:

if( M_IS_HOST_IN_DATA( s ) ) // DEF_USB_PID_DATA0 or DEF_USB_PID_DATA1

{ ?

if( s & BIT_STAT_TOG_MATCH )?

return( USB_INT_SUCCESS ); ?// 不同步則需丟棄后重試

}

else if ((r == DEF_USB_PID_STALL) || (r == DEF_USB_PID_NAK) )?

return( r | 0x20 );

else if ( ! M_IS_HOST_TIMEOUT( s ) )?

return( r | 0x20 ); ?// 不是超時(shí)/出錯(cuò),意外應(yīng)答

break;

default:

return( ERR_USB_UNKNOWN ); ? ? ? // 不可能的情況

}

}

else // 其它中斷,不應(yīng)該發(fā)生的情況

{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

//delay_us(200);// 等待傳輸完成

OSTimeDly(1); //延時(shí)1*20ms = 20ms ? ?

CH374_WRITE_REGISTER( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); /* 清中斷標(biāo)志 */

if(retry) return( ERR_USB_UNKNOWN ); ?// 不是第一次檢測(cè)到則返回錯(cuò)誤 ?FA

}

}

return( 0x20 );// 應(yīng)答超時(shí)

}

/**

? *@Name:WaitHostTransact374

*@Describe: CH374傳輸事務(wù)

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-21

**/

/* ?CH374傳輸事務(wù),輸入目的端點(diǎn)地址/PID令牌/同步標(biāo)志/以mS為單位的NAK重試總時(shí)間(0xFFFF無(wú)限重試),返回同CH375,NAK重試,超時(shí)出錯(cuò)重試 */

u8 WaitHostTransact374(u8 endp_addr,u8 pid,u8 tog,u16 timeout )

{

u8 i, s;

while(1)?

{

for(i = 0; i < 1; i++ )?

{

s = HostTransact374( endp_addr, pid, tog );//01 09 00

/*

if(s == 0x14)

?printf("獲取按鍵成功:%02X\r\n",s);

else

?printf("獲取按鍵失敗:%02X\r\n",s);

*/

if( (s != ( DEF_USB_PID_NAK | 0x20 )) || (timeout == 0) ) // 0X0A | 0X20

return( s );//返回 0X2A ?和 ?0X20

delay_us( 20 );

//OSTimeDly(1); //延時(shí)14*20ms = 280ms ? ?

}

if(timeout < 0xFFFF) timeout --;

}

}

/**

? *@Name:HostCtrlTransfer374

*@Describe: 執(zhí)行控制傳輸

*@Output:Not

*@Input:

*@Date:2017-02-20

**/

/* 執(zhí)行控制傳輸,ReqBuf指向8字節(jié)請(qǐng)求碼,DatBuf為收發(fā)緩沖區(qū) */

u8 HostCtrlTransfer374(u8 *ReqBuf,u8 *DatBuf,u8 *RetLen ) ?

{// 如果需要接收和發(fā)送數(shù)據(jù),那么DatBuf需指向有效緩沖區(qū)用于存放后續(xù)數(shù)據(jù),實(shí)際成功收發(fā)的總長(zhǎng)度保存在ReqLen指向的字節(jié)變量中

u8 s,len,count,total;

u8 tog;

CH374_WRITE_BLOCK(RAM_HOST_TRAN,8,ReqBuf );

CH374_WRITE_REGISTER( REG_USB_LENGTH, 8 );

delay_us(100);

s = WaitHostTransact374(0,DEF_USB_PID_SETUP,0,200 ); // SETUP階段,200mS超時(shí)

if( s == USB_INT_SUCCESS )// SETUP成功

? {

tog = 1;// 默認(rèn)DATA1,默認(rèn)無(wú)數(shù)據(jù)故狀態(tài)階段為IN

if((*(ReqBuf+3))==0x22)

? ? {

total = *( ReqBuf+6) - 0x40;

?}

else?

{

total = *( ReqBuf + 6 );

}

if(total && DatBuf)// 需要收數(shù)據(jù)

? ? {

len = total;

if( *ReqBuf & 0x80 )// 收

? ? ? {

while(len)?

? ? ? ? {

delay_us(100);

s = WaitHostTransact374( 0, DEF_USB_PID_IN, tog, 200 ); ?// IN數(shù)據(jù)

if ( s != USB_INT_SUCCESS ) break;

count = CH374_READ_REGISTER( REG_USB_LENGTH );

CH374_READ_BLOCK( RAM_HOST_RECV, count, DatBuf );

DatBuf += count;

if( count <= len )?

len -= count;

else?

len = 0;

if( count & (UsbDevEndpSize - 1) )?

break; ?// 短包

if(tog)

tog = 0;

else

tog = 1;

}

tog = 0;// 狀態(tài)階段為OUT

}

else?

{// 發(fā)

while( len )?

? ? ? ? {

delay_us(100);

count = len >= UsbDevEndpSize ? UsbDevEndpSize : len;

/*

if(len >= UsbDevEndpSize)

count = UsbDevEndpSize;

else

?count = len;

*/

CH374_WRITE_BLOCK( RAM_HOST_TRAN, count, DatBuf );

CH374_WRITE_REGISTER( REG_USB_LENGTH, count );

s = WaitHostTransact374(0,DEF_USB_PID_OUT,tog,200); ?// OUT數(shù)據(jù)

if ( s != USB_INT_SUCCESS ) break;

DatBuf += count;

len -= count;

if(tog)

tog = 0;

else

tog = 1;

}

tog = 1; ? ? ? ? ? ? ? ?// 狀態(tài)階段為IN

}

total -= len; ? ? ? ? ? ? ? ? ?// 減去剩余長(zhǎng)度得實(shí)際傳輸長(zhǎng)度

}

if( s == USB_INT_SUCCESS ) ? ? ? ?// 數(shù)據(jù)階段成功

? ? {

CH374_WRITE_REGISTER( REG_USB_LENGTH,0);

delay_us( 100 );

if(tog)

?s = WaitHostTransact374(0,DEF_USB_PID_IN,1,200); ?// STATUS階段

else

s = WaitHostTransact374(0,DEF_USB_PID_OUT,1,200); ?// STATUS階段

if ( tog && s == USB_INT_SUCCESS ) ? ?// 檢查IN狀態(tài)返回?cái)?shù)據(jù)長(zhǎng)度

? ? ? {

if( CH374_READ_REGISTER(REG_USB_LENGTH) )?

s = USB_INT_BUF_OVER; ?// 狀態(tài)階段錯(cuò)誤

}

}

}

if( RetLen )?

*RetLen = total;// 實(shí)際成功收發(fā)的總長(zhǎng)度

return s;

}

/**

? *@Name:SetUsbAddress

*@Describe:設(shè)置USB設(shè)備地址?

*@Output:Not

*@Input:addr 地址

*@Date:2017-02-20

**/

u8 SetUsbAddress(u8 addr ) ?

{

u8 s;

u8 BufSetAddr[sizeof(SetupSetUsbAddr)] ;

memcpy ( BufSetAddr,SetupSetUsbAddr, sizeof( SetupSetUsbAddr ) );

((PUSB_SETUP_REQ)BufSetAddr) -> wValueL = addr;// USB設(shè)備地址

s = HostCtrlTransfer374( BufSetAddr, NULL, NULL );// 執(zhí)行控制傳輸

if (s == USB_INT_SUCCESS)?

{

SetHostUsbAddr(addr);// 設(shè)置USB主機(jī)當(dāng)前操作的USB設(shè)備地址

}

delay_us(3000);// 等待USB設(shè)備完成操作

return(s);

}

/**

? *@Name:GetDeviceDescr

*@Describe:設(shè)置USB設(shè)備配置?

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-20

**/


u8 SetUsbConfig(u8 cfg ) ?

{

u8 BufSetCfg[ sizeof( SetupSetUsbConfig ) ] ;

memcpy ( BufSetCfg, SetupSetUsbConfig, sizeof( SetupSetUsbConfig ) );

((PUSB_SETUP_REQ)BufSetCfg )-> wValueL = cfg;// USB設(shè)備配置

return(HostCtrlTransfer374(BufSetCfg,NULL, NULL )); ?// 執(zhí)行控制傳輸

}


/**

? *@Name:GetDeviceDescr

*@Describe:獲取設(shè)備描述符

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-20

**/

u8 GetDeviceDescr(u8 *buf ) ?

{

u8 s,len;

s = HostCtrlTransfer374((u8 *)SetupGetDevDescr,buf,&len );// 執(zhí)行控制傳輸

if ( s == USB_INT_SUCCESS )?

{

UsbDevEndpSize = ((PUSB_DEV_DESCR)buf) -> bMaxPacketSize0; // 端點(diǎn)0最大包長(zhǎng)度,這是簡(jiǎn)化處理,正常應(yīng)該先獲取前8字節(jié)后立即更新UsbDevEndpSize再繼續(xù)

if( len < ((PUSB_SETUP_REQ)SetupGetDevDescr) -> wLengthL ) s = USB_INT_BUF_OVER; ?// 描述符長(zhǎng)度錯(cuò)誤

}

return(s);

}

/**

? *@Name:GetConfigDescr

*@Describe:獲取配置描述符?

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-20

**/

u8 GetConfigDescr(u8 *buf) ?

{

u8 s,len,i,c,j;

u8 BufLogDescr[sizeof(SetupGetCfgDescr)] ;


s = HostCtrlTransfer374((u8*)SetupGetCfgDescr,buf,&len ); ? ?// 執(zhí)行控制傳輸

if(s == USB_INT_SUCCESS)?

? {

// for(i=0;i!=len;i++)

// ?printf("%02x ",(unsigned short)buf[i]);

// printf("\n");

if( len < ((PUSB_SETUP_REQ)SetupGetCfgDescr) -> wLengthL )?

{

s = USB_INT_BUF_OVER; ?// 返回長(zhǎng)度錯(cuò)誤

}

else?

? ? {

memcpy(BufLogDescr,SetupGetCfgDescr,sizeof( SetupGetCfgDescr));

((PUSB_SETUP_REQ)BufLogDescr ) -> wLengthL = ((PUSB_CFG_DESCR)buf) -> wTotalLengthL; ?// 完整配置描述符的總長(zhǎng)度

s = HostCtrlTransfer374(BufLogDescr,buf,&len); ? // 執(zhí)行控制傳輸

if(s == USB_INT_SUCCESS )?

? ? ? {

? ? ? ? //簡(jiǎn)單分析配置描述符,獲取端點(diǎn)地址,這里只處理一個(gè)端點(diǎn)的情況

printf("獲取配置描述符:\r\n");

for ( i = 0; i < ( (PUSB_CFG_DESCR)buf ) -> wTotalLengthL; i ++ )?

?printf("%02X ", (UINT16)( buf[i] ) ); ?//配置描述符

printf( "\r\n" );

for(i=0;i<((PUSB_CFG_DESCR)buf) -> wTotalLengthL;i++)?

{

if((buf[i]==0x09) && (buf[i+1]==0x21) && (buf[i+6]==0x22))

{

hid_des_leng=buf[i+7]; ? ?//獲取報(bào)告描述符的長(zhǎng)度 ? ? ? ?

? ? ? ? ? ? break;

}

}

printf("hid_des_leng=%02x\r\n",hid_des_leng);

endp_out_addr =0;

endp_in_addr = 0;

c = 0;

for(i=0;i<( (PUSB_CFG_DESCR)buf ) -> wTotalLengthL;i++)?

{

if(((buf[i]==0x09) && (buf[i+1]==0x04)&&(buf[i+5]==0x03) && (buf[i+7]==0x01)) || (buf[i+7]==0x02)) ?//接口描述符為HID的鼠標(biāo)、鍵盤(pán) ??

{?

for(j=0;j<(((PUSB_CFG_DESCR)buf ) -> wTotalLengthL-i);j++)?

{

?if((buf[i+j]==0x07) && (buf[i+j+1]==0x05) && (buf[i+j+3]==0x03)) ??

c = buf[i+j+2];//判斷是否為中斷端點(diǎn)

if(c & 0x80) ? ?

endp_in_addr = (c&0x0f);// IN端點(diǎn)的地址 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

else ? ? ? ? ? ??

endp_out_addr = (c&0x0f);

if((endp_out_addr!=0)||(endp_in_addr!=0)) ??

break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

}

}

if((endp_out_addr!=0)||(endp_in_addr!=0)) ??

break; ? ? ? ? ??

}

printf("endp_in_addr=%02x\r\n",(unsigned short)endp_in_addr);

printf("endp_out_addr=%02x\r\n",(unsigned short)endp_out_addr);

}

}

? }

return s ;

}


/**

? *@Name:SetIdle

*@Describe:設(shè)置IDLE

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-21

**/

u8 SetIdle(void)//設(shè)置IDLE

{

u8 s;

s = HostCtrlTransfer374(SetupSetidle,NULL,NULL);

return s;

}



/**

? *@Name:GetHidDes

*@Describe:獲取報(bào)表描述符

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-21

**/

u8 GetHidDes(u8 *p)//獲取報(bào)表描述符

{

u8 s;

u8 buffer[8];

//leng=SetupGetHidDes[0x06]-0x40;//報(bào)表描述符的長(zhǎng)度在發(fā)送數(shù)據(jù)長(zhǎng)度的基礎(chǔ)上減去0X40

//0x81,0x06,0x00,0x22,0x00,0x00,0x81,0x00

memcpy(buffer,SetupGetHidDes,8);

buffer[0x06] = hid_des_leng+0x40;

s=HostCtrlTransfer374(buffer,p,&buffer[0x06]);

return s;

}

/**

? *@Name:SetReport

*@Describe:

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-21

**/

u8 SetReport(u8 *p)

{

u8 s,l=1;

s = HostCtrlTransfer374(SetupSetReport,p,&l);//實(shí)際的數(shù)據(jù)可以寫(xiě)別的數(shù)據(jù),這個(gè)你可以用計(jì)算機(jī)抓下數(shù)據(jù)在發(fā)下去

return s;

}

?

/**

? *@Name:SetReport

*@Describe:通過(guò)中斷端點(diǎn)獲取鼠標(biāo)、鍵盤(pán)上傳的數(shù)據(jù)?

*@Output:Not

*@Input:返回是否獲取設(shè)備描述符成功

*@Date:2017-02-21

**/

u8 Interrupt_Data_Trans(u8 *p)

{

u8 s,count;

s = WaitHostTransact374(endp_in_addr,DEF_USB_PID_IN,ReadDataFlag,1000 );// IN數(shù)據(jù) 01 09 00 1000


if(s != USB_INT_SUCCESS )

? {

? ? //delay_us(5000);?

OSTimeDly(3); //延時(shí)14*20ms = 280ms ? ?

? ? return s;

? }

else

? {

count = CH374_READ_REGISTER(REG_USB_LENGTH);

CH374_READ_BLOCK(RAM_HOST_RECV,count,p);

if(ReadDataFlag)

ReadDataFlag = 0;

else

ReadDataFlag = 1;

}

return s;

}

/**

? *@Name:USB_Equipment

*@Describe:USB設(shè)備初始化,枚舉

*@Output:Not

*@Input:

*@Date:2017-02-19

**/

int USB_Equipment(void)

{

u8 i=0,s=0;

u8 close_bit_flag=0;

u8 DeviceDescribe_buf[80];//由于報(bào)告描述符大小不定,緩沖區(qū)的大小最好定義大些

Init374Host();// 初始化USB主機(jī)

while(1)

{

SetHostLeisure();//設(shè)定USB主機(jī)空閑

while(1)

{

if (Query374Interrupt()) HostDetectInterrupt(); ?// 如果有USB主機(jī)中斷則處理

if (Query374DeviceIn()) break; ? ? ? ? ? ? ? ? ? // 有USB設(shè)備

?OSTimeDly(5); //100ms

}

OSTimeDly(14); //延時(shí)14*20ms = 280ms ? ? ?// 由于USB設(shè)備剛插入尚未穩(wěn)定,故等待USB設(shè)備數(shù)百毫秒,消除插拔抖動(dòng)

if(Query374Interrupt()) HostDetectInterrupt(); // 如果有USB主機(jī)中斷則處理

? ??

HostSetReset();// USB總線復(fù)位

for(i=0;i<100;i++ )// 等待USB設(shè)備復(fù)位后重新連接

? ? {

if(Query374DeviceIn()) ?break; // 有USB設(shè)備

delay_us(1000);

}

if(Query374Interrupt()) HostDetectInterrupt( ); // 如果有USB主機(jī)中斷則處理

if(Query374DeviceIn())// 有USB設(shè)備

? ? { ?

if(Query374DevFullSpeed())

? ? ? {

HostSetFullSpeed();// 檢測(cè)到全速USB設(shè)備

// printf("全速USB設(shè)備插入:\r\n");

printf("Full-Speed Device\r\n");

}

else?

? ? ? {

HostSetLowSpeed();// 檢測(cè)到低速USB設(shè)備

//printf("低速USB設(shè)備插入:\r\n");

printf("Low-Speed Device\r\n");

}

}

else?

? ? {

continue;// 設(shè)備已經(jīng)斷開(kāi),繼續(xù)等待

}

OSTimeDly(3); //延時(shí)3*20ms = 60ms?

close_bit_flag=0;//設(shè)備是否拔出

//1、獲取設(shè)備描述符

s = GetDeviceDescr(DeviceDescribe_buf); // 獲取設(shè)備描述符

if(s != USB_INT_SUCCESS )

? ? {

printf("獲取設(shè)備描述符失敗\r\n");

goto WaitDeviceOut;// 終止操作,等待USB設(shè)備拔出

}

printf("設(shè)備描述符:");

for(i=0;i <((PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL;i++ )?

?printf("%02X ",DeviceDescribe_buf[i]);//輸出描述符

printf( "\r\n" );

//2、設(shè)置USB設(shè)備地址 ? ?

s = SetUsbAddress(0x02);// 設(shè)置USB設(shè)備地址

if(s != USB_INT_SUCCESS )

{

printf("設(shè)置USB設(shè)備地址錯(cuò)誤\r\n");

goto WaitDeviceOut;// 終止操作,等待USB設(shè)備拔出

}

printf("設(shè)置USB設(shè)備地址0X02成功\r\n");


//3、獲取配置描述符

s = GetConfigDescr(DeviceDescribe_buf); // 獲取配置描述符

//printf("config_status=%02x\r\n",(unsigned short)s);

if ( s != USB_INT_SUCCESS )

{

printf("獲取配置描述符錯(cuò)誤\r\n");

goto WaitDeviceOut;// 終止操作,等待USB設(shè)備拔出

}

//4、設(shè)置USB設(shè)備配置

// 分析配置描述符,獲取端點(diǎn)數(shù)據(jù)/各端點(diǎn)地址/各端點(diǎn)大小等,更新變量endp_addr和endp_size等?

s = SetUsbConfig( ( (PUSB_CFG_DESCR)DeviceDescribe_buf ) -> bConfigurationValue ); // 設(shè)置USB設(shè)備配置

if ( s != USB_INT_SUCCESS )?

{

printf("獲取配置描述符錯(cuò)誤\r\n");

? ? goto WaitDeviceOut;// 終止操作,等待USB設(shè)備拔出

}

printf("設(shè)置USB設(shè)備配置成功\r\n");


//-------------------------以下進(jìn)行HID類(lèi)的簡(jiǎn)單操作-----------------------------------------------------------

//5、設(shè)置IDLE

s = SetIdle();//設(shè)置IDLE,這個(gè)步驟是按照HID類(lèi)的協(xié)議來(lái)做的

if(s != USB_INT_SUCCESS)

? ? {

? ? ? if((s&0x0f) == USB_INT_RET_STALL) ?goto next_operate1; //返回STALL可能本身不支持

}

printf("設(shè)置IDLE成功\r\n");

next_operate1:

//6、獲取報(bào)表描述符

s=GetHidDes(DeviceDescribe_buf);// 獲取報(bào)表描述符

if(s==USB_INT_SUCCESS)

? ? {

printf("HID_Desc: ");

for(i=0;i!=hid_des_leng;i++) ?

?printf("%02x ",DeviceDescribe_buf[i]);

printf("\r\n");

}

else

? ? {

printf("獲取報(bào)表描述符描述符錯(cuò)誤\r\n");

goto WaitDeviceOut;//出錯(cuò)退出

}

DeviceDescribe_buf[0]=0x01;

//設(shè)置報(bào)表

s = SetReport(DeviceDescribe_buf);//設(shè)置報(bào)表

if(s==USB_INT_SUCCESS) ??

{

printf("Set_Report success\r\n");

}

else //設(shè)置報(bào)告出錯(cuò)

? ? {?

? ? ?if((s&0x0f) == USB_INT_RET_STALL) ?goto next_operate2; ? ? ?//返回STALL可能本身不支持 ?

}

next_operate2:

// 下面開(kāi)始讀取數(shù)據(jù) ( 實(shí)際在讀取數(shù)據(jù)的時(shí)候,要先發(fā)送中斷端點(diǎn)的令牌來(lái)讀取數(shù)據(jù),接著才能獲取到數(shù)據(jù) )

ReadDataFlag = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//開(kāi)始取DATA0

while(1)

? ? {

s = Interrupt_Data_Trans(DeviceDescribe_buf);


printf("s = %X\r\n",s);

if(s==USB_INT_SUCCESS)

? ? ? {

for(i=0;i!=8;i++)

?printf("%02x ",DeviceDescribe_buf[i]);

printf("\r\n");

}

else if(s == USB_INT_DISCONNECT)// ?這個(gè)是為了知道設(shè)備拔出產(chǎn)生的中斷狀態(tài)

? ? ? {

close_bit_flag=1;

break;

}

OSTimeDly(5); //100ms

}

//-------------------------------------------------------------------------------------------------------

WaitDeviceOut: // 等待USB設(shè)備拔出

?printf( "Wait Device Out\r\n" );

?if(close_bit_flag==0)//設(shè)備拔出

{

while(1)

{

if(Query374Interrupt()) HostDetectInterrupt( );// 如果有USB主機(jī)中斷則處理

if(Query374DeviceIn() == FALSE ) break; ? // 沒(méi)有USB設(shè)備

OSTimeDly(5); //100ms?

}

?}

OSTimeDly(5); //延時(shí)5*20ms = 100ms ?

}

}

//--------------------------------------------------------------------------------------

串口輸出信息:

Low-Speed Device

設(shè)備描述符:12 01 10 01 00 00 00 08 D5 05 89 06 03 01 00 01 00 01?

設(shè)置USB設(shè)備地址0X02成功

獲取配置描述符:

09 02 3B 00 02 01 00 A0 32?

09 04 00 00 01 03 01 01 00?

09 21 10 01 00 01 22 41 00?

07 05 81 03 08 00 0A?

09 04 01 00 01 03 00 00 00?

09 21 10 01 00 01 22 32 00?

07 05 82 03 05 00 0A?

hid_des_leng=41

endp_in_addr=01

endp_out_addr=00

設(shè)置USB設(shè)備配置成功

設(shè)置IDLE成功

HID_Desc: 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 95 08 75 01 81 02 95 08 75 01 81 01 05 08 19 01 29 03 95 03 75 01 91 02 95 01 75 05 91 01 05 07 19 00 2a ff 00 15 00 26 ff 00 95 06 75 08 81 00 c0?

Set_Report success

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 2A

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20

s = 20


Wait Device Out


急,在線等。有哪位朋友用CH374枚舉過(guò)USB鍵盤(pán)的嗎。

如果朋友有代碼的話可以發(fā)一份給我嗎。個(gè)人信息保護(hù),已隱藏 ?謝謝


這是雙接口HID,setidle必須要分別對(duì)兩個(gè)端點(diǎn)都發(fā)一次。


抓的包:

Bus Hound 6.01 capture on Windows Vista Service Pack 1 (x64). Complements of www.perisoft.net


雙飛燕數(shù)字小鍵盤(pán)


? Device - Device ID (followed by the endpoint for USB devices)

? ? ? ? ? ? (15) USB 輸入設(shè)備

? ? ? ? ? ? (17) HID Keyboard Device

? Phase ?- Phase Type

? ? ? ? ? ? CTL ? USB control transfer ? ? ??

? ? ? ? ? ? IN ? ?Data in transfer ? ? ? ? ??

? ? ? ? ? ? OUT ? Data out transfer ? ? ? ? ?

? Data ? - Hex dump of the data transferred

? Descr ?- Description of the phase

? Cmd... - Position in the captured data



Device ?Phase ?Data ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Description ? ? ? ? ? ? ? ? ? ? ? Cmd.Phase.Ofs(rep)

------ ?----- ?------------------------------------------------------------------------------------------------------ ?-------------------------------- ?------------------

? 15.0 ?CTL ? ?80 06 00 01 ?00 00 12 00 ? ? ? ? ? ?GET DESCRIPTOR ? ? ? ? ? ? ? ? ? ? ? ? ? 1.1.0 ? ? ? ?

? 15.0 ?IN ? ? 12 01 10 01 ?00 00 00 08 ?d5 05 89 06 ?03 01 00 01 ?00 01 ? ? ? ? ? .................. ? ? ? ? ? ? ? 1.2.0 ? ? ? ?

? 15.0 ?CTL ? ?80 06 00 02 ?00 00 09 00 ? ? ? ? ? GET DESCRIPTOR ? ? ? ? ? ? ? ? ? ? ? ? ? 2.1.0 ? ? ? ?

? 15.0 ?IN ? ? 09 02 22 00 ?01 01 00 a0 ?32 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ..".....2 ? ? ? ? ? ? ? ? ? ? ?2.2.0 ? ? ??

? 15.0 ?CTL ? ?80 06 00 02 ?00 00 22 00 ? ? ? ? ? ? ? GET DESCRIPTOR ? ? ? ? ? ? ? ? ? ? ? ? ? 3.1.0 ? ? ? ?

? 15.0 ?IN ? ? 09 02 22 00 ?01 01 00 a0 ?32 09 04 00 ?00 01 03 01 ?01 00 09 21 ?10 01 00 01 ?22 41 00 07 ?05 81 03 08 ?..".....2..........!...."A...... ? ? ? ? 3.2.0 ? ? ? ?

? ? ? ? ? ? ? ?00 0a ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .. ? ? ? ? ? ? ? ? ? ? ?3.2.32 ? ? ??

? 15.0 ?CTL ? ?00 09 01 00 ?00 00 00 00 ? ? ? ? ? ? ? ? SET CONFIG ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 4.1.0 ? ? ? ?

? 15.0 ?CTL ? ?21 0a 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? SET IDLE ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 5.1.0 ? ? ? ?

?

? 15.0 ?CTL ? ?81 06 00 22 ?00 00 81 00 ? ? ? ? ? ? ? ? ?GET DESCRIPTOR ? ? ? ? ? ? ? ? ? ? ? ? ? 6.1.0 ? ? ? ?

? 15.0 ?IN ? ? 05 01 09 06 ?a1 01 05 07 ?19 e0 29 e7 ?15 00 25 01 ?95 08 75 01 ?81 02 95 08 ?75 01 81 01 ?05 08 19 01 ?..........)...%...u.....u....... ? ? ? ? 6.2.0 ? ? ? ?

? ? ? ? ? ? ? ?29 03 95 03 ?75 01 91 02 ?95 01 75 05 ?91 01 05 07 ?19 00 2a ff ?00 15 00 26 ?ff 00 95 06 ?75 08 81 00 ?)...u.....u.......*....&....u... ? ? ? ? 6.2.32 ? ? ??

? ? ? ? ? ? ? ?c0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?6.2.64 ? ? ??

? 15.0 ?CTL ? ?21 09 00 02 ?00 00 01 00 ? ? ? ? ? ? ?SET REPORT ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 7.1.0 ? ? ? ?

? 15.0 ?OUT ? ?01 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? . ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?7.2.0 ? ? ? ?

?

? 15.1 ?IN ? ? 00 00 59 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?..Y..... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 8.1.0 ? ? ? ?

? 17 ? ?IN ? ? 01 00 4f 00 ?00 00 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ..O......... ? ? ? ? ? ? ? ? ? ? ? ? ? ? 9.1.0 ? ? ? ?

? 15.1 ?IN ? ? 00 00 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?........ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?10.1.0 ? ? ? ?

? 17 ? ?IN ? ? 01 00 4f 00 ?01 00 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ..O......... ? ? ? ? ? ? ? ? ? ? ? ? ? ?11.1.0 ? ? ? ?

? 15.1 ?IN ? ? 00 00 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?........ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?12.1.0 ? ? ? ?

? 15.1 ?IN ? ? 00 00 5a 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?..Z..... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?13.1.0 ? ? ? ?

? 17 ? ?IN ? ? 01 00 50 00 ?00 00 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ..P......... ? ? ? ? ? ? ? ? ? ? ? ? ? ?14.1.0 ? ? ? ?

? 15.1 ?IN ? ? 00 00 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?........ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?15.1.0 ? ? ? ?

? 17 ? ?IN ? ? 01 00 50 00 ?01 00 00 00 ?00 00 00 00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ..P......... ? ? ? ? ? ? ? ? ? ? ? ? ? ?16.1.0 ? ? ? ?



RTX截圖未命名.png

這個(gè)數(shù)組怎么能定義成常量數(shù)組呢?那你豈不是把0配置進(jìn)去了。


間接性改變,

u8 BufSetCfg[ sizeof( SetupSetUsbConfig ) ] ;

memcpy ( BufSetCfg, SetupSetUsbConfig, sizeof( SetupSetUsbConfig ) );

((PUSB_SETUP_REQ)BufSetCfg )-> wValueL = cfg;

? ? ? return(HostCtrlTransfer374(BufSetCfg,NULL, NULL ));



只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频