CH579F usb host

在peripheral例程上添加usb host,对应usb部分有点疑问,对usb协议不是很熟悉,之前用libusb写过上位机,看usb host例程不是很清楚,流程可能有点差别,所以,请问usb host的收发是怎么样的,CH357有个例程倒是跟其他usb device通信的,非U盘之类。

// 获取透传数据
__align(4) const UINT8  GetTranData[] = { 0xc0,0x33,0x00,0x00,0x00,0x00,0x09,0x00 };

// 发送透传数据
__align(4) const UINT8  SetTranData[] = { 0x40,0x35,0x00,0x00,0x00,0x00,0x09,0x00 };


// USB Host检测设备连接
UINT8  UsbDectConn(void)
{
	UINT8	s;

    s = ERR_SUCCESS;
    if ( R8_USB_INT_FG & RB_UIF_DETECT )                               // 如果有USB主机检测中断则处理
    {  
        R8_USB_INT_FG = RB_UIF_DETECT ; 
        s = AnalyzeRootHub( );   
        
        if ( s == ERR_USB_CONNECT ) 		
            FoundNewDev = 1;
    }
    
    if ( FoundNewDev || s == ERR_USB_CONNECT )                        // 有新的USB设备插入
    {  
        FoundNewDev = 0;
        // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
        mDelaymS( 200 );        
        
        s = InitRootDevice();                                        // 初始化USB设备
        
        if((ThisUsbDev.DeviceVID == 0x1213)&&(ThisUsbDev.DevicePID == 0x3435))
        {
            ThisUsbDev.DeviceType = DEV_TYPE_OTHER;
            s = ERR_SUCCESS;
            UsbConnStatus = 1;
        }
        else                                                        
        {
            s = ERR_USB_UNKNOWN;    
            UsbConnStatus = 0;
        }
    }
    
    return s;
}    


// Usb host接收
UINT8  UsbHostRecv(void)
{
    PUINT8 len;
    *len = MYUSB_RX_LEN;
    
    memset(myUsbRxBuf,0,sizeof(myUsbRxBuf));
    
    CopySetupReqPkg( (PCHAR)GetTranData );                              // 设置控制请求包
    
    // 执行控制传输
    if(ERR_SUCCESS == HostCtrlTransfer( (PUINT8)myUsbRxBuf, len, 10000000))
    {
        return 1;
    }  
    
    return 0;
}    

// Usb host发送
UINT8  UsbHostSend(void)   
{
    UINT8 s;
    PUINT8 len;
    
    *len = MYUSB_TX_LEN;
    
    CopySetupReqPkg((PCHAR)SetTranData);
    s = HostCtrlTransfer((PUINT8)myUsbTxBuf, len, 200000/20 );           // 执行控制传输
    
    if ( s != ERR_SUCCESS )
    {
        return 0;
    }

    return 1;
}


www.wch.cn/bbs/thread-65023-1.html

你好,这里面有USB主机的相应例程,可以参考。如果想在蓝牙的基础上添加USB主机功能,注意需要通过TMOS设置蓝牙任务操作USB。


我已经在BLE基础上加上USB host功能,我使用的是中断传输方式,在蓝牙周期任务中周期执行IN事务,可以正确收到device的数据,也就是说IN是没问题,但是OUT事务有问题,OUT事务最后返回的状态是ERR_SUCCESS,但是device是没有收到数据的,因为我在收到host数据时直接返回,用PC上位机测试通过,但是CH579 OUT后没能IN到数据。

接口信息如下:

image.png


我在控制传输基础上写的中断传输如下:

