This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294NCPDT:使 TivaWare USBLIB 不直接支持的 USB 器件类正常工作

Guru**** 2528260 points
Other Parts Discussed in Thread: SYSCONFIG

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/915346/tm4c1294ncpdt-getting-a-usb-device-class-not-supported-directly-by-tivaware-usblib-to-work

器件型号:TM4C1294NCPDT
Thread 中讨论的其他器件:SysConfig

2月份 ,我问了“实施其他 USB 设备类”, 我去了一个兔子洞,雪塔在里面迷路了,因为其他紧迫的工作需要注意,所以把它放在一边。

我现在回到这个问题上。 我做了一项关于其他处理器的调查,这些处理器可以满足我的需求,包括 USB 高速支持、100Mb 以太网和外部总线接口。 Tiva M4可满足所有要求、因此我开始深入探究。

我选择 USB MIDI 类有两个原因。 第一、它很简单。 第二、我需要它用于设计。 因此、有必要将其用作演示如何实现 TivaWare 不支持的 USB 器件类。 与 TivaWave USB 散装演示不同、所有主要操作系统都支持 USB MIDI、这意味着无需自定义主机驱动程序。

我基本上从零开始。 我更新到了 CCS 10和 TivaWave 2.2。 我使用 PinMux 工具(现在是 SysConfig)生成引脚分配文件。 我已将器件驱动程序库和 USB 库添加到项目中。 我将类器件描述符放入 TivaWare USB 库所需的格式中。 (我开发了 Silicon Labs EFM8UB2的描述符、因此我知道它们在设计工作时是正确的。)

我使用 usbdbulk 器件驱动程序作为指南、但删除了旨在支持复合器件的内容(即、同一器件类的两个实例)。 首先、我的目标是枚举器件、并跟踪批量端点上的数据传输、因此 tCustomHandlers 中设置的处理程序只是桩模块。 USB0DeviceIntHandler 放置在启动源中的正确位置。 器件信息的所有结构都按照示例进行设置、我调用 USBDCDInit()。

然后什么也没有发生。 没有枚举尝试--根据我的分析器,根本没有 USB 流量。

单步执行代码没有帮助、因为您无法单步执行编译的库。 因此、我从链接器选项中删除了库引用、并将所有源代码拉到项目中。 进行编译的示例、现在我可以单步执行。 我看到它正在达到我的预期、甚至会"使用软连接连接连接连接设备"和"启用 USB 中断"。 连接后不会发生任何情况。

但是! "启用 USB 中断。" 中断是否甚至被触发? 答案是... 否 为什么不呢? 它已启用。 启用全局中断。 批量示例有效、但我的示例无效。 有什么不同? 我开始单步执行批量示例,进入 PinoutSet()函数。 由于 bool bUSB 为 true、因此它会初始化 USB 相关引脚。 我检查了代码以查看 SysConfig 在 pinout.c 中创建的内容

在 SysConfig 中、我启用了 USB 外设、并检查了 DM、DP、VBUS 和 EPEN 信号。 这会产生一个引脚 out.c、该引脚为这些引脚中的每个引脚调用 GPIOPinType。

回到 USB 大容量示例的引脚分配中、我看到引脚的调用相同、除了添加了以下内容:

       

HWREG (GPIO_PORTD_BASE + GPIO_O_LOCK)= GPIO_LOCK_KEY;
HWREG (GPIO_PORTD_BASE + GPIO_O_CR)= 0xff;
MAP_GPIOPinConfigure (GPIO_PD6_USB0EPEN);

好的、什么是 GPIO_LOCK_KEY? 这与引脚 PD6有什么关系?

不管怎样--我把这个片段添加到我的代码和语音--枚举是一个 USB MIDI 设备。 我似乎已经启动并在运行。


数据表告诉我们 USB0EPEN 可以分配给引脚 PD6、并且"可选用于主机模式、以控制外部电源为 USB 总线供电"。 我是一个设备、那么谁在乎呢。 但锁的作用是什么?

  1. 10.3.4 提交控制

    GPIO 确认控制寄存器提供了一层保护、防止对关键硬件外设进行意外编程。 对可用作4个 JTAG/SWD 管脚和 NMI 管脚的 GPIO 管脚提供了保护(管脚编号请参阅第1772页的‚ÄúSignal 表‚Äù)。 写入 GPIO 备用功能选择寄存器(GPIOAFSEL)(见770页)、GPIO 上拉选择寄存器(GPIOPUR)(见776页)、GPIO 下拉选择寄存器(GPIOPDR)(见778页)的保护位。 和 GPIO 数字使能(GPIODEN)寄存器(见781页)不会提交存储、除非 GPIO 锁定(GPIOLOCK)寄存器(见783页)已解锁并且 GPIO 确认(GPIOCR)寄存器(见784页)的相应位已置位。

