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.

[参考译文] EK-TM4C123GXL:USB 速度

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/564952/ek-tm4c123gxl-usb-speed

器件型号:EK-TM4C123GXL

大家好、

我尝试使用 TM4C123G LaunchPad 作为示波器、与主机侧的应用进行通信。 为了能够测量不同的电压范围、我们开发了一个 BoosterPack、允许我们这样做。  在通过 USB 发送测量数据之前、我需要对其进行准备、因为主机端有一些通信法规。  

我的目标是使用 ADC0实现一个通道的采样率至少为500kHz。 我在乒乓模式下配置了一个 DMA 通道来连续采样 ADC 数据。 准备数据所需的时间大约是两个 ADC 中断之间经历的时间的1/4。 剩余的时间(理论上)应该足够大,以摆脱准备好的数据(基于12位*500000kHz 的传输速率)。

我根据 TivaWare USB 批量驱动程序(usbdbbulk.c/.h)的某些部分创建了定制的 USB 批量器件。  未为我通过其发送准备数据的端点启用 USB_EP_AUTO_SET 位。 因此、我将带 USBEndpointDataPut 的数据放入指定的 FIFO、然后将带 USBEndpointDataSend 的数据发送到主机。 我的问题是,我无法达到足以满足我的需要的样例。 如果我通过启用32次硬件过采样将 ADC 采样率设置为31、25kHz、我将获得令人满意的结果。 如果采样率高于此值、SEND_PACKET 函数中的错误计数器将迅速增加。 那么、我的问题是、是否有比我现在更好的方法来发送数据(请参阅下面的代码示例)?

非常感谢您的帮助! 如果您需要更多信息、请告诉我。

此致、

Felix  

