2.18. USB

Overview

提供 usb 应用示例、配置介绍和常见问题。

2.18.1. 应用实例

示例演示:

  • USB做masstorge主从机方法

  • USB做UAC主从机方法

  • USB做UVC主从机方法

  • USB做HID主从机方法

  • USB与PC通信

2.18.2. 公共配置说明

  • 1.在 apps/demo/demo_DevKitBoard/app_main.c 中增加USB任务名字如下
    /*任务列表 */
    const struct task_info task_info_table[] = {
        {"app_core",            15,     2048,     1024 },
        {"sys_event",           29,     512,       0 },
        {"systimer",            14,     256,       0 },
        {"sys_timer",            9,     512,      128 },
    #if CPU_CORE_NUM > 1
        {"#C0usb_msd",           1,      512,   128   },
    #else
        {"usb_msd",              1,      512,   128   },
    #endif
    
        {0, 0, 0, 0, 0},
    };
    

  • 2.在 apps/demo/demo_DevKitBoard/board/wl82/DevKitBoard.c 中增加USB配置如下

    #if TCFG_USB_SLAVE_ENABLE || TCFG_USB_HOST_ENABLE
    #include "otg.h"
    #include "usb_host.h"
    #include "usb_common_def.h"
    #include "usb_storage.h"
    #include "asm/uvc_device.h"
    #endif
    
    
    #if TCFG_USB_SLAVE_ENABLE || TCFG_USB_HOST_ENABLE
    static const struct otg_dev_data otg_data = {
        .usb_dev_en = 0x01, //USB口使能:0x1-->USB0;0x2-->USB1;0x3--->USB0和USB1
    #if TCFG_USB_SLAVE_ENABLE
        .slave_online_cnt = 10,//USB从机的上线检测次数,单位为detect_time_interval值
        .slave_offline_cnt = 10,//USB从机的下线检测次数,单位为detect_time_interval值
    #endif
    #if TCFG_USB_HOST_ENABLE
        .host_online_cnt = 10,//US主机的上线检测次数,单位为detect_time_jjjinterval值
        .host_offline_cnt = 10,//US主机的下线检测次数,单位为detect_time_interval值
    #endif
        .detect_mode = OTG_HOST_MODE | OTG_SLAVE_MODE | OTG_CHARGE_MODE,//检测模式:主机检测、从机检测、拔插充电检测。
        .detect_time_interval = 50,//检测上下线的时间间隔,单位ms,默认50ms(不建议修改变小,否则USB事件可能会丢,最低为10ms)。
    };
    #endif
    
    
    REGISTER_DEVICES(device_table) = {
    #if TCFG_USB_SLAVE_ENABLE || TCFG_USB_HOST_ENABLE
        { "otg", &usb_dev_ops, (void *)&otg_data},
    #endif
    
    };
    

    USB的拔插事件通知在 apps/common/system/device_mount.cdevice_event_handler 函数,当注册app状态机,则状态机事件处理也会有事件通知(详情 app_state_machine )。

