cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 CDC_Receive_FS Doesn't get called

MMurr.2
Associate II

I'm trying to send data from my PC to my STM32 board over USB VCP, but the function CDC_Receive_FS never seems to get called. In fact none of the "_FS" functions in usbd_cdc_if.c seem to get called (except CDC_Transmit_FS) as setting a breakpoint in them doesn't halt the program.

The COM port shows up on my computer and CDC_Transmit_FS works perfectly fine, plus I've tried sending data using putty, platformio device monitor, arduino serial monitor, and a python script but none of them worked so I don't think the issue is on the PC side.

I'm using an STM32F401CCU6. I cant add links but the board I'm using is called "Songhe STM32F401 Development Board" on amazon. Here is my code - its just supposed to send back any data received:

main.c:

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usbd_cdc.h"
#include "usbd_cdc_if.h"
#include <stdio.h>
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t buffer[64];
uint8_t newData = 0;
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	  if(!newData) continue;
 
	  CDC_Transmit_FS(buffer, newData);
	  newData = 0;
  }
  /* USER CODE END 3 */
}

CDC_Receive_FS:

extern uint8_t buffer[64];
extern uint8_t newData;
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
 
  memset(buffer, '\0', 64);
  uint8_t len = (uint8_t)*Len;
  memcpy(buffer, Buf, len);
  memset(Buf, 0, len);
  newData = len;
  return (USBD_OK);
  /* USER CODE END 6 */
}

Is there anything else I need to do to set up VCP receive?

6 REPLIES 6
gbm
Lead III

You should not call Transmit() from main, as it will sooner or later hang the USB stack. Transmit is never called in the main loop because newData is not declared as volatile. Still, it doesn't explain why Receive is not called. Is your VCOM listed in Device Manager. In old versions of CubeMX the VCOM was not automatically initialized for reception but this problem is long gone - current CubeIDE generates the working VCOM code.

Your CDC_Receive() code is incorrect. You should process the data before calling ReceivePacket().

Yes its listed in device manager and I can still receive data on my PC over the COM port.

My CubeIDE version is 1.9.0 which I'm pretty sure is the latest so that shouldnt be an issue.

Any chance breakpoints aren't working because its in an interrupt (at least I assume CDC_Receive_FS is called within an ISR)? I've had them work in timer interrupts so I would guess they would also work in usb interrupts.

I made the changes you suggested - still no luck, although why would transmitting from main hang the USB stack? Ive never had an issue myself.

What function calls CDC_Receive_FS? I couldnt find anything searching for references within the project but maybe I could put a breakpoint there and see if the interrupt is even being triggered.

Avan .12
Associate III

I try to fix this exact same problem: for now it seems that the CDC_Receive_FS() is never called, I have set a breakpoint and it never breaks there.

The other way around is no problem: receiving data from an UART and sensing it to the HOST via USB using CDC_Transmit_FS.

That would require extra hardware for the USB-UART bridge though which I cant do.

Avan .12
Associate III

I found a sort of solution: when I dont debug and just install or run an image than it works just fine, I simply toggle a LED to see if it entered the CDC_Receive_FS().

The disadvantage is that I cant debug this code which is a hassle.

Avan .12
Associate III

I have to correct myself: I found the problem to be in not calling the hard reset of the chip due to changing the default pin selection,

After that I ran into a problem that the first interrupt hangs because the data retreived from the BLUENRG is somehow corrupted (doesn't start with 0x02) which means that the interrupt is never cleared. I started a new thread for this problem.