STM32
直播中

敷衍作笑谈

9年用户 979经验值
擅长:制造/封装 连接器 光电显示 接口/总线/驱动 RF/无线
私信 关注
[问答]

STM32F407 USB HOST HID部分鼠标键盘无法读取数据的原因?

初学STM32F4 USB,现在使用正点原子USB HID鼠标键盘例程,该历程使用2.1的库,调试发现手里的鼠标(一个有线,一个无线)可以识别,也能进键盘或鼠标的初始化程序,但是之后动键鼠就无法收到任何数据(仿真发现压根不会进解码函数)。这是支持的鼠标串口信息:

  • 检测到USB设备插入!

  • 复位设备...
  • 低速(LS)USB设备!

  • VID: 18F8h
  • PID: 0F97h
  • 从机地址分配成功!

  • HID 设备!
  • Manufacturer: N/A
  • Product: USB OPtiCAL MOUSE
  • Serial Number: N/A

  • 设备枚举完成!

  • 跳过用户确认步骤!

  • USB Connected    USB MouseBUTTON:X POS:Y POS:Z POS:btn,X,Y,Z:0x1,0,-11,0
  • btn,X,Y,Z:0x1,0,-6,0

  • btn,X,Y,Z:0x1,0,-3,0
  • btn,X,Y,Z:0x1,0,-2,0
  • btn,X,Y,Z:0x1,0,-1,0

这是不支持的鼠标串口信息:

  • 检测到USB设备插入!

  • 复位设备...
  • 全速(FS)USB设备!

  • VID: 1D57h
  • PID: AD03h
  • 从机地址分配成功!

  • HID 设备!
  • Manufacturer: SOAI
  • Product: Gaming Mouse
  • Serial Nu
  • mber: N/A
  • 设备枚举完成!

  • 跳过用户确认步骤!

  • USB Connected    USB Mouse

继续仿真后发现在 USB_OTG_USBH_handle_hc_n_In_ISR()函数中支持的键鼠在有数据时会进入

  • else if (hcint.b.xfercompl)
  • {
  • ........
  • pdev->host.URB_State[num] = URB_DONE;
  • }

然后由 URB_DONE标志就可以进入解码函数,但不支持的键鼠却不会进入该 if 语句。和支持的键盘对比也没发现进入了其他语句,再查询发现条件 else if (hcint.b.xfercompl) 貌似是读取的寄存器中的值(对这一块完全小白),在该函数开始部分由这一串语句给出:

  • hcreg = pdev->regs.HC_REGS[num];
  •   hcint.d32 = USB_OTG_READ_REG32( hcreg->HCINT);
  •   hcintmsk.d32 = USB_OTG_READ_REG32( hcreg->HCINTMSK);
  •   hcint.d32 = hcint.d32   hcintmsk.d32;
  •   hcchar.d32 = USB_OTG_READ_REG32( pdev->regs.HC_REGS[num]->HCCHAR);
  •   hcintmsk.d32 = 0;

这是USB_OTG_READ_REG32的宏定义:

  • #define USB_OTG_READ_REG32(reg)  (*(__IO uint32_t *)reg)