2.18.3. 操作说明

  • 1.USB做masstorge从机方法 打开四个宏即可

    • 1.1 配置SD卡相关参考 SD例子

    • 1.2 app_config.h 修改配置, 注意:读卡器功能,同时需要打开SD卡功能并插SD卡,电脑端才能显示读卡器的U盘盘符。

      #define TCFG_SD0_ENABLE  1   //使能sd卡
      #define TCFG_PC_ENABLE  1     //使用从机模式
      #define USB_PC_NO_APP_MODE                  2 //不使用app_core
      #define USB_DEVICE_CLASS_CONFIG    (MASSSTORAGE_CLASS)   //msd
      

  • 2.USB做UAC从机方法

    • 2.1 配置AUDIO工程相关参考 demo_audio工程

    • 2.2 app_config.h 修改配置

      #define TCFG_PC_ENABLE  1     //使用从机模式
      #define USB_DEVICE_CLASS_CONFIG    (AUDIO_CLASS)   //audio
      #define CONFIG_PCM_ENC_ENABLE
      #define CONFIG_PCM_DEC_ENABLE
      
      #define CONFIG_AUDIO_ENC_SAMPLE_SOURCE      AUDIO_ENC_SAMPLE_SOURCE_MIC
      

    • 2.3 增加uac相关库

      audio_config.c | 用到了相关的api函数(get_ps_cal_api)

      usb_audio_api.c | usb和audio对接api函数

      audio_server.a | 音频编解码库

      lib_usb_syn.a | 用于变采样 专用于usb 不能用于其他地方

    • 2.4 在 board.c 初始化dac相关硬件

      void board_early_init()
         {
             extern void dac_early_init(u8 trim_en, u8 pwr_sel, u32 dly_msecs);
             dac_early_init(1, 1, 1000);
             devices_init();
         }
         \
      

    • 2.5 在 app_main.c 增加相关代码

      {"uac_sync",            20,      512,   0     },
      {"uac_play",             7,      768,   0     },
      {"uac_record",           7,      768,   32    },
      

  • 3.USB做UVC从机方法 (支持DVP摄像头数据到电脑)

    • 3.1 配置VIDEO工程相关参考 demo_video工程 ,先要移植摄像头并调试可以出图,电脑端才能有图像。

      //*********************************************************************************//
      //          USB配置    USB查看软件 请在sdk_tools文件夹中找到AMCapSetup.exe            //
      //*********************************************************************************//
      
      #define TCFG_PC_ENABLE                                              1    //打开usb从机功能(打开连接PC电脑模式)
      #if TCFG_PC_ENABLE
      #define USB_PC_NO_APP_MODE                                  2   //不用APP状态机接收消息
      #define USB_MALLOC_ENABLE                     1   //buff采用申请方式
      #define USB_DEVICE_CLASS_CONFIG (UVC_CLASS)     //从机UVC电脑查看功能选择
      //#define USB_DEVICE_CLASS_CONFIG (MASSSTORAGE_CLASS) //从机电脑盘符功能选择
      #if ((USB_DEVICE_CLASS_CONFIG & UVC_CLASS) == UVC_CLASS)
      #define CONFIG_USR_VIDEO_ENABLE
      #endif
      #endif
      

    • 3.2 增加uvc相关库

      stream_protocol.c | 实时流中间层

      user_video_rec.c | 打开实时流api

      video_rt_usr.c | 封装给stream_protocol

      gc0308.c | 摄像头驱动,根据实际摄像头选择驱动

    1. USB做HID从机方法(演示做键盘的方法)

    • 4.1 在 apps/demo/demo_DevKitBoard/include/demo_config.h ,开启宏 USE_USB_HID_SLAVE_TEST_DEMO

    • 4.2 增加 hid_keyboard.c

    • 4.3 在 app_config.h 修改宏和选择增加枚举键盘还是pos机,pos机流程一样,具体可以参考 apps/scan_box/app_main.c

      #define USB_DEVICE_CLASS_CONFIG    (HID_CLASS)
      
      #if TCFG_USB_SLAVE_HID_ENABLE
      #define USB_HID_KEYBOARD_ENABLE             1
      

    1. USB做主机读U盘

    • 5.1 在 board.c 增加配置

      { "udisk", &mass_storage_ops, NULL },
      
    • 5.2 在 app_config.h 打开宏

       #define TCFG_UDISK_ENABLE                   1    //U盘功能
      // #define USB_DEVICE_CLASS_CONFIG                (AUDIO_CLASS)
      

    • 5.3 在 apps/demo/demo_DevKitBoard/include/demo_config.h ,开启宏 USE_USB_UDISK_HOST_TEST_DEMO

    1. USB做UVC主机(设备USB口接上UVC摄像头)

    • 6.1 在 app_config.h 打开宏

      #define TCFG_HOST_UVC_ENABLE                 1   //打开USB 后拉摄像头功能,需要使能住机模式
      

    • 6.2 查看USB摄像头方法:

      A:设备连接后,打开电脑自带的相机出图。下面三种方法是跑 wifi_camera 工程时的方法。

      B:使用DVrunning2的APP可以直接连接wifi热点出图。

      C:使用 wifi_camerademo_ui ,则开启UI,打开UI宏:codeblock的工程编译选项(build options)的#define选项加上CONFIG_UI_ENABLE,可以显示到屏幕(或者linux环境下的makefile加上UI宏CONFIG_UI_ENABLE)。

      D: 在 apps\wifi_camera\app_main.c 开启插卡录像功能,如下代码块。插USB UVC摄像头后,再插SD卡就可以开启录像功能,在录像一个文件结束(默认3分钟)就可以拔出SD卡来插卡查看UVC录像视频。

    1. USB做HID主机方法(演示做键盘的方法)

    • 7.1 在 app_config.h 修改宏 ,开启宏 #define TCFG_HID_HOST_ENABLE

      #ifdef CONFIG_USB_ENABLE
      #define TCFG_PC_ENABLE                          0   //使用从机模式
      #define USB_PC_NO_APP_MODE                      2   //不使用app_core
      #define USB_MALLOC_ENABLE                       1
      #define USB_DEVICE_CLASS_CONFIG                 (HID_CLASS)
      #define TCFG_HOST_AUDIO_ENABLE                  0
      #define TCFG_HOST_UVC_ENABLE                    0   //打开USB 后拉摄像头功能,需要使能住机模式
      #define TCFG_HID_HOST_ENABLE                                1     //HID主机功能
      #define TCFG_UDISK_ENABLE                       0   //U盘功能
      

    1. USB做UAC主机方法,具体代码参考 uac_host_demo.c ,跑 wifi_story_machine 工程

    • 8.1 在 board_config.h 修改宏

      #ifdef CONFIG_USB_ENABLE
      #define TCFG_PC_ENABLE                      0   //使用从机模式
      #define TCFG_HOST_AUDIO_ENABLE              1     //uac主机功能,用户需要自己补充uac_host_demo.c里面的两个函数
      

