cancel
Showing results for 
Search instead for 
Did you mean: 

USB device not recognized with RNDIS using USBX

KoCT
Associate II

Hello,

I am trying to get Ethernet-over-USB working on a STM32U585. I want to be able to use both RNDIS and CDC-ECM, but I decided to start with RNDIS first. After a lot of trial and error and research, I am running out of ideas as to why my PC does not show any devices in USB Viewer on the port where I connected the circuit board. I am developing on a B-U585I-IOT02A.
I based my work on the following example: https://github.com/STMicroelectronics/stm32-usbx-examples/tree/main/Projects/STM32H735G-DK/Applications/USBX/Ux_Device_RNDIS

I provide my code here (if not mentioned it is generated by CubeMX). I did not touch files if code is not shown here:

main.c: 

int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the System Power */
  SystemPower_Config();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ICACHE_Init();
  
  // HINT: this function is called later as in the example project
  // MX_USB_OTG_FS_PCD_Init();

  MX_ThreadX_Init();
  while(1);
}

app_usbx_device.c:

#include "app_usbx_device.h"

/* Private define ------------------------------------------------------------*/
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;

/* Private variables ---------------------------------------------------------*/
static ULONG rndis_interface_number;
static ULONG rndis_configuration_number;
static UCHAR rndis_local_nodeid[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
static UCHAR rndis_remote_nodeid[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
static UX_SLAVE_CLASS_RNDIS_PARAMETER rndis_parameter;
static TX_THREAD ux_device_app_thread;

/* Private function prototypes -----------------------------------------------*/
static VOID app_ux_device_thread_entry(ULONG thread_input);

UINT MX_USBX_Device_Init(VOID *memory_ptr)
{
   UINT ret = UX_SUCCESS;
  UCHAR *device_framework_high_speed;
  UCHAR *device_framework_full_speed;
  ULONG device_framework_hs_length;
  ULONG device_framework_fs_length;
  ULONG string_framework_length;
  ULONG language_id_framework_length;
  UCHAR *string_framework;
  UCHAR *language_id_framework;

  UCHAR *pointer;
  TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;

  /* Allocate the stack for USBX Memory */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer,
                       USBX_DEVICE_MEMORY_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }

  /* Initialize USBX Memory */
  if (ux_system_initialize(pointer, USBX_DEVICE_MEMORY_STACK_SIZE, UX_NULL, 0) != UX_SUCCESS)
  {
    return UX_ERROR;
  }

  /* Get Device Framework High Speed and get the length */
  device_framework_high_speed = USBD_Get_Device_Framework_Speed(USBD_HIGH_SPEED,
                                                                &device_framework_hs_length);

  /* Get Device Framework Full Speed and get the length */
  device_framework_full_speed = USBD_Get_Device_Framework_Speed(USBD_FULL_SPEED,
                                                                &device_framework_fs_length);

  /* Get String Framework and get the length */
  string_framework = USBD_Get_String_Framework(&string_framework_length);

  /* Get Language Id Framework and get the length */
  language_id_framework = USBD_Get_Language_Id_Framework(&language_id_framework_length);

  /* Install the device portion of USBX */
  if (ux_device_stack_initialize(device_framework_high_speed,
                                 device_framework_hs_length,
                                 device_framework_full_speed,
                                 device_framework_fs_length,
                                 string_framework,
                                 string_framework_length,
                                 language_id_framework,
                                 language_id_framework_length,
                                 UX_NULL) != UX_SUCCESS)
  {
    return UX_ERROR;
  }

  /* Initialize the rndis class parameters for the device */
  rndis_parameter.ux_slave_class_rndis_instance_activate   = USBD_RNDIS_Activate;
  rndis_parameter.ux_slave_class_rndis_instance_deactivate = USBD_RNDIS_Deactivate;

  /* Get RNDIS local MAC address */
  USBD_RNDIS_GetMacAdd((uint8_t *)RNDIS_LOCAL_MAC_STR_DESC, rndis_local_nodeid);

  /* Define RNDIS local node id */
  rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[0] = rndis_local_nodeid[0];
  rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[1] = rndis_local_nodeid[1];
  rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[2] = rndis_local_nodeid[2];
  rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[3] = rndis_local_nodeid[3];
  rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[4] = rndis_local_nodeid[4];
  rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[5] = rndis_local_nodeid[5];

  /* Get RNDIS local MAC address */
  USBD_RNDIS_GetMacAdd((uint8_t *)RNDIS_REMOTE_MAC_STR_DESC, rndis_remote_nodeid);

  /* Define RNDIS remote node id */
  rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[0] = rndis_remote_nodeid[0];
  rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[1] = rndis_remote_nodeid[1];
  rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[2] = rndis_remote_nodeid[2];
  rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[3] = rndis_remote_nodeid[3];
  rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[4] = rndis_remote_nodeid[4];
  rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[5] = rndis_remote_nodeid[5];

  rndis_parameter.ux_slave_class_rndis_parameter_vendor_id      = USBD_VID;
  rndis_parameter.ux_slave_class_rndis_parameter_driver_version = USBD_RNDIS_DRIVER_VERSION;

  ux_utility_memory_copy(rndis_parameter.ux_slave_class_rndis_parameter_vendor_description,
                         USBD_PRODUCT_STRING, sizeof(USBD_PRODUCT_STRING));

  /* Get rndis configuration number */
  rndis_configuration_number = USBD_Get_Configuration_Number(CLASS_TYPE_RNDIS, 0);

  /* Find rndis interface number */
  rndis_interface_number = USBD_Get_Interface_Number(CLASS_TYPE_RNDIS, 0);

  /* Initialize the device RNDIS */
  if (ux_device_stack_class_register(_ux_system_slave_class_rndis_name,
                                     ux_device_class_rndis_entry,
                                     rndis_configuration_number,
                                     rndis_interface_number,
                                     &rndis_parameter) != UX_SUCCESS)
  {
    return UX_ERROR;
  }

  /* Perform the initialization of the network driver. This will initialize the
     USBX network layer */

  ux_network_driver_init();

  /* Allocate the stack for device application main thread */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer, UX_DEVICE_APP_THREAD_STACK_SIZE,
                       TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }

  /* Create the device application main thread */
  if (tx_thread_create(&ux_device_app_thread, UX_DEVICE_APP_THREAD_NAME, app_ux_device_thread_entry,
                       0, pointer, UX_DEVICE_APP_THREAD_STACK_SIZE, UX_DEVICE_APP_THREAD_PRIO,
                       UX_DEVICE_APP_THREAD_PREEMPTION_THRESHOLD, UX_DEVICE_APP_THREAD_TIME_SLICE,
                       UX_DEVICE_APP_THREAD_START_OPTION) != TX_SUCCESS)
  {
    return TX_THREAD_ERROR;
  }

  return ret;
}

static VOID app_ux_device_thread_entry(ULONG thread_input)
{
	MX_USB_OTG_FS_PCD_Init();

	HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x200);
	HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x80);
	HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);

	ux_dcd_stm32_initialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS);

	if (HAL_PCD_Start(&hpcd_USB_OTG_FS) != HAL_OK) Error_Handler();

  while(1);
}

app_usbx_device.h:

* Includes ------------------------------------------------------------------*/
#include "ux_api.h"
#include "ux_device_rndis.h"
#include "ux_device_descriptors.h"
#include "app_azure_rtos_config.h"
#include "ux_dcd_stm32.h"
/* Private includes ----------------------------------------------------------*/
#include "usb_otg.h"
#include "ux_dcd_stm32.h"

/* Exported constants --------------------------------------------------------*/
#define USBX_DEVICE_MEMORY_STACK_SIZE       35840

#define UX_DEVICE_APP_THREAD_STACK_SIZE   2048
#define UX_DEVICE_APP_THREAD_PRIO         10

/* Exported functions prototypes ---------------------------------------------*/
UINT MX_USBX_Device_Init(VOID *memory_ptr);

#ifndef UX_DEVICE_APP_THREAD_NAME
#define UX_DEVICE_APP_THREAD_NAME  "USBX Device App Main Thread"
#endif

#ifndef UX_DEVICE_APP_THREAD_PREEMPTION_THRESHOLD
#define UX_DEVICE_APP_THREAD_PREEMPTION_THRESHOLD  UX_DEVICE_APP_THREAD_PRIO
#endif

#ifndef UX_DEVICE_APP_THREAD_TIME_SLICE
#define UX_DEVICE_APP_THREAD_TIME_SLICE  TX_NO_TIME_SLICE
#endif

#ifndef UX_DEVICE_APP_THREAD_START_OPTION
#define UX_DEVICE_APP_THREAD_START_OPTION  TX_AUTO_START
#endif

I would be very grateful for any hints and tips.

Thank You!

K.S.

1 REPLY 1
FBL
ST Employee

Hi @KoCT 

Did you check the example provided here for CDC ECM as a reference and port it to your target.
Did you check the code properly implemented in your generated code as in the reference example for RNDIS? It seems your FIFO configuration is not completed. See here.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.




Best regards,
FBL