cancel
Showing results for 
Search instead for 
Did you mean: 

STM32C0 USBX CDC send data un-stoppable

thomas123
Associate II

Hello, I am using STM32C071 in my project, the main work is to receive data from PC, then do some controls, then send data to PC.

However, during the send data to PC step, sometimes the data will be sent continuously, it doesn't meet my requirements, sometimes it working well, this is very unusual. please provide some advise.

After I send the data and proceduce the 'handleRecvData()' func, the data I received from PC is not un-stoppable.

I have checked several days and I can't find what caused this ab-normal.

thomas123_0-1758849792661.png

I follow the steps from @B.Montanari , this link:https://community.st.com/t5/stm32-mcus/how-to-implement-the-usb-device-cdc-vcom-in-stm32-using-the/ta-p/599170

the write and read threads code shows as below:

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
uint8_t resultCode = 0;
extern TX_MUTEX mutexCode;
/* USER CODE END PFP */

 

VOID usbx_cdc_acm_write_thread_entry(ULONG thread_input)
{
      /* Private Variables */
      ULONG tx_actual_length;
      uint8_t initGoodMsg[]    = "Init     Good!";
      uint8_t opGoodMsg[]      = "Operate  Good!";
      uint8_t opErrorMsg[]     = "Operate Error!";
      uint8_t headerErrorMsg[] = "Header  Error!";
      uint8_t flameErrorMsg[]  = "Flame   Error!";
      uint8_t msgToSend[15];

      while(1)
      {
    	if(tx_mutex_get(&mutexCode, TX_WAIT_FOREVER) == TX_SUCCESS){
    	     while(resultCode != 0){
    	    	 switch(resultCode){
    	    	 case initGood:
    	    	        memcpy(msgToSend, initGoodMsg, sizeof(initGoodMsg));
    	    	 	break;
    	    	    case opGood:
    	    	    	memcpy(msgToSend, opGoodMsg, sizeof(opGoodMsg));
    	    	     	break;
    	    	    case opError:
    	    	    	memcpy(msgToSend, opErrorMsg, sizeof(opErrorMsg));
    	    	     	break;
    	    	    case headerError:
    	    	    	memcpy(msgToSend, headerErrorMsg, sizeof(headerErrorMsg));
    	    	     	break;
    	    	    case flameError:
    	    	    	memcpy(msgToSend, flameErrorMsg, sizeof(flameErrorMsg));
    	    	     	break;
    	    	    default:
    	    	     	break;
    	    	}
    	    	resultCode = 0;
    	        ux_device_class_cdc_acm_write(cdc_acm, (UCHAR *)(msgToSend), sizeof(msgToSend), &tx_actual_length);
    	     }
    	}
    	tx_mutex_put(&mutexCode);
    	tx_thread_sleep(150);
    }
}

 

VOID usbx_cdc_acm_read_thread_entry(ULONG thread_input)
{
      /* Private Variables */
      ULONG rx_actual_length;
      uint8_t UserRxBuffer[10];

      /* Infinite Loop */
      while(1)
      {
             if(cdc_acm != UX_NULL)
             {
                 ux_device_class_cdc_acm_read(cdc_acm, (UCHAR *)UserRxBuffer, 10, &rx_actual_length);
                 if(rx_actual_length != 0){
                	 if(tx_mutex_get(&mutexCode, TX_WAIT_FOREVER) == TX_SUCCESS){
                		//handle receive data
                	 	handleRecvData((uint8_t *)UserRxBuffer, rx_actual_length);
                	    tx_mutex_put(&mutexCode);
                	}
                 }else{
                	 tx_thread_sleep(100);
                 }
             }
         tx_thread_sleep(100);
      }
}
VOID handleRecvData(uint8_t *RecvRxBuffer, ULONG bufferLength)
{
	if((RecvRxBuffer[0] == 0xAA) && (RecvRxBuffer[1] == 0xCC) && (RecvRxBuffer[bufferLength-2] == 0xAA) && (RecvRxBuffer[bufferLength-1] == 0x55))
	{
		// 帧头帧尾 OK
		if(RecvRxBuffer[2] == (bufferLength - 4)){
			// 帧长确认OK
			switch(RecvRxBuffer[3]) // 功能位
			{
			case 0x00:
				resultCode = 1;
				HAL_NVIC_SystemReset();
				break;
			case 0x01:
				if(boardInit() == HAL_OK){
					resultCode = initGood;
				}
				else{
					resultCode = opError;
				}
				break;
			case 0x02:
				if(setFingerCh(RecvRxBuffer[4], RecvRxBuffer[5], RecvRxBuffer[6]) == HAL_OK){
					resultCode = opGood;
				}
				else{
					resultCode = opError;
				}
				break;
			default:
				resultCode = flameError;
				break;
			}
		}else{
			// 帧长错误
			resultCode = flameError;
		}
	}else{
		// 帧头帧尾 error
		resultCode = headerError;
	}
}

 

 

 

4 REPLIES 4
MOBEJ
ST Employee

Hello @thomas123 , 

Please kindly check the USBX application provided by ST for the NUCLEO-C071RB board. You can find it at the link below:

STM32CubeC0/Projects/NUCLEO-C071RB/Applications/USBX at main · STMicroelectronics/STM32CubeC0 · GitHub

thank you

Br

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi, @MOBEJ 

I checked the demo example, and checked my code, the read thread and write thread can work very well respectively. My point is, when I use Mutex or Semaphore to make the parameter "resultCode" change in two thread, the write thread working ab-normal.

or could you demo the mutex or semaphore 's usage for two thread, thank you very much.

thomas123
Associate II

Does it acceptible to use ' HAL_NVIC_SystemReset() ' in thread for reset the STM32 MCU?

HAL_NVIC_SystemReset();

 

FBL
ST Employee

Hi @thomas123 

  • Make sure you only call tx_mutex_put() if tx_mutex_get() succeeded.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.