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.

[参考译文] TM4C123FH6PM:USB 复合器件:TX 不适用于从3开始的 CDC 复合器件

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1050481/tm4c123fh6pm-usb-composite-device-tx-does-not-work-for-cdc-composite-devices-started-from-3

器件型号:TM4C123FH6PM

您好!

我正在设计一个用作集线器的器件、将多个串行器件连接到计算机、用作 USB CDC 器件。 此器件使用 usblib 来创建具有所需 CDC 器件名称的复合器件。

它可以与多达3个器件完美配合、但当我尝试添加更多器件时、我面临以下问题:当我从主机接收数据并且我的底层器件发回一些响应时、主机从未收到过该数据。

调试应用程序我看到器件结构将 iCDCTxState 字段设置为 eCDCStateWaitData 并读取 usbcdc.c 我看到该字段应 通过 ProcessDataToHost()函数(由 HandleEndpoints()函数调用)设置为 eCDCStateIdle,但  HandleEndpoints()仅在从主机接收数据时调用。 但绝不在 从 USB 缓冲区调用 ScheduleNextTransmission ()之后。

CDC 器件的初始化方式相同:

    int i;
    for(i = 0; i < nPorts; i++)
    {
        g_sCompDevice.psDevices[i].pvInstance =
                USBDCDCCompositeInit(0, &g_psCDCDevice[i], &g_psCompEntries[i]);
        USBBufferInit(&g_psTxBuffer[i]);
        USBBufferInit(&g_psRxBuffer[i]);
    }
    g_sCompDevice.ui32NumDevices = nPorts;
    pCompInst = USBDCompositeInit(0, (tUSBDCompositeDevice *)&g_sCompDevice, COMPOSITE_DCDC_SIZE * nPorts,
                      g_pucDescriptorData);

这些结构被声明为:

extern tUSBBuffer g_psTxBuffer[MAX_SERIAL_DEVICES];
extern tUSBBuffer g_psRxBuffer[MAX_SERIAL_DEVICES];
extern tUSBDCDCDevice g_psCDCDevice[MAX_SERIAL_DEVICES];
extern uint8_t g_pui8USBTxBuffer[];
extern uint8_t g_pui8USBRxBuffer[];
extern uint32_t ControlHandler(void *pvCBData, uint32_t ui32Event,
                               uint32_t ui32MsgValue, void *pvMsgData);
extern uint32_t RxHandlerCDC(void *pvCBData, uint32_t ui32Event,
                              uint32_t ui32MsgValue, void *pvMsgData);
extern uint32_t TxHandlerCDC(void *pvlCBData, uint32_t ui32Event,
                              uint32_t ui32MsgValue, void *pvMsgData);


#define CDC_DEV_STRUCT(n)                           \
        {                                           \
            USB_VID_TI_1CBE,                        \
            USB_PID_SERIAL,                         \
            0,                                      \
            USB_CONF_ATTR_BUS_PWR,                  \
            ControlHandler,                         \
            (void *)&g_psCDCDevice[n],              \
            USBBufferEventCallback,                 \
            (void *)&g_psRxBuffer[n],               \
            USBBufferEventCallback,                 \
            (void *)&g_psTxBuffer[n],               \
            g_pui8StringDescriptorsCDC,             \
            NUM_STRING_DESCRIPTORS                  \
        }

tUSBDCDCDevice g_psCDCDevice[MAX_SERIAL_DEVICES] =
{
 CDC_DEV_STRUCT(0),
 CDC_DEV_STRUCT(1),
 CDC_DEV_STRUCT(2),
 CDC_DEV_STRUCT(3),
 CDC_DEV_STRUCT(4),
 CDC_DEV_STRUCT(5),
 CDC_DEV_STRUCT(6),
 CDC_DEV_STRUCT(7),
 CDC_DEV_STRUCT(8),
 CDC_DEV_STRUCT(9),
 CDC_DEV_STRUCT(10),
 CDC_DEV_STRUCT(11),
 CDC_DEV_STRUCT(12),
 CDC_DEV_STRUCT(13),
 CDC_DEV_STRUCT(14),
 CDC_DEV_STRUCT(15)
};

