VSF模块文档--USBD.应用层

[复制链接]
1283|0
 楼主| vsf 发表于 2018-4-9 19:17 | 显示全部楼层 |阅读模式
本帖最后由 vsf 于 2018-4-9 19:36 编辑

1. 数据结构
  1. struct vsfusbd_iface_t
  2. {
  3.         // public
  4.         struct vsfusbd_class_protocol_t *class_protocol;
  5.         void *protocol_param;

  6.         // private
  7.         ......
  8. };

  9. struct vsfusbd_config_t
  10. {
  11.         // public
  12.         vsf_err_t (*init)(struct vsfusbd_device_t *device);
  13.         vsf_err_t (*fini)(struct vsfusbd_device_t *device);

  14.         uint8_t num_of_ifaces;
  15.         struct vsfusbd_iface_t *iface;

  16.         // private
  17.         ......
  18. };

  19. struct vsfusbd_device_t
  20. {
  21.         // public
  22.         uint8_t num_of_configuration;
  23.         struct vsfusbd_config_t *config;
  24.         struct vsfusbd_desc_filter_t *desc_filter;
  25.         uint8_t device_class_iface;
  26.         struct vsfhal_usbd_t *drv;
  27.         int32_t int_priority;
  28.         void (*on_EVENT)(struct vsfusbd_device_t *device,
  29.                         enum vsfusbd_usr_evt_t evt, void *param);

  30.         // private
  31.         ......
  32. };
VSF种的USB设备端协议栈,基本只需要按照需要,定义好数据结构,然后配合简单的代码就可以实现功能。
其中,最主要的就是定义vsfusbd_device_t结构,表明是实现什么USB设备,以及相应的设备参数。

struct vsfusbd_device_t:
1. uint8_t num_of_configuration:USB设备的配置数量,一般为1
2. struct vsfusbd_config_t *config:USB设备的配置数组指针
3. struct vsfusbd_desc_filter_t *desc_filter:设备的描述符列表
4. uint8_t device_class_iface:设备默认的设备类型对应的接口
5. struct vsfhal_usbd_t *drv和int32_t int_priority:底层USB驱动接口和中断优先级
6. void (*on_EVENT)(......):事件回调接口,一般设置为NULL

栗子:
  1. .usbd.device.num_of_configuration                = dimof(usrapp.usbd.config),
  2. .usbd.device.config                                                = usrapp.usbd.config,
  3. .usbd.device.desc_filter                                = (struct vsfusbd_desc_filter_t *)usrapp_param.usbd.StdDesc,
  4. .usbd.device.device_class_iface                        = 0,
  5. .usbd.device.drv                                                = (struct vsfhal_usbd_t *)&vsfhal_usbd,
  6. .usbd.device.int_priority                                = 0xFF,


struct vsfusbd_config_t:
1. init和fini:配置初始化和终止化接口,一般设置为NULL
2. uint8_t num_of_ifaces:接口数量
3. struct vsfusbd_iface_t *iface:接口数组指针

栗子:
  1. .usbd.config[0].num_of_ifaces                        = dimof(usrapp.usbd.ifaces),
  2. .usbd.config[0].iface                                        = usrapp.usbd.ifaces,


struct vsfusbd_iface_t:
1. struct vsfusbd_class_protocol_t *class_protocol:接口类驱动
2. void *protocol_param:接口类参数

栗子:
  1. .usbd.ifaces[0].class_protocol                        = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMControl_class,
  2. .usbd.ifaces[0].protocol_param                        = &usrapp.usbd.cdc.param,
  3. .usbd.ifaces[1].class_protocol                        = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMData_class,
  4. .usbd.ifaces[1].protocol_param                        = &usrapp.usbd.cdc.param,
对于USB CDC(USB转串口),需要实现2个接口,一个是CDCACM控制接口(vsfusbd_CDCACMControl_class),一个是CDCACM数据接口(vsfusbd_CDCACMData_class)。当然,还需要应用程序设置要usrapp.usbd.cdc.param的数据结构。

