cancel
Showing results for 
Search instead for 
Did you mean: 

Read data from PC to STM32 via USB CDC

rwmao
Senior
Posted on February 24, 2016 at 06:02

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 implemented

CDC_Receive_FS

, and in main(), it constants call the function

CDC_Receive_FS

to read data.

UserRxBufferFS

is the buffer created by cubemx. In main(), I get the received data via the array

Buf

. I do receive the input from PC, but the problem is everytime I call the function

CDC_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 array

Buf

, 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 */
}

18 REPLIES 18
rwmao
Senior
Hello
It has been long time ago.
Please go to my bit hub I make it public.
https://bitbucket.org/rwmao/cdc_onstm32f411rc/src/master/
There is readme file and detailed source file.
Thanks


Dr. RongWei Mao
2019-01-04

On 2019-01-04 at 03:02, ST Community wrote:

@rwmao Interesting But would it be possible to detail CDC_Init_FS(void) which set buffers? (UserTxBufferFS & s_RxBuffers.UserRxBufferFS)






cnhx27 (Community Member)
@rwmao Interesting
But would it be possible to detail CDC_Init_FS(void) which set buffers?
(UserTxBufferFS & s_RxBuffers.UserRxBufferFS)

View/Answer View/Answer
or reply to this email




Replying to



rwmao (Community Member) to ST Community (STMicroelectronics): asked a question.
Edited by STCommunity Wednesday, October 10, 2018 11:01 AM
Read data from PC to STM32 via USB CDC
Posted on February 24, 2016 at 06:02
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 implemented
CDC_Receive_FS
, and in main(), it constants call the function
CDC_Receive_FS
to read data.
UserRxBufferFS
is the buffer created by cubemx. In main(), I get the received data via the array
Buf
. I do receive the input from PC, but the problem is everytime I call the function
CDC_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 array
Buf
, 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 */
}







cnhx27 (Community Member)
@rwmao Interesting
But would it be possible to detail CDC_Init_FS(void) which set buffers?
(UserTxBufferFS & s_RxBuffers.UserRxBufferFS)
Friday, January 4, 2019 5:02 AM






You're receiving emails when someone "Comments on my posts."

To change or turn off ST Community email, log in as rwmao@uci.edu.st.

Are notifications about this post getting annoying? Reply to this email with the word " mute ".

STMicroelectronics N.V.
cnhx27
Associate III

@rwmao​  Thank you very much.

Smalik
Associate II

Which Software you are using to monitor the Receive and transmit data from USB. Do you have any suggestions for the USB data Loggers ?

rwmao
Senior
Please check the link attached. This is the one I used for debug. Very convenient to use.
https://www.dropbox.com/sh/fgpul1zx1tjx58x/AADTu5Go1q1XyHeB6q4PWpnFa?dl=0

Dr. William Mao
2020-05-18
On 2020-05-18 at 00:13, ST Community wrote:

Which Software you are using to monitor the Receive and transmit data from USB. Do you have any suggestions for the USB data Loggers ?






SMali.1 (Community Member)
Which Software you are using to monitor the Receive and transmit data from USB. Do you have any suggestions for the USB data Loggers ?

View/Answer View/Answer
or reply to this email




Replying to



rwmao (Community Member) to ST Community (ST Employee): asked a question.
Edited by STM Community Wednesday, October 10, 2018 11:01 AM
Read data from PC to STM32 via USB CDC
Posted on February 24, 2016 at 06:02
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 implemented
CDC_Receive_FS
, and in main(), it constants call the function
CDC_Receive_FS
to read data.
UserRxBufferFS
is the buffer created by cubemx. In main(), I get the received data via the array
Buf
. I do receive the input from PC, but the problem is everytime I call the function
CDC_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 array
Buf
, 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 */
}







SMali.1 (Community Member)
Which Software you are using to monitor the Receive and transmit data from USB. Do you have any suggestions for the USB data Loggers ?
Monday, May 18, 2020 2:13 AM






You're receiving emails when someone "Comments on my posts."

To change or turn off ST Community email, log in as rwmao@uci.edu.st.

Are notifications about this post getting annoying? Reply to this email with the word " mute ".

STMicroelectronics N.V.
Smalik
Associate II

Thank you so much @rwmao​ 

Davorin
Senior

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...

Davorin
Senior

Ah..my fault (o;

Forgot to point it to the right RX buffer in CDC_Init_FS() (o;

Dnguy.1
Associate

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;

}

Paulus
Associate II

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

 

}