CDC EEM Subclass Configuration

General Configuration

There are various configuration constants necessary to customize the CDC EEM subclass. These constants are located in the usbd_cfg.h file.  Table - CDC EEM Configuration Constants shows a description of each constant.

Table - CDC EEM Configuration Constants
ConstantDescriptionPossible Values
USBD_CDC_EEM_CFG_MAX_NBR_DEVConfigures the maximum number of class instances. Unless you plan having multiple configuration or interfaces using different class instances, this should be set to 1.From 1 to 254. Default value is 1.
USBD_CDC_EEM_CFG_MAX_NBR_CFGConfigures the maximum number of configuration in which CDC EEM is used. Keep in mind that if you use a high-speed device, two configurations will be built, one for full-speed and another for high-speed.From 1 (full-speed) or 2 (high-speed) to 254. Default value is 2.
USBD_CDC_EEM_CFG_RX_BUF_LENConfigures the length, in octets, of the buffer(s) used to receive the data from the host. This buffer must ideally be a multiple of the max packet size of the endpoint. However, most of the time this can be set to the Ethernet Maximum Transmit Unit (MTU -> 1518) + 2 for the CDC EEM header for better performances.64 or more. Multiple of maximum packet size if below (MTU + 2). Default value is 1520.
USBD_CDC_EEM_CFG_ECHO_BUF_LENConfigures the length, in octets, of the echo buffer used to transmit an echo response command upon reception of an echo command from the host. Size of this buffer depends on the largest possible echo data that can be sent by the host.Higher than 2. Default value is 64.
USBD_CDC_EEM_CFG_RX_BUF_QTY_PER_DEV (optional)Configures the quantity of receive buffers to be used to receive data from the host. It is not mandatory to set the value in your usbd_cfg.h file. Before setting this value to something higher than 1, you MUST ensure that you USB device driver supports URB queuing. You must also correctly configure the constant USBD_CFG_MAX_NBR_URB_EXTRA. Increasing this value will improve the data reception performances by providing multiple buffering mechanism.1 or more. Default value is 1.

Class Instance Configuration

Before starting the communication phase, your application needs to initialize and configure the class to suit its needs. Table - Class Instance Initialization API Functions summarizes the initialization functions provided by the CDC EEM implementation. Please refer to the CDC EEM API reference for a full listing of the CDC EEM API.

Table - Class Instance Initialization API Functions
Function nameOperation
USBH_CDC_EEM_Init() Initializes CDC EEM internal structures and variables.
USBH_CDC_EEM_Add() Adds a new instance of the CDC EEM subclass.
USBD_CDC_EEM_CfgAdd() Adds existing CDC EEM instance into USB device configuration.


To successfully initialize the CDC EEM subclass, you need to follow these steps:

  1. Call USBD_CDC_EEM_Init()
    This is the first function you should call, and it should be called only once regardless of the number of class instances you intend to have. This function will initialize all internal structures and variables that the class will need.
  2. Call USBD_CDC_EEM_Add()
    This function will add a new instance of the CDC EEM subclass.
  3. Call USBD_CDC_EEM_CfgAdd()
    Once the class instance is correctly configured and initialized, you will need to add it to a USB configuration. High speed devices will build two separate configurations, one for full speed and one for high speed by calling USBD_CDC_EEM_CfgAdd() for each speed configuration.
  4. Add a network interface using CDC EEM as the physical link.
    For more information on how to initialize the µC/TCP-IP stack, see UserManual

Listing - CDC EEM Initialization Example shows how the latter functions are called during CDC EEM initialization and an example of creation and initialization of a CDC EEM network interface using µC/TCP-IP.

USBD_ERR       err;
NET_IF_NBR     net_if_nbr;
NET_IPv4_ADDR  addr;
NET_IPv4_ADDR  subnet_mask;
NET_IPv4_ADDR  dflt_gateway;
NET_ERR        err_net;


USBD_CDC_EEM_Init(&err);                                    /* CDC EEM class initialization.                        */  (1)
if (err != USBD_ERR_NONE) {
    return (DEF_FAIL);
}

cdc_eem_nbr = USBD_CDC_EEM_Add(&err);                       /* Create CDC EEM class instance.                       */  (2)
if (err != USBD_ERR_NONE) {
    return (DEF_FAIL);
}

                                                            /* Add CDC EEM class instance to USB configuration(s).  */  (3)
if (cfg_hs != USBD_CFG_NBR_NONE) {
    USBD_CDC_EEM_CfgAdd(cdc_eem_nbr,
                        dev_nbr,
                        cfg_hs,
                       "CDC EEM interface",
                       &err);
    if (err != USBD_ERR_NONE) {
        return (DEF_FAIL);
    }
}

if (cfg_fs != USBD_CFG_NBR_NONE) {
    USBD_CDC_EEM_CfgAdd(cdc_eem_nbr,
                        dev_nbr,
                        cfg_fs,
                       "CDC EEM interface",
                       &err);
    if (err != USBD_ERR_NONE) {
        return (DEF_FAIL);
    }
}
                                                            /* Add uC/TCP-IP interface using CDC EEM.               */   
NetDev_Cfg_Ether_USBD_CDCEEM.ClassNbr = cdc_eem_nbr;        /* Set CDC EEM class instance number to drv cfg.        */   (4)
net_if_nbr = NetIF_Add((void *)&NetIF_API_Ether,                                                                         (5)
                       (void *)&NetDev_API_USBD_CDCEEM,
                                DEF_NULL,
                       (void *)&NetDev_Cfg_Ether_USBD_CDCEEM,
                                DEF_NULL,
                                DEF_NULL,
                               &err_net);
if (err_net != NET_IF_ERR_NONE) {
    return (DEF_FAIL);
}
                                                            /* Set static address to device.                        */   (6)
