Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

STM32CubeMX USB CDC VCP?

I've found large number of examples, but nothing on how to do it "properly" from STM32MXCube.

How do I create skeleton code from STM32CubeMX for USB CDC virtual COM port communications (if possible STM32F4 Discovery)?

like image 516
user505160 Avatar asked Nov 05 '15 15:11

user505160


2 Answers

A STM32CubeMX project for Discovery F4 with CDC as USB device should work out of the box. Assuming you use an up-to-date STM32CubeMX and library:

  • Start STM32CubeMX
  • Select the board Discovery F4
  • Enable peripheral UBS_OTG_FS device only (leave over stuff uncheck)
  • Enable midlleware USB_Device Communication .. .aka CDC

In the clock tab check the clock source is HSE HCLK. It shall give 168 MHz HLCK and 48 MHz in the 48 MHz (USB). Check there is no red anywhere.

Save the project

Generate code (I used SW4STM32 toolchains)

Build (you may need to switch to internal CDT builder vs. GNU make).

Now add some code to send data over the COM port and voila it should work.

Actually, the tricky part is not try to make any "CDC" access until the host USB connects (no CDC setup yet)

Here is how I did it for quick emit test:

In file usbd_cdc_if.c

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
    uint8_t result = USBD_OK;

    /* USER CODE BEGIN 7 */
    if (hUsbDevice_0 == NULL)
        return -1;

    USBD_CDC_SetTxBuffer(hUsbDevice_0, Buf, Len);
    result = USBD_CDC_TransmitPacket(hUsbDevice_0);
    /* USER CODE END 7 */

    return result;
}

static int8_t CDC_DeInit_FS(void)
{
    /* USER CODE BEGIN 4 */
    hUsbDevice_0 = NULL;
    return (USBD_OK);
    /* USER CODE END 4 */
}

In file main.c

/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
/* USER CODE END Includes */
....

/* USER CODE BEGIN WHILE */
while (1)
{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    uint8_t HiMsg[] = "hello\r\n";
    CDC_Transmit_FS(HiMsg, strlen(HiMsg));
    HAL_Delay(200);
}

As soon you plug the micro USB (CN5) CDC data will start to show on the host terminal.

That works. I can see "hello" on the terminal (you may need to install a driver, http://www.st.com/web/en/catalog/tools/PF257938).

For reception, it needs to be first armed, say, started by a first call to USBD_CDC_ReceivePacket() in a good place. For that it can be CDC_Init_FS.

Then you can handle data as it arrives in CDC_Receive_FS and rearming reception again from here.

That works for me.

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
    /* USER CODE BEGIN 6 */
    USBD_CDC_ReceivePacket(hUsbDevice_0);
    return (USBD_OK);
    /* USER CODE END 6 */
}

static int8_t CDC_Init_FS(void)
{
    hUsbDevice_0 = &hUsbDeviceFS;

    /* USER CODE BEGIN 3 */
    /* Set Application Buffers */
    USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBufferFS, 0);
    USBD_CDC_SetRxBuffer(hUsbDevice_0, UserRxBufferFS);
    USBD_CDC_ReceivePacket(hUsbDevice_0);

    return (USBD_OK);
    /* USER CODE END 3 */
}
like image 158
Michel Sanches Avatar answered Oct 10 '22 07:10

Michel Sanches


There are a number of STM32F4 Discovery boards supported by the STM32Cube software, and you haven’t said which you’re using, but I’ve had exactly the same issue with the Discovery board with the F401VCT MCU.

After installing the STM virtual COM port driver, Windows Device Manager showed a STMicroelectronics virtual COM port, but with a yellow warning mark. The COM port was not accessible with a terminal application (PuTTY).

I eventually found that there is a problem with source code output from the STMCube program. But there is a simple fix:

  1. Open a new STM32Cube project and enable the USB_OTG_FS as Device Only and select CDC Virtual Port COM from the MiddleWares USB_Device drop-down.
  2. Generate the source code with no other changes needed to any USB settings.
  3. In file usbd_cdc_if.c, change #define USB_HS_MAX_PACKET_SIZE from 512 to 256.
  4. In file usbd_cdc.c, change the #define CDC_DATA_HS_MAX_PACKET_SIZE from 512 to 256.

After doing this, the yellow warning disappeared from Device Manager, and I could receive data at the CDC_Receive_FS function (in usbd_cdc_if.c file) when using PuTTY. Be aware that these definitions return to their incorrect values each time the STM32Cube generates code, and I haven’t found a way around this yet.

I hope this helps.

like image 24
iChal Avatar answered Oct 10 '22 07:10

iChal