查看: 2776|回复: 4

[分享] 【经验分享】鼠标HID例程简析(下)

[复制链接]

该用户从未签到

124

主题

3600

帖子

0

金牌会员

Rank: 6Rank: 6

积分
5781
最后登录
1970-1-1
发表于 2014-9-18 16:35:27 | 显示全部楼层 |阅读模式
本帖最后由 FSL_TICS_ZP 于 2014-9-18 16:37 编辑

鼠标HID例程简析
         前两天已经陆续分享了两篇帖子来介绍鼠标HID例程,今天再接再励继续扫尾工作。闲话少叙,马上开整。
       TestApp_Init()
       在TestApp_Init()函数内,通过Emulate_Mouse_WithButton()
函数来模拟鼠标各式功能:左击、右击,上移、下移,左移、右移,而其中的USB_Class_HID_Send_Data()函数用于实现中断端点与Host  PC进行数据通信。
  1. *****************************************************************************
  2. * Application task function. It is called from the main loop
  3. *****************************************************************************/
  4. void TestApp_Task(void)
  5. {
  6.         /* call the periodic task function */
  7.         USB_Class_HID_Periodic_Task();

  8.         if(mouse_init) /*check whether enumeration is
  9.                                         complete or not */
  10.         {
  11.                 /* run the button emulation code */
  12.                 Emulate_Mouse_WithButton();
  13.         }
  14. }
复制代码
        Emulate_Mouse_WithButton()
        在本例程中,通过连接PTA4脚的SW3按键来模拟鼠标的右键,当然像鼠标的左击、上移、下移,左移、右移功能,也可通过SW3按键进行操作,而实现以上功能的关键就是:需要网友朋友们在理解鼠标报表描述符的基础上修改数据,并将其传递给中断端点。对报表描述符的介绍就不在本文展开啊,不了解的网友可以去参考先前分享的《USBHID设备应用(进阶篇)》一文。
  1. *****************************************************************************
  2. * This function sends the mouse data depending on which key was pressed on
  3. * the board
  4. *****************************************************************************/
  5. static void Emulate_Mouse_WithButton(void)
  6. {
  7.     if(kbi_stat > 0)
  8.     {
  9.         switch(kbi_stat & KBI_STAT_MASK)
  10.         {
  11.            case LEFT_CLICK : /* PTG0 (left click) is pressed */
  12.                rpt_buf[0] = LEFT_CLICK;
  13.                rpt_buf[1] = 0x00;
  14.                rpt_buf[2] = 0x00;
  15.                break;

  16.            case RIGHT_CLICK : /* PTG1 (right click)   is pressed */
  17.                rpt_buf[0] = RIGHT_CLICK;
  18.                rpt_buf[1] = 0x00;
  19.                rpt_buf[2] = 0x00;

  20.                break;

  21.            case MOVE_LEFT_RIGHT :  /* PTG2 (left
  22.                                       or right movement--depends on
  23.                                       UP_LEFT macro) is pressed*/
  24.                rpt_buf[1] = SHIFT_VAL;
  25.                rpt_buf[0] = 0x00;
  26.                rpt_buf[2] = 0x00;
  27.                break;

  28.            case MOVE_UP_DOWN :          /* PTG3 (up or down
  29.                                           movement--depends on
  30.                                           UP_LEFT macro) is pressed*/
  31.                rpt_buf[2] = SHIFT_VAL;
  32.                rpt_buf[1] = 0x00;
  33.                rpt_buf[0] = 0x00;
  34.                break;
  35.            default:break; /* otherwise */
  36.         }
  37.         kbi_stat = 0x00; /* reset status after servicing interrupt*/
  38.         (void)USB_Class_HID_Send_Data(CONTROLLER_ID,HID_ENDPOINT,rpt_buf,
  39.                                         MOUSE_BUFF_SIZE);

  40.         if(rpt_buf[0])
  41.         {
  42.             /* required to send Click Release for Click Press Events */
  43.             (void)USB_Class_HID_Send_Data(CONTROLLER_ID,HID_ENDPOINT,null_buf,
  44.                                         MOUSE_BUFF_SIZE);

  45.         }
  46.     }
  47.     return;
  48. }
复制代码
       IRQ_ISR_PORTA()
       SW3按键在按下松开后吗,触发此中断函数,修改kbi_stat值,来模拟鼠标右击功能。
  1. void IRQ_ISR_PORTA(void)
  2. {
  3. #if defined(MCU_MK20D5)
  4.     NVICICPR1 = 1 << ((40)%32);
  5.     NVICISER1 = 1 << ((40)%32);
  6. #elif defined (MCU_MKL25Z4)
  7.     NVIC_ICPR = 1 << 30;
  8.     NVIC_ISER = 1 << 30;
  9. #else
  10.     NVICICPR2 = 1 << ((87)%32);
  11.     NVICISER2 = 1 << ((87)%32);
  12. #endif
  13.         DisableInterrupts;
  14. #if defined MCU_MKL25Z4
  15.     if(PORTA_ISFR & (1<<4))
  16.     {
  17.         kbi_stat |= 0x02;                 /* Update the kbi state */
  18.         PORTA_ISFR = (1 << 4);            /* Clear the bit by writing a 1 to it */
  19.     }
  20. #else
  21.         if(PORTA_ISFR & (1<<19))
  22.         {
  23.                 kbi_stat |= 0x02;                                 /* Update the kbi state */
  24.                 PORTA_ISFR = (1 << 19);                        /* Clear the bit by writing a 1 to it */
  25.         }
  26. #endif
  27.         EnableInterrupts;
  28. }
