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.

[参考译文] F28M35H52C:DMA 端点可能存在 F28M35 usblib 错误

Guru**** 2535590 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1227226/f28m35h52c-possible-f28m35-usblib-bug-with-dma-endpoints

器件型号:F28M35H52C

我有一个板、将 F28M35H52C1配置为 USB 主机、并连接4端口 USB 集线器、条形码扫描仪、USB 闪存驱动器和定制 USB 大容量器件。  该项目的 USB MSC 部分源自控制套件中的 USB MSC 示例。

该问题 与配置为使用 DMA 的端点有关。  如果端点配置为使用 DMA、并且该端点的管道索引>= 3、则数据传输失败。  USBHCDPipeRead 或 USBHCDipeWrite 将在无限循环中挂起、等待:while (g_sUSBHCD.USBINPipes[ulPipeIdx].estay == pipe_reading) -在管道中。

该问题从 USBHCDPipeAllocSize ()开始,适用于"输入"和"输出"管道。  该函数的相关代码如下所示:

if (ulEndpointType & EP_PIPE_USE_UDMA)

//
//前三个端点的某些通道是固定的
//部件使管道偏压以匹配这一点,因为最好是
//可能的。
//
if (lIdx < 3)

//
//检查固定通道是否可用于此目的
// USB 管道。
//
if (g_sUSBHCD.ucDMAChannels[lIdx * 2]==
USBHCD_DMA_unused)

//
//默认通道可用,因此请使用它。
//
g_sUSBHCD.ucDMAChannels[lIdx * 2]= lIdx;
g_sUSBHCD.USBINPipes [lIdx].ucDMAChannel = lIdx * 2;
}
方案

//
//如果固定的 USB 管道没有,则转到下一个 USB 管道
//可用。
//
继续;
}
}
方案

//
//固定通道不可用或
//管道索引大于前3个管道
///适用于所有器件。
//
for (lDMAIdx = 0;lDMAIdx < MAX_NUM_DMA_CHANNELS;
lDMAIdx += 2)

//
//找到任何可用的通道。
//
if (g_sUSBHCD.ucDMAChannels[lDMAIdx]==
USBHCD_DMA_unused)

//
//保存索引和 DMA 通道
//信息。
//
g_sUSBHCD.ucDMAChannels[lDMAIdx]= lIdx;
g_sUSBHCD.USBINPipes [lIdx].ucDMAChannel =
lDMAIdx;
}
}
}

当 lIdx >= 3时、否则分支会运行 for 循环以查找其他在较低索引中未使用的可用通道。  如果发现未使用的通道、则会进行相应的设置。  但是、对于每个可用通道、循环执行不会中断、循环会继续。

我在"输入"和"输出"管道设置中添加了一个断点、以防止这种情况发生。  但是、当我重新编译 usblib 并运行代码时、在管道读取和管道写入中仍然存在挂起的情况。

在 USBHCDPipeRead ()和 USBHCDipeWrite ()中,没有对  g_sUSBHCD.USBBINPipes[lIdx].ucDMAChannel,这是用于输入/输出管道传输的实际 DMA 通道。  该代码会假设管道索引小于3、并且可以使用 USB DMA 端点的默认索引。  例如、以下行:

uDMAChannelTransferSet (uDMA_channel_USBEP1RX +(ulPipeIdx * 2)、uDMA_MODE_AUTO、(void *) USBFIFOAddrGet (USB0_BASE、ulEndpoint)、pucData、 (ulBytesRead);

uDMAChannelEnable (uDMA_channel_USBEP1RX +(ulPipeIdx * 2));

(ulPipeIdx * 2)用于计算错误的偏移。  我认为代码应该参考  g_sUSBHCD.USBINPipes[ulPipeIdx].ucDMAChannel 以获取正确的 DMA 通道。

我意识到托管3个 USB 设备和集线器可能是 M3的一个极端用例、但我想指出这一点、以防其他人遇到这样的问题。  在我的例子中,作为一个短期的权变措施,我计划修改 USBHCDPipeAllocSize()以在索引大于等于3时禁用 DMA 的使用。  我可以控制正常产品使用中的 USB 端口、以强制 USB 闪存驱动器连接到第一个 USB 集线器端口。

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

    感谢您指出这一点。  如果有人遇到这个问题、这肯定会有所帮助。

    此致

    Siddharth