在紀錄 In/Out Report 收發之前先來看一下一個struct

 typedef struct _Device_cb
{
uint8_t (*Init) (void *pdev , uint8_t cfgidx);
uint8_t (*DeInit) (void *pdev , uint8_t cfgidx);
/* Control Endpoints*/
uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req);
uint8_t (*EP0_TxSent) (void *pdev );
uint8_t (*EP0_RxReady) (void *pdev );
/* Class Specific Endpoints*/
uint8_t (*DataIn) (void *pdev , uint8_t epnum);
uint8_t (*DataOut) (void *pdev , uint8_t epnum);
uint8_t (*SOF) (void *pdev);
uint8_t (*IsoINIncomplete) (void *pdev);
uint8_t (*IsoOUTIncomplete) (void *pdev); uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length);
#ifdef USB_OTG_HS_CORE
uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length);
#endif #ifdef USB_SUPPORT_USER_STRING_DESC
uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length);
#endif } USBD_Class_cb_TypeDef;

這邊有特別註解 Control Endpoint, Class Specific Endpoint,理解翻譯就是Control Endpoint 即是所謂的Endpoint 0

在USB協定中,一定是透過Endpoint 0,而且一個裝置只能有一個,而且一定要支援。

它一次最大能傳的資料大小為64 bytes,並且是雙向傳輸。基本上一個USB裝置一插上電腦,電腦就會透過Endpoint 0來問一些資料。

根據USB2.0規格,Host必須保留10%的頻寬給Control傳輸。

而Class Specific Endpoint則是我定義 In/Out Report 需要使用的Function,在USB HID Init 時我會初始化我的Endpoint

 static uint8_t  USBD_HID_Init (void  *pdev,
uint8_t cfgidx)
{ /* Open EP IN */
DCD_EP_Open(pdev,
HID_IN_EP,
HID_IN_PACKET,
USB_OTG_EP_INT); /* Open EP OUT */
DCD_EP_Open(pdev,
HID_OUT_EP,
HID_OUT_PACKET,
USB_OTG_EP_INT); DCD_EP_PrepareRx(pdev, HID_OUT_EP, WRReport_buf, USB_HID_RECEIVE_FRAME_SIZE); return USBD_OK;
}

在Window API理頭,主要是利用 WriteFile/ReadFile 跟 HidD_GetInputReport / HidD_SetOutputReport 來收發資料。

在Firmware裡頭對應 WriteFile/ReadFile 的是 Class Specific Endpoint

而對應 HidD_GetInputReport / HidD_SetOutputReport 則是透過 Endpoint 0去對Firmware 做控制。

GetInputReport / SetOutputReport 在 Firmeware 需要在 USBD_HID_Setup 裡頭加上 Set/Get Report的Case

 static uint8_t  USBD_HID_Setup (void  *pdev, USB_SETUP_REQ *req)
{
uint8_t USBD_HID_Report_LENGTH = ;
uint16_t len = ;
uint8_t *pbuf = NULL; switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{ case HID_REQ_SET_PROTOCOL:
USBD_HID_Protocol = (uint8_t)(req->wValue);
break; case HID_REQ_GET_PROTOCOL:
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_Protocol, );
break; case HID_REQ_SET_IDLE:
USBD_HID_IdleState = (uint8_t)(req->wValue >> );
break; case HID_REQ_GET_IDLE:
USBD_CtlSendData (pdev, (uint8_t *)&USBD_HID_IdleState, );
break; case HID_REQ_SET_REPORT:
/* HidD_SetOutputReport 1-byte = Report ID (IN) */
flag = ;
USBD_HID_Report_ID = (uint8_t)(req->wValue);
USBD_HID_Report_LENGTH = (uint8_t)(req->wLength);
USBD_CtlPrepareRx (pdev, WRReport_buf, USBD_HID_Report_LENGTH);
break; case HID_REQ_GET_REPORT:
/* HidD_GetInputReport 1-byte = Report ID (OUT) */
flag = ;
WRReport_buf[] = 0x11;
WRReport_buf[] = 0x22;
WRReport_buf[] = 0x33;
WRReport_buf[] = 0x44;
WRReport_buf[] = 0x55;
WRReport_buf[] = 0x66;
WRReport_buf[] = 0x77;
WRReport_buf[] = 0x88;
USBD_CtlSendData (pdev, (uint8_t *)&WRReport_buf, ); // to pc
break; default:
USBD_CtlError (pdev, req);
return USBD_FAIL;
}
break; case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
if( req->wValue >> == HID_REPORT_DESC)
{
len = MIN(CUSTOMHID_SIZ_REPORT_DESC , req->wLength);
pbuf = CustomHID_ReportDescriptor;
//pbuf = HID_MOUSE_ReportDesc; }
else if( req->wValue >> == HID_DESCRIPTOR_TYPE)
{
//#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
// pbuf = USBD_HID_Desc;
//#else
// pbuf = USBD_HID_CfgDesc + 0x12;
//#endif
pbuf = USBD_HID_CfgDesc + 0x12;
len = MIN(USB_HID_DESC_SIZ , req->wLength);
}
USBD_CtlSendData (pdev, pbuf, len);
break;
case USB_REQ_GET_INTERFACE :
USBD_CtlSendData (pdev, (uint8_t *)&USBD_HID_AltSet, ); break; case USB_REQ_SET_INTERFACE :
USBD_HID_AltSet = (uint8_t)(req->wValue);
break;
}
}
return USBD_OK;
}