void
ADC0IntHandler (void)
{
//
//清除 ADC 中断
//
map_ADCIntClear (ADC0_base、0);

if (g_OsziRun)
{


if (!map_uDMAChannelSizeGet (UDMA_CHANNE_ADC0 | UDMA_PIN_SELECT))}{

//



完成 GPIO4+、GPIO_PEDIT_RECODE_TO_4;GPIO4+ TOP_ TOP_ TO_TOP_ TOP_ TOP_ 4;GPIO+ TOP_ TOP_ TOP_ TOP_ TOP_ TOP_ 4 TOP_ TOP_ TOP_ TOP_ TOP_ 4 TOP_ TOP_ TOP_ TOP_ TOP_ TOP_ TOP_ TOP_ TOP_ TOP_ TOP_


//调试用途

MAP_uDMAChannelTransferSet (UDMA_CHANGE_ADC0 | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
(void *)(ADC0_BASE + ADC_O_SSFIFO0 +(0x20 * 0))、
G_ulAdc0Buf_ping、ADC0_base (ADC0_GP_SDK_MAP_ENABLE_DRESS_UDC0_SDO +(0x20 * 0)))、gpin_PORTAM_PORTAL_SDO
(UDIOSIZE
(UANCE_MA_BOOSIZE (0x20 *) GPIO_PIN_7、GPIO_PIN_7);//调试目的
create_oszi_packet (g_ui8ADCModules、ping_done);
map_GPIOPinWrite (GPIO_Porta_base、GPIO_PIN_7、0);//调试用途
MAP_GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_0、GPIO_PIN_0);
SEND_PACKET (PING_DONE);
MAP_GPIOPinWrite (GPIO_PORTB_BASE、 GPIO_PIN_0、0);
}
否则(!map_uDMAChannelSizeGet (UDMA_CHANNE_ADC0 | UDMA_ALT_SELECT)
){
// g_ulAdcBuf_pong 已准备好处理
//重写通道配置以进行下一个传输
//翻转引脚 PA4

g_ulBadiphap_is0+
、GPIO2+、GPIO0_PON_PON_TO_PED;GPIO0_GPIO0_GPIO_PON_PON_TO_PON_PON_PON_TO_PON_PON_TO_PON_P= GPIOR

//调试用途

MAP_uDMAChannelTransferSet (UDMA_CHANGE_ADC0 | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
(void *)(ADC0_BASE + ADC_O_SSFIFO0 +(0x20 * 0))、
G_ulAdc0Buf_pong、ADC0_base + ADC0_ADC0_MA_SET_ENABLE_MA_SIZE

;GP_SDK_REGPT_MA_SET_MA_MA_USDK_SIZE (0x20 *)、GPADCK_REGPT_MA_MA_MA_MA_MA_MA_MA_MA_MA_MAK_SIZE GPIO_PIN_7、GPIO_PIN_7);//调试目的
create_oszi_packet (g_ui8ADCModules、pong_done);
send_packet (pong_done);
//map_GPIOPinWrite (GPIO_Porta_base、GPIO_PIN_7、 0);
}
否则
{
//正常 ADC 中断、不是 uDMA 中断/什么?????
g_ulIntOsziCount++;
}



}void send_packet (uint8_t ui8PingPoong)
{
static uint32_t routine_count、packet_sent、errorcounter;
uint8_t buffer_mode = ui8PingPoong;
uint8_t *pData;
int32_t Ret32_t i32code;
uint32+


例程;uint+ uintePing+

pData =(uint8_t *)&packet_one;
i32Retcode = map_USBEndpointDataPut (USB0_BASE、USB_EP_4、pData、63);
ui32EPStatus = MAP_USBEndpointStatus (USB0_BASE、USB_EP_4);
if (i32Retcode!=-1)
{
i32Retcode = MAP_USBEndpointDataSend (USB0_BASE、USB_EP_4、USB_TRANS_IN);
packet_send++;

}
else
{

error+};

}


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

    我相信您应该按原样使用 usblib、而不是像 EP Auto Set 那样进行功能更改。 通过进行此类更改,您会导致应用程序和 usblib 驱动程序文件之间发生冲突。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Amit、您好!
    感谢您的快速回复。 到目前为止、我只更改了 tDeviceInfo 结构、因此还创建了自定义事件处理程序。 出于我的目的、我需要一个具有3个接口和每个接口1-2个 EPS 的 USB 器件。 是否有更好的方法来根据提供的 TivaWare 驱动程序创建这样一个器件?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Refe

    如果要使用的器件类型不同、则需要为此类实现使用复合器件。 您是否尝试了基本批量示例以首先获取吞吐量?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Amit、您好!
    再次感谢您的帮助。 是的、基本批量示例是达到所需的吞吐量。
    我现在创建了一个复合器件。 我现在要坚持的最后一点是、如何使用与默认使用的端点不同的端点。 我有一个 CDC 器件、并希望在控制接口中将 EP3用作中断 EP。 和 EP1输入/EP2输出、用于 CDC 器件的数据接口。 此外、我还有一个要在中使用 EP4的大容量器件。 在 usbdbulk.c/usbdcdcdc.c 中更改特定定义无效。 我会错过什么?
    此致、
    Felix
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Refe

    您是如何创建不同的描述符结构的、以及如何分配回调的?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Amit、您好!

    我为每个器件创建了一个 tUSBDBulkDevice 和 tUSBDCDCDevice。 对于复合器件、我创建了一个 tUSBDCompositeDevice。 然后、我通过 USBDCDCCompositeInit/USBDBulkCompositeInit 函数初始化器件。 我不再使用实例数据。

    tUSBDBulkDevice g_sBulkDeviceA =
    {
    
    USB_VID_TI_1CBE、
    USB_PID_BULK、
    0、
    USB_CONF_ATTR_SELF、
    USBBufferEventCallback、
    (空*)&g_sRxBuffer、
    USBBufferEventCallback、
    (空*)&g_sTxBuffer、
    G_ppui8字符串描述符、
    num_string_descriptors
    
    };
    
    
    tUSBDCDCDevice g_psCDCDevice =
    {
    
    USB_VID_TI_1CBE、
    USB_PID_SERIAL、
    0、
    USB_CONF_ATTR_SELF、
    ControlHandler、
    (void *)&g_psCDCDevice、
    USBBufferEventCallback、
    (void *)&g_sRxBufferCDC、
    USBBufferEventCallback、
    (void *)&g_sTxBufferCDC、
    G_ppui8字符串描述符、
    num_string_descriptors
    };
    
    //*************
    //
    //接收缓冲区批量(从 USB 角度)。
    ////
    *****************
    uint8_t g_pui8USBRxBufferBulk [bulk_buffer_size];
    tUSBBuffer g_sRxBuffer =
    {
    错误、 //这是一个接收缓冲区。
    RxHandler、 // pfnCallback
    (空*)&g_sBulkDeviceA、 //回调数据是我们的器件指针。
    USBDBulkPacketRead、 // pfnTransfer
    USBDBulkRxPacketAvailable、 // pfnAvailable
    (空*)&g_sBulkDeviceA、 // pvHandle
    G_pui8USBRxBufferBulk、 // pi8Buffer
    bulk_buffer_size、 // ui32BufferSize
    };
    
    //*********
    //
    ///发送缓冲区(从 USB 角度)。
    ////
    *****************
    uint8_t g_pui8USBTxBufferBulk [bulk_buffer_size];
    tUSBBuffer g_sTxBuffer =
    {
    对、 //这是一个发送缓冲区。
    TxHandler、 // pfnCallback
    (空*)&g_sBulkDeviceA、 //回调数据是我们的器件指针。
    USBDBulkPacketWrite、 // pfnTransfer
    USBDBulkTxPacketAvailable、 // pfnAvailable
    (空*)&g_sBulkDeviceA、 // pvHandle
    G_pui8USBTxBufferBulk、 // pi8Buffer
    bulk_buffer_size、 // ui32BufferSize
    };
    
    
    //*********
    //
    //接收缓冲器 CDC (从 USB 角度)。
    ////
    *****************
    uint8_t g_pui8USBRxBufferCDC[256];
    tUSBBuffer g_sRxBufferCDC =
    {
    错误、 //这是一个接收缓冲区。
    RxHandler、 // pfnCallback
    (void *)&g_psCDCDevice、 //回调数据是我们的器件指针。
    USBDCDCPacketRead、 // pfnTransfer
    USBDCDCRxPacketAvailable、 // pfnAvailable
    (void *)&g_psCDCDevice、 // pvHandle
    G_pui8USBRxBufferCDC、 // pui8Buffer
    256、 // ui32BufferSize
    };
    
    //*********
    //
    ///发送缓冲区(从 USB 角度)。
    ////
    *****************
    uint8_t g_pui8USBTxBufferCDC[256];
    tUSBBuffer g_sTxBufferCDC =
    {
    对、 //这是一个发送缓冲区。
    TxHandler、 // pfnCallback
    (void *)&g_psCDCDevice、 //回调数据是我们的器件指针。
    USBDCDCPacketWrite、 // pfnTransfer
    USBDCDCTxPacketAvailable、 // pfnAvailable
    (void *)&g_psCDCDevice、 // pvHandle
    G_pui8USBTxBufferCDC、 // pui8Buffer
    256、 // ui32BufferSize
    };
    tCompositeEntry g_psComp实体[2];
    
    tUSBDCompositeDevice g_sCompDevice =
    {
    //
    德州仪器 C 系列 VID。
    //
    USB_VID_TI_1CBE、
    //
    德州仪器(TI)为复合串行器件插入 C 系列 PID。
    //
    PID_Assigned_by TI、
    //
    //此增量为2mA、因此为500mA。
    //
    250、
    //
    //总线供电设备。
    //
    USB_CONF_ATTR_SELF,
    //
    复合事件处理程序。
    //
    0、
    //
    /字符串表。
    //
    g_ppui8StringDescriptors、
    NUM_STRING_descriptors、
    //
    //复合设备数组。
    //
    2、
    g_psCompEntry
    
    };
    
    uint8_t g_pui8描述符 Data[descriptor_data_size];
    
    
    。
    。
    。
    //将设备信息传递到 USB 库并将设备放置在总线上
    
    pvCDCDevice = USBDCDCCompositeInit (0、&g_psCDCDevice、&g_psCompEntry[0]);
    
    pvBulkDeviceA = USBDBulkCompositeInit (0、&g_sBulkDeviceA、&g_psCompEntry[1]);
    
    
    USBDCompositeInit (0、&g_sComp.Device、描述符_data_size、g_pui8描述符数据);
    

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

    当使用具有 CDC 类的复合器件时、据我所知、中断端点生成的中断状态保留了一定的数量。 我不确定这个固定值是多少(应该在规格中)。 您能否在 USB 规格中检查相同的内容?

    我不确定这种混合的性能概况、尤其是在发送实时数据时。 此外、当您提到错误计数器 send_packet 函数增加时、USB 管道可能正忙、但它不会将相同的内容释放到端点。 由于您能够在批量实施中获得性能、您是否可以依赖相同的数据传输?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Amit、您好!
    很抱歉耽误你的回答。 这两个不同的类来自主机应用程序的早期版本。 使用最新的硬件(旧版本的 Atmel-MCU 和现在的 TI LaunchPad)、数据将通过批量 EP 发送、而针对 μ µC 的命令将通过 CDC 类器件发送。 为了确保与较旧和较新硬件兼容、我尝试在 LaunchPad 中使用较旧硬件的给定 USB-Configuration。 在这些器件中、使用了相同的器件组合并正常工作。 因此、我认为分配不同的 EPS 在这里也应该起作用。
    到目前为止、主机应用程序能够连接 LaunchPad 并与之通信。 我现在达到大约250kHz 的样片。 我认为、通过更高效地使用 USB 缓冲器、我将能够实现更高的效率。 这就是我现在正在做的工作。 如果我会遇到更多问题,我会向你提出更多问题:-)
    目前、这里唯一开放的主题是为每个器件使用不同的 EPS、而不是复合器件驱动程序默认分配的 EPS。
    再次感谢您的意见。 该器件的工作效果比以前好得多!
    此致、
    Felix
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Refe

    处理复合器件时需要不同的 EP。 因此、它是您拥有的正确模型。 我始终使用一组 EP 作为批量输入和输出、其数据包结构包含控制和数据信息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Amit、您好!

    我觉得不够清楚。 我的意思是、我希望使用 EP4等 EP 作为数据信息。 现在、默认情况下会分配 EP 编号(从 EP1开始向上计数;请参阅下图)。 为了确保与较旧的硬件板兼容、我希望使用中的 EP3作为中断 EP、而不是中的 EP1。 此外、我还想更改与不同器件和接口相关的其他 EP 编号。
    在创建单个批量器件时、我能够通过在第73-74行的 usbdbbbbulk.c 中设置它来更改分配给接口的 EPS (定义名为 DATA_IN_端 点和 DATA_OUT_终结 点)。 更改这些值对复合器件没有影响。

    此致、

    Felix

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

    可以使用不同的 EP。 我认为我们不会对实施模型提出硬性和快速的规则。 相反、我们以在 USB 内核中出现的递增顺序使用了 EP。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Amit、您好!

    您的提示非常有用、软件可以按计划发布。  

    下一次升级应该能提供更好的示波器采样率、这意味着提高 USB 传输的速度。 现在、我们将达到0.5 MB/s 的传输速率 USB 批量示例达到的传输速率约为0.8MB/s  

    两者都远低于 USB 2.0速率(60MB/s)和 USB 1.0速率(1.5MB/s)。 TM4C 是否能够使用 USB2.0?  

    在此线程中、我了解了双数据包缓冲(USB-Speed Thread)并遵循 Tsuno Chinzeis 建议/代码片段。 遗憾的是、它无助于提高传输速率。

    到目前为止、我已经测试了不同的 usblib 函数 USBBufferWrite 和 USBBufferDataWritten。 正如预期 的那样、USBBufferDataWritten 函数比 USBBufferWrite 函数快得多。 下一步是实现 USB-DMA 通道并测试这是如何提高 USB 速度的。 但是、因为我们远低于可能的最大值 传输速率、恐怕这不会像预期的那样有用。

    您对如何加快变速器有其他建议吗?

    我们希望实现尽可能高的传输速率、但至少要达到大约2MB/s

    非常感谢您的参与、

    Felix