CH32V307 USB键盘示例不能接扫码枪【紧急】

接USB键盘正常,接一个USB的扫码枪就不正常了

理论上USB键盘和扫码枪是一个东西。

这个当一扫码时,扫码枪先发一个8字节包,其中第2个字节是控制大小写的,即0x39,然后收到这个后自动回复

if( keybufdata[0x02] == 0x39 )

 {

    endp0outdata[ 0 ] ^= 0x02;

    lockflag = 1;

},就在自动回复的代码中返回了0x2a错误

错误码如下:#define ERR_USB_TRANSFER     0x20

用的是【\HOST_KM】示例,没有做任何修改,USB HS/FS都试了,都有这个问题,

紧急求救,之前一直用键盘试,感觉没问题,谁知道插这个扫码枪就出现此毛病。

SystemClk:144000000
USBFS HOST KM Test
New Device In
Enum Succeed
Device Desc
12 01 10 01 00 00 00 40 10 20 38 76 00 00 01 02 03 01 
Configuration Desc
09 02 22 00 01 01 00 80 c8 09 04 00 00 01 03 01 01 00 09 21 10 01 00 01 22 3f 00 07 05 83 03 08 00 01 
Device Status 00
Device Speed  01
Device Type   01
Device Addr   02
InterFace Type 01
EndpIn   00
Addr     03
Type     03
Size     08
InterVal 01
Recv 00 00 39 00 00 00 00 00 
err 2a
Recv 00 00 00 00 00 00 00 00 
Device Out


以下是HOST-KM代码,默认的示例:

int main(void)
{
    UINT8  s;
    UINT16 i, j, k;
    UINT16 desclen;
    UINT8  lockflag = 0;
    UINT8  len;
    UINT8  endp0outdata[16];
    UINT8  keybufdata[16];
    USART_Printf_Init(115200);
    Delay_Init();
    printf("SystemClk:%d\r\n",SystemCoreClock);
    printf("USBFS HOST KM Test\r\n");
    Timer3_Init( );

    USBOTG_HostInit(ENABLE);
    while(1)
    {
        s = ERR_SUCCESS;
        if ( USBOTG_H_FS->INT_FG & USBHD_UIF_DETECT )
        {
            USBOTG_H_FS->INT_FG = USBHD_UIF_DETECT ;
            s = AnalyzeRootHub( );
            HostCtl[0].DeviceState = s;
            if ( s == ERR_USB_CONNECT )
            {
                printf( "New Device In\r\n" );
                /* 准备设备操作相关的存储空间 */
                Clear_HOST_CTL_Struct( 0 );
                lockflag = 0;
                FoundNewDev = 1;
                for( i=0; i<16; i++ )
                {
                    keybufdata[i] = 0;
                    endp0outdata[i] = 0;
                }
                endp0outdata[ 0 ] = 0x01;
            }
            if( s == ERR_USB_DISCON )
            {
                printf( "Device Out\r\n" );
                HostCtl[0].DeviceState = 0xFF;
                HostCtl[0].DeviceType  = 0xFF;
                USBOTG_H_FS->HOST_RX_DMA = (UINT32)&endpRXbuff[0];                 //host rx DMA address
                USBOTG_H_FS->HOST_TX_DMA = (UINT32)&endpTXbuff[0];                 //host tx DMA address
            }
        }

        if ( FoundNewDev || s == ERR_USB_CONNECT )
        {
            FoundNewDev = 0;
            Delay_Ms( 200 );
            s = USBOTG_HostEnum( endpRXbuff );
            HostCtl[0].DeviceState = s;
            if ( s == ERR_SUCCESS )
            {
                TIM_Cmd(TIM3, ENABLE);
                printf( "Enum Succeed\r\n" );

                printf( "Device Desc\n" );
                desclen = DeviceDescriptor[0];
                for( i=0; i= HostCtl[0].Interface[i].InEndpInterval[j] )
                        {
                            HostCtl[0].Interface[i].InEndpTimeCount[j] = 0;
                            /* 使用单独的缓冲区地址 */
                            USBOTG_H_FS->HOST_RX_DMA = (UINT32)keybufdata;                                //设置接收DMA地址
                            s = USBHostTransact( USB_PID_IN << 4 | HostCtl[0].Interface[i].InEndpAddr[j], HostCtl[0].Interface[i].InEndpTog[j], 0 );
                            if ( s == ERR_SUCCESS )
                            {
                                HostCtl[0].Interface[i].InEndpTog[j] ^= USBHD_UH_R_TOG;
                                if( USBOTG_H_FS->RX_LEN > 0 )
                                {
                                    printf( "Recv " );
                                    for( k=0; kRX_LEN; k++ )
                                    {
                                        printf( "%02x ", keybufdata[k] );
                                    }
                                    printf( "\n" );
                                    /* CapsLock */
//                                  NUMLOCK 0X01
//                                  CAPLOCK 0X02
//                                  SCROLLLOCK 0X04
                                    if( keybufdata[0x02] == 0x39 )
                                    {
                                       endp0outdata[ 0 ] ^= 0x02;
                                       lockflag = 1;
                                    }
                                    /* ScrollLock */
                                    else if( keybufdata[0x02] == 0x47 )
                                    {
                                       endp0outdata[ 0 ] ^= 0x04;
                                       lockflag = 1;
                                    }
                                    /* NumLock */
                                    else if( keybufdata[0x02] == 0x53 )
                                    {
                                       endp0outdata[ 0 ] ^= 0x01;
                                       lockflag = 1;
                                    }
                                    if( lockflag )
                                    {
                                        lockflag = 0;
                                        /* SetReport */
                                        CopySetupReqPkg( HIDSetReport );
                                        USBOTG_H_FS->HOST_TX_DMA = (UINT32)endpTXbuff;
                                        USBOTG_H_FS->HOST_TX_LEN = 8;
                                        s = HostCtrlTransfer( endp0outdata, &len );
                                        if ( s != ERR_SUCCESS )
                                        {
                                           printf( "err %02x\n", s );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
     }
}



用的示例是【CH32V307\EVT\EXAM\USB\USBFS\HOST_KM】


image.png

这里返回了错误0x2a


非常感谢客服,下班了也有人接技术电话。


最新情况:

换了两把扫描枪,有问题的是得力的,没有问题的是霍尼韦尔

两个插电脑上都是正常的。

可以肯定的是示例没有考虑到某一块的兼容性,明天再继续查找问题。

客户用这个板子我们不能限定他使用什么扫描枪。

希望能得到官方回复。



两者区别是:

得力先发送0x39/CAPS LOCK,再发送正常的文本,即使发送纯文本也会发送该条消息。

霍尼韦尔则是利用的HID的本身的前2个字节来确定大小写

霍尼韦尔扫码:abcABC收到的HID消息

Recv?00?00?00?00?00?00?00?00?
Recv?00?00?04?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?00?00?05?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?00?00?06?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?02?00?00?00?00?00?00?00?
Recv?02?00?04?00?00?00?00?00?
Recv?02?00?00?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?02?00?05?00?00?00?00?00?
Recv?02?00?00?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?02?00?06?00?00?00?00?00?
Recv?02?00?00?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?00?00?28?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00?
Recv?03?00?00?00?00?00?00?00?
Recv?03?00?0d?00?00?00?00?00?
Recv?03?00?00?00?00?00?00?00?
Recv?00?00?00?00?00?00?00?00

得力的消息:

Recv 00 00 39 00 00 00 00 00?

然后回复时就报错了。


加了调试日志,发现在

ch32vf30x_usbfs.host.c文件中

【USBHostTransact】函数中

image.png

此行代码报超时错误,并且只要在插上USB扫码枪后,即使没有扫码动作也报超时错误。扫码时报这个错误后就造成扫码枪直接复位了。


有问题型号:

image.png


正常型号:

image.png



两者插了数个电脑,扫码都是正常。


您好,可以通过USB分析仪抓一下307与扫码枪的数据交互过程,如果有新的问题可以加我微信沟通。V:19951759326


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