2024-01-23 04:24 AM
Hey. I'm trying to create a program that receives 4 bytes long strings from my pc and transfer them through an spi connection to a peripheral device, throught a usb connection.
I've set my stm32 nucleo board up as a usb device and generated the required file. The thing that i noticed though is that i could use the cdc_transmit_hs function inside the main.c super loop, if declared as extern, but i couldn't do the same with the receive counterpart. The only thing that i tried and seemed to work is echoing the data inside the receive function, meaning :
static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 11 */
USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceHS);
uint8_t rxMessage[40]={'\0'};
sprintf(rxMessage, "Command is %c,%d,%d,%d\r\n",Buf[0],Buf[1], Buf[2], Buf[3] );
CDC_Transmit_HS(rxMessage,sizeof(rxMessage));
return (USBD_OK);
/* USER CODE END 11 */
}
Is there an actual way to use this function inside the main?Should i use a global array and a flag to signal the main file, that some data is being received, or is it not thread safe ?
Solved! Go to Solution.
2024-01-23 06:56 AM
USB data is received via an interrupt in the CDC_Receive_HS function. This is in usbd_cdc_if.c. Implement that with what you need.
static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 11 */
USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceHS);
memcpy(rxMessage, Buf, Len); // <----- your implementation
return (USBD_OK);
/* USER CODE END 11 */
}
Set a flag so your main loop is aware that data has come in and should be processed.
> Should i use a global array and a flag to signal the main file, that some data is being received, or is it not thread safe ?
Yes, exactly this. It will be thread safe if you write it as such. Consider the case where more data comes in while you're still processing the old data.
2024-01-23 06:56 AM
USB data is received via an interrupt in the CDC_Receive_HS function. This is in usbd_cdc_if.c. Implement that with what you need.
static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 11 */
USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceHS);
memcpy(rxMessage, Buf, Len); // <----- your implementation
return (USBD_OK);
/* USER CODE END 11 */
}
Set a flag so your main loop is aware that data has come in and should be processed.
> Should i use a global array and a flag to signal the main file, that some data is being received, or is it not thread safe ?
Yes, exactly this. It will be thread safe if you write it as such. Consider the case where more data comes in while you're still processing the old data.
2024-01-24 01:08 AM
Is it safe to use functions like spi_transfer, or further cdc transfers inside the callback, or will the program hang ?
I tried doing something like this inside the callback function :
static volatile uint8_t newDataAvailable=0;
static uint8_t receivedDataBuffer[100];
static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 11 */
memcpy(receivedDataBuffer, Buf, *Len);
newDataAvailable = 1;
USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceHS);
return (USBD_OK);
/* USER CODE END 11 */
}
Na something like this inside the main.c :
extern volatile uint8_t newDataAvailable;
extern uint8_t receivedDataBuffer[100];
while (1)
{
if (newDataAvailable)
{
uint8_t rxMessage[100]={'\0'};
sprintf(rxMessage, "Command is %c,%d,%d,%d\r\n",receivedDataBuffer[0],receivedDataBuffer[1], receivedDataBuffer[2], receivedDataBuffer[3] );
CDC_Transmit_HS(rxMessage,sizeof(rxMessage));
newDataAvailable = 0;
}
}
But i get Undefined errors for both of the extern variables.
2024-01-24 06:02 AM
> Is it safe to use functions like spi_transfer, or further cdc transfers inside the callback, or will the program hang ?
Generally, it fine to use whatever functions you need as long as they complete quickly.
> But i get Undefined errors for both of the extern variables.
Remove "static" from the variable definition. Global variables defined with "static" cannot be seen in other compilation groups (i.e. other *.c files).
Probably also want to move your code to after the two USBD_CDC_* calls, not before.