AnsweredAssumed Answered

RNDIS USB device help

Question asked by smith.greg.005 on Nov 8, 2015
Latest reply on Apr 12, 2017 by Shail Shah
I'm trying to get port the code at https://github.com/fetisov/lrndis/tree/master/lrndis/rndis-stm32 over to the Cube firmware libs, but running into troubles.

Using STM32F429 Eval board, Keil uVision, Cube F4 V1.9.0 (also tried earlier version.)

Its works fine right up until I try to send Ethernet data back to the PC on the bulk endpoint.
As soon as I send, the foreground execution stops and it gets stuck repeatedly firing the USB interrupt. USB logging on the PC shows that data on that endpoint never arrives.

Here's some of the code:

#define RNDIS_NOTIFICATION_IN_EP 0x81
#define RNDIS_DATA_IN_EP         0x82
#define RNDIS_DATA_OUT_EP        0x03
 
#define RNDIS_NOTIFICATION_IN_SZ 0x08
#define RNDIS_DATA_IN_SZ         0x40
#define RNDIS_DATA_OUT_SZ        0x40
 
 
/* USB RNDIS device Configuration Descriptor */
static uint8_t USBD_RNDIS_CfgDesc[USB_RNDIS_CONFIG_DESC_SIZ] =
{
    //  RNDIS requires only one configuration as follows..
     
    9,                                 //  bLength         = 9 bytes.
    USB_DESC_TYPE_CONFIGURATION,       //  bDescriptorType = CONFIGURATION
    USB_RNDIS_CONFIG_DESC_SIZ, 0x00,   //  wTotalLength    = From offset 18 to end <---
    0x02,                              //  bNumInterfaces  = 2 (RNDIS spec).
    0x01,                              //  bConfValue      = 1
    0x00,                              //  iConfiguration  = unused.
    0x40,                              //  bmAttributes    = Self-Powered.
    0x01,                              //  MaxPower        = x2mA
     
    //  Communication Class INTERFACE descriptor
     
    9,                                 //  bLength         = 9 bytes.
    USB_DESC_TYPE_INTERFACE,           //  bDescriptorType = INTERFACE
    0x00,                              // bInterfaceNo     = 0
    0x00,                              // bAlternateSet    = 0
    0x01,                              // bNumEndPoints    = 1 (RNDIS spec)
    0x02,                              // bInterfaceClass  = Comm if class (RNDIS spec)
    0x02,                              // bIfSubClass      = Comm if sub
    0xff,                              // bIfProtocol      = Vendor specific
    0x00,                              // iInterface       = unused
     
    //  Functional Descriptors for Communication Class Interface per RNDIS spec.
     
    // Header Functional Descriptor
    0x05,                              // bFunctionLength
    0x24,                              // bDescriptorType = CS Interface
    0x00,                              // bDescriptorSubtype
    0x10,                              // bcdCDC = 1.10
    0x01,                              // bcdCDC = 1.10
     
    // Call Management Functional Descriptor
    0x05,                              // bFunctionLength
    0x24,                              // bDescriptorType = CS Interface
    0x01,                              // bDescriptorSubtype = Call Management
    0x00,                              // bmCapabilities
    0x01,                              // bDataInterface
     
    // Abstract Control Management Functional Descriptor
    0x04,                              // bFunctionLength
    0x24,                              // bDescriptorType = CS Interface
    0x02,                              // bDescriptorSubtype = Abstract Control Management
    0x00,                              // bmCapabilities = Requests/notifications not supported
     
    // Union Functional Descriptor
    0x05,                              // bFunctionLength
    0x24,                              // bDescriptorType = CS Interface
    0x06,                              // bDescriptorSubtype = Union
    0x00,                              // bControlInterface = "RNDIS Communications Control"
    0x01,                              // bSubordinateInterface0 = "RNDIS Ethernet Data"
     
    // Endpoint descriptors for Communication Class Interface
     
    7,                                 //  bLength         = 7 bytes
    USB_DESC_TYPE_ENDPOINT,             //  bDescriptorType = ENDPOINT
    RNDIS_NOTIFICATION_IN_EP,          //  bEndpointAddr   = IN - EP3
    0x03,                              //  bmAttributes    = Interrupt endpoint
    8, 0,                              //  wMaxPacketSize
    80,                                //  bInterval       = 1 ms polling from host
     
    //  Data Class INTERFACE descriptor
    9,                                 //  bLength         = 9 bytes
    USB_DESC_TYPE_INTERFACE,           //  bDescriptorType = INTERFACE
    0x01,                              //  bInterfaceNo    = 1
    0x00,                              //  bAlternateSet   = 0
    0x02,                              //  bNumEndPoints   = 2 (RNDIS spec)
    0x0A,                              //  bInterfaceClass = Data if class (RNDIS spec)
    0x00,                              //  bIfSubClass     = unused
    0x00,                              //  bIfProtocol     = unused
    0x00,                              //  iInterface      = unused
     
    // Endpoint descriptors for Data Class Interface   
    7,                                 //  bLength         = 7 bytes.
    USB_DESC_TYPE_ENDPOINT,            //  bDescriptorType = ENDPOINT [IN]
    RNDIS_DATA_IN_EP,                  //  bEndpointAddr   = IN EP
    0x02,                              //  bmAttributes    = BULK
    RNDIS_DATA_IN_SZ, 0,               //  wMaxPacketSize
    0,                                 //  bInterval       = ignored for BULK.
     
    7,                                 //  bLength         = 7 bytes.
    USB_DESC_TYPE_ENDPOINT,             //  bDescriptorType = ENDPOINT [OUT]
    RNDIS_DATA_OUT_EP,                 //  bEndpointAddr   = OUT EP
    0x02,                              //  bmAttributes    = BULK
    RNDIS_DATA_OUT_SZ, 0,              //  wMaxPacketSize
    0                                  //  bInterval       = ignored for BULK
};
 
 
 