复制代码
        USB_Class_HID_Send_Data()
        USB_Class_HID_Send_Data()实现将报告描述符定义的4个字节的报告数据返回给HOST PC。
  1. ******************************************************************************
  2. * This function is used by Application to send data through HID class
  3. *****************************************************************************/
  4. uint_8 USB_Class_HID_Send_Data (
  5.     uint_8 controller_ID,       /* [IN] Controller ID */
  6.     uint_8 ep_num,              /* [IN] Endpoint Number */
  7.     uint_8_ptr app_buff,        /* [IN] Buffer to Send */
  8.     USB_PACKET_SIZE size        /* [IN] Length of the Transfer */
  9. )
  10. {
  11.     uint_8 index;
  12.     //volatile uint_8 producer, consumer;
  13.     uint_8 producer, consumer;
  14.     uint_8 status = USB_OK;

  15.     USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
  16.         USB_Desc_Get_Endpoints(controller_ID);

  17.     DisableInterrupts;
  18.      /* map the endpoint num to the index of the endpoint structure */
  19.     index = USB_Map_Ep_To_Struct_Index(controller_ID, ep_num);

  20.     producer = g_hid_endpoint_data.ep[index].bin_producer;
  21.     consumer = g_hid_endpoint_data.ep[index].bin_consumer;

  22.     if((uint_8)(producer - consumer) != (uint_8)(MAX_QUEUE_ELEMS))
  23.     {
  24.         /* the bin is not full*/

  25.         uint_8 queue_num = (uint_8)(producer % MAX_QUEUE_ELEMS);

  26.         /* queue the send request */
  27.         /* put all send request parameters in the endpoint data structure */
  28.         g_hid_endpoint_data.ep[index].queue[queue_num].controller_ID =
  29.             controller_ID;
  30.         g_hid_endpoint_data.ep[index].queue[queue_num].channel = ep_num;
  31.         g_hid_endpoint_data.ep[index].queue[queue_num].app_buff = app_buff;
  32.         g_hid_endpoint_data.ep[index].queue[queue_num].size = size;

  33.         /* increment producer bin by 1*/
  34.         g_hid_endpoint_data.ep[index].bin_producer++;
  35.         producer++;

  36.         if((uint_8)(producer - consumer) == (uint_8)1)
  37.         {
  38.             /* send the IO if there is only one element in the queue */
  39.             status = USB_Class_Send_Data(controller_ID, ep_num, app_buff,size);
  40.         }

  41.     }
  42.     else /* bin is full */
  43.     {
  44.         status = USBERR_DEVICE_BUSY;
  45.     }
  46.     EnableInterrupts;
  47.     return status;
  48. }
复制代码
3. 例程调试
    运行平台
    1. TWR-KL25Z48M
    2.CW10.6
   运行例程(CW)
1)  使用USB cable连接TWR-KL25Z48M开发板Min-B USB连接器(J23;
2)  加载工程后,点击 6.jpg 进行编译;
3)  编译成功后,点击 7.jpg 进入调试界面;
4)  进入调试界面后,使用USB cable连接-KL25Z48M开发板micro USB连接器(J13),接着点击 8.jpg 运行例程。

   平台搭建
IMG_20140918_112818.jpg
图 1 TWRKL25Z48M开发板
      USB分析仪监测
·     枚举过程数据包分析
       枚举过程的数据包分析,已在《USBHID设备应用(进阶篇)》中进行过详细介绍,在此就不重复介绍了,大家可以到论坛去下载《USB HID设备应用(进阶篇)》文档。
·      报告数据分析
9.jpg
参考文献:



回复

使用道具 举报

该用户从未签到

124

主题

3600

帖子

0

金牌会员

Rank: 6Rank: 6

积分
5781
最后登录
1970-1-1
 楼主| 发表于 2014-9-18 16:40:09 | 显示全部楼层

如有什么错误或者不足,欢迎网友指正,请在后面跟帖!
回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
发表于 2014-9-18 17:44:23 | 显示全部楼层
感谢楼主的经验分享,支持。
回复 支持 反对

使用道具 举报

  • TA的每日心情
    慵懒
    2016-12-22 14:33
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    34

    主题

    512

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1378
    最后登录
    1970-1-1
    发表于 2014-9-19 11:02:10 | 显示全部楼层
    不错
    回复

    使用道具 举报

    该用户从未签到

    124

    主题

    3600

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    5781
    最后登录
    1970-1-1
     楼主| 发表于 2014-9-28 15:57:42 | 显示全部楼层

    谢谢支持,如有问题请在帖子后面跟帖!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-21 13:13 , Processed in 0.100167 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表