/*******************************************************************************
* Function Name  : HostInterrupTransfer
* Description    : 执行中断传输
* Input          : DataBuf : 如果需要接收和发送数据,那么DataBuf需指向有效缓冲区用于存放后续数据
*                  RetLen  : 实际成功收发的总长度保存在RetLen指向的字节变量中
*                  type:     IN/OUT
*                  endAddr:  端点地址
* Return         : ERR_USB_BUF_OVER IN状态阶段出错
                   ERR_SUCCESS     数据交换成功
                   其他错误状态
*******************************************************************************/
UINT8 HostInterrupTransfer( PUINT8 DataBuf, PUINT8 RetLen,UINT8 type, UINT8 endAddr)  
{
    UINT16  RemLen  = 0;
    UINT8   s, RxLen, RxCnt, TxCnt;
    PUINT8  pBuf;
    PUINT8   pLen;
    
    pBuf = DataBuf;
    pLen = RetLen;
    mDelayuS( 200 );

    // R8_UH_RX_CTRL = R8_UH_TX_CTRL = 0x80 | 0x10 | 0x40 | 0x10 = D0
    R8_UH_RX_CTRL = R8_UH_TX_CTRL = RB_UH_R_TOG | RB_UH_R_AUTO_TOG | RB_UH_T_TOG | RB_UH_T_AUTO_TOG;// 默认DATA1
    R8_UH_TX_LEN = 0x01;                                                                            // 默认无数据故状态阶段为IN
    
    RemLen = 0x09;
    
    if ( RemLen && pBuf )                                                                           // 需要收发数据
    {
        if ( type == USB_REQ_TYP_IN )                                                               // 中断IN
        {
            while ( RemLen )
            {
                mDelayuS( 200 );
                s = USBHostTransact( USB_PID_IN << 4 | endAddr, R8_UH_RX_CTRL, 200000/200);         // IN数据
                
                if ( s != ERR_SUCCESS )
                {
                    // PRINT( "recv tran1: %d...\n",s);
                    return( s );
                }
                
                RxLen = R8_USB_RX_LEN < RemLen ? R8_USB_RX_LEN : RemLen;
                RemLen -= RxLen;
                
                /*
                if ( pLen )				
                    *pLen += RxLen;                                                                 // 实际成功收发的总长度
                */
                
                for ( RxCnt = 0; RxCnt != RxLen; RxCnt ++ )
                {
                    *pBuf = pHOST_RX_RAM_Addr[ RxCnt ];
                    pBuf ++;
                }
                
                if ( R8_USB_RX_LEN == 0 || ( R8_USB_RX_LEN & ( UsbDevEndp0Size - 1 ) ) )            // 短包
                    break;                                                                  
            }
            R8_UH_TX_LEN = 0x00;                                                                    // 状态阶段为OUT 
            return( ERR_SUCCESS );  
        }
        else                                                                                        // OUT
        {   
            while ( RemLen )
            {
                mDelayuS( 200 );
                // R8_UH_TX_LEN = RemLen >= 9 ? 9 : RemLen;
                R8_UH_TX_LEN = RemLen >= UsbDevEndp0Size ? UsbDevEndp0Size : RemLen;
                
                for ( TxCnt = 0; TxCnt != R8_UH_TX_LEN; TxCnt ++ )
                {
                    pHOST_TX_RAM_Addr[ TxCnt ] = *pBuf;
                    pBuf ++;
                }
                
                s = USBHostTransact( USB_PID_OUT << 4 | endAddr, R8_UH_TX_CTRL, 200000/20 );      // OUT数据
                
                if ( s != ERR_SUCCESS ) 
                {
                    PRINT( "cannot transact:%d  addr: %d \n" ,s,endAddr);
                    return( s );
                } 
                
                RemLen -= R8_UH_TX_LEN;
                
                /*
                if ( pLen )					   
                    *pLen += R8_UH_TX_LEN;   		                                              // 实际成功收发的总长度
                */
            }
            
            R8_UH_TX_LEN = 0x01;                                                                 // 状态阶段为IN
            
            return( s ); 
        }
    }
    
    /*
    // STATUS阶段(握手)
    mDelayuS( 200 );
    s = USBHostTransact( ( R8_UH_TX_LEN ? USB_PID_IN << 4 | endAddr: USB_PID_OUT << 4 | endAddr ), RB_UH_R_TOG | RB_UH_T_TOG, 200000/20 );  
    
    if ( s != ERR_SUCCESS ) 
    {
        PRINT("******** transact 1 ************\n");
        return( s );    
    }
    */
    
    if ( R8_UH_TX_LEN == 0 )        
        return( ERR_SUCCESS );                                                                      // 状态OUT
    
    if ( R8_USB_RX_LEN == 0 )       
        return( ERR_SUCCESS );                                                                      // 状态IN,检查IN状态返回数据长度
    
    return( ERR_USB_BUF_OVER );                                                                     // IN状态阶段错误
}


状态如下:


image.png




icon_rar.gifPeripheral_usb_host_work.zip

简单的demo例程演示,可以参考一下


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