cancel
Showing results for 
Search instead for 
Did you mean: 

What is the bare minimum code to get USB CDC working reliable?

JoniS
Senior

Title pretty much asks the question itself, so what is the bare minimium code to get "Comport" working reliable? for now it seems that i can call CDC_Transmit_FS X amount of times before usb is getting locked(Always returning BUSY flag, from next write attempt never recovering from that state before power cycle)

is CDC_Control_FS function i have filled the CDC_SET_LINE_CODING case in a way that the settings are "echoed" back to pc in the CDC_GET..... case, which seems to work.

 case CDC_SET_LINE_CODING:
	  LineCoding.bitrate    = (uint32_t)(pbuf[0] | (pbuf[1] << 8) | \
	                          (pbuf[2] << 16) | (pbuf[3] << 24));
	  LineCoding.format     = pbuf[4];
	  LineCoding.paritytype = pbuf[5];
	  LineCoding.datatype   = pbuf[6];
    	
	  break;
 
  case CDC_GET_LINE_CODING:
	  pbuf[0] = (uint8_t)(LineCoding.bitrate);
	  pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8);
	  pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16);
	  pbuf[3] = (uint8_t)(LineCoding.bitrate >> 24);
	  pbuf[4] = LineCoding.format;
	  pbuf[5] = LineCoding.paritytype;
	  pbuf[6] = LineCoding.datatype;     
	  break;

the transmit function looks like this

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;
  /* USER CODE BEGIN 7 */
	if (hUsbDevice_ptr == NULL)   // just a pointer to the hUsbDevice_FS
		return USBD_FAIL;
	
  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;
}
  1. Enumeration of the device always works reliable and i can connect to it.
  2. Clock speeds should be okay since Can and UART hardware works flawless, and the enumeration is fine.
  3. CDC_Transmit_FS works X amount of times, before it always return USBD_BUSY.

1 ACCEPTED SOLUTION

Accepted Solutions
JoniS
Senior

uh, i found the root cause, its really silly "mistake" from my part, don't know when this happened, but really important line from my CanMailbox(circular buffer for CanMessages) was missing for no obvious reason, i had allready tested the can stuff and it worked great in my car, so i never looked back to the code, well or so i thought atleast, no idea how the _size = size disappeared from there.

CanMailbox::CanMailbox(uint8_t size){
	
	CanMessage* messages = new CanMessage[size];
>>>>	_size = size;   <<<<  Had disappeared to thin air
	_head = _tail;
	_isFull = false;
}

ps. Everyone slap me throught the monitor please.

View solution in original post

5 REPLIES 5
Pavel A.
Evangelist III

What is on the host side? Windows?

Keep in mind, in order for USB transmit to work, the host must be pumping the data in. If the host drops the ball, you cannot transmit.

-- pa

Windows yeah, and it happens with all ​software at the receiving end(teraterm, termite and my own application).

Either way couple hours ago i managed to track it down to a possible overflow somewhere since random part of the hUsbDevice_FS is getting overwrited always when it gets stuck to the Busy state. Once TxState was over million and once pClassData went to null.

​​

Downloaded the new cubeide and made new project from scratch and it's transmitting reliable now, but it's nowhere near as good as visualstudio to work with sadly, so I guess I need to keep debugging the issue to find root cause.

JoniS
Senior

uh, i found the root cause, its really silly "mistake" from my part, don't know when this happened, but really important line from my CanMailbox(circular buffer for CanMessages) was missing for no obvious reason, i had allready tested the can stuff and it worked great in my car, so i never looked back to the code, well or so i thought atleast, no idea how the _size = size disappeared from there.

CanMailbox::CanMailbox(uint8_t size){
	
	CanMessage* messages = new CanMessage[size];
>>>>	_size = size;   <<<<  Had disappeared to thin air
	_head = _tail;
	_isFull = false;
}

ps. Everyone slap me throught the monitor please.

Pavel A.
Evangelist III

Congrats : )

And if you like VIsual Studio, have a look at this: https://visualgdb.com/?features=embedded

I've asked about Windows because someone claims that in Win10 the usbser driver has a bug that can result more or less in behavior that you've described:

https://social.msdn.microsoft.com/Forums/en-US/b61dad9b-48f7-4eca-ab56-3c2ee92d62fa/windows-10-usbsersys-has-a-bug-it-corrupts-data-how-can-i-report-it-and-how-can-i-demonstrate-it?forum=wdk

-- pa

I actually have copy of visualGDB 🙂

There are not many ide's that comes even close to visual studio in my opinion, besides I still have plenty of 8-bit avr mcu's in the stash so the visualGDB did not seem to be so heavily priced after all.

Interesting bug claim, maybe i need ​to test out if i can reproduce that, well if the Hal driver is fast enought with the usb_fs. Allready found out that it is fast enought to crash termite frequently, something that doesn't happen with my own software or teraterm.