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}, };
- 1.在
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.c
的device_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
- 1.2
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.2
- 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.4 在
- 2.5 在
app_main.c
增加相关代码 {"uac_sync", 20, 512, 0 }, {"uac_play", 7, 768, 0 }, {"uac_record", 7, 768, 32 },
- 2.5 在
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 | 摄像头驱动,根据实际摄像头选择驱动
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
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.2 在
5.3 在
apps/demo/demo_DevKitBoard/include/demo_config.h
,开启宏USE_USB_UDISK_HOST_TEST_DEMO
。
USB做UVC主机(设备USB口接上UVC摄像头)
- 6.1 在
app_config.h
打开宏 -
#define TCFG_HOST_UVC_ENABLE 1 //打开USB 后拉摄像头功能,需要使能住机模式
- 6.1 在
6.2 查看USB摄像头方法:
A:设备连接后,打开电脑自带的相机出图。下面三种方法是跑
wifi_camera
工程时的方法。B:使用DVrunning2的APP可以直接连接wifi热点出图。
C:使用
wifi_camera
下demo_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录像视频。
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盘功能
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)
例如:使用工程
wifi_camera
进行编译测试 。
配置芯片使用SROM 即 去掉 CONFIG_NO_SDRAM_ENABLE宏 一般在全局宏配置。
在
app_config.h
中将CONFIG_UVC_VIDEO2_ENABLE宏开启。
在
video_buf_config.h
中改大NET_VREC0_FBUF_SIZE宏大小。
将CONFIG_VIDEO_REC_PPBUF_MODE宏进行屏蔽 屏蔽默认使用LBUF 即帧buf。
有关帧数使用规格640*480 25fps(USB摄像头) wifi图传20fps。
当想要使用UI显示UVC摄像头时候需要提前确认好屏幕驱动已经调好能正常显示,然后将CONFIG_UI_ENABLE宏开启 并且在
app_config.h
中将TCFG_DEMO_UI_RUN, NO_UI_LCD_TEST 均配置为 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.h
和 apps/common/usb/usb_common_def.h``中查看。
如需移植usb从机功能时,需包含 ``usb_std_class_def.h
和 usb_common_def.h
这两个文件。
2. 需要移植usb功能时,需要添加 ``apps/common/system/device_mount.c``文件。