Other Parts Discussed in Thread: EK-TM4C1294XL
Hello,
I have to functioning USB projects for the 123GX launchpad and I'm trying to take these two USB projects and combine them into a composite device. After a few days of reading the documentation and usblib source code I've run into what looks like conflicting information - or I just got confused.
I see here that the usblib users guide says you need to support 3x strings which makes sense (shown below):

But when I look at the source code it requires more than this. See below.
//
//! 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 above user's guide screenshot and source code snippet are referring to a section of the composite device structure (found in usbdcomp.h) shown below:

complete structure source found in usbdcomp.h
//*****************************************************************************
//
//! 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.
//
const 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;
}
tUSBDCompositeDevice;
Questions:
1. Should I just follow the comments in the structure source code for string desc pointer which says the following are required {language desc, manf name string, product name str, serial num string, composite dev interface desc string, configuration desc string}? I ask because this is more than the user's guide says to have.
2. So what format are the strings supposed to be in? An example of the hid string descriptors are shown below. Should I copy and paste these and just change the contents for the composite strings?
//*****************************************************************************
//
// 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[] =
{
(19 + 1) * 2,
USB_DTYPE_STRING,
'G', 0, 'e', 0, 'n', 0, 'e', 0, 'r', 0, 'i', 0, 'c', 0, ' ', 0, 'B', 0,
'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0,
'e', 0
};
//*****************************************************************************
//
// The data interface description string.
//
//*****************************************************************************
const uint8_t g_pui8DataInterfaceString[] =
{
(19 + 1) * 2,
USB_DTYPE_STRING,
'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,
'a', 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[] =
{
(23 + 1) * 2,
USB_DTYPE_STRING,
'B', 0, 'u', 0, 'l', 0, 'k', 0, ' ', 0, 'D', 0, 'a', 0, 't', 0,
'a', 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 comments in the structure almost sound like you should end up with the below pointer to pointers to these strings.
//*****************************************************************************
//
// The descriptor string table.
//
//*****************************************************************************
const uint8_t * const g_ppui8StringDescriptors[] =
{
g_pui8LangDescriptor,
g_pui8ManufacturerString,
g_pui8ProductString,
g_pui8SerialNumberString,
g_pui8DataInterfaceString,
g_pui8ConfigString
};
3. For number of strings field (ppui8StringDescriptors pointer) the structure source says the following:
//
//! The number of descriptors provided in the ppStringDescriptors
//! array. This must be 1 + ((5 + (number of strings)) *
//! (number of languages)).
//
const uint32_t ui32NumStringDescriptors;
so what strings count towards the "number of strings" part of that equation? All of the ones pointed to by
const uint8_t * const *ppui8StringDescriptors;
4. When passing a HID and Bulk device structure do you pass the standard structure? I noticed the example uses buffers that I'm not using? My two device interfaces just use the standard structs from USBLIB. So for example my bulk device interface in my bulk project that is working just uses the following structure - I've removed the buffering support that comes with the example project.
//*****************************************************************************
//
//! The structure used by the application to define operating parameters for
//! the bulk device.
//
//*****************************************************************************
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 milliamps.
//
const uint16_t ui16MaxPowermA;
//
//! Indicates whether the device is self- or bus-powered and whether or not
//! it supports remote wakeup. Valid values are USB_CONF_ATTR_SELF_PWR or
//! USB_CONF_ATTR_BUS_PWR, optionally ORed with USB_CONF_ATTR_RWAKE.
//
const uint8_t ui8PwrAttributes;
//
//! A pointer to the callback function which will be called to notify
//! the application of events related to the device's data receive channel.
//
const tUSBCallback pfnRxCallback;
//
//! A client-supplied pointer which will be sent as the first
//! parameter in all calls made to the receive channel callback,
//! pfnRxCallback.
//
void *pvRxCBData;
//
//! A pointer to the callback function which will be called to notify
//! the application of events related to the device's data transmit
//! channel.
//
const tUSBCallback pfnTxCallback;
//
//! A client-supplied pointer which will be sent as the first
//! parameter in all calls made to the transmit channel callback,
//! pfnTxCallback.
//
void *pvTxCBData;
//
//! A pointer to the string descriptor array for this device. This array
//! must contain pointers to the following string descriptors in this
//! order. Language descriptor, Manufacturer name string (language 1),
//! Product name string (language 1), Serial number string (language 1),
//! Interface description string (language 1) and Configuration description
//! string (language 1).
//!
//! If supporting more than 1 language, the strings for indices 1 through 5
//! must be repeated for each of the other languages 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 supported languages).
//
const uint32_t ui32NumStringDescriptors;
//
//! The private instance data for this device. This memory must
//! not be modified by any code outside the bulk class driver.
//
tBulkInstance sPrivateData;
}
tUSBDBulkDevice;
Is this ok because it looks like the user's guide example passes the CDC device with the buffers and stuff which I'm not using in my bulk example anymore.