這邊提及一下Firmware 發送 Class Specific Endpoint In/Out Report 是利用

DCD_EP_Tx (pdev, HID_IN_EP, report, len); // In Report
DCD_EP_PrepareRx(pdev, HID_OUT_EP, WRReport_buf, HID_OUT_PACKET);

(USB HID) In/Out Report 收發 Function的更多相关文章

  1. (USB HID) Report Descriptor 理解

    在這理整理一下基本 Report Descriptor 對於入門基礎的了解. 在很多文件.Blog都有提到HID report 總共分為3種 : Input.Output.Feature report ...

  2. USB HID Report Descriptor 报告描述符详解

    Report descriptors are composed of pieces of information. Each piece of information is called an Ite ...

  3. USB HID介绍【转】

    本文转载自:http://blog.csdn.net/leo_wonty/article/details/6721214 HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复 ...

  4. USB HID usage table

    This usage table lets usbhidctl decode the HID data correctly for the APC RS/XS1000's. This work was ...

  5. USB HID介绍

    HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复习一下USB协议的相关内容. USB设备描述符-概述 当插入USB设备后,主机会向设备请求各种描述符来识别设备.那什么是设 ...

  6. (USB HID) Configuration Descriptor

    最近完成了HID的基本收發,使用的配置用了2個Endpoint,把一些特別重要要的地方紀錄下來 整個Configuration 分成4大部分 : 1. Configuration 2. Interfa ...

  7. C#进阶——记一次USB HID的各种坑(x86,x64,win10,win7)

    一.简叙 写工控上位机的搬砖人,难免会遇到USB通讯,在一个项目中,我写的上位机使用USB HID协议和STM32通讯传输数据,从零大概花了几天找例程,找资料,最后是各种搬砖修补,终于出来了一个出版D ...

  8. USB HID描述符【转】

    本文转载自: USB是个通用的总线,端口都是统一的.但是USB设备却各种各样,例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的设备的呢?这就要依赖于描述符了.USB的描述符主要有 ...

  9. C#与USB HID间的通信

    原文:C#与USB HID间的通信 C#与USBHID接口的通讯相对于与串口间的通讯较为复杂,其中需要多次调用到Windows的一些API.其原理编者尚未全部理清,以下提供简单的USBHID通讯流程. ...

随机推荐

  1. 第一个Django应用程序_part3

    一.概述 此文延续第一个Django应用程序part2. 官方文档:https://docs.djangoproject.com/en/1.11/intro/tutorial03/ view是Djan ...

  2. #error用法

    #error命令是C/C++语言的预处理命令之一,当预处理器预处理到#error命令时将停止编译并输出用户自定义的错误消息. 语法: #error [用户自定义的错误消息] 注:上述语法成份中的方括号 ...

  3. shared_ptr / weak_ptr 代码片段

    参考<<Boost程序库完全开放指南>> shared_ptr  类摘要(只列出了常用的部分)和相关说明 template <class T> class shar ...

  4. maven环境快速搭建(转)

    出处:http://www.cnblogs.com/fnng/archive/2011/12/02/2272610.html 最近,开发中要用到maven,所以对maven进行了简单的学习.因为有个m ...

  5. jquery 常用工具方法

    inArray(value, array [, fromIndex ])方法类似于原生javascript的indexOf()方法,没有找到匹配元素时它返回-1.如果数组第一个元素匹配参数,那么$.i ...

  6. gkd

    ## Part 0. 开篇 组长博客:[戳我进入]() 作业博客:[班级博客本次作业的链接](https://edu.cnblogs.com/campus/fzu/Grade2016SE/homewo ...

  7. FileInputStream和FileOutStream的使用——文件字节输入/输出流

    最近又退回到java EE的学习,这篇博客就来讲解一下字节流中最重要的两个类FileInputStream和FileOutputStream的用法: FileInputStream:全称是文件字节输入 ...

  8. 深入探讨 Java 类加载器(转载)

    类加载器(class loader)是 Java™中的一个很重要的概念.类加载器负责加载 Java 类的字节代码到 Java 虚拟机中.本文首先详细介绍了 Java 类加载器的基本概念,包括代理模式. ...

  9. linux权限及目录

    [-][rwx][r-x][r--] r:4 - 读  w:2 - 写  x:1 - 执行 1:代表文件类型 2:代表文件所有者的权限 3:代表文件所在组的权限 4:代表其他用户的权限 chgrp:修 ...

  10. Nutch2.2.1 爬虫问题列表

    http://www.cnblogs.com/cy163/archive/2013/02/14/2912630.html http://blog.csdn.net/wangzhaodong001/ar ...