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:每64字节事务之前的 NAK 事务

Guru**** 1693050 points
Other Parts Discussed in Thread: EK-TM4C1294XL, TM4C1294NCPDT
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1362572/tm4c1294ncpdt-nak-transaction-before-every-64-bytes-transaction

器件型号:TM4C1294NCPDT
Thread 中讨论的其他器件:EK-TM4C1294XL

您好!

我 使用 USB 设备模式。 当主机(Windows 10)使用 Get_Feature 获取 2962字节数据时、我看到 在每64字节事务之前有一个 NAK 事务。 USB 协议为1.1 (全速)。

1.是否有办法避免64字节事务之前的 NAK 事务?

2.可以在端点0使用 DMA 控制器来避免这次的 NAK 传输吗?

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

    您好!

     NAK 通常意味着 器件临时无法发送或接收数据。 我不确定您运行的是哪种器件类别。 从您的捕获来看、它们在交易中。 这意味着数据从器件传输到主机。 是这样吗? 主机是否发送 NAK? 如果出现这种情况、您需要在主机端进行调查。

     如果您查看 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\usb_dev_bulk example、会发现其为 #define BULK_BUFFER_SIZE 256。 我不确定通过增加缓冲区大小是否能够缓解这种情况、因为 NAK 由硬件 USB 模块处理并在需要保留任何进一步的传入数据时进行响应。  

     可以看到、在另一个批量传输中、事务在端点3中执行、端点3在64字节后没有 NAK。 但这些是输出事务(从主机到器件)。

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

    尊敬的 Charles:

    感谢您的答复。

    我使用 HID 类。 器件发送 NAK。 这是端点0的控制传输。 当器件从 SPI 获取数据时、它将通过端点1向主机发送中断。 主机将使用 HIDD_GetFeature ()来获取数据。

    这是否 意味着在将64字节 数据复制到 FIFO 上花费了过多的时间?

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

    您好!

     我不知道如何回答您的问题、即在什么情况下会在64字节后插入 NAK、而在什么情况下不会插入 NAK。  我认为 在中断事务期间、NAK 用于通知主机没有要发送的数据。 有些 EP0控制事务在64字节后没有 NAK。 下面的内容 基于 TivaWare CDC 器件示例、其中 get_descriptor 在获取 EP0上的超过64个字节时不具有 NAK。

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

    您好、Charles、

    我使用  C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\usb_dev_cdcserial 中的 TivaWare CDC 器件示例、并发现在 get_ddescriptor 中的64字节事务之前仍有 NAK。

    我发现、如果我使用 USB 2.0集线器连接笔记本电脑和设备、在数据事务之前没有 NAK。 如果我在笔记本电脑和设备之间设置了 USB 2.0集线器、NAK 会消失、您有什么想法吗?

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

    尊敬的 KF:

     USB 2.0集线器的工作方式远非我所知。 您是在器件和集线器之间还是在集线器和主机之间嗅探? 在这种情况下、也许集线器中有一些缓冲会有所帮助。  

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

    尊敬的 Charles:

    感谢您的答复。

    如果我使用 采用 USB 协议1.1的 TM4C1294NCPDT 直接连接主机、您对有 NAK 事务有什么想法吗?

    或者你知道谁可能知道什么可能导致这个 NAK?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="606544" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1362572/tm4c1294ncpdt-nak-transaction-before-every-64-bytes-transaction/5204346 #5204346"]

    如果我使用 采用 USB 协议1.1的 TM4C1294NCPDT 直接连接主机、您对有 NAK 事务有什么想法吗?

    [报价]

    尊敬的 KF:

     不、我不知道是否会有所帮助。 请尝试并告诉我您的结果。 我能想到的就是 NAK 的插入取决于 USB 硬件(可用缓冲区的数量)和 USB 堆栈(传入事务时 USB 堆栈的状态)的组合。 我不知道如何调整堆栈、当然也不知道硬件是如何按预期删除 NAK。 Get_Feature 是自定义命令吗?  您是否可以将其他 EP 用于 Get_Feature? 它会产生影响吗?

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

    尊敬的 Charles:

     我所使用的 Get_Feature 命令在 Windows API:HIDD_GetFeature function (hidsdi.h )- Windows 驱动程序| Microsoft Learn 中受支持

    我将尝试为  Get_Feature 使用其他 EP。  有没有在另一个端点创建控制类型端点的示例?

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

    尊敬的 KF:

      这看起来是一个标准的 USB 请求作为控制事务、通常在 EP0上执行。 我认为您不能将此请求移至其他 EP、因为我认为 Windows 将仅发送至 EP0。  

     难道 Get_Feature ()只是在主机和设备之间的枚举过程中发生的控制事务吗? 枚举完成后、其余的数据事务将在其他 EPS 上执行、我希望 NAK 断言的行为会有所不同。 我的重点是、对于主要发生在初始枚举期间的控制事务、NAK 插入可能对整体性能没有太大影响。 不能确定是否同意、除非即使在枚举完成后、get_feature()也会不断发生。  

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

    尊敬的 Charles:

    在某些情况下、我需要持续使用 Get_Feature 来检索大量字节。 我   在 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\usb_dev_bulk 中使用 TivaWare 示例尝试 USB 批量传输、当主机读取2048个字节时、它仍然具有两个64字节事务之间的 NAK。  

    如果我可以在前一个传输完成后立即将64个字节复制到 USB FIFO、NAK 会消失吗?

    在前64个字节的事务完成后、是否可以使用 DMA 控制器立即将64个字节从存储器复制到 USB FIFO 中?

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

    尊敬的 KF:

      看看下面的批量传输捕获、我可以看到对于输入或输出传输、没有插入 NAK (例如、交易18、19、20、21、22)、还有地方可以声明 NAK (例如、交易13、15、23、27)。  我真的不知道何时插入了 NAK。 正如我提到过的、这将取决于  USB 硬件(可用缓冲区数量)和 USB 堆栈(传入事务时 USB 堆栈的状态)的组合。  

    USB 控制器具有集成 DMA、但我们没有示例来 展示 该功能。 有一些可能有用的双缓冲功能。 USB 规范采用保密协议形式。 如果您与 TI 签订了 NDA 设置、则我可以与您私下分享。

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

    尊敬的 KF:

    [报价 userid="606544" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1362572/tm4c1294ncpdt-nak-transaction-before-every-64-bytes-transaction/5254903 #5254903"]

    我正在尝试使用 DMA。 "发送多个数据包"不起作用、而"发送单个数据包"起作用。

    [报价]

     我想您在使用集成 DMA 方面比我更有把握。  您说过发送单个数据包是有效的。 如果你在这个模式下看到 NAK、你可以详细说明一下吗? 换句话说、如果您使用单数据包模式发送1024个字节、您是否获得 NAK? 这意味着您需要手动触发每个单个数据包传输(64字节)、总共触发16次。 我知道您的愿望是一次性使用多个数据包、但我不知道为什么它不起作用。 你的代码似乎与多数据包操作驱动程序库用户指南中介绍的代码相同、但我不知道什么错。 当您表示无法正常工作时、是意味着没有数据从 USB 控制器传出、还是只有部分数据传出?

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

    尊敬的 Charles:

    如果在此模式下看到 NAK、您能详细说明一下吗? 换句话说、如果您要使用单数据包模式发送1024个字节、是否会得到 NAK?[/QUOT]

    使用"发送单个数据包"方法时、其行为与正常批量示例类似。 在将每个64字节数据块传输到主机之前仍然有一个 NAK、重复16次以完成1024字节数据的传输。

    如果您说它不起作用、是意味着没有数据从 USB 控制器传出、还是只有部分数据传出?

    数据不会从 USB 控制器发出。

    使用"USB_EP_DMA_MODE_1"标志时、是否缺少一些内容?

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

    尊敬的 KF:

     我不知道该怎么办才好。 您的代码看起来与用户指南中所示基本相同、只是使用了通道1而不是您的通道0。 您可能需要检查中断是否被触发 、并确定是否 输入了 ScheduleNextTransmission ()以及中断在哪里?

    //
    // Endpoint 1 uses Mode 1 and transmit and enables automatic sending
    // when a full packet is sent to the FIFO.
    //
    USBEndpointDMAConfigSet(USB0_BASE, USB_EP_1, USB_EP_HOST_OUT |
    USB_EP_DMA_MODE_1 |
    USB_EP_AUTO_SET);
    //
    // Assign endpoint 1 to DMA channel 1 using Mode 1, no bursting, transmit,
    // and enable DMA interrupts.
    //
    USBDMAChannelConfigSet(USB0_BASE, 1, USB_EP_1, USB_DMA_CFG_MODE_1 |
    USB_DMA_CFG_BURST_NONE |
    USB_DMA_CFG_DIR_TX |
    USB_DMA_CFG_INT_EN);
    
    //
    // Set the source address for the transfer to pvBuffer.
    //
    USBDMAChannelAddressSet(USB0_BASE, 1, pvBuffer);
    //
    // Set the transfer size to 1024 bytes and the packet count to 16.
    // The packet count does not require a + 1 because 1024/64 leaves no
    // remaining bytes to send in a final packet.
    //
    USBDMAChannelCountSet(USB0_BASE, 0, 1024);
    USBEndpointPacketCountSet(USB0_BASE, 0, 1024/64);
    //
    // Enable the DMA transfer.
    //
    USBDMAChannelEnable();