• 2--STM32+USB移植+HID 与AUDIO类MIDI设备组成的复合设备(原创)


     

    前期准备:

    一、硬件资源:STM32F103,USB-FS固件库。

    链接:

    STM32 之 标准外设版USB驱动库详解(架构+文件+函数+使用说明+示例程序)

    https://blog.csdn.net/ZCShouCSDN/article/details/78936456?utm_source=blogxgwz1

    二、调试软件:usbtrace3.0或者BusHound,用于看USB设备的信息。KEIL编译环境-用于开发。

    后续相关工作:

    (1)用STM32CubeMX配置,具体实现其它的HID,自定义虚拟串口等实验;

    链接:利用STM32CubeMX生成BID通信

    https://www.cnblogs.com/libra13179/p/6891685.html?utm_source=itdadao&utm_medium=referral

    (2)了解USB的枚举配置过程。

    链接:https://blog.csdn.net/huohongpeng/article/details/54927337

     

    三、重点掌握的知识点:

    (1)USB设备描述符,

    (2)STM32F103的USB-FS固件库相关架构;

    (3)USB的数据发送与接收,即通信原理;

    本次USB做成复合设备,HID+AUDIO_MIDI设备,HID与上位机通信,MIDI设备与主流音乐DAW软件通信

    (4)调试USB数据包的过程;

    (5)移植步骤:

    --配置好相关的KEIL工程,或者STM32CubeMX配置;

    --添加USB固件库里面的HID工程-参考正点原子的STM32F1开发指南-库函数版本_V3.1;

    --修改相应的usb描述符,VID/PID等,可以添加原子自己的USB启动通用函数;

    (6)技术参考以下博文:

    1-STM32 USB 之从0开始移植笔记https://blog.csdn.net/gzzxbcxm2005/article/details/51347624

    2-从头调试STM32 HID http://www.cnblogs.com/sz189981/p/7291121.html

    3-移植STM32固件库用于HID双向通信https://blog.csdn.net/a827415225/article/details/51745013

    调试中期:

    一、移植好修改配置描述符后插入PC端,显示HID-人体学输入设备与USB输入设备,AUDIO设备也增加了一个

    图一:

    ​图二:

    BUS Hound 软件捕捉到的信息:

    至此,产品已经能正确的MIDI通信,至于HID上位机通信,后面将补充代码

    二、程序解析

    (1)USB数据包的发送与接收;

    --USB数据的发送与接收流程分析https://www.cnblogs.com/skl374199080/p/3910066.html

    自己重写的MIDI发送代码:

    uint32_t USB_SendData(uint8_t *data,uint32_t dataNum)
    {
    //    #ifndef STM32F10X_MD           //¸Ä±äÈ«¾Ö¶¨Òå
        //½«Êý¾Ýͨ¹ýUSB·¢ËͳöÈ¥-----------by EP2¶Ëµã·¢ËÍTX
        UserToPMABufferCopy(data, ENDP4_TXADDR, dataNum);
        SetEPTxCount(ENDP4, 8);
        SetEPTxValid(ENDP4); //ʹÄÜ
    //    #else
    //    USB_SIL_Write(EP4_IN, data, dataNum);
    //    SetEPTxValid(ENDP4);
    //    #endif
        //return dataNum;  
    }
    uint32_t USB_GetData(uint8_t *data,uint32_t dataNum)
    {
        uint32_t len=0;
        if(dataNum>sizeof(USB_Receive_Buffer))
        {
            dataNum = sizeof(USB_Receive_Buffer);
        }
        for(len=0;len<dataNum;len++)
        {
            *data=USB_Receive_Buffer[len];
            data++;
        }
        return dataNum;            //·µ»Ø
    }

    (2)主要的USB描述符--HID+AUDIO_MIDI设备

    /* USB Standard Device Descriptor */
    const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] =
      {
        0x12,                       /*bLength */
        USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
        0x10,                       /*bcdUSB 1.0*/
        0x01,
        0x00,                       /*bDeviceClass*/
        0x00,                       /*bDeviceSubClass*/
        0x00,                       /*bDeviceProtocol*/
        0x40,                       /*bMaxPacketSize 64 bytes*/       //ÕâÀïµÄsize»áÔì³ÉÉ豸ÇëÇóÃèÊö·ûʧ°Ü
    /************** ÉèÖÃVID and PID ****************/      
        0x11,                       /*idVendor (0x0483)*/
        0x20,
        0x15,                       /*idProduct = 0x5750*/
        0x07,
          
        0x00,                       /*bcdDevice rel. 2.00*/
        0x00,
        1,                          /*Index of string descriptor describing
                                                  manufacturer */
        2,                          /*Index of string descriptor describing
                                                 product*/
        3,                          /*Index of string descriptor describing the
                                                 device serial number */
        0x01                        /*bNumConfigurations*/
      };
      /* CustomHID_DeviceDescriptor */
      
    /* USB Configuration Descriptor */
    /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
    const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
      {
    /************** Descriptor of standard audio +HID Configuration ****************///ÅäÖÃÃèÊö·û
        0x09,         /* bLength: Configuration Descriptor size */
        USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
        0x85,                                                     //Õâ¸ö³¤¶ÈÐèҪȷ¶¨ÏÂ133
        /* wTotalLength: Bytes returned */
        0x00,
        0x03,         /* bNumInterfaces: 1 HID interface +MIDI 2 interface 03*/
        0x01,         /* bConfigurationValue: Configuration value */
        0x00,         /* iConfiguration: Index of string descriptor describingthe configuration*/
        0x00,         /* bmAttributes: Self powered */
        0xFA,         /* MaxPower 0xFA:500 mA */
    
    /************** Descriptor of µÚÒ»¸ö HID ½Ó¿ÚÃèÊö·û ****************/
          
        /* Interface Descriptor 0/0 HID, 2 Endpoints */
        0x09,         /* bLength: Interface Descriptor size */
        USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
        0x00,         /* bInterfaceNumber: Number of Interface */                                   //¸Ã½Ó¿ÚµÄ±àºÅ0
        0x00,         /* bAlternateSetting: Alternate setting */                                         //±¸ÓñàºÅ
        0x02,         /* bNumEndpoints */                                                            //¶ËµãÊýÁ¿2£¬ÖжÏÊäÈëºÍÊä³ö
        0x03,         /* bInterfaceClass: HID */
        0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
        0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */           //ʹÓõÄЭÒé
        0x00,            /* iInterface: Index of string descriptor */             //¸Ã½Ó¿ÚµÄ×Ö·û´®Ë÷ÒýºÅ0ûÓÐ×Ö·û´®
        
        /******************** Descriptor of  HID ÃèÊö·û ********************/
        0x09,         /* bLength: HID Descriptor size */
        HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID *///0x21
        0x11,         /* bcdHID: HID Class Spec release number *///HID 1.1ЭÒé
        0x01,
        0x00,         /* bCountryCode: Hardware target country */
        0x01,         /* bNumDescriptors: Number of HID class descriptors to follow *///ϼ¶ÃèÊö·ûÊýÁ¿-±¨¸æÃèÊö·û
        0x22,         /* bDescriptorType */ //ϼ¶ÃèÊö·ûÀàÐÍΪ±¨¸æÃèÊö·û£¬±àºÅ0x22
        /* wItemLength: Total length of Report descriptor */
        CUSTOMHID_SIZ_REPORT_DESC,              //±¨¸æÃèÊö·ûµÄ´óС
        0x00,
        
         /******************** Descriptor of Custom HID endpoints ¶ËµãÃèÊö·û******************/
        /* Endpoint Descriptor 81 1 In, Interrupt, 1 ms */       //ÊäÈë¶Ëµã
        0x07,          /* bLength: Endpoint Descriptor size */
        USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
        /*    Endpoint descriptor type */
        0x81,          /* bEndpointAddress: Endpoint Address (IN) */                //  1  IN Endpoint
        0x03,          /* bmAttributes: Interrupt endpoint */                         //Ñ¡ÔñΪÖж϶˵ã
        0x20,          /* wMaxPacketSize: 32 Bytes max */                       //µÍ×Ö½ÚÔÚÇ°
        0x00,
        0x01,          /* bInterval: Polling Interval (1 ms) */                 //¶Ëµã²éѯʱ¼ä
        
        /* Endpoint Descriptor 02 2 Out, Interrupt, 1 ms*/           
        0x07,    /* bLength: Endpoint Descriptor size */
        USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType: */
        /*    Endpoint descriptor type */
        0x02,    /* bEndpointAddress: */
                    /*    Endpoint Address (OUT) */                             
        0x03,    /* bmAttributes: Interrupt endpoint */
        0x20,    /* wMaxPacketSize: 32 Bytes max */                       //µÍ×Ö½ÚÔÚÇ°
        0x00,
        0x01,          /* bInterval: Polling Interval (1 ms) */                 //¶Ëµã²éѯʱ¼ä
      
    /************** Descriptor of µÚ¶þ¸ö MIDI AUDIO ½Ó¿ÚÃèÊö·û ****************/ 
       /* Interface Descriptor 1/0 Audio, 0 Endpoints */              //ûÓÐ¶Ëµã          
        0x09,         /*bLength: Interface Descriptor size*/
        0x04,         /*bDescriptorType: Interface descriptor type*/
        0x01,         /*bInterfaceNumber: Number of Interface*/  //½Ó¿Ú±àºÅ01
        0x00,         /*bAlternateSetting: Alternate setting*/
        0x00,         /*bNumEndpoints: no endpoints*/
        0x01,         /*bInterfaceClass: Audio device class 0x01*/
        0x01,         /*bInterfaceSubClass : Audio control*/
        0x00,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
        0x00,         /*iInterface: Index of string descriptor*/
    
        /* Audio Control Interface Header Descriptor  */ 
        //class_specific_interface_descritor        //ÀàÌØÊâ½Ó¿ÚÃèÊö·û£ºÀàÌØÊâÒôƵ¿ØÖƽӿÚ
        0x09,                           //ÀàÌØÊâ½Ó¿ÚÃèÊö·ûµÄ×Ö½ÚÊý´óС
        0x24,                           //ÀàÌØÊâ½Ó¿ÚÃèÊö·ûÀàÐͱàºÅ
        0x01,                           //ÃèÊö·û×ÓÀà
        0x00,
        0x01,                           //×ÓÀà°æ±¾£¬1.0
        0x09,
        0x00,                           //ÀàÌØÊâÃèÊö´óС
        0x01,                           //Á÷½Ó¿ÚÊýÁ¿         
        0x02,                           //MIDI Á÷½Ó¿Ú1ÊôÓÚ´ËÒôƵ¿ØÖƽӿÚ
    
      /* Interface Descriptor 2/0 Audio, 2 Endpoints */   //Á½¸ö¶Ëµã
        //Standard MS Interface Descriptor£¬Ê¹ÓÃÁ½¸öÅúÁ¿¶ËµãÀ´·Ö±ðÊä³öºÍÊäÈëMIDIÊý¾ÝÁ÷---µÚ¶þ¸ö½Ó¿Ú
        0x09,                           //bLength½Ó¿ÚÃèÊö·ûµÄ×Ö½ÚÊý´óС
        0x04,                           //bDescriptorType½Ó¿ÚÃèÊö·ûÀàÐͱàºÅ  
        0x02,                           //bInterfaceNumber½Ó¿Ú±àºÅΪ02
        0x00,                           //bAlternateSetting±¸ÓñàºÅΪ0
        0x02,                           //bNumEndpoints·Ç0¶ËµãÊýÁ¿Îª2 bNumEndpoints,Ò»¶ÔÅúÁ¿¶Ëµã
        0x01,                           //bInterfaceClassÒôƵÉ豸£¨AUDIO£©Àà0x01 bInterfaceSubClass0x03
        0x03,                           //ʹÓõÄ×ÓÀࣺMIDIÁ÷(MIDI STREAMING)Àà                                   
        0x00,                           //δÓÃbInterfaceProtocol
        0x00,                           //δÓÃbInterfaceProtocol
        
    /************** ÀàÌØÊâMIDIÁ÷½Ó¿ÚÃèÊö·û----ÖصãÅäÖÃ**************************************/
    /*ÀàÌØÊâMIDIÁ÷ÃèÊöÉ豸ÄÚ¸÷¸öÄ£¿éµÄÁ¬½Ó¹Øϵ£¬ÓÐËÄÖÖ²å¿×£ºÄÚǶÊäÈ룬ÄÚǶÊä³ö£¬ÍⲿÊäÈ룬ÍⲿÊä³ö£¨·½ÏòÏà¶ÔÓÚÉ豸£©
    ÿ¸ö²å¿×¶¼Î¨Ò»µÄID±àºÅ£¬
    É豸µÄÊý¾Ýͨ¹ýÄÚǶÊä³ö²å¿×Êä³öµ½¼ÆËã»ú£¬²»ÊÇÖ±½Óµ½PC,¶øÊÇͨ¹ýÐéÄâÍⲿÊäÈë²å¿×Á¬½Ó
    
    */      
        /* MIDI Streaming Interface Header Descriptor */     
        0x07,                          //ÀàÌØÊâMS½Ó¿ÚÍ·ÃèÊö·ûµÄ×Ö½ÚÊý´óС----Í·ÃèÊö·û
        0x24,                          //ÀàÌØÊâ½Ó¿ÚÃèÊö·ûÀàÐͱàºÅ0x24
        0x01,                          //ÃèÊö·û×ÓÀà
        0x00,
        0x01,                          //×ÓÀà°æ±¾£¬1.0
        0x41,
        0x00,                          //ÀàÌØÊâÃèÊö×ܳ¤¶È0x0041
         
        //MIDI IN Jack Descriptor(Embedded)                              ÄÚǶIN½Ó¿Ú
        0x06,                          //MIDIÊäÈë²å¿×ÃèÊö·û
        0x24,                          //ÀàÌØÊâ½Ó¿Ú
        0x02,                          //MIDI_IN_JACK×ÓÀà0x02
        0x01,                          //EMBEDDED²å¿×Àà
        0x01,                          //¸Ã²å¿ÚµÄID-------------------1
        0x00,                          //δÓÃ
       
        //MIDI IN Jack Descriptor (External)                             ÍⲿIN½Ó¿Ú
        0x06,                          //MIDIÊäÈë²å¿×ÃèÊö·û
        0x24,                          //ÀàÌØÊâ½Ó¿Ú
        0x02,                          //MIDI_IN_JACK×ÓÀà
        0x02,                          //EXTERNAL²å¿×Àà
        0x02,                          //¸Ã²å¿ÚµÄID-------------------2
        0x00,                          //δÓÃ
       
        //MIDI OUT Jack Descriptor                                       ÄÚǶOUT½Ó¿Ú
        0x09,                          //MIDIÊäÈë²å¿×ÃèÊö·û
        0x24,                          //ÀàÌØÊâ½Ó¿Ú
        0x03,                          //MIDI_OUT_JACK×ÓÀà
        0x01,                          //EMBEDDED²å¿×Àà
        0x03,                          //¸Ã²å¿ÚµÄID------------------3
        0x01,                          //¸Ã²å¿ÚµÄÊäÈëÒý½ÅÊý
        0x02,                          //Á¬½Ó¸ÃÒý½ÅËùÔÚʵÌåµÄID-----ÍⲿIN²å¿×---ÐéÄâÁ¬½ÓÆðÀ´
        0x01,                          //Á¬½Óµ½¸ÃʵÌåÊä³ö½ÅµÄÊäÈë½ÅµÄ±àºÅ
        0x00,                          //δÓÃ
       
        //MIDI OUT Jack Descriptor (External)                             ÍⲿOUT½Ó¿Ú
        0x09,                          //MIDIÊäÈë²å¿×ÃèÊö·û
        0x24,                          //ÀàÌØÊâ½Ó¿Ú
        0x03,                          //MIDI_OUT_JACK×ÓÀà
        0x02,                          //EXTERNAL²å¿×Àà
        0x04,                          //¸Ã²å¿ÚµÄID------------------4
        0x01,                          //¸Ã²å¿ÚµÄÊäÈëÒý½ÅÊý
        0x01,                          //¸ÃÒý½ÅËùÔÚʵÌåµÄID--------ÄÚǶÊäÈë²å¿×
        0x01,                          //Á¬½Óµ½¸ÃʵÌåÊä³ö½ÅµÄÊäÈë½ÅµÄ±àºÅ
        0x00,    
    
    /***************************¶ËµãÃèÊö·ûºÍÀàÌØÊâ¶ËµãÃèÊö·û£¨MS£©*********************
    ÿ¸ö±ê×¼µÄÅúÁ¿Êý¾Ý¶ËµãÃèÊö·ûºóÃæ¸ú×ÅÒ»¸öÀàÌØÊâÊý¾Ý¶ËµãÃèÊö·û*********************/
        /* Endpoint Descriptor 03 3 Out, Bulk, 64 bytes */
        0x09,                          //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
        0x05,                          //¶ËµãÃèÊö·ûÀàÐͱàºÅ
        0x03,                          //3 out bEndpointAddress
        0x02,                          //ʹÓõĴ«ÊäÀàÐÍ£ºÅúÁ¿´«ÊäBULK
        0x40,                          //¸Ã¶ËµãÖ§³ÖµÄ×î´ó°ü³ß´ç£¬64×Ö½Ú
        0x00,                           
        0x00,                          //ÖжÏɨÃèʱ¼ä£¬ÎÞЧ//bInterval                         
        0x00,                          //bRefresh
        0x00,                          //bSynchAddress
        
        /* Unrecognized Audio Class-Specific Descriptor  */ 
        0x05,                          //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
        0x25,                          //Unrecognized Audio Class-Specific
        0x01,                           
        0x01,                           
        0x01,                           
        
        /* Endpoint Descriptor 84 4 In, Bulk, 64 bytes */                                          
        0x09,                          //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
        0x05,                          //¶ËµãÃèÊö·ûÀàÐͱàºÅ
        0x84,                          //4 IN bEndpointAddress
        0x02,                          //ʹÓõĴ«ÊäÀàÐÍ£ºÅúÁ¿´«ÊäBULK
        0x40,                          //¸Ã¶ËµãÖ§³ÖµÄ×î´ó°ü³ß´ç£¬64×Ö½Ú
        0x00,                          
        0x00,                          //ÖжÏɨÃèʱ¼ä£¬ÎÞЧ0x0A//bInterval
        0x00,                          //bRefresh
        0x00,                          //bSynchAddress
        
        /* Unrecognized Audio Class-Specific Descriptor  */     
        0x05,                          //¶ËµãÃèÊö·ûµÄ×Ö½ÚÊý´óС
        0x25,                          //Unrecognized Audio Class-Specific
        0x01,                           
        0x01,                           
        0x03       
      
      };

    (3)其中的4个端点地址的设置需要研究下,

    链接:

    stm32 usb数据缓冲区疑问

     http://blog.sina.com.cn/s/blog_640029b30100vwfp.html

    #define BTABLE_ADDRESS      (0x00)
    /* EP0  */
    /* rx/tx buffer base address */
    //#define ENDP0_RXADDR        (0x18)
    //#define ENDP0_TXADDR        (0x58)
    #define ENDP0_RXADDR           (0x40)    
    #define ENDP0_TXADDR           (0x80)    
    
    /* EP1  */
    /* tx buffer base address */
    #define ENDP1_TXADDR        (0xC0)   //ENDP0_TXADDR+0x40¿ªÊ¼
    //#define ENDP1_RXADDR        (0x130+0x40)
    
    /* EP2 */
    /* rx buffer base address */
    #define ENDP2_RXADDR        (0xE0)
    //#define ENDP2_TXADDR        (0x170+0x40)
    
    /* EP3  RX*/
    /* tx buffer base address */
    //#define ENDP3_TXADDR        (0x210)
    #define ENDP3_RXADDR        (0x100)
    
    /* EP4  TX*/
    /* tx buffer base address */
    #define ENDP4_TXADDR        (0x100+0x40)
    //#define ENDP4_RXADDR        (0x250+0x40)

     (4)对于USB HID的理解参考以下博文:

     

     

     

  • 相关阅读:
    生物学上描述DNA/RNA的长度常用的kb、nt、bp是指什么
    置换检验代码, matlab codes for permutation tests
    MATLAB命令大全——以字母顺序进行分类
    2011年春季C语言课程设计指导书
    C/C++语言课程设计任务书
    hibernate 自动生成数据库表
    利用Tomcat的用户名和密码构建“永久”后门
    flex成品作不知道有哪位大神能看懂是干嘛的
    wikioi1014 装箱问题
    怎样把USB键盘接到Android手机上
  • 原文地址:https://www.cnblogs.com/linxw-blog/p/10499475.html
Copyright © 2020-2023  润新知