cancel
Showing results for 
Search instead for 
Did you mean: 

STM32C071 USB Host

vermas
Associate

I'm looking to implement USB host functionality on an STM32C071 to connect with a single device that sends/receives serial data over USB so the only class I'm interested in is CDC, but I'm having trouble using USBX (I'm not using RTOS).

 

For now I haven't used and read/write functions, my goal was to start by checking the functionality of the callbacks inside "app_usbx_host.c" which are: device inserted/removed/connected/disconnected, enumeration fail and no USB device found. Each one sets a different flag to be handled inside the main loop.

 

I put a breakpoint inside the USB IRQ and when I connect the USB device it stops execution and confirms the breakpoint has been reached, however none of my flags are ever set,.

 

I suspect the reason might be because I haven't done anything to link the USB peripheral to the USBX stack, if the function responsible for that is ux_host_stack_hcd_register, I have no idea how to use it. The function prototype is:

UINT _ux_host_stack_hcd_register(UCHAR *hcd_name, UINT (*hcd_init_function)(struct UX_HCD_STRUCT *), ULONG hcd_param1, ULONG hcd_param2);

I'm completely lost in the description for each of the arguments.

 

My main.c is basically this:

#include "main.h"
#include "app_usbx_host.h"

#include <stdio.h>
#include <string.h>

UART_HandleTypeDef huart1;
HCD_HandleTypeDef hhcd_USB_DRD_FS;

uint8_t my_TX_buffer[64];
uint8_t my_RX_buffer[64];
uint16_t written_len;

// THESE ARE THE FLAGS (NOT) BEING SET INSIDE THE CALLBACKS IN "app_usbx_host.c"
extern char DEVICE_INSERTED;
extern char DEVICE_REMOVED;
extern char DEVICE_CONNECTED;
extern char DEVICE_DISCONNECTED;
extern char ENUMERATION_FAIL;
extern char NOTHING_CONNECTED;

void SystemClock_Config(void);
static void MX_USART1_UART_Init(void);
static void MX_USB_HCD_Init(void);

int main(void){

  HAL_Init();
  SystemClock_Config();
  MX_USART1_UART_Init();
  MX_USB_HCD_Init();
  MX_USBX_Host_Init();
  HAL_HCD_Start(&hhcd_USB_DRD_FS);

  while (1){

   ux_system_tasks_run();

   if (DEVICE_INSERTED){
   written_len = snprintf((char *) my_TX_buffer, sizeof(my_TX_buffer), "USB Device Inserted\r\n");
   HAL_UART_Transmit(&huart1, my_TX_buffer, written_len, 100);
   DEVICE_INSERTED = 0;
   }
   
   // REST OMITTED, all the other flags get treated in the same way here   
  }
}

void SystemClock_Config(void){
  // OMITTED FOR CLARITY
}

static void MX_USART1_UART_Init(void){
  // OMITTED, UART IS WORKING
}

static void MX_USB_HCD_Init(void){
  hhcd_USB_DRD_FS.Instance = USB_DRD_FS;
  hhcd_USB_DRD_FS.Init.dev_endpoints = 8;
  hhcd_USB_DRD_FS.Init.Host_channels = 8;
  hhcd_USB_DRD_FS.Init.speed = USBD_FS_SPEED;
  hhcd_USB_DRD_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
  hhcd_USB_DRD_FS.Init.Sof_enable = DISABLE;
  hhcd_USB_DRD_FS.Init.low_power_enable = DISABLE;
  hhcd_USB_DRD_FS.Init.vbus_sensing_enable = DISABLE;
  hhcd_USB_DRD_FS.Init.bulk_doublebuffer_enable = DISABLE;
  hhcd_USB_DRD_FS.Init.iso_singlebuffer_enable = DISABLE;
  if (HAL_HCD_Init(&hhcd_USB_DRD_FS) != HAL_OK) Error_Handler();
}

void Error_Handler(void){
  __disable_irq();
  while (1){}
}

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line){}
#endif /* USE_FULL_ASSERT */

 

I don't remember making significant changes to any other file apart from creating the flags inside app_usbx_host.c.

 

The images below contain the CubeMX settings I used.

 

USB peripheral configurationUSB peripheral configuration

 

 

Class configurationClass configuration

 

USBX configurationUSBX configuration

 

I'd be extremely grateful if anyone could tell me what I missed.


Edited to apply proper source code formatting - please see How to insert source code for future reference.

2 REPLIES 2
Pavel A.
Super User

I put a breakpoint inside the USB IRQ

USB is time-sensitive. Delays caused by breakpoints can confuse the device. Debug using non-blocking methods. USB bus analyzer can help too.

 

 

FBL
ST Employee

Hi @vermas 

You need to ensure initialization the USBX host stack, ensure it has enough memory, and poll its task function in the main loop. MX_USBX_Host_Init() must be called after MX_USB_HCD_Init() so the USBX host stack can properly register and link to the USB peripheral.

MX_USB_HCD_Init();        // Initialize the USB host controller
MX_USBX_Host_Init();      // Then initialize the USBX host stack

In your main loop, you also need to call ux_system_tasks_run(); and poll on your CDC task.

As a reference, start from this official example and then adapt/port it to your standalone application.

If still having issues, don't hesitate to share your project.

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