描述符列表栗子:
  1. .usbd.StdDesc =
  2. {
  3.         VSFUSBD_DESC_DEVICE(0, usrapp_param.usbd.DeviceDescriptor, sizeof(usrapp_param.usbd.DeviceDescriptor)),
  4.         VSFUSBD_DESC_CONFIG(0, 0, usrapp_param.usbd.ConfigDescriptor, sizeof(usrapp_param.usbd.ConfigDescriptor)),
  5.         VSFUSBD_DESC_STRING(0, 0, usrapp_param.usbd.StringLangID, sizeof(usrapp_param.usbd.StringLangID)),
  6.         VSFUSBD_DESC_STRING(0x0409, 1, usrapp_param.usbd.StringVendor, sizeof(usrapp_param.usbd.StringVendor)),
  7.         VSFUSBD_DESC_STRING(0x0409, 2, usrapp_param.usbd.StringProduct, sizeof(usrapp_param.usbd.StringProduct)),
  8.         VSFUSBD_DESC_STRING(0x0409, 4, usrapp_param.usbd.StringFunc_CDC, sizeof(usrapp_param.usbd.StringFunc_CDC)),
  9.         VSFUSBD_DESC_NULL,
  10. },
定义了设备描述符,配置描述符,各种字符串描述符。具体的描述符就不说了,只是简单数组。

这些数据结构如果定义OK之后,要启动USB就非常简单了:
  1. vsfusbd_device_init(&app->usbd.device);
  2. vsfusbd_connect(&app->usbd.device);
最简单的启动代码只需要2行,2个API即可。当然,如果为了调试方便,可以在启动的时候,先断开USB的上拉电阻200ms,然后再启动USBD:
  1. static void usrapp_usbd_conn(void *p)
  2. {
  3.         struct usrapp_t *app = (struct usrapp_t *)p;

  4.         vsfusbd_device_init(&app->usbd.device);
  5.         vsfusbd_connect(&app->usbd.device);
  6.         if (app_hwcfg.usbd.pullup.port != VSFHAL_DUMMY_PORT)
  7.                 vsfhal_gpio_set(app_hwcfg.usbd.pullup.port, 1 << app_hwcfg.usbd.pullup.pin);
  8. }

  9. void usrapp_srt_init(struct usrapp_t *app)
  10. {
  11.         STREAM_INIT(&app->usbd.cdc.stream_rx);
  12.         STREAM_INIT(&app->usbd.cdc.stream_tx);
  13.         vsfshell_init(&app->shell);

  14.         if (app_hwcfg.usbd.pullup.port != VSFHAL_DUMMY_PORT)
  15.         {
  16.                 vsfhal_gpio_init(app_hwcfg.usbd.pullup.port);
  17.                 vsfhal_gpio_clear(app_hwcfg.usbd.pullup.port, 1 << app_hwcfg.usbd.pullup.pin);
  18.                 vsfhal_gpio_config(app_hwcfg.usbd.pullup.port, app_hwcfg.usbd.pullup.pin, VSFHAL_GPIO_OUTPP);
  19.         }
  20.         vsfusbd_disconnect(&app->usbd.device);

  21.         vsftimer_create_cb(200, 1, usrapp_usbd_conn, app);
  22. }
usrapp_srt_init为初始化软实时的代码,这里初始化了CDC的收发数据流,然后初始化USB上拉控制GPIO,并且关闭上拉,同时调用vsfusbd_disconnect断开USB连接,最后启动200ms定时器。200ms之后,就是之前看到的USBD启动代码,然后使能USB的1.5K上拉。

需要用到的API:
1. vsfusbd_device_init:初始化USB设备
2. vsfusbd_connect:连接USB设备
3. vsfusbd_disconnect:断开USB设备
4. vsfusbd_wakeup:远程唤醒USB主机
vsf

27

主题

60

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部