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

[复制链接]
914|0
手机看帖
扫描二维码
随时随地手机跟帖
vsf|  楼主 | 2018-4-9 19:17 | 显示全部楼层 |阅读模式
本帖最后由 vsf 于 2018-4-9 19:36 编辑

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

        // private
        ......
};

struct vsfusbd_config_t
{
        // public
        vsf_err_t (*init)(struct vsfusbd_device_t *device);
        vsf_err_t (*fini)(struct vsfusbd_device_t *device);

        uint8_t num_of_ifaces;
        struct vsfusbd_iface_t *iface;

        // private
        ......
};

struct vsfusbd_device_t
{
        // public
        uint8_t num_of_configuration;
        struct vsfusbd_config_t *config;
        struct vsfusbd_desc_filter_t *desc_filter;
        uint8_t device_class_iface;
        struct vsfhal_usbd_t *drv;
        int32_t int_priority;
        void (*on_EVENT)(struct vsfusbd_device_t *device,
                        enum vsfusbd_usr_evt_t evt, void *param);

        // private
        ......
};
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

栗子:
.usbd.device.num_of_configuration                = dimof(usrapp.usbd.config),
.usbd.device.config                                                = usrapp.usbd.config,
.usbd.device.desc_filter                                = (struct vsfusbd_desc_filter_t *)usrapp_param.usbd.StdDesc,
.usbd.device.device_class_iface                        = 0,
.usbd.device.drv                                                = (struct vsfhal_usbd_t *)&vsfhal_usbd,
.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:接口数组指针

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


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

栗子:
.usbd.ifaces[0].class_protocol                        = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMControl_class,
.usbd.ifaces[0].protocol_param                        = &usrapp.usbd.cdc.param,
.usbd.ifaces[1].class_protocol                        = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMData_class,
.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的数据结构。

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

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

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

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

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

        vsftimer_create_cb(200, 1, usrapp_usbd_conn, app);
}
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

粉丝