CH559 USB 枚举 返回0x2E错误

又返回来继续检查2E这个问题,我在初始化失败后,再次重新初始化,还是失败。image.png


可以考虑将设备寄过来,我们尝试来操作该设备。联系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


只有登录才能回复,可以选择微信账号登录