打印

STM32的HID通信不能向主机发送信息的原因有哪些呢?

[复制链接]
6436|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cy757|  楼主 | 2009-12-28 23:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我使用以下函数向主机发送数据不成功。请有经验的大虾帮帮忙。
UserToPMABufferCopy(InBuffer, ENDP1_TXADDR, 8);  
SetEPTxCount(ENDP1, 8);  
SetEPTxValid(ENDP1);

我利用STM32库中的Custom_HID例程修改如下:
usb_config.h文件中:
#define ENDP1_TXADDR        (0x100)
#define ENDP1_RXADDR        (0x110)
#define IMR_MSK (CNTR_CTRM  | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM  | CNTR_SOFM \
                 | CNTR_ESOFM | CNTR_RESETM )
/* associated to defined endpoints */
#define  EP1_IN_Callback   NOP_Process
#define  EP2_IN_Callback   NOP_Process
#define  EP3_IN_Callback   NOP_Process
#define  EP4_IN_Callback   NOP_Process
#define  EP5_IN_Callback   NOP_Process
#define  EP6_IN_Callback   NOP_Process
#define  EP7_IN_Callback   NOP_Process

void EP1_OUT_Callback(void);

usb_prop.c文件修改如下
  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxCount(ENDP1, 16);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
  SetEPTxStatus(ENDP1, EP_TX_NAK);

  /* Initialize Endpoint 1 */
// SetEPType(ENDP1, EP_INTERRUPT);
  SetEPRxAddr(ENDP1, ENDP1_RXADDR);
  SetEPRxCount(ENDP1, 16);
// SetEPTxStatus(ENDP1, EP_TX_DIS);
  SetEPRxStatus(ENDP1, EP_RX_VALID);

/* USB Standard Device Descriptor */
const u8 CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] =
  {

0x12, //bLength字段。设备描述符的长度为18(0x12)字节
0x01, //bDescriptorType字段。设备描述符的编号为0x01
0x10,  //bcdUSB字段。这里设置版本为USB1.1,即0x0110。//由于是小端结构,所以低字节在先,即0x10,0x01。
0x01,
0x00, //bDeviceClass字段。我们不在设备描述符中定义设备类//而在接口描述符中定义设备类,所以该字段的值为0。
0x00, //bDeviceSubClass字段。bDeviceClass字段为0时,该字段也为0。  
0x00, //bDeviceProtocol字段。bDeviceClass字段为0时,该字段也为0。
0x40,   //bMaxPacketSize0字段。
//idVender字段。厂商ID号,我们这里取0x8888,仅供实验用。
//实际产品不能随便使用厂商ID号,必须跟USB协会申请厂商ID号。
//注意小端模式,低字节在先。
0x88,
0x88,
//idProduct字段。产品ID号,由于是第六个实验,我们这里取0x0006。
//注意小端模式,低字节应该在前。
0x10,
0x10,
//bcdDevice字段。设备版本号,取1.0版,即0x0100。
//小端模式,低字节在先。
0x00,
0x01,
//iManufacturer字段。厂商字符串的索引值,为了方便**和管理,
//字符串索引就从1开始吧。
0x01,
//iProduct字段。产品字符串的索引值。刚刚用了1,这里就取2吧。
//注意字符串索引值不要使用相同的值。
0x02,
//iSerialNumber字段。设备的序列号字符串索引值。
//这里取3就可以了。
0x03,
//bNumConfigurations字段。该设备所具有的配置数。
//我们只需要一种配置就行了,因此该值设置为1。
0x01
  }
  ; /* CustomHID_DeviceDescriptor */


