新唐MCU技术
直播中

王晾其

9年用户 1106经验值
私信 关注
[问答]

如何确定 M483 HSUSB 描述符?

我们使用M843SIDAE对于USB 2.0设备,时钟和寄存器等的初始化是正确的,但是在与主机通信时,发生了错误:

“ USB 1-6:设备描述符读取/64,错误 -71
USB 1-6:设备不响应设置地址
USB 1-6:设备不接受地址 7,错误 -71”

而BSP中的例子和独立的例子都是为了M487JIDAE,
我无法决定示例中的 USB 描述符参数(例如“idProduct”)是否可以用于M483SIDAE?
如果是这样,哪些参数或设置导致了错误?

回帖(1)

李晶

2025-9-3 18:01:18

确定 M483 HSUSB 描述符并解决设备枚举错误(错误 -71)需要结合硬件配置、描述符设置和初始化流程进行系统排查。以下是关键步骤和建议:




1. 关键原因分析(错误 -71)


错误代码 -71 (EPROTO) 表明 USB 协议层通信失败,常见原因包括:



  • 设备描述符格式错误(长度、字段值不符合规范)

  • 端点0通信失败(最大包大小不匹配、数据未及时响应)

  • 硬件问题(时钟不稳定、DP/DM 引脚未正确配置)

  • 初始化流程不匹配(寄存器配置未适配 M483)




2. M483SIDAE 与 M487JIDAE 的差异


尽管两者同属新唐 M4 系列,但需验证以下差异:



  • 时钟配置:确认 M483 的 USB 时钟源(HXT/HIRC/PLL)与分频器配置是否与 M487 不同。

  • USB 寄存器地址:检查 BSP 头文件(如 M483S.h),确保寄存器定义与 M487 一致。

  • 引脚复用:确认 USB_DP/DM 引脚(通常为 PA.12/PA.11)已正确映射到 USB 功能。




3. USB 描述符配置要点


(1) 设备描述符(Device Descriptor)


确保以下字段正确:


typedef struct {
    uint8_t  bLength;            // 描述符长度 (固定18)
    uint8_t  bDescriptorType;    // 设备描述符类型 (0x01)
    uint16_t bcdUSB;             // USB 规范版本 (0x0200)
    uint8_t  bDeviceClass;       // 设备类 (0x00 表示由接口定义)
    uint8_t  bDeviceSubClass;    // 子类
    uint8_t  bDeviceProtocol;    // 协议
    uint8_t  bMaxPacketSize0;    // 端点0最大包大小 (必须为64)
    uint16_t idVendor;           // 厂商ID (需合法)
    uint16_t idProduct;          // 产品ID (需唯一)
    uint16_t bcdDevice;          // 设备版本
    // ... iManufacturer, iProduct, etc.
} S_USBD_INFO;


  • 关键参数

    • bMaxPacketSize0:必须设为 64(对应 USB 2.0 高速设备)。

    • idVendor/idProduct:可沿用 M487 示例的值(如 0x0416/0x1234),但需确保主机无冲突。

    • bcdUSB:设置为 0x0200(USB 2.0)。



(2) 其他描述符



  • 配置描述符:确认总长度正确,接口/端点数量匹配。

  • 端点描述符:端点0必须为控制传输,方向为双向。




4. 初始化代码适配 M483


(1) 时钟配置


检查 USB 时钟是否稳定在 48MHz:


/* 示例:使用 PLL 生成 48MHz USB 时钟 */
CLK_SetCoreClock(96000000);      // 主频 96MHz
CLK->CLKSEL0 |= CLK_CLKSEL0_USBSEL_PLL; // USB 时钟源选择 PLL
CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_USBDIV_Msk) | (2 << CLK_CLKDIV0_USBDIV_Pos); // 分频系数=2

(2) USB 外设使能


SYS->GPB_MFP0 |= SYS_GPB_MFP0_PB10_USB_DAT | SYS_GPB_MFP0_PB11_USB_DAT; // 配置 DP/DM 引脚
SYS->IPRST1 |= SYS_IPRST1_USBRST_Msk;    // USB 复位
SYS->IPRST1 &= ~SYS_IPRST1_USBRST_Msk;   // 结束复位
SYS->AHBCLK |= SYS_AHBCLK_USBD_EN_Msk;   // 使能 USB 时钟

(3) 端点0缓冲区对齐


确保描述符表和端点缓冲区地址对齐到 4KB 边界:


__align(4096) uint8_t g_au8UsbBuffer[1024]; // 对齐缓冲区



5. 调试步骤


(1) 检查硬件信号



  • 使用示波器测量 DP/DM 线:

    • 主机发起复位时应有 10ms 低电平。

    • 设备响应时应能看到 DATA0 包。



(2) 简化描述符


临时使用最简描述符排除配置错误:


const uint8_t g_dev_descriptor[] = {
    18,     // bLength
    1,      // bDescriptorType
    0x00, 0x02, // bcdUSB 2.0
    0x00,   // bDeviceClass
    0x00,   // bDeviceSubClass
    0x00,   // bDeviceProtocol
    64,     // bMaxPacketSize0 (关键!)
    0x34, 0x12, // idVendor (示例)
    0x78, 0x56, // idProduct (示例)
    0x00, 0x00, // bcdDevice
    0x01,   // iManufacturer
    0x02,   // iProduct
    0x00,   // iSerialNumber
    0x01    // bNumConfigurations
};

(3) 捕获 USB 日志



  • Linux: 启用内核调试(echo 'module ehci_hcd +p' > /sys/kernel/debug/dynamic_debug/control)。

  • Windows: 使用 USBlyzer 或 Wireshark 捕获枚举过程。




6. 常见解决方案




  1. 修复端点0包大小


    // 在设备描述符中明确设置
    #define EP0_MAX_PKT_SIZE 64



  2. 延迟初始化
    在 USB 复位后添加延迟(100ms),确保电源稳定。




  3. 对比 M487 差异
    检查 M483 的 BSP 中是否有特殊寄存器位(如 USB 控制寄存器的 PHY 使能位)。




  4. 更新 BSP 库
    确认使用 M483 专用 BSP 包(非 M487),确保驱动兼容性。






结论


优先排查:



  1. 端点0包大小(必须为 64)。

  2. USB 48MHz 时钟稳定性。

  3. 描述符地址对齐(4KB 边界)。

  4. DP/DM 引脚配置(复用为 USB 功能)。


示例代码中的 idVendor/idProduct 可直接沿用,但核心问题是初始化流程和描述符格式需针对 M483 适配。建议从新唐官网下载 M483 专用 USB 示例代码,对比关键配置(时钟、引脚、描述符表地址)。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分