2.18.4. USB摄像头使用说明(UVC)

    1. 例如:使用工程 wifi_camera 进行编译测试 。

    1. 配置芯片使用SROM 即 去掉 CONFIG_NO_SDRAM_ENABLE宏 一般在全局宏配置。

    1. app_config.h 中将CONFIG_UVC_VIDEO2_ENABLE宏开启。

    1. video_buf_config.h 中改大NET_VREC0_FBUF_SIZE宏大小。

    1. 将CONFIG_VIDEO_REC_PPBUF_MODE宏进行屏蔽 屏蔽默认使用LBUF 即帧buf。

    1. 有关帧数使用规格640*480 25fps(USB摄像头) wifi图传20fps。

    1. 当想要使用UI显示UVC摄像头时候需要提前确认好屏幕驱动已经调好能正常显示,然后将CONFIG_UI_ENABLE宏开启 并且在 app_config.h 中将TCFG_DEMO_UI_RUN, NO_UI_LCD_TEST 均配置为 1。(其他工程暂不支持)

    1. 支持屏幕和UVC同时显示摄像头内容。

2.18.5. USB与PC通信

列举了两种USB与PC端通信协议的使用方式,SCSI协议与CDC协议,可参考应用于PC端的上位机开发。

  • 1.USB SCSI协议的使用

    • 1.USB配置。SCSI协议一般用于U盘、读卡器等大容量存储设备。在SDK中,将USB配置成从机模式,并配置设备类型为存储设备;在 app_config.h 文件中进行配置,如下:

      #define TCFG_PC_ENABLE          1    //打开usb从机功能(打开连接PC电脑模式)
      
      #define USB_DEVICE_CLASS_CONFIG (MASSSTORAGE_CLASS) //从机电脑盘符功能选择
      

    • 2.SCSI协议数据处理。在 include_lib/driver/device/usb/scsi.h 文件中,添加自定义的SCSI协议的操作码,注意不能和现有的操作码重复,如下:

      #define MY_TEST_OPCODE        0x7d
      

    • 3.在 apps/common/usb/device/msd.c 文件中,添加SCSI协议数据的处理函数,如下:

      enum {
        TEST_CMD_0,
        TEST_CMD_1,
        };
      void test_cmd_deal(const struct usb_device_t *usb_device)
      {
        u8 len;
        u8 buf[32];
      
        switch (msd_handle[usb_id]->cbw.lun) {
            case TEST_CMD_0:
                printf("^^^TEST_CMD_0\n");
                //返回数据至USB主机
                memset(buf, 0xaa, sizeof(buf));
                msd_mcu2usb(usb_device, buf, sizeof(buf));
                break;
            case TEST_CMD_1:
                printf("^^^TEST_CMD_1\n");
                //接收USB主机发送的数据
                len = msd_handle[usb_id]->cbw.LengthL;
                msd_usb2mcu(usb_device, buf, len);
                put_buf(buf, sizeof(buf));
                break;
            default:
                printf("^^^no support cmd\n");
                break;
        }
      }
      
      void USB_MassStorage(const struct usb_device_t *usb_device)
      {
        //......
        switch (msd_handle[usb_id]->cbw.operationCode) {
            //......
            case MY_TEST_OPCODE:  //自定义的操作码处理
                test_cmd_deal(usb_device);
                break;
            //......
        }
      }
      

    • 4.数据收发测试。可使用USB调试助手,向USB从机发送SCSI命令进行测试,如下:

  • 2.USB CDC协议的使用

    • 1.USB配置。CDC协议将USB设备枚举为虚拟串口,PC端通过串口协议与USB从机进行通信。在SDK中,将USB配置成从机模式,并配置设备类型为CDC类设备;在 app_config.h 文件中进行配置,如下:

        //3.从机连接PC模式下:电脑盘符功能、UVC功能
      #define TCFG_PC_ENABLE                1    //打开usb从机功能(打开连接PC电脑模式)
      #if TCFG_PC_ENABLE
      ...
      #define USB_DEVICE_CLASS_CONFIG (CDC_CLASS) //从机电脑盘符功能选择
      #endif
      

    • 2.CDC协议数据处理。在 apps/common/usb/device/cdc.c 中,添加自定义的CDC协议数据处理函数,如下:

      s32 usb_cdc_output_handler(void *priv, u8 *buf, u32 len)
      {
      //将收到的数据打印
      printf("len = %d, buf = %s\n", len, buf);
      
      //将收到的数据发送至终端
      u32 ret = cdc_write_data(0, buf, len);
      printf("tx_ret = %d\n", ret);
      return 0;
      }
      
      void cdc_register(const usb_dev usb_id)
      {
        //......
      cdc_set_output_handle(0,NULL, usb_cdc_output_handler);//注册数据处理函数
      return;
      __exit_err:
      //......
      }
      

    * 3.数据收发测试。可通过串口调试助手进行收发测试,如下:

2.18.6. 常见问题

1. 宏TCFG_PC_ENABLE,是USB从机功能总包起来的宏,具体的定义可以进入 apps/common/usb/usb_std_class_def.happs/common/usb/usb_common_def.h``中查看。 如需移植usb从机功能时,需包含 ``usb_std_class_def.husb_common_def.h 这两个文件。 2. 需要移植usb功能时,需要添加 ``apps/common/system/device_mount.c``文件。