The STM32CubeMX project for Discovery F4 with CDC as a USB device should work out of the box. Assuming you are using the updated STM32CubeMX and library:
- Launch STM32CubeMX
- Choose a Discovery F4 board
- Enable only UBS_OTG_FS peripheral (leave the disable checkbox checked)
- Enable the middle program USB_Device Communication ... aka CDC
On the clock tab, verify that the clock source is HSE HCLK. It should give HLCK 168 MHz and 48 MHz at a frequency of 48 μs (USB). Check for red color anywhere.
Save project
Generate code (I used SW4STM32 program chains)
Build (you may have to switch to an internal CDT constructor against GNU make).
Now add the code to send data through the COM port, and it will work.
In fact, the hard part is not trying to access the "CDC" until the host USB host is connected (there is no CDC installation yet)
Here's how I did it to quickly emit a test:
In the usbd_cdc_if.c file
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) { uint8_t result = USBD_OK; if (hUsbDevice_0 == NULL) return -1; USBD_CDC_SetTxBuffer(hUsbDevice_0, Buf, Len); result = USBD_CDC_TransmitPacket(hUsbDevice_0); return result; } static int8_t CDC_DeInit_FS(void) { hUsbDevice_0 = NULL; return (USBD_OK); }
In the main.c file
#include "usbd_cdc_if.h" .... while (1) { uint8_t HiMsg[] = "hello\r\n"; CDC_Transmit_FS(HiMsg, strlen(HiMsg)); HAL_Delay(200); }
As soon as you connect micro USB (CN5), CDC data will be displayed on the main terminal.
It works. I see hello on the terminal (you may need to install the driver, http://www.st.com/web/en/catalog/tools/PF257938 ).
To receive it, it must first be armed with, say, the first call to USBD_CDC_ReceivePacket () in a good place. There may be CDC_Init_FS for this.
You can then process the data as it arrives at CDC_Receive_FS and restart the reception from here again.
This works for me.
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); } static int8_t CDC_Init_FS(void) { hUsbDevice_0 = &hUsbDeviceFS; USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBufferFS, 0); USBD_CDC_SetRxBuffer(hUsbDevice_0, UserRxBufferFS); USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); }