/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const u8 CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
  {
     /***************配置描述符***********************/
0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,
    /* wTotalLength: Bytes returned */
    0x00,
    0x01,         //bNumInterfaces字段。该配置包含的接口数,只有一个接口。
    0x01,         //bConfiguration字段。该配置的值为1。
    0x00,         //iConfigurationz字段,该配置的字符串索引。这里没有,为0。
    0xC0,         //bmAttributes字段,该设备的属性。/* bmAttributes: Bus powered */
    0x32,         //bMaxPower字段,该设备需要的最大电流量。/* MaxPower 100 mA: this current is used for detecting Vbus */

    /*******************接口描述符*********************/
    /* 09 */
    0x09,         /* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
    0x00,         //bInterfaceNumber字段。该接口的编号,第一个接口,编号为0。/* bInterfaceNumber: Number of Interface */
    0x00,         //bAlternateSetting字段。该接口的备用编号,为0。/* bAlternateSetting: Alternate setting */
    0x02,         //bNumEndpoints字段。非0端点的数目。本实例需要二个/* bNumEndpoints */
    0x03,         //bInterfaceClass字段。该接口所使用的类。本实例是HID类,//HID类的编码为0x03。
    0x00,         //bInterfaceSubClass字段。该接口所使用的子类。在HID1.1协议中,
  //只规定了一种子类:支持BIOS引导启动的子类。
  //USB键盘、鼠标属于该子类,子类代码为0x01。
  //但这里我们是自定义的HID设备,所以不使用子类。/* bInterfaceSubClass : 1=BOOT, 0=no boot */
    0x00,         //bInterfaceProtocol字段。如果子类为支持引导启动的子类,
  //则协议可选择鼠标和键盘。键盘代码为0x01,鼠标代码为0x02。
  //自定义的HID设备,也不使用协议。/* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
    0,            //iConfiguration字段。该接口的字符串索引值。这里没有,为0。/* iInterface: Index of string descriptor */
     /******************HID描述符************************/
    /* 18 */
    0x09,         /* bLength: HID Descriptor size */
    HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
    0x10,         //bcdHID字段。本协议使用的HID1.1协议。注意低字节在先。/* bcdHID: HID Class Spec release number */
    0x01,
    0x00,         //bCountyCode字段。设备适用的国家代码,/* bCountryCode: Hardware target country */
    0x01,          //bNumDescriptors字段。下级描述符的数目。我们只有一个报告描述符。/* bNumDescriptors: Number of HID class descriptors to follow */
    0x22,          //bDescritporType字段。下级描述符的类型,为报告描述符,编号为0x22。/* bDescriptorType */
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: 下级描述符的长度。下级描述符为报告描述符。Total length of Report descriptor */
    0x00,
     /**********************输入端点描述符***********************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

    0x81,          /*端点地址,b.7表示方向(1为in,0为out)b.0-b.3为端点标号 bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x10,          /*最大数据包大小*//* wMaxPacketSize: 16 Bytes max */
    0x00,
    0x20,          /* bInterval: Polling Interval (32 ms) */
    /* 34 */
     
    0x07, /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
/* Endpoint descriptor type */
    0x01, /* bEndpointAddress: */
/* Endpoint Address (OUT) */
    0x03, /* bmAttributes: Interrupt endpoint */
    0x10, /* wMaxPacketSize: 16 Bytes max  */
    0x00,
    0x20, /* bInterval: Polling Interval (20 ms) */
    /* 41 */
  }
  ; /* CustomHID_ConfigDescriptor */
const u8 CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{     
//每行开始的第一字节为该条目的前缀,前缀的格式为:
//D7~D4:bTag。D3~D2:bType;D1~D0:bSize。以下分别对每个条目注释。

//这是一个全局(bType为1)条目,将用途页选择为普通桌面Generic Desktop Page。
//后面跟1字节数据(bSize为1),后面的字节数就不注释了,自己根据bSize来判断。
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
//这是一个局部(bType为2)条目,用途选择为0x00。在普通桌面页中,
//该用途是未定义的,如果使用该用途来开集合,那么系统将不会把它
//当作标准系统设备,从而就成了一个用户自定义的HID设备。
0x09, 0x00, // USAGE (0)
//这是一个主条目(bType为0)条目,开集合,后面跟的数据0x01表示
//该集合是一个应用集合。它的性质在前面由用途页和用途定义为
//用户自定义。
0xa1, 0x01, // COLLECTION (Application)
//这是一个全局条目,说明逻辑值最小值为0。
0x15, 0x00, //     LOGICAL_MINIMUM (0)
//这是一个全局条目,说明逻辑值最大为255。
0x25, 0xff, //     LOGICAL_MAXIMUM (255)
//这是一个局部条目,说明用途的最小值为1。
0x19, 0x01, //     USAGE_MINIMUM (1)
//这是一个局部条目,说明用途的最大值8。
0x29, 0x08, //     USAGE_MAXIMUM (8)  
//这是一个全局条目,说明数据域的数量为八个。
0x95, 0x08, //     REPORT_COUNT (8)
//这是一个全局条目,说明每个数据域的长度为8bit,即1字节。
0x75, 0x08, //     REPORT_SIZE (8)
//这是一个主条目,说明有8个长度为8bit的数据域做为输入。
0x81, 0x02, //     INPUT (Data,Var,Abs)
//这是一个局部条目,说明用途的最小值为1。
0x19, 0x01, //     USAGE_MINIMUM (1)
//这是一个局部条目,说明用途的最大值8。
0x29, 0x08, //     USAGE_MAXIMUM (8)  
//这是一个主条目。定义输出数据(8字节,注意前面的全局条目)。
0x91, 0x02, //   OUTPUT (Data,Var,Abs)
//下面这个主条目用来关闭前面的集合。bSize为0,所以后面没数据。
0xc0        // END_COLLECTION
}; /* CustomHID_ReportDescriptor */

相关帖子

沙发
cy757|  楼主 | 2009-12-29 16:12 | 只看该作者
找到原因了,原来是STM32库中的Custom_HID例程中定义了几个外部中断不停地发送数据。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

103

主题

161

帖子

0

粉丝