/**
  * @brief  USBD_RNDIS_Init
  *         Initialize the RNDIS interface
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  USBD_RNDIS_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
  RNDIS_DEBUG_OUT("RNDIS Init\n");
       
  // open data end points
  USBD_LL_OpenEP(pdev, RNDIS_DATA_IN_EP, USBD_EP_TYPE_BULK, RNDIS_DATA_IN_SZ);
  USBD_LL_OpenEP(pdev, RNDIS_DATA_OUT_EP, USBD_EP_TYPE_BULK, RNDIS_DATA_OUT_SZ);
     
  // open control end point
  USBD_LL_OpenEP(pdev, RNDIS_NOTIFICATION_IN_EP, USBD_EP_TYPE_INTR, RNDIS_NOTIFICATION_IN_SZ);
     
  USBD_LL_PrepareReceive(pdev, RNDIS_DATA_OUT_EP, (uint8_t*)usb_rx_buffer, RNDIS_DATA_OUT_SZ);
  return USBD_OK;
}
 
 
 
__ALIGN_BEGIN static uint8_t RNDIS_SendBuff[ETH_MTU + sizeof(rndis_data_packet_t)] __ALIGN_END;
 
static inline uint8_t usbd_cdc_transfer(void *pdev, uint8_t *data, uint16_t size)
{   
    rndis_data_packet_t *hdr;
     
    RNDIS_DEBUG_OUT("RNDIS cdc transfer start\n");
    rndis_sending = 1;
     
    // build header
    hdr = (rndis_data_packet_t *)RNDIS_SendBuff;
    memset(hdr, 0, sizeof(rndis_data_packet_t));
     
    hdr->MessageType = REMOTE_NDIS_PACKET_MSG;
    hdr->MessageLength = sizeof(rndis_data_packet_t) + size;
    hdr->DataOffset = sizeof(rndis_data_packet_t) - offsetof(rndis_data_packet_t, DataOffset);
    hdr->DataLength = size;
    
    // add payload
    memcpy(RNDIS_SendBuff + sizeof(rndis_data_packet_t), data, size);
 
    USBD_LL_Transmit(pdev, RNDIS_DATA_IN_EP, RNDIS_SendBuff, sizeof(rndis_data_packet_t) + size);
     
    RNDIS_DEBUG_OUT("RNDIS cdc transfer end\n");
     
    return USBD_OK;
}


usbd_cdc_transfer() I initially was calling from the foreground, but then switched to calling it from a timer interrupt (like the CDC example.)
Both had the same problem.

Can anyone help out with what is wrong with the RNDIS_DATA_IN_EP endpoint?
Thanks. 




Outcomes