zoukankan      html  css  js  c++  java
  • 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的理解参考以下博文:

     

     

     

  • 相关阅读:
    Hadoop 学习笔记 (十) hadoop2.2.0 生产环境部署 HDFS HA Federation 含Yarn部署
    hadoop 2.x 安装包目录结构分析
    词聚类
    Hadoop 学习笔记 (十一) MapReduce 求平均成绩
    Hadoop 学习笔记 (十) MapReduce实现排序 全局变量
    Hadoop 学习笔记 (九) hadoop2.2.0 生产环境部署 HDFS HA部署方法
    Visual Studio Code 快捷键大全(Windows)
    Eclipse安装教程 ——史上最详细安装Java &Python教程说明
    jquery操作select(取值,设置选中)
    $.ajax 中的contentType
  • 原文地址:https://www.cnblogs.com/linxw-blog/p/10499475.html
Copyright © 2011-2022 走看看