This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Send data through USB as a virtual COM

Hi all!

I am trying to include a virtual COM through an USB in KEIL uVision5 with the API and functions that KEIL provides. 

I have been improving my code, and now I am at the point to be able to receive characters from the host (PC). My problem now is that I don't understand how the function "USBD_CDCn_ACM_SendData" works.

My purpose is to include the function "USBD_CDC_ACM_WriteData" inside "SendData" function. I know that WriteData is an asynchronous function, but it never interrupts the program.

My code is:

// Called when when all data was sent.
void USBD_CDC0_ACM_SendData (int32_t len) {
  // Add code for handling new data send
	int32_t cnt;
	
	cnt = USBD_CDC_ACM_WriteData(0, mantTxBuf, len);
		
	if(cnt<0) {}
		//error	
}

// Called when when all data was sent.
void USBD_CDC0_ACM_SendData (int32_t len) {
  // Add code for handling new data send
	int32_t cnt;
	
	cnt = USBD_CDC_ACM_WriteData(0, mantTxBuf, len);
		
	if(cnt<0) {}
		//error	
}

where "mantTxBuf" is my pointer to the transmitter buffer. I am sharing the same buffer with UART and USB, because my intention is that when I use the USB, the UART will be disable and viceversa. I am secure that there are data ready to be sent on my buffer, but this function never interrupts.

I have tried to implement the "WriteData" function inside the function "USBD_CDC0_ACM_DataSent" (www.keil.com/.../group__usbd__cdc_functions__acm__api.html but it neither interrupts.

I have the following questions about it:

   1. How "USBD_CDCn_ACM_SendData" works?

   2. Should I implement the asynchronous function to send data ("USBD_CDC_ACM_WriteData") as a independent function?

   3. Is there another strategy to send data when I have characters in my Tx buff ("mantTxBuff")??

Thank you very much!

  • Hi javierrobledo.

    I suggest you first clarify the callback name because in the documentation and latest MDK-Middleware the callback is called USBD_CDCn_ACM_DataSent,, where n is an index of the CDC class instance.

    In your code you have a function USBD_CDC0_ACM_SendData which will never be called because the USB stack will call the function with name  USBD_CDC0_ACM_DataSent which if you haven't provided will be used as empty weak one provided by the USB stack.

    1. How "USBD_CDCn_ACM_SendData" works?

    I'm not sure about USBD_CDCn_ACM_SendData but USBD_CDCn_ACM_DataSent works in a way that it is called after data was sent on the USB.
    To get this function called for the first time you have to initially send some data with the USBD_CDC_ACM_WriteData function.

    2. Should I implement the asynchronous function to send data ("USBD_CDC_ACM_WriteData") as a independent function?

    There is an example template as part of MDK-Middleware (USBD_User_CDC_ACM_UART.c) which shows the example of bridge between USART to USB.
    In that case USBD_CDC_ACM_WriteData is called from a thread which checks if anything was received on UART, if so that data is sent over USB with USBD_CDC_ACM_WriteData.
    USBD_CDCn_ACM_DataSent callback is not used at all.

    3. Is there another strategy to send data when I have characters in my Tx buff ("mantTxBuff")??

    The only thing is you need to do is start first transfer from somewhere else then the callback itself because callback will be called after initial data was sent.
    And of course have the correct name of the callback.

    In general that callback is used if you need to send data as fast as possible because you can react when previous data was sent, usually you do not need that and you can send the data from a separate thread responsible for that task.

    Best regards, Milorad