2016-02-23 09:02 PM
I am working on a project. One of the part is exchanging data between PC and MCU(STM32F4) via the USB CDC.
Sending data from STM32 to PC is very easy, but there is difficulty receiving data from PC. In the file usbd_cdc_if.c, I implementedCDC_Receive_FS
, and in main(), it constants call the functionCDC_Receive_FS
to read data.UserRxBufferFS
is the buffer created by cubemx. In main(), I get the received data via the arrayBuf
. I do receive the input from PC, but the problem is everytime I call the functionCDC_Receive_FS
I get the same data until new data were received. This is not the supposed logic I want. I want to keep the buffer empty until new data were received. Or receive nothing if no new data were received. Therefore I try to clear the buffer once the data were copied to arrayBuf
, but if I do this, Ialways receive a empty string in main(). What to do?int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
uint8_t status=USBD_CDC_ReceivePacket(hUsbDevice_0);
if
(status==USBD_OK)
{
if
(UserRxBufferFS[0]!=
'\0'
)
//there are data received
{
memcpy(Buf,UserRxBufferFS,APP_RX_DATA_SIZE);
// memset(UserRxBufferFS,1,APP_RX_DATA_SIZE);
// UserRxBufferFS[0]='\0';
}
}
return
status;
/* USER CODE END 6 */
}
2019-01-04 10:04 AM
2019-01-04 10:09 AM
@rwmao Thank you very much.
2020-05-18 12:13 AM
Which Software you are using to monitor the Receive and transmit data from USB. Do you have any suggestions for the USB data Loggers ?
2020-05-18 11:24 AM
2020-05-18 10:03 PM
Thank you so much @rwmao
2020-06-10 06:44 AM
Good afternoon (o;
Nice function...though...
Almost on every startup when I send 8 characters via USB to it...
the function returns it received 8 characters, but all contain 0x00....
On the second transmit all is fine...
2020-06-10 06:58 AM
Ah..my fault (o;
Forgot to point it to the right RX buffer in CDC_Init_FS() (o;
2020-12-18 11:00 AM
Hi,
How I can receive HID data from PC? I'm using this but it seems does not work
uint8_t USBD_HID_GetReport (USBD_HandleTypeDef*pdev,
uint8_t *report,
uint16_t len)
{
USBD_LL_PrepareReceive (pdev,
HID_EPOUT_ADDR,
report,
len);
return USBD_OK;
}
2023-10-22 08:50 PM
USBD_cdc_if.c needs
/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables
* @brief Private variables.
* @{
*/
/* Create buffer for reception and transmission */
/* It's up to user to redefine and/or remove those define */
/** Received data over USB are stored in this buffer */
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
/** Data to send over USB CDC are stored in this buffer */
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
/* USER CODE BEGIN PRIVATE_VARIABLES */
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static int8_t CDC_Init_FS(void);
static int8_t CDC_DeInit_FS(void);
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
#define MaxCommandsInBuffer 10
static struct
{
int pos_receive, pos_process;
//pos_receive is the current position in buffer to save incoming data. pos_process is the index of data in buffer which has been processed.
//if pos_receive=pos_process, it means all data were processed, waiting for new data coming
unsigned char IsCommandDataReceived;
//anynumber >0 means data were received. 0 means no data is available
uint8_t UserRxBufferFS[MaxCommandsInBuffer][APP_RX_DATA_SIZE];
//it could save <MaxCommandsInBuffer> number of commands
uint8_t CommandsLens[MaxCommandsInBuffer];
//save the len of each command
} s_RxBuffers;
/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
/**
* @}
*/
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
{
CDC_Init_FS,
CDC_DeInit_FS,
CDC_Control_FS,
CDC_Receive_FS,
CDC_TransmitCplt_FS
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the CDC media low layer over the FS USB IP
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Init_FS(void)
{
/* USER CODE BEGIN 3 */
/* Set Application Buffers */
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* @brief Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will issue a NAK packet on any OUT packet received on
* USB endpoint until exiting this function. If you exit this function
* before transfer is complete on CDC interface (ie. using DMA controller)
* it will result in receiving more data while previous ones are still
* not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
/*
* Paul's code to retrieve data within the CallBack routine driven by USB interrupt vector
*/
// CDC_Receive_FS is a callback function. When data were received, the system calls this function. The received data can be accessed via Buf,and *Len
s_RxBuffers.IsCommandDataReceived=1;
s_RxBuffers.CommandsLens[s_RxBuffers.pos_receive]=*Len;
s_RxBuffers.pos_receive++;
if(s_RxBuffers.pos_receive>=MaxCommandsInBuffer)
{
s_RxBuffers.pos_receive=0;
}
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, s_RxBuffers.UserRxBufferFS[s_RxBuffers.pos_receive]);
// USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
/**
* @brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function.
* @note
*
*
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 7 */
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hcdc->TxState != 0){
return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
/* USER CODE END 7 */
return result;
}
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
/*
* @brief VCP_retrieveInputData, defined by user
* Call this function frequently to check if data is received.
*
*
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval 0 means no data was received. 1 means data was received
*/
uint8_t VCP_retrieveInputData(uint8_t* Buf, uint32_t *Len)
{
if (s_RxBuffers.IsCommandDataReceived==0) {
return 0; // No data received so break out
} //no data received
int index=s_RxBuffers.pos_process;
*Len=s_RxBuffers.CommandsLens[index];
//return the length
memcpy(Buf,s_RxBuffers.UserRxBufferFS[index],*Len);
Buf[*Len]= '\0';
//testing only. make sure there is ending char in the returned command string
//check if all data were processed.
s_RxBuffers.pos_process++;
if (s_RxBuffers.pos_process>=MaxCommandsInBuffer)
//reach the last buffer, need to rewind to 0
{
s_RxBuffers.pos_process=0;
}
if (s_RxBuffers.pos_process==s_RxBuffers.pos_receive) {
s_RxBuffers.IsCommandDataReceived=0;
}
//check if all data were processed
return 1; // data was received end.
}
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
// In main you use
while (VCP_retrieveInputData(buffer,&pos32)==0 ) // while (USB_OTG_dev.dev.device_config == 0 )
{
Blink(); // do something while waiting to get usb data connection
}