到这里就找不到头绪了。对了,好像支持的都是低速设备,不支持的都是全速设备,不知道这里有什么影响没有。具体的USB_OTG_USBH_handle_hc_n_In_ISR()函数在后面。

  • /*******************USB_OTG_USBH_handle_hc_n_In_ISR()函数 **********************************/
  • uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
  • {
  •   USB_OTG_HCINTn_TypeDef     hcint;
  •   USB_OTG_HCINTMSK_TypeDef  hcintmsk;
  •   USB_OTG_HCCHAR_TypeDef     hcchar;
  •   USB_OTG_HCTSIZn_TypeDef  hctsiz;
  •   USB_OTG_HC_REGS *hcreg;


  •   hcreg = pdev->regs.HC_REGS[num];
  •   hcint.d32 = USB_OTG_READ_REG32( hcreg->HCINT);
  •   hcintmsk.d32 = USB_OTG_READ_REG32( hcreg->HCINTMSK);
  •   hcint.d32 = hcint.d32   hcintmsk.d32;
  •   hcchar.d32 = USB_OTG_READ_REG32( pdev->regs.HC_REGS[num]->HCCHAR);
  •   hcintmsk.d32 = 0;


  •   if (hcint.b.ahberr)
  •   {
  •     CLEAR_HC_INT(hcreg ,ahberr);
  •     UNMASK_HOST_INT_CHH (num);
  •   }
  •   else if (hcint.b.ack)
  •   {
  •     CLEAR_HC_INT(hcreg ,ack);
  •   }

  •   else if (hcint.b.stall)
  •   {
  •     UNMASK_HOST_INT_CHH (num);
  •     pdev->host.HC_Status[num] = HC_STALL;
  •     CLEAR_HC_INT(hcreg , nak);   /* Clear the NAK Condition */
  •     CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */
  •     hcint.b.nak = 0;           /* NOTE: When there is a 'stall', reset also nak,
  •                                   else, the pdev->host.HC_Status = HC_STALL
  •     will be overwritten by 'nak' in code below */
  •     USB_OTG_HC_Halt(pdev, num);
  •   }
  •   else if (hcint.b.datatglerr)
  •   {

  •     UNMASK_HOST_INT_CHH (num);
  •     USB_OTG_HC_Halt(pdev, num);
  •     CLEAR_HC_INT(hcreg , nak);
  •     pdev->host.HC_Status[num] = HC_DATATGLERR;
  •     CLEAR_HC_INT(hcreg , datatglerr);
  •   }

  •   if (hcint.b.frmovrun)
  •   {
  •     UNMASK_HOST_INT_CHH (num);
  •     USB_OTG_HC_Halt(pdev, num);
  •     CLEAR_HC_INT(hcreg ,frmovrun);
  •   }

  •   else if (hcint.b.xfercompl)       //正常的键鼠在输入数据时会进入该if
  •   {

  •     if (pdev->cfg.dma_enable == 1)
  •     {
  •       hctsiz.d32 = USB_OTG_READ_REG32( pdev->regs.HC_REGS[num]->HCTSIZ);
  •       pdev->host.XferCnt[num] =  pdev->host.hc[num].xfer_len - hctsiz.b.xfersize;
  •     }

  •     pdev->host.HC_Status[num] = HC_XFRC;
  •     pdev->host.ErrCnt [num]= 0;
  •     CLEAR_HC_INT(hcreg , xfercompl);

  •     if ((hcchar.b.eptype == EP_TYPE_CTRL)||
  •         (hcchar.b.eptype == EP_TYPE_BULK))
  •     {
  •       UNMASK_HOST_INT_CHH (num);
  •       USB_OTG_HC_Halt(pdev, num);
  •       CLEAR_HC_INT(hcreg , nak);
  •       pdev->host.hc[num].toggle_in ^= 1;

  •     }
  •     else if(hcchar.b.eptype == EP_TYPE_INTR)
  •     {
  •       hcchar.b.oddfrm  = 1;
  •       USB_OTG_WRITE_REG32( pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
  •       pdev->host.URB_State[num] = URB_DONE;
  •     }

  •   }
  •   else if (hcint.b.chhltd)
  •   {
  •     MASK_HOST_INT_CHH (num);

  •     if(pdev->host.HC_Status[num] == HC_XFRC)

  •     {
  •       pdev->host.URB_State[num] = URB_DONE;
  •     }

  •     else if (pdev->host.HC_Status[num] == HC_STALL)
  •     {
  •       pdev->host.URB_State[num] = URB_STALL;
  •     }

  •     else if((pdev->host.HC_Status[num] == HC_XACTERR) ||
  •             (pdev->host.HC_Status[num] == HC_DATATGLERR))
  •     {
  •       pdev->host.ErrCnt[num] = 0;
  •       pdev->host.URB_State[num] = URB_ERROR;

  •     }
  •     else if(hcchar.b.eptype == EP_TYPE_INTR)//in
  •     {
  •       pdev->host.hc[num].toggle_in ^= 1;
  •     }

  •     CLEAR_HC_INT(hcreg , chhltd);

  •   }
  •   else if (hcint.b.xacterr)
  •   {
  •     UNMASK_HOST_INT_CHH (num);
  •     pdev->host.ErrCnt[num] ++;
  •     pdev->host.HC_Status[num] = HC_XACTERR;
  •     USB_OTG_HC_Halt(pdev, num);
  •     CLEAR_HC_INT(hcreg , xacterr);

  •   }
  •   else if (hcint.b.nak)
  •   {
  •     if(hcchar.b.eptype == EP_TYPE_INTR)
  •     {
  •       UNMASK_HOST_INT_CHH (num);
  •       USB_OTG_HC_Halt(pdev, num);
  •     }
  •     else if  ((hcchar.b.eptype == EP_TYPE_CTRL)||
  •               (hcchar.b.eptype == EP_TYPE_BULK))
  •     {
  •       /* re-activate the channel  */
  •       hcchar.b.chen = 1;
  •       hcchar.b.chdis = 0;
  •       USB_OTG_WRITE_REG32( pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
  •     }
  •     pdev->host.HC_Status[num] = HC_NAK;
  •     CLEAR_HC_INT(hcreg , nak);
  •   }

  •   return 1;
  • }


回帖(2)

罗兰君

2024-4-22 10:00:32
改用STM32Cube就可以了
举报

杨福林

2024-4-22 15:59:02
有几个可能的原因导致您无法读取鼠标和键盘的数据:

1. 驱动问题:请确认您是否正确安装了USB驱动程序,并且驱动程序是否与您的设备兼容。检查驱动程序的版本和功能是否符合鼠标和键盘的要求。

2. 硬件连接问题:请检查您是否正确连接了鼠标和键盘。确保USB连接正常,并且设备已经启动。

3. 中断问题:USB HOST库通常使用中断来处理USB设备的数据。请确保您的中断配置正确,并且中断服务程序已正确编写。

4. 电源问题:USB设备需要足够的电源供应才能正常工作。请确保您的系统提供足够的电源,并且电源线路连接正确。

5. USB协议问题:检查您是否正确实现了USB协议中的HID部分。确保您的代码正确处理HID鼠标和键盘的数据报文。

6. 软件配置问题:请确保您的代码正确配置了USB HOST库和相关的GPIO、时钟等外设。

以上是一些可能导致无法读取鼠标和键盘数据的常见原因。通过仔细检查硬件和软件配置,您应该能够解决问题。如果问题仍然存在,建议使用调试工具来进一步分析和诊断错误。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分