搜索
bottom↓
回复: 5

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

[复制链接]

出0入0汤圆

发表于 2014-9-18 16:11:36 | 显示全部楼层 |阅读模式
鼠标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按键进行操作,而实现以上功能的关键就是:需要网友朋友们在理解鼠标报表描述符的基础上修改数据,并将其传递给中断端点。对报表描述符的介绍就不在本文展开啊,不了解的网友可以去参考先前分享的《USB HID设备应用(进阶篇)》一文。
  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)        加载工程后,点击进行编译;
     3)        编译成功后,点击进入调试界面;
     4)        进入调试界面后,使用USB cable连接-KL25Z48M开发板micro USB连接器(J13),接着点击运行例程。
     平台搭建
   

图 1 TWRKL25Z48M开发板

     USB分析仪监测
•        枚举过程数据包分析
       枚举过程的数据包分析,已在《USB HID设备应用(进阶篇)》中进行过详细介绍,在此就不重复介绍了,大家可以到论坛去下载《USB HID设备应用(进阶篇)》文档。
•        报告数据分析

文档下载:
参考文献:
[1] Freescale USB Device Stack Users Guide
[2] Freescale USB Stack Device API Reference Manual
[3] FSL USB Stack v4.1.1

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2014-9-18 16:13:08 | 显示全部楼层
如有什么错误或者不足,欢迎网友指正,请在后面跟帖!

出0入0汤圆

发表于 2014-9-18 16:26:53 | 显示全部楼层
可以把‘鼠标HID例程简析(上)’的帖子链接加上

出0入0汤圆

发表于 2014-9-18 17:16:08 | 显示全部楼层
找不到 鼠标HID例程简析(上)的帖子 啊..麻烦楼主加上啊.

出0入0汤圆

 楼主| 发表于 2014-9-18 17:17:46 | 显示全部楼层
子鱼 发表于 2014-9-18 16:26
可以把‘鼠标HID例程简析(上)’的帖子链接加上

从这个链接可以找到所有三篇文章的链接。
http://www.amobbs.com/thread-5578500-1-1.html

出0入0汤圆

 楼主| 发表于 2014-9-18 17:34:30 | 显示全部楼层
shian0551 发表于 2014-9-18 17:16
找不到 鼠标HID例程简析(上)的帖子 啊..麻烦楼主加上啊.

从这个链接可以找到所有三篇文章的链接。
http://www.amobbs.com/thread-5578500-1-1.html
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 10:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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