这与 JTAG/SWD 或 NMI 没有关系--这种锁定要求对于评估套件板来说是特别的,还是通常需要?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andy:

    您是否仅添加 GPIO_LOCK_KEY 序列、还是添加 PD6行?

    我看不到该引脚需要 LOCK_KEY 的任何东西、尽管某些 TM4C 也需要 PD7用于 USB。 因此、该代码可能是由于该原因而不是 PD6。

    您能否移除 GPIO_LOCK_KEY 片段并测试代码是否仍然有效?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Ralph Jacobi"]

    您是否仅添加 GPIO_LOCK_KEY 序列、还是添加 PD6行?

    我已经在 SysConfig 中将 PD6设置为 USB0EPEN、因此我添加了 GPIO_LOCK_KEY 序列、就像在批量驱动程序中一样(也在其他驱动程序中)。

    [引用]我看不到该引脚需要 LOCK_KEY 的任何东西、尽管某些 TM4C 也需要用于 USB 的 PD7。 因此、该代码可能是由于该原因而不是 PD6。

    数据表中的一些搜索将 PD7作为 USB0PFLT 的可能引脚、被描述为"可选由外部电源在主机模式下使用
    以指示该电源的错误状态。" 但我不处于主机模式、因此这不相关。

    [报价]是否可以删除 GPIO_LOCK_KEY 片段并测试代码是否仍然有效?

    我是这样做的,而且... 确实如此。 我猜是因为 PD7可以配置为 NMI 输入、所以有解锁功能。 因此、如果设计将 PD7用于任何目的、则必须将其解锁。 由于我处于设备模式、而不是主机或 OTG、因此我根本不需要该输入。


    一些人进一步调查。 在 if (bUSB)中的批量驱动程序示例(drivers\pinout.c)中、我们发现:

    MAP_GPIOPinTypeUSBAnalog (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);

    PB1是 USB0VBUS I/O、PB0是 USB0ID 输入。

    在使用 SysConfig 从头开始编写代码时、我没有设置 USB0ID。 如果您未设置、USB 将永远不会连接。 我从批量示例复制的代码将该引脚设置为 USB Analog、这就是它的作用原因。

    进一步读数为"如果 USB 控制器用作专用主机或设备、USB 通用控制和状态(USBGPCS)寄存器中的 DEVMOD 域可用于将 USB0VBUS 和/或 USB0ID 输入内部连接到固定电平、 释放 PB0和 PB1引脚以供 GPIO 使用。"  

    所以就在这里... 完整版数据表中实际上记录了 Mentor Graphics USB 内核、这一点很有帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andy:

    很抱歉、计算出所有这些片段需要额外的时间。 我不确定它是否会帮助您向前发展、但如果您不使用此 API、您不必配置 USB0ID 或 USB0VBUS:

    //
    //设置 USB 堆栈模式以强制器件模式、而不进行 VBUS/ID 监控。
    //
    USBStackModeSet (0、eUSBModeForceDevice、0); 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、Ralph。

    BTW、使用 eUSBModeForceDevice 对 USBStackModeSet()的调用位于 USB_dev_cdcserial 示例中、但在 USB_dev_bulk 中 、调用仅使用 eUSBModeDevice。 CDC 代码示例确实对该函数的使用有很好的注释。

    //
    //强制器件模式、以便不使用 VBUS 和 ID 引脚、或者
    //由 USB 控制器监控。 对于 USB OTG、该功能应该是
    //不被调用。 USB 主机和 LaunchPad 供电
    //电源跳线设置为"OTG",不应调用此函数。
    //
    USBStackModeSet (0、eUSBModeForceDevice、0);
    

    不管怎样... 枚举正在起作用、现在可以对数据传输进行分类。 我认为 CDC 示例是一个很好的模型。