要将Cypress FX3配置为复合USB设备(同时支持大容量存储类MSC和自定义批量传输接口),需要仔细规划USB描述符结构并合理分配端点资源。以下是分步指南:
1. USB描述符配置
1.1 设备描述符
const uint8_t CyFxUSBDeviceDscr[] __attribute__ ((aligned (32))) = {
0x12, // bLength
USB_DESC_DEVICE, // bDescriptorType
0x00, 0x02, // bcdUSB (2.00)
0x00, // bDeviceClass (Composite)
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
0x40, // bMaxPacketSize0
0xB4, 0x04, // idVendor
0x00, 0x00, // idProduct
0x00, 0x01, // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x03, // iSerialNumber
0x01 // bNumConfigurations
};
关键点:设备类设为0x00(复合设备),使用接口关联描述符(IAD)。
1.2 配置描述符结构
复合设备需要包含两个接口组:
// MSC接口描述符
0x09, // bLength
USB_DESC_INTRFC, // bDescriptorType
0x00, // bInterfaceNumber (0)
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x08, // bInterfaceClass (MSC)
0x06, // bInterfaceSubClass (SCSI)
0x50, // bInterfaceProtocol (Bulk-Only Transport)
0x04, // iInterface
// 端点描述符 (Bulk-IN EP1)
0x07, // bLength
USB_DESC_ENDPNT,
0x81, // bEndpointAddress (EP1 IN)
0x02, // bmAttributes (Bulk)
0x00, 0x02, // wMaxPacketSize (512)
0x00, // bInterval
// 端点描述符 (Bulk-OUT EP2)
0x07,
USB_DESC_ENDPNT,
0x02, // bEndpointAddress (EP2 OUT)
0x02,
0x00, 0x02,
0x00,
// 自定义接口描述符(使用IAD)
0x08, // IAD长度
USB_DESC_INTRFC_ASSOC,
0x01, // bFirstInterface
0x01, // bInterfaceCount
0xFF, // bFunctionClass (Vendor Specific)
0x00, // bFunctionSubClass
0x00, // bFunctionProtocol
0x00, // iFunction
0x09, // 接口描述符
USB_DESC_INTRFC,
0x01, // bInterfaceNumber (1)
0x00,
0x02, // 两个端点
0xFF, // 类代码(自定义)
0x00,
0x00,
0x05, // iInterface
// 端点描述符 (Bulk-IN EP3)
0x07,
USB_DESC_ENDPNT,
0x83, // EP3 IN
0x02,
0x00, 0x02,
0x00,
// 端点描述符 (Bulk-OUT EP4)
0x07,
USB_DESC_ENDPNT,
0x04, // EP4 OUT
0x02,
0x00, 0x02,
0x00
关键点:
- 使用IAD(Interface Association Descriptor)关联接口组
- 确保端点地址唯一(EP1-IN, EP2-OUT用于MSC;EP3-IN, EP4-OUT用于自定义接口)
- 自定义接口类设为
0xFF(厂商特定)
2. 端点管理
2.1 MSC端点处理
使用SDK内置的MSC处理机制:
CyU3PMscInit(); // 初始化MSC模块
CyU3PUsbRegisterSetupCallback(msc_handle_req, CY_TRUE); // 注册SCSI命令回调
2.2 自定义接口端点管理
初始化批量传输通道:
CyU3PDmaChannel_t chHandle;
CyU3PDmaChannelConfig_t dmaConfig;
CyU3PMemSet((uint8_t *)&dmaConfig, 0, sizeof(dmaConfig));
dmaConfig.size = 16*1024; // DMA缓冲区大小
dmaConfig.count = 4; // 缓冲区数量
dmaConfig.prodSckId = CY_U3P_PIB_EP3; // 生产端socket
dmaConfig.consSckId = CY_U3P_CPU_SOCKET_CONS; // 消费端
CyU3PDmaChannelCreate(&chHandle, CY_U3P_DMA_TYPE_AUTO, &dmaConfig);
CyU3PDmaChannelSetXfer(&chHandle, CY_FX_EP_BULK_XFER_SIZE); // 启动传输
3. 示例参考
SDK参考案例
- MSC示例:
CypressFX3 SDK1.3firmwareserialif_examplescyfxusbmsc
- 批量传输示例:
CypressFX3 SDK1.3firmwareserialif_examplescyfxbulklpauto
复合设备实现步骤:
- 复制MSC示例的存储处理逻辑
- 添加自定义接口描述符到
CyFxUSBDscr.c
- 在
CyFxUsbEventCallback中处理接口切换事件
- 创建独立线程处理自定义端点数据
4. 调试建议
- 使用USBTreeView验证描述符结构
- 通过
CyU3PDebugPrint输出调试信息
- 使用
Bus Hound监控USB数据流
- 验证端点冲突:确保没有重复使用端点地址
常见问题处理
- 枚举失败:检查描述符长度和层次结构
- 端点无响应:确认DMA通道正确绑定到物理端点
- 数据传输冲突:为不同接口使用独立线程处理
完整实现代码示例可参考AN75779应用笔记,需要特别注意同步访问共享资源时的互斥保护。