#define CDC_RX_BUFFER(n)                            \
        {                                           \
            false,                                  \
            RxHandlerCDC,                           \
            (void *)&g_psCDCDevice[n],              \
            USBDCDCPacketRead,                      \
            USBDCDCRxPacketAvailable,               \
            (void *)&g_psCDCDevice[n],              \
            g_ppui8USBRxBuffer[n],                  \
            UART_BUFFER_SIZE,                       \
        }

uint8_t g_ppui8USBRxBuffer[MAX_SERIAL_DEVICES][UART_BUFFER_SIZE];
tUSBBuffer g_psRxBuffer[MAX_SERIAL_DEVICES] =
{
 CDC_RX_BUFFER(0),
 CDC_RX_BUFFER(1),
 CDC_RX_BUFFER(2),
 CDC_RX_BUFFER(3),
 CDC_RX_BUFFER(4),
 CDC_RX_BUFFER(5),
 CDC_RX_BUFFER(6),
 CDC_RX_BUFFER(7),
 CDC_RX_BUFFER(8),
 CDC_RX_BUFFER(9),
 CDC_RX_BUFFER(10),
 CDC_RX_BUFFER(11),
 CDC_RX_BUFFER(12),
 CDC_RX_BUFFER(13),
 CDC_RX_BUFFER(14),
 CDC_RX_BUFFER(15)
};

#define CDC_TX_BUFFER(n)                            \
        {                                           \
            true,                                   \
            TxHandlerCDC,                           \
            (void *)&g_psCDCDevice[n],              \
            USBDCDCPacketWrite,                     \
            USBDCDCTxPacketAvailable,               \
            (void *)&g_psCDCDevice[n],              \
            g_ppcUSBTxBuffer[n],                    \
            UART_BUFFER_SIZE,                       \
        }

uint8_t g_ppcUSBTxBuffer[MAX_SERIAL_DEVICES][UART_BUFFER_SIZE];
tUSBBuffer g_psTxBuffer[MAX_SERIAL_DEVICES] =
{
 CDC_TX_BUFFER(0),
 CDC_TX_BUFFER(1),
 CDC_TX_BUFFER(2),
 CDC_TX_BUFFER(3),
 CDC_TX_BUFFER(4),
 CDC_TX_BUFFER(5),
 CDC_TX_BUFFER(6),
 CDC_TX_BUFFER(7),
 CDC_TX_BUFFER(8),
 CDC_TX_BUFFER(9),
 CDC_TX_BUFFER(10),
 CDC_TX_BUFFER(11),
 CDC_TX_BUFFER(12),
 CDC_TX_BUFFER(13),
 CDC_TX_BUFFER(14),
 CDC_TX_BUFFER(15)
};

