打印
[APM32F1]

APM32USB双CDC配置_1

[复制链接]
491|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 宫影空明人不往 于 2023-9-27 17:12 编辑

前言
最近在学习USB设备,刚好看见Geehy出了一个USB相关的SDK。
具体链接为:https://www.geehy.com/support/apm32?id=489
里面集结了F0,F1,F4的USB例程,非常方便USB的开发。

正好我手里面有一块F103的板子,可以去参照它的SDK进行修改,将其单个CDC的工程修改成一个双CDC的工程。
因为时间有限,改写后的效果只是能被电脑识别出双CDC,CDC2的数据收发在后续进行补充。
那就让我们开始吧。

1.  修改设备描述符
因为需要修改为双CDC设备即复合设备(严格意义上应该是组合设备,但是电脑也是这么显示的那就成为复合设备),因此首先需要更改设备描述符。
设备描述符修改部分如下:
 /* bDeviceClass */
0xEF,
/* bDeviceSubClass */
0x02,
/* bDeviceProtocol */
0x01,

2.修改配置描述符
从单CDC修改成双CDC,接口的数量从2改为4。
/* bNumInterfaces */
    0x04,

接着就是加上接口关联描述符(IAD描述符)。
 /* IAD Interface Association Descritor */
        /* blength */
        0x08,
        /* IAD */
        0x0b,
        /* FirstInterface */
        0x00,
        /* InterfaceCount */
        0x02,
        /* FunctionClass:CDC */
        0x02,
        /* FunctionSubClass */
        0x02,
        /* FunctionProtcol */
        0x01,
        /* Function */
        0x02,

一共需要添加两个IAD描述符,需要更改的是第一个接口编号以及接口数量。
每一个IAD描述符包含CDC的两个接口,控制接口以及输入输出接口。因此一共有四个接口(需要注意接口编号的更改)。

接口描述符下则包含其端点(控制端点一个,输入输出端点两个)。因此,双CDC一共需要6个端点。
因此在usbd_cdc.h中需要新增CDC2的端点定义
#define USBD_CDC2_FS_MP_SIZE                     0x40
#define USBD_CDC2_HS_MP_SIZE                     0x200
#define USBD_CDC2_CMD_MP_SIZE                    0x08
#define USBD_CDC2_DATA_MP_SIZE                   0x07
#define USBD_CDC2_CMD_EP_ADDR                    0x84
#define USBD_CDC2_DATA_IN_EP_ADDR                0x83
#define USBD_CDC2_DATA_OUT_EP_ADDR               0x03

同时还需要更改配置描述符数组的大小
#define USBD_CONFIG_DESCRIPTOR_SIZE             141
这样,配置描述符就完成了。

2.  端点初始化
USB的端点初始化在USBD_CDC_ClassInitHandler这一个函数中。通过查看函数可以知道它首先对usbDevCDC这一个结构体的数据进行初始化,向里面赋上端点的相应的信息,在调用usbDevCDC这个结构体里面的参数进行端点进行初始化。
因此首先对usbDevCDC进行修改。
<blockquote>uint8_t                 epInAddr2;

主要是根据CDC1增加CDC2相应的参数。
完成之后就对USBD_CDC_ClassInitHandler函数进行修改,大致代码如下:
usbDevCDC->epCmdAddr2 = USBD_CDC2_CMD_EP_ADDR;
usbDevCDC->epInAddr2 = USBD_CDC2_DATA_IN_EP_ADDR;
具体请根据函数进行修改。

3.  PMA初始化
端点传输数据需要缓冲空间进行传输,该空间又称为PMA。新增了3个端点则需要对其PMA进行初始化,具体代码如下:
    USBD_ConfigPMA(&usbDeviceHandler, USBD_CDC2_EP_OUT_ADDR, USBD_EP_BUFFER_SINGLE, USBD_CDC2_EP_OUT_SIZE);
    USBD_ConfigPMA(&usbDeviceHandler, USBD_CDC2_EP_IN_ADDR, USBD_EP_BUFFER_SINGLE, USBD_CDC2_EP_IN_SIZE);
    USBD_ConfigPMA(&usbDeviceHandler, USBD_CDC2_EP_CMD_ADDR, USBD_EP_BUFFER_SINGLE, USBD_CDC2_EP_CMD_SIZE);

同时,缓冲区的地址以及大小也要定义,这里我就延续CDC1的分配,输入输出端点缓冲区为64,控制端点缓冲区为16。具体配置如下:
#define USBD_CDC2_EP_OUT_ADDR                0x03
#define USBD_CDC2_EP_OUT_SIZE                0x1A0
#define USBD_CDC2_EP_IN_ADDR                 0x83
#define USBD_CDC2_EP_IN_SIZE                 0x150
#define USBD_CDC2_EP_CMD_ADDR                0x84
#define USBD_CDC2_EP_CMD_SIZE                0x190

到这里,双CDC的配置就完成了。

4.  程序验证
将修改好的工程进行编译,没有错误后将其烧到F103的板子上。将板子复位并通过USB线接入到电脑。
打开设备管理器查看可以发现,电脑将其识别成了一个复合设备,同时多出了COM7以及COM8两个串口。

查看复合设备的属性,其PID和VID值符合我编写的USB设备。
#define USBD_GEEHY_VID              12619
#define USBD_FS_PID                    1002


这样的话至少描述符那边是没有什么问题了。接着就是通过串口助手工具进行查看。COM7是能够正常打印信息的,
而COM8(即CDC2)因为还没有编写相应的输出输入函数,因此没有数据打印。


5.总结
通过上述可知,修改描述符以及初始化相应端点使得电脑能够识别出多个CDC,但没有相应的数据传输。
因此后续对CDC2的数据传输代码进行编写。





使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

11

帖子

0

粉丝