addr         = NetASCII_Str_to_IPv4("192.168.0.10",
                                    &err_net);
subnet_mask  = NetASCII_Str_to_IPv4("255.255.255.0",
                                    &err_net);
dflt_gateway = NetASCII_Str_to_IPv4("192.168.0.1",
                                    &err_net);
NetIPv4_CfgAddrAdd(net_if_nbr,
                   addr,
                   subnet_mask,
                   dflt_gateway,
                  &err_net);
if (err_net != NET_IPv4_ERR_NONE) {
    return (DEF_FAIL);
}

NetIF_Start(net_if_nbr, &err_net);                          /* Start uC/TCP-IP interface.                           */   (7)
if (err_net != NET_IF_ERR_NONE) {
    return (DEF_FAIL);
}

(1) Initialize CDC EEM subclass.

(2) Create an instance of the CDC EEM subclass.

(3) Add CDC EEM subclass instance to USB configuration(s).

(4) Set CDC EEM class instance number in network driver configuration structure to be retrieved by µC/TCP-IP's USBD_CDCEEM driver.

(5) Add a new ethernet interface using USBD_CDCEEM driver.

(6) In this example, a static address is assigned to the device.

(7) Start the network interface.


Class Instance Configuration by Network Driver

The network driver that interfaces with the CDC EEM subclass must initialize the class instance with its specific requirements. This is done by calling the function USBD_CDC_EEM_InstanceInit() from the interface initialization function of the network driver. This function must be called only once. Listing - CDC EEM Instance init function gives the prototype of the function USBD_CDC_EEM_InstanceInit().

void  USBD_CDC_EEM_InstanceInit (CPU_INT08U         class_nbr,
                                 USBD_CDC_EEM_CFG  *p_cfg,              (1)
                                 USBD_CDC_EEM_DRV  *p_cdc_eem_drv,      (2)
                                 void              *p_arg,              (3)
                                 USBD_ERR          *p_err)

(1) Takes a pointer to a structure that contains the desired size of the receive and transmit buffers queue . Following listing gives the prototype of the configuration structure.

typedef  struct  usbd_cdc_eem_cfg {
    CPU_INT08U  RxBufQSize;                                     /* Size of rx buffer Q.                                 */
    CPU_INT08U  TxBufQSize;                                     /* Size of tx buffer Q.                                 */
} USBD_CDC_EEM_CFG;

(2) Takes a pointer to the CDC EEM driver. Following listing gives the details of the CDC EEM driver API.

typedef  const  struct  usbd_cdc_eem_drv {
                                                                /* Retrieve a Rx buffer.                                */
    CPU_INT08U  *(*RxBufGet)   (CPU_INT08U   class_nbr,
                                void        *p_arg,
                                CPU_INT16U  *p_buf_len);
                                                                /* Signal that a rx buffer is ready.                    */
    void         (*RxBufRdy)   (CPU_INT08U   class_nbr,
                                void        *p_arg);
                                                                /* Free a tx buffer.                                    */
    void         (*TxBufFree)  (CPU_INT08U   class_nbr,
                                void        *p_arg,
                                CPU_INT08U  *p_buf,
                                CPU_INT16U   buf_len);
} USBD_CDC_EEM_DRV;

(3) Pointer to network driver data.


Configuration of Network Driver

The network driver used to interact with the CDC EEM class MUST follow some guidelines for the configuration of its buffers.

  • The size of the receive AND transmit buffers MUST be set to 1518 bytes or more (MTU including CRC).
  • The alignment of transmit buffers MUST be a multiple of the alignment required by the USB controller.
  • The transmit buffers MUST have an offset of two (2) bytes at the beginning. This is necessary as the CDC EEM subclass will prepend the header.

Listing - Network Driver Configuration Example gives an example of configuration when the µC/TCP-IP's USBD_CDCEEM driver is used.

NET_DEV_CFG_USBD_CDC_EEM  NetDev_Cfg_Ether_USBD_CDCEEM = {
    NET_IF_MEM_TYPE_MAIN,           /* Desired receive  buffer memory pool type :                                       */
                                    /*   NET_IF_MEM_TYPE_MAIN        buffers allocated from main memory                 */
                                    /*   NET_IF_MEM_TYPE_DEDICATED   buffers allocated from (device's) dedicated memory */
    1518u,                          /* Desired size      of device's large receive  buffers (in octets).                */
      10u,                          /* Desired number    of device's large receive  buffers.                            */
    sizeof(CPU_ALIGN),              /* Desired alignment of device's       receive  buffers (in octets).                */
       0u,                          /* Desired offset from base receive  index, if needed   (in octets).                */
    NET_IF_MEM_TYPE_MAIN,           /* Desired transmit buffer memory pool type :                                       */
                                    /*   NET_IF_MEM_TYPE_MAIN        buffers allocated from main memory                 */
                                    /*   NET_IF_MEM_TYPE_DEDICATED   buffers allocated from (device's) dedicated memory */
    1518u,                          /* Desired size      of device's large transmit buffers (in octets).                */
       2u,                          /* Desired number    of device's large transmit buffers.                            */
      60u,                          /* Desired size      of device's small transmit buffers (in octets).                */
       1u,                          /* Desired number    of device's small transmit buffers.                            */
    USBD_CFG_BUF_ALIGN_OCTETS,      /* Desired alignment of device's       transmit buffers (in octets).                */
       2u,                          /* Desired offset from base transmit index, if needed   (in octets).                */
      "00:AB:CD:EF:80:01",          /* HW address.                                                                      */
       0u                           /* USBD CDC EEM class nbr. MUST be set at runtime after call to USBD_CDC_EEM_Add(). */
};