STM32F4 USB VCP, PC receive all 0x00
I am using the ST USB Library for a different ST ARM microcontroller (STM32F105), but the structure looks the same. I, too, have based my code off of the VCP example.

First, there is some additional initialization required for the USB to work. Following is a list of things to verify. You may new to adjust some of these examples to work with your microcontroller:


You need to have enabled the OTG_FS_IRQHandler interrupt:

NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&amp;NVIC_InitStructure);


The following is in my interrupt vector file:

#include "usb_core.h"
#include "usbd_core.h"
#include "usbd_cdc_core.h"

extern USB_OTG_CORE_HANDLE USB_OTG_dev;
extern uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);

void OTG_FS_IRQHandler(void)
{
    USBD_OTG_ISR_Handler (&amp;USB_OTG_dev);
} // end OTG_FS_IRQHandler()

You must select and enable a 48 MHz clock source for the OTG/USB model before calling USBD_Init. In my case, this was derived by dividing the 144 MHz PLLVCO by 3. The clock tree can be tricky; make sure you understand that section of the Reference Manual.

// Configure USB Clock Source
RCC_OTGFSCLKConfig(RCC_OTGFSCLKSource_PLLVCO_Div3);

// Enable USB Clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE);

In the USB Library is the usb_conf.h file. This is a tangle of conditional defines. Make sure that these are actually getting defined (if they are appropriate to your application):

#define USE_USB_OTG_FS
#define USB_OTG_FS_CORE
#define USE_EMBEDDED_PHY
#define VBUS_SENSING_ENABLED
#define USE_DEVICE_MODE





Next, as @Tut pointed out in the comments, your VCP_DataTX function needs modification. It is currently using the USART peripheral as the source of the USB data.  You want to change it so that it uses Buf and Len. Even though the function call includes the Buf and Len arguments, these aren't actually used in the function.

The VCP_DataTx stuffs data, one byte at a time, into the APP_Rx_Buffer array. Every time it writes a byte to the array it also increments the APP_Rx_ptr_in value. This buffer is regularly checked and processed by the OTG/USB library code. 

My function looks like this:

uint16_t VCP_DataTx(uint8_t *Buf, uint32_t Len)
{
    uint32_t i;

    // Put the data into the buffer. It will be processed by the USB stack.
    for (i=0; i&lt;Len; i++)
    {
        // Add a byte to the buffer
        APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i];

        // Update the circular buffer index
        APP_Rx_ptr_in++;

        // Loop the index if necessary
        if (APP_Rx_ptr_in == APP_RX_DATA_SIZE)
        {
            APP_Rx_ptr_in = 0;
        }
    }
    return USB_SUCCESS;
}




Finally, there are a few other issues in your code. I expect you are aware of some of these, but I'll list them just in case:


The statement uint8_t Buf[6] = "A"; only initializes the first value to 'A'. The remaining five values are '\0'. See here for more information.
When the counter variable i exceeds your delay limit, it should be cleared back to zero.  This could be a primary problem.  Currently, when the delay finishes up the first time, it never delays again.  The outer while loop starts calling VCP_DataTx(Buf, 6); continuously. This will overflow the USB buffer and lead to all sorts of problems.
Once you fix the delay problem you will still get two calls to VCP_DataTx(Buf, 6); back-to-back with no delays. Once before the delay loop, and immediately again before the first delay. This shouldn't cause a problem but I wanted to point it out.




FYI, if you are only trying to send data back and forth to a PC via USB then you don't need to enable any USART functionality in the microcontroller.  The VCP example uses the USART as a data source (and destination), but you aren't trying to do that. Your data source is your Buf[] array.