端点数量是否有任何限制?

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

    您好 Oleg、

    这里没有足够的信息让我真正评估这一点。 您能否提供整个 USB_structs.c 和 usb_structs.h 文件作为附件、以便我可以查看所有声明和定义的变量?

    我 非常相信您可以完成3个以上的端口、但 我不确定上限是多少、我肯定没有看到使用的端口数量减少了8个16个。 如果不修改 USB 库、我怀疑16位可能会是可行的。

    此致、

    Ralph Jacobi

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

    问题从第4个 CDC 器件开始。 3个器件运行良好。 外部变量 nPorts 定义活动 CDC 器件的数量。 我 的所有 USB 部件代码都位于 usb.c 文件中、这里是:

    /*
     * usb.c
     *
     *  Created on: 8 ёхэЄ. 2021 у.
     *      Author: Kit
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_uart.h"
    #include "inc/hw_qei.h"
    #include "inc/hw_i2c.h"
    #include "inc/hw_can.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "driverlib/usb.h"
    #include "driverlib/gpio.h"
    #include "driverlib/i2c.h"
    #include "driverlib/qei.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/can.h"
    #include "usblib/usblib.h"
    #include "usblib/usbcdc.h"
    #include "usblib/usbhid.h"
    #include "usblib/usb-ids.h"
    #include "usblib/device/usbdevice.h"
    #include "usblib/device/usbdcomp.h"
    #include "usblib/device/usbdcdc.h"
    #include "usblib/device/usbdhid.h"
    #include "usblib/device/usbdhidkeyb.h"
    
    
    //*****************************************************************************
    //
    // The languages supported by this device.
    //
    //*****************************************************************************
    const uint8_t g_pui8LangDescriptor[] =
    {
        4,
        USB_DTYPE_STRING,
        USBShort(USB_LANG_EN_US)
    };
    
    //*****************************************************************************
    //
    // The manufacturer string.
    //
    //*****************************************************************************
    const uint8_t g_pui8ManufacturerString[] =
    {
        (17 + 1) * 2,
        USB_DTYPE_STRING,
        'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0,
        't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0,
    };
    
    //*****************************************************************************
    //
    // The product string.
    //
    //*****************************************************************************
    const uint8_t g_pui8ProductString[] =
    {
        2 + (16 * 2),
        USB_DTYPE_STRING,
        'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0,
        'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0
    };
    const uint8_t g_pui8ProductStringComp[] =
    {
        2 + (16 * 2),
        USB_DTYPE_STRING,
        'P', 0, 'o', 0, 'r', 0, 't', 0, 'l', 0, 'a', 0, 'b', 0, ' ', 0,
        'B', 0, 'r', 0, 'e', 0, 'a', 0, 'k', 0, 'o', 0, 'u', 0, 't', 0
    };
    
    uint8_t g_pui8SerialNumberStringComp[] =
    {
        2 + (8 * 2),
        USB_DTYPE_STRING,
        '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '1', 0
    };
    
    //*****************************************************************************
    //
    // The control interface description string.
    //
    //*****************************************************************************
    const uint8_t g_pui8ControlInterfaceString[] =
    {
        2 + (21 * 2),
        USB_DTYPE_STRING,
        'A', 0, 'C', 0, 'M', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0,
        'r', 0, 'o', 0, 'l', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0,
        'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0
    };
    
    //*****************************************************************************
    //
    // The configuration description string.
    //
    //*****************************************************************************
    const uint8_t g_pui8ConfigString[] =
    {
     2 + (26 * 2),
     USB_DTYPE_STRING,
     'B', 0, 'u', 0, 's', 0, ' ', 0, 'P', 0, 'o', 0, 'w', 0,
     'e', 0, 'r', 0, 'e', 0, 'd', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0,
     'f', 0, 'i', 0, 'g', 0, 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0,
     'o', 0, 'n', 0
    };
    const uint8_t g_pui8ConfigStringComp[] =
    {
        2 + (26 * 2),
        USB_DTYPE_STRING,
        'B', 0, 'u', 0, 's', 0, ' ', 0, 'P', 0, 'o', 0, 'w', 0,
        'e', 0, 'r', 0, 'e', 0, 'd', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0,
        'f', 0, 'i', 0, 'g', 0, 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0,
        'o', 0, 'n', 0
    };
    
    //*****************************************************************************
    //
    // The descriptor string table.
    //
    //*****************************************************************************
    const uint8_t * const g_pui8StringDescriptorsCDC[] =
    {
        g_pui8LangDescriptor,
        g_pui8ManufacturerString,
        g_pui8ProductString,
        g_pui8SerialNumberStringComp,
        g_pui8ControlInterfaceString,
        g_pui8ConfigString
    };
    
    const uint8_t * const g_pui8StringDescriptorsComp[] =
    {
        g_pui8LangDescriptor,
        g_pui8ManufacturerString,
        g_pui8ProductStringComp,
        g_pui8SerialNumberStringComp,
        g_pui8ControlInterfaceString,
        g_pui8ConfigStringComp
    };
    
    #define NUM_STRING_DESCRIPTORS (sizeof(g_pui8StringDescriptorsCDC) /             \
                                    sizeof(uint8_t *))
    #define NUM_STRING_DESCRIPTORS_COMP (sizeof(g_pui8StringDescriptorsComp) /             \
                                    sizeof(uint8_t *))
    
    #define MAX_SERIAL_DEVICES      16
    #define UART_BUFFER_SIZE        256
    
    extern tUSBBuffer g_psTxBuffer[MAX_SERIAL_DEVICES];
    extern tUSBBuffer g_psRxBuffer[MAX_SERIAL_DEVICES];
    extern tUSBDCDCDevice g_psCDCDevice[MAX_SERIAL_DEVICES];
    extern uint8_t g_pui8USBTxBuffer[];
    extern uint8_t g_pui8USBRxBuffer[];
    extern uint32_t ControlHandler(void *pvCBData, uint32_t ui32Event,
                                   uint32_t ui32MsgValue, void *pvMsgData);
    extern uint32_t RxHandlerCDC(void *pvCBData, uint32_t ui32Event,
                                  uint32_t ui32MsgValue, void *pvMsgData);
    extern uint32_t TxHandlerCDC(void *pvlCBData, uint32_t ui32Event,
                                  uint32_t ui32MsgValue, void *pvMsgData);
    
    
    #define CDC_DEV_STRUCT(n)                           \
            {                                           \
                USB_VID_TI_1CBE,                        \
                USB_PID_SERIAL,                         \
                0,                                      \
                USB_CONF_ATTR_BUS_PWR,                  \
                ControlHandler,                         \
                (void *)&g_psCDCDevice[n],              \
                USBBufferEventCallback,                 \
                (void *)&g_psRxBuffer[n],               \
                USBBufferEventCallback,                 \
                (void *)&g_psTxBuffer[n],               \
                g_pui8StringDescriptorsCDC,             \
                NUM_STRING_DESCRIPTORS                  \
            }
    
    tUSBDCDCDevice g_psCDCDevice[MAX_SERIAL_DEVICES] =
    {
     CDC_DEV_STRUCT(0),
     CDC_DEV_STRUCT(1),
     CDC_DEV_STRUCT(2),
     CDC_DEV_STRUCT(3),
     CDC_DEV_STRUCT(4),
     CDC_DEV_STRUCT(5),
     CDC_DEV_STRUCT(6),
     CDC_DEV_STRUCT(7),
     CDC_DEV_STRUCT(8),
     CDC_DEV_STRUCT(9),
     CDC_DEV_STRUCT(10),
     CDC_DEV_STRUCT(11),
     CDC_DEV_STRUCT(12),
     CDC_DEV_STRUCT(13),
     CDC_DEV_STRUCT(14),
     CDC_DEV_STRUCT(15)
    };
    
    #define CDC_RX_BUFFER(n)                            \
            {                                           \
                false,                                  \
                RxHandlerCDC,                           \
                (void *)&g_psCDCDevice[n],              \
                USBDCDCPacketRead,                      \
                USBDCDCRxPacketAvailable,               \
                (void *)&g_psCDCDevice[n],              \
                g_ppui8USBRxBuffer[n],                  \
                UART_BUFFER_SIZE,                       \
            }
    
    uint8_t g_ppui8USBRxBuffer[MAX_SERIAL_DEVICES][UART_BUFFER_SIZE];
    tUSBBuffer g_psRxBuffer[MAX_SERIAL_DEVICES] =
    {
     CDC_RX_BUFFER(0),
     CDC_RX_BUFFER(1),
     CDC_RX_BUFFER(2),
     CDC_RX_BUFFER(3),
     CDC_RX_BUFFER(4),
     CDC_RX_BUFFER(5),
     CDC_RX_BUFFER(6),
     CDC_RX_BUFFER(7),
     CDC_RX_BUFFER(8),
     CDC_RX_BUFFER(9),
     CDC_RX_BUFFER(10),
     CDC_RX_BUFFER(11),
     CDC_RX_BUFFER(12),
     CDC_RX_BUFFER(13),
     CDC_RX_BUFFER(14),
     CDC_RX_BUFFER(15)
    };
    
    #define CDC_TX_BUFFER(n)                            \
            {                                           \
                true,                                   \
                TxHandlerCDC,                           \
                (void *)&g_psCDCDevice[n],              \
                USBDCDCPacketWrite,                     \
                USBDCDCTxPacketAvailable,               \
                (void *)&g_psCDCDevice[n],              \
                g_ppcUSBTxBuffer[n],                    \
                UART_BUFFER_SIZE,                       \
            }
    
    uint8_t g_ppcUSBTxBuffer[MAX_SERIAL_DEVICES][UART_BUFFER_SIZE];
    tUSBBuffer g_psTxBuffer[MAX_SERIAL_DEVICES] =
    {
     CDC_TX_BUFFER(0),
     CDC_TX_BUFFER(1),
     CDC_TX_BUFFER(2),
     CDC_TX_BUFFER(3),
     CDC_TX_BUFFER(4),
     CDC_TX_BUFFER(5),
     CDC_TX_BUFFER(6),
     CDC_TX_BUFFER(7),
     CDC_TX_BUFFER(8),
     CDC_TX_BUFFER(9),
     CDC_TX_BUFFER(10),
     CDC_TX_BUFFER(11),
     CDC_TX_BUFFER(12),
     CDC_TX_BUFFER(13),
     CDC_TX_BUFFER(14),
     CDC_TX_BUFFER(15)
    };
    
    #define DESCRIPTOR_DATA_SIZE    (COMPOSITE_DCDC_SIZE * MAX_SERIAL_DEVICES)
    
    //****************************************************************************
    //
    // The memory allocated to hold the composite descriptor that is created by
    // the call to USBDCompositeInit().
    //
    //****************************************************************************
    uint8_t g_pui8DescriptorData[DESCRIPTOR_DATA_SIZE];
    
    tCompositeEntry g_psCompEntries[MAX_SERIAL_DEVICES];
    
    //*****************************************************************************
    //
    //! The structure used by the application to define operating parameters for
    //! the composite device class.
    //
    //*****************************************************************************
    typedef struct
    {
        //
        //! The vendor ID that this device is to present in the device descriptor.
        //
        const uint16_t ui16VID;
    
        //
        //! The product ID that this device is to present in the device descriptor.
        //
        const uint16_t ui16PID;
    
        //
        //! The maximum power consumption of the device, expressed in mA.
        //
        const uint16_t ui16MaxPowermA;
    
        //
        //! Indicates whether the device is self or bus-powered and whether or not
        //! it supports remote wake up.  Valid values are \b USB_CONF_ATTR_SELF_PWR
        //! or \b USB_CONF_ATTR_BUS_PWR, optionally ORed with
        //! \b USB_CONF_ATTR_RWAKE.
        //
        const uint8_t ui8PwrAttributes;
    
        //
        //! A pointer to the callback function which will be called to notify
        //! the application of events relating to the operation of the composite
        //! device.
        //
        const tUSBCallback pfnCallback;
    
        //
        //! A pointer to the string descriptor array for this device.  This array
        //! must contain the following string descriptor pointers in this order.
        //! Language descriptor, Manufacturer name string (language 1), Product
        //! name string (language 1), Serial number string (language 1), Composite
        //! device interface description string (language 1), Configuration
        //! description string (language 1).
        //!
        //! If supporting more than 1 language, the descriptor block (except for
        //! string descriptor 0) must be repeated for each language defined in the
        //! language descriptor.
        //!
        //
        const uint8_t * const *ppui8StringDescriptors;
    
        //
        //! The number of descriptors provided in the ppStringDescriptors
        //! array.  This must be 1 + ((5 + (number of strings)) *
        //!                           (number of languages)).
        //
        const uint32_t ui32NumStringDescriptors;
    
        //
        //! The number of devices in the psDevices array.
        //
        uint32_t ui32NumDevices;
    
        //
        //! This application supplied array holds the the top level device class
        //! information as well as the Instance data for that class.
        //
        tCompositeEntry * const psDevices;
    
        //
        //! The private data for this device instance.  This memory must remain
        //! accessible for as long as the composite device is in use and must
        //! not be modified by any code outside the composite class driver.
        //
        tCompositeInstance sPrivateData;
    }
    tUSBDCompositeDeviceM;
    
    //****************************************************************************
    //
    // Allocate the Device Data for the top level composite device class.
    //
    //****************************************************************************
    tUSBDCompositeDeviceM g_sCompDevice =
    {
        //
        // Stellaris VID.
        //
        USB_VID_TI_1CBE,
    
        //
        // Stellaris PID for composite serial device.
        //
        USB_PID_COMP_HID_SER,
    
        //
        // This is in 2mA increments so 500mA.
        //
        250,
    
        //
        // Bus powered device.
        //
        USB_CONF_ATTR_BUS_PWR,
    
        //
        // There is no need for a default composite event handler.
        //
        0,
    
        //
        // The string table.
        //
        g_pui8StringDescriptorsComp,
        NUM_STRING_DESCRIPTORS_COMP,
    
        //
        // The Composite device array.
        //
        0,                                                          // To be changed on reinit
        g_psCompEntries
    };
    
    bool bConnected[16] = {false, false, false, false, false, false, false, false,
                           false, false, false, false, false, false, false, false};
    
    int nPorts = 1;
    
    uint32_t
    ControlHandler(void *pvCBData, uint32_t ui32Event,
                   uint32_t ui32MsgValue, void *pvMsgData)
    {
        tUSBDCDCDevice *pDev = (tUSBDCDCDevice *)pvCBData;
        uint8_t nPort = (((uint8_t *)pDev) - ((uint8_t *)g_psCDCDevice)) / sizeof(tUSBDCDCDevice);
        switch(ui32Event)
        {
            //
            // We are connected to a host and communication is now possible.
            //
            case USB_EVENT_CONNECTED:
            {
                int i;
                for(i = 0; i < nPorts; i++)
                {
                    bConnected[i] = true;
                    //
                    // Flush our buffers.
                    //
                    USBBufferFlush(&g_psTxBuffer[i]);
                    USBBufferFlush(&g_psRxBuffer[i]);
                }
    
                break;
            }
    
            //
            // The host has disconnected.
            //
            case USB_EVENT_DISCONNECTED:
            {
                bConnected[nPort] = false;
                break;
            }
    
            //
            // Return the current serial communication parameters.
            //
            case USBD_CDC_EVENT_GET_LINE_CODING:
            {
                {
                    tLineCoding *psLineCoding = (tLineCoding *)pvMsgData;
                    psLineCoding->ui32Rate = 19200;
                    psLineCoding->ui8Databits = 8;
                    psLineCoding->ui8Parity = USB_CDC_PARITY_NONE;
                    psLineCoding->ui8Stop = USB_CDC_STOP_BITS_1;
                }
                break;
            }
    
            //
            // Set the current serial communication parameters.
            //
            case USBD_CDC_EVENT_SET_LINE_CODING:
            {
                /*{
                    tLineCoding *psLineCoding = (tLineCoding *)pvMsgData;
                    BaudRate = psLineCoding->ui32Rate;
                }*/
                break;
            }
    
            //
            // Set the current serial communication parameters.
            //
            case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE:
            {
                /*if(((unsigned short)ui32MsgValue) == 0)
                    RTSPaused[Port] = true;
                if(((unsigned short)ui32MsgValue) == 1)
                    RTSPaused[Port] = false;
                if(((unsigned short)ui32MsgValue) == 2)
                    RTSPaused[Port] = true;
                if(((unsigned short)ui32MsgValue) == 3)
                    RTSPaused[Port] = false;*/
                // TODO: control lines
                break;
            }
    
            //
            // Send a break condition on the serial line.
            //
            case USBD_CDC_EVENT_SEND_BREAK:
            {
                //SendBreak(true);
                break;
            }
    
            //
            // Clear the break condition on the serial line.
            //
            case USBD_CDC_EVENT_CLEAR_BREAK:
            {
                //SendBreak(false);
                break;
            }
    
            //
            // Ignore SUSPEND and RESUME for now.
            //
            case USB_EVENT_SUSPEND:
            case USB_EVENT_RESUME:
            {
                break;
            }
    
            //
            // We don't expect to receive any other events.  Ignore any that show
            // up in a release build or hang in a debug build.
            //
            default:
            {
                break;
            }
        }
    
        return(0);
    
    }
    
    void SendCAN(uint8_t nPort, uint8_t *Data, uint8_t Len);
    
    uint32_t RxHandlerCDC(void *pvCBData, uint32_t ui32Event,
                                  uint32_t ui32MsgValue, void *pvMsgData)
    {
        tUSBDCDCDevice *pDev = (tUSBDCDCDevice *)pvCBData;
        uint8_t nPort = (((uint8_t *)pDev) - ((uint8_t *)g_psCDCDevice)) / sizeof(tUSBDCDCDevice);
        //
        // Which event are we being sent?
        //
        switch(ui32Event)
        {
            //
            // A new packet has been received.
            //
            case USB_EVENT_RX_AVAILABLE:
            {
                uint32_t DataRead = 0;
                uint8_t Data[64];
                while((DataRead = USBBufferRead(g_psRxBuffer + nPort, Data, 64)) != 0)
                {
                    SendCAN(nPort, Data, DataRead);
                }
                break;
            }
    
            //
            // We are being asked how much unprocessed data we have still to
            // process. We return 0 if the UART is currently idle or 1 if it is
            // in the process of transmitting something. The actual number of
            // bytes in the UART FIFO is not important here, merely whether or
            // not everything previously sent to us has been transmitted.
            //
            case USB_EVENT_DATA_REMAINING:
            {
                return CANStatusGet(CAN0_BASE, CAN_STS_TXREQUEST) & (1 << (nPort + 1)) ? 1 : 0;
            }
    
            //
            // We are being asked to provide a buffer into which the next packet
            // can be read. We do not support this mode of receiving data so let
            // the driver know by returning 0. The CDC driver should not be
            // sending this message but this is included just for illustration and
            // completeness.
            //
            case USB_EVENT_REQUEST_BUFFER:
            {
                return(0);
            }
    
            //
            // We don't expect to receive any other events.  Ignore any that show
            // up in a release build or hang in a debug build.
            //
            default:
            {
                break;
            }
        }
    
        return(0);
    }
    
    uint32_t TxHandlerCDC(void *pvlCBData, uint32_t ui32Event,
                                  uint32_t ui32MsgValue, void *pvMsgData)
    {
        tUSBDCDCDevice *pDev = (tUSBDCDCDevice *)pvlCBData;
        uint8_t nPort = (((uint8_t *)pDev) - ((uint8_t *)g_psCDCDevice)) / sizeof(tUSBDCDCDevice);
        return(0);
    }
    
    void USBSend(uint8_t nPort, uint8_t *Data, uint8_t Len)
    {
        if(bConnected[nPort])
            USBBufferWrite((tUSBBuffer *)&g_psTxBuffer[nPort], Data, Len);
    }
    
    void *pCompInst = 0;
    uint8_t g_pucDescriptorData[DESCRIPTOR_DATA_SIZE];
    
    void ReinitUSB()
    {
        if(pCompInst)
        {
            USBDCompositeTerm(pCompInst);
            SysCtlPeripheralDisable(SYSCTL_PERIPH_USB0);
            SysCtlDelay(80000000);
            SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
            uint32_t Clk = SysCtlClockGet();
            uint32_t Power = USBLIB_FEATURE_POWER_BUS;
            USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &Clk);
            USBDCDFeatureSet(0, USBLIB_FEATURE_POWER, &Power);
            USBStackModeSet(0, eUSBModeForceDevice, 0);
        }
        int i;
        for(i = 0; i < nPorts; i++)
        {
            g_sCompDevice.psDevices[i].pvInstance =
                    USBDCDCCompositeInit(0, &g_psCDCDevice[i], &g_psCompEntries[i]);
            USBBufferInit(&g_psTxBuffer[i]);
            USBBufferInit(&g_psRxBuffer[i]);
        }
        g_sCompDevice.ui32NumDevices = nPorts;
        pCompInst = USBDCompositeInit(0, (tUSBDCompositeDevice *)&g_sCompDevice, COMPOSITE_DCDC_SIZE * nPorts,
                          g_pucDescriptorData);
    }
    
    int InitCtr = 0;
    
    void TimersInt()
    {
        TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
        if(InitCtr++ == 5)
        {
            ReinitUSB();
            TimerDisable(TIMER1_BASE, TIMER_A);
        }
    }
    
    void InitUSB()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_5 | GPIO_PIN_4);
        uint32_t Clk = SysCtlClockGet();
        uint32_t Power = USBLIB_FEATURE_POWER_BUS;
        USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &Clk);
        USBDCDFeatureSet(0, USBLIB_FEATURE_POWER, &Power);
        USBStackModeSet(0, eUSBModeForceDevice, 0);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
        TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
        TimerLoadSet(TIMER1_BASE, TIMER_A, SysCtlClockGet());
        TimerIntRegister(TIMER1_BASE, TIMER_A, &TimersInt);
        TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
        TimerEnable(TIMER1_BASE, TIMER_A);
    
    }
    
    
    
    

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

    您好 Oleg、

    感谢您提供代码。

    [引用 userid="140078" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1050481/tm4c123fh6pm-usb-composite-device-tx-does-not-work-for-cdc-composite-devices-started-from-3/3886746 #3886746"]问题始于第4个 CDC 器件。 3个器件运行良好。 外部变量 nPorts 定义活动 CDC 器件的数量。

    那么、我的理解是、应用程序将 nPorts 设置为等于某个值、如果您设置 nPorts = 3并调用 ReinitUSB、那么它可以正常工作、但是如果您设置 nPorts = 4并调用 ReinitUSB、那么您只能获得三个 CDC 接口?

    虽然我没有像设置代码那样使用您放置的代码、但我确实将其移植到项目中并进行测试、并且 我能够获得最多7个枚举端口。 在这里、最初不清楚这是否是 USB 库的限制、但我确实能够获得4、5、6和7个 CDC 端口来正确枚举。

    有关尝试使用7个以上端口的进一步调查需要几天时间、因为我需要深入研究 USB 分析仪捕获、以了解7个端口和8个端口之间的区别、以查看其是否是库限制或其他内容。

    此致、

    Ralph Jacobi

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

    错误。 在启动5秒后调用一次 ReinitUSB,这次将 nPorts 设置为正确的值。 所有 CDC 端口都已设置并显示在 Windows 设备管理器中、我可以连接它们。 但是、当我连接任何大于第三方的端口时、我可以将数据写入该端口、并且我可以接收器件上的所有数据、但当器件将数据写回主机时、主机不会接收到数据、 并且端口的 iCDCTxState 字段会 永远设置为 eCDCStateWaitData。

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

    我找到了原因。

    每个使用的 CDC 端口有2个输入端点、一个中断和一个批量。

    由于最多有7个端点、因此第4个器件超出端点。

    是否有任何可能的解决方法?

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

    找到了简单的权变措施:只需从描述符结构中删除中断端点。 多达7个器件的一切正常。

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

    您好 Oleg、

    很高兴您找到了权变措施。  我认为这是一个根本原因和一个变通办法。 很抱歉、我一开始不太了解核心问题。 通常、在涉及复合材料时、其他器件的枚举存在问题、这是我最初关注的问题、但我看到您更关注数据传输元素。

    7个端点限制也是允许最多连接7个器件的原因、这也说明了这一点。 老实说、我以前没有考虑过硬件限制、也没有昨天的软件那样。

    此致、

    Ralph Jacobi