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.

0 REPLIES 0