CH554如何HOST如何进行USB同步传输

您好。我现在ch554作为host连接一个usb设备,已经枚举完成得到设备的各描述符,设备interface 1、endp 1需要开始同步传输(等时传输),我要如何向设备端发消息并接收数据呢?

谢谢!

同步传输和批量、中断传输的主要差别在于对于IN、OUT事务不做相应,实现对事务不响应配置如下图。

image.png

image.png


您好,按照您的回复,参考CH554EVT_参考例程写了代码测试,同步传输看上去是成功了,可接收的数据没有填充到RxBuffer里。请帮忙看看哪里做的不对,接收的值应该在哪里取到?谢谢!





不好意思为什么空格都变成了问号。越改越乱,重贴一次。抱歉


//这两个变量修改了,因为同步传输时可能一次接收了126个字节。经测试RxBuffer是64还是126效果都一样
UINT8XRxBuffer[126]_at_0x0000;//IN,mustevenaddress
UINT8XTxBuffer[MAX_PACKET_SIZE]_at_0x007E;//OUT,mustevenaddress

voidmain()
{
    UINT8i,r,s,len,endp;
    UINT16isoc_len,loc;

    CfgFsys();
    mDelaymS(50);
    mInitSTDIO();//串口0初始化(按12MHz内部晶振),为了让计算机通过串口监控演示过程
    printf("Start@ChipID=%02X\n",(UINT16)CHIP_ID);
    InitUSB_Host();//初始化USB主机
    printf("initusbhostok\n");

    while(1){
        if(UIF_DETECT){//如果有USB主机检测中断则处理
            UIF_DETECT=0;//清中断标志
            s=AnalyzeRootHub();//分析ROOT-HUB状态
            if(s==ERR_USB_CONNECT//有USB设备接入
                &&ThisUsbDev.DeviceStatus==ROOT_DEV_CONNECTED//刚插入设备尚未初始化
            ){
                s=InitRootDevice();//初始化/枚举指定HUB端口的USB设备
                if(s!=ERR_SUCCESS){
                    printf("EnumAllRootDeverr=%02X\n",(UINT16)s);
                }
            }
        }

        //SETINTERFACE
        //GETCUR
        //SETCUR
        //SETINTERFACE(COMMIT)
        //pSetupReq结构各成员赋值,然后HostCtrlTransfer传输
        s=HostCtrlTransfer(Com_Buffer,(PUINT8)&len);

        ......//一些杂七杂八的get/set,略
        //以上看上去都没什么问题,打出来的值也对

        mDelayuS(200);

    while(1){
        len=0;
        memset(RxBuffer,0x78,sizeof(RxBuffer));//初始化值
        
        UH_RX_CTRL=UH_RX_CTRL|bUH_R_RES;//主机响应控制
        UH_TX_CTRL=UH_TX_CTRL|bUH_T_RES;//主机响应控制
        
        //endp:0不报错但收到长度为0
        //endp:1收到长度126字节,但RxBuffer内容全是初始值
        //endp:2、3报错USB_INT_ST为0x03
        UH_EP_PID=USB_PID_IN<<4|0x01;//指定令牌PID和目的端点号
        
        UIF_TRANSFER=0;//允许传输
        for(i=WAIT_USB_TOUT_200US;i!=0&&UIF_TRANSFER==0;i--);//等待传输完成
        UH_EP_PID=0x00;//停止USB传输
        if(UIF_TRANSFER==0){
            printf("ISOCERROR::NoTransact\n");
            while(1){mDelaymS(1000);}
        }
        if(U_TOG_OK){
            printf("ISOCTOG_OKsuccess\n");
            break;
        }
        
        s=USB_INT_ST&MASK_UIS_H_RES;//USB设备应答状态MASK_UIS_H_RES:0x0F
        if(s==USB_PID_STALL){
            printf("ISOCERROR::STALL:%02X\n",(UINT16)(s));
            while(1){mDelaymS(1000);}
        }
        else{
            if(s==USB_PID_NAK){
                ;
            }
            else{
                if(s){
                    printf("ISOCERROR::othererror:%02X%02X\n",(UINT16)(s),(UINT16)USB_INT_ST);
                    while(1){mDelaymS(1000);}
                }
            }
        }
        len=USB_RX_LEN;
        if(len>4){
            //len大于0时,RxBuffer却总全部是初始化的值
            if(RxBuffer[0]!=0x78&&RxBuffer[1]!=0x78&&RxBuffer[2]!=0x78&&RxBuffer[3]!=0x78){
                printf("ISOClen::%02X\n",(UINT16)len);//能够看到len:0x7E,但数据在哪里呢
                for(i=0;i



len = USB_RX_LEN;

    if(len > 4) {

        if(RxBuffer[0]!=0x78 && RxBuffer[1]!=0x78 && RxBuffer[2]!=0x78 && RxBuffer[3]!=0x78) {  

            printf("ISOC len::%02X\n", (UINT16)len);

            for(i = 0; i < len && i < sizeof(RxBuffer); i ++) {

                printf("%02X ", (UINT16)(RxBuffer[i]));

            }

            printf("\n");

        }

        //else {

        //    printf("ISOC data zero len::%02X\n", (UINT16)len);

        //}

    }


    mDelayuS(15);


。。。 。。。

}


修改USBHostTransact()函数,在赋值tog时,同时将应答状态修改到无响应。

直接调用这个函数,而不是在主循环中尝试独立执行每一步。

image.png


其次USB设备通常需要根据类协议、厂商协议来进行初始化。确保前面的初始化的步骤准确、完善,才可能实现同步端点上的数据传输。


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