又返回来继续检查2E这个问题,我在初始化失败后,再次重新初始化,还是失败。
查看: 5312
回复: 18
CH559 USB 枚举 返回0x2E错误
可以考虑将设备寄过来,我们尝试来操作该设备。联系025-52632854
my code is a bit different because i use my own header files for compiling in Keil, SDCC and IAR but its based on WCH code. Here is the module for sending Control Requests in Hostmode:
/* this module contains the std ctrl requests to get a device enumerated. The functions are universal written and can be used to enum various usb devices. */ #include "..\inc\mytypes.h" #include "..\inc\ch559.h" #include "..\inc\udisklib.h" extern uint8_t XDATA RxBuffer[]; extern uint8_t XDATA TxBuffer[]; uint8_t DeviceEp0Size; //holds bMaxPacketSize0 #define pSetupReq ((PUSB_SETUP_REQ)TxBuffer) //to be compatible with WCH code /* perform a Setup request in Hostmode The function expects a vaild USB setup packet allready prepared in TxBuffer and then handles the complete request. This includes control stage, optionaly datastages and finaly the status stage. Params: [in,out] DataBuf pointer to a buffer for the datastage [out] Retlen pointer to size of the buffer Result: ERR_SUCCESS or a some errorcode if the function fails */ uint8_t Host_CtrlTransfer(uint8_t XDATA *DataBuf, uint8_t IDATA *RetLen) { uint8_t error; uint8_t remLen; uint8_t rxLen; uint8_t stageCnt; mDelayuS(200); if (RetLen) *RetLen = 0; UH_TX_LEN = sizeof(USB_SETUP_REQ); // // Setup Stage // error = Host_UsbTransact((uint8_t)((USB_PID_SETUP << 4) | 0x00), 0x00, 10000); if (error) return error; UH_RX_CTRL = UH_TX_CTRL = bUH_R_TOG | bUH_R_AUTO_TOG | bUH_T_TOG | bUH_T_AUTO_TOG; UH_TX_LEN = 0x01; // check if the request has a wlength >= 256 remLen = pSetupReq -> wLengthH ? 0xFF : pSetupReq -> wLengthL; // // Data Stage // if (remLen && DataBuf) // is there a data stage at all? { if (pSetupReq -> bRequestType & _HOST) // check the direction { // GetRequest while (remLen) { // split the RX stages mDelayuS( 200 ); error = Host_UsbTransact((uint8_t)((USB_PID_IN << 4) | 0x00), UH_RX_CTRL, 10000); if (error) return error; rxLen = (USB_RX_LEN < remLen) ? USB_RX_LEN : remLen; remLen -= rxLen; if (RetLen) *RetLen += rxLen; for (stageCnt = 0; stageCnt != rxLen; stageCnt ++) { *DataBuf = RxBuffer[stageCnt]; DataBuf ++; } if ( (USB_RX_LEN == 0) || (USB_RX_LEN & (DeviceEp0Size -1)) ) break; } UH_TX_LEN = 0x00; } else { // SetRequest while ( remLen ) { mDelayuS( 200 ); UH_TX_LEN = remLen >= DeviceEp0Size ? DeviceEp0Size : remLen; for ( stageCnt = 0; stageCnt != UH_TX_LEN; stageCnt ++ ) { TxBuffer[stageCnt] = *DataBuf; DataBuf ++; } error = Host_UsbTransact( USB_PID_OUT << 4 | 0x00, UH_TX_CTRL, 10000/*200000/20*/ ); if (error) return error; remLen -= UH_TX_LEN; if ( RetLen ) *RetLen += UH_TX_LEN; } UH_TX_LEN = 0x01; } } // // Status stage // mDelayuS (200); error = Host_UsbTransact(UH_TX_LEN ? USB_PID_IN << 4 | 0x00 : USB_PID_OUT << 4 | 0x00, bUH_R_TOG | bUH_T_TOG, 10000); if (error) return error; if (UH_TX_LEN == 0) return ERR_SUCCESS; if (USB_RX_LEN == 0) return ERR_SUCCESS; return( ERR_USB_BUF_OVER ); } /* read the device descriptor to learn about bMaxPacketSize0 optionally just allow special devices based on Vendor and Product to connect. */ uint8_t Host_CtrlGetDeviceDescr(uint16_t Vendor,uint16_t Product) { uint8_t error; uint8_t len; uint16_t id; // // first just request 8 bytes since bMaxPacketSize0 is unknown // this is how OSX is enumerating Win does it a bit different // TxBuffer[0]= _HOST | _DEVICE; TxBuffer[1]= USB_GET_DESCRIPTOR; TxBuffer[2]= 0x00; TxBuffer[3]= USB_DEVICE_DESCRIPTOR; TxBuffer[4]= 0x00; TxBuffer[5]= 0x00; TxBuffer[6]= 0x08; TxBuffer[7]= 0x00; error = Host_CtrlTransfer(TxBuffer, &len); // perform the request if (error) return error; DeviceEp0Size = ((pDeviceDescriptor)TxBuffer) -> bMaxPacketSize0; if ((Vendor) || (Product)) { // // read the complete device descriptor // to learn about VID / PID // TxBuffer[0]= _HOST | _DEVICE; TxBuffer[1]= USB_GET_DESCRIPTOR; TxBuffer[2]= 0x00; TxBuffer[3]= USB_DEVICE_DESCRIPTOR; TxBuffer[4]= 0x00; TxBuffer[5]= 0x00; TxBuffer[6]= sizeof(DeviceDescriptor); TxBuffer[7]= 0x00; error = Host_CtrlTransfer(TxBuffer, &len); // perform the request if (error) return error; // // check for matches // if (Vendor) { id = ((pDeviceDescriptor)TxBuffer) -> idVendorHi; id = id << 8 | ((pDeviceDescriptor)TxBuffer)->idVendorLo; if (id!=Vendor) return ERR_USB_UNSUPPORT; } if (Product) { id = ((pDeviceDescriptor)TxBuffer) -> idProductHi; id = id << 8 | ((pDeviceDescriptor)TxBuffer)->idProductLo; if (id!=Vendor) return ERR_USB_UNSUPPORT; } } return error; } /* send the configure comand */ uint8_t Host_CtrlSetUsbConfig(uint8_t cfg) { uint8_t error; TxBuffer[0]= _DEVICE; TxBuffer[1]= USB_SET_CONFIGURATION; TxBuffer[2]= cfg; TxBuffer[3]= 0; TxBuffer[4]= 0x00; TxBuffer[5]= 0x00; TxBuffer[6]= 0; TxBuffer[7]= 0x00; error = Host_CtrlTransfer(NULL, NULL); return error; } /* get the config descriptor */ uint8_t Host_CtrlGetConfigDescr(void) { uint8_t error; uint8_t len; uint16_t wTotalLen; TxBuffer[0]= _HOST | _DEVICE; TxBuffer[1]= USB_GET_DESCRIPTOR; TxBuffer[2]= 0x00; TxBuffer[3]= USB_CONFIGURATION_DESCRIPTOR; TxBuffer[4]= 0x00; TxBuffer[5]= 0x00; TxBuffer[6]= sizeof(ConfigurationDescriptor); TxBuffer[7]= 0x00; error = Host_CtrlTransfer(TxBuffer, &len); if (error) return error; if (len < sizeof(ConfigurationDescriptor)) return ERR_USB_BUF_OVER; wTotalLen = ((pConfigurationDescriptor)TxBuffer)-> wTotalLengthHi; wTotalLen = (wTotalLen << 8) | ((pConfigurationDescriptor)TxBuffer)-> wTotalLengthLo; TxBuffer[0]= _HOST | _DEVICE; TxBuffer[1]= USB_GET_DESCRIPTOR; TxBuffer[2]= 0x00; TxBuffer[3]= USB_CONFIGURATION_DESCRIPTOR; TxBuffer[4]= 0x00; TxBuffer[5]= 0x00; TxBuffer[6]= wTotalLen & 0xFF; TxBuffer[7]= wTotalLen >> 8; error = Host_CtrlTransfer(TxBuffer, &len); if (error) return error; if (len !=wTotalLen) return ERR_USB_UNSUPPORT; return( ERR_SUCCESS ); } .....
and then a enum module for a memory stick:
/* enumerate the memory stick */ uint8_t Host_EnumMemStick(void) { uint8_t error; // learn about the device ignore VID / PID error = Host_CtrlGetDeviceDescr(0x0000,0x0000); if (error) return error; Debug(printf("DevDesc ok\n")); // set the USB Address error = Host_CtrlSetUsbAddress(0x02); if (error) return error; Debug(printf("UsbAdr ok\n")); error = Host_CtrlGetConfigDescr(); if (error) return error; Debug(printf("CfgDesc ok\n")); // check the fields if (((pConfigurationDescriptor)TxBuffer)-> wTotalLengthHi) { Debug(printf("wLenght err\n")); return ERR_USB_UNSUPPORT; } // has to be 32 bytes in size if (((pConfigurationDescriptor)TxBuffer)-> wTotalLengthLo != 0x20) { Debug(printf("wLenght != 0x20\n")); return ERR_USB_UNSUPPORT; } // has to be CLASS_MSD if ((((PUSB_CFG_DESCR_LONG)TxBuffer)->itf_descr.bInterfaceClass) != 0x08) { Debug(printf("Class err\n")); return ERR_USB_UNSUPPORT; } // has to be bulk only protocol if ((((PUSB_CFG_DESCR_LONG)TxBuffer)->itf_descr.bInterfaceProtocol) != 0x50) { Debug(printf("protocoll err\n")); return ERR_USB_UNSUPPORT; } // save both bulk eps if((((PUSB_CFG_DESCR_LONG)TxBuffer) -> endp_descr[0].bEndPointAddress)>0x80) { DevEndpOUTAddr = (((PUSB_CFG_DESCR_LONG)TxBuffer)-> endp_descr[1].bEndPointAddress)&0x0f; DevEndpINAddr = (((PUSB_CFG_DESCR_LONG)TxBuffer)-> endp_descr[0].bEndPointAddress)&0x0f; } else { DevEndpOUTAddr = (((PUSB_CFG_DESCR_LONG)TxBuffer)-> endp_descr[0].bEndPointAddress)&0x0f; DevEndpINAddr = (((PUSB_CFG_DESCR_LONG)TxBuffer)-> endp_descr[1].bEndPointAddress)&0x0f; } return Host_CtrlSetUsbConfig(((pConfigurationDescriptor)TxBuffer)->bConfigurationValue); }
i hope that can help
请勿发布广告和违法内容, 代码可以选择编辑器代码语言格式, 更易他人阅读帮助您, 或者留下联系方式,以便更好更快服务您
只有登录才能回复,可以选择微信账号登录