cancel
Showing results for 
Search instead for 
Did you mean: 

Calculating FS USB CDC transfer speed

Ehill.16
Senior

I am sending a 140kB array from the stm32f746 DISCO board. I am using the core cycle counter to measure the speed. The SYSCLK is set to 50Mhz, 20ns per cycle. It takes 709 core cycles to complete the transfer. I calculate the transfer speed to be 70kB/s. Is this the correct way to calculate the rate?

7 REPLIES 7
S.Ma
Principal

hmm usb is packet based with nacks and time multiplex between devices. Ideal condition 64 bytes every 512us, so 128bytes per msec 128 kb per second being the usb fs limit.

TDK
Guru

> Is this the correct way to calculate the rate?

It's a fine way to calculate speed, but there's no way you're transferring 140kB in 709 ticks.

709 cycles is 1.4us.

140kB / 1.4us is 800,000,000,000 bits/sec.

The most you can get with FS USB is around 8 Mbps.

If you feel a post has answered your question, please click "Accept as Solution".
Ehill.16
Senior

How much time does one cycle represent with a 50Mhz SYSCLK? The calculations are not making sense to me.

The 709 ticks was with the interrupts disabled. Without disabling the interrupts, I get 3445 ticks.

TDK
Guru

Why don't you show your code to explain what you're actually measuring? You could be stopping the timer even though the operation isn't yet complete. Note that CDC_Transmit_FS is a non-blocking function.

1 tick at 50MHz is of course 20ns.

If you feel a post has answered your question, please click "Accept as Solution".

What does a non blocking function mean? Thanks for the help!

while (1) {
		/* USER CODE END WHILE */
 
		/* USER CODE BEGIN 3 */
		if (VCP_retrieveInputData(buffer, len) != 0) {
			switch (buffer[0]) {
			case 'A':// if 'A' command ( command to invoke sending of a 140KB of data to the host PC )						//
				/* Disable interrupts */
				//__disable_irq();
				DWT->CYCCNT = 0;	// reset the counter
				start = DWT->CYCCNT;// get the core cycle count and store it in start variable
				do {
					status = CDC_Transmit_FS(ramArray, sizeof(ramArray));// send the 140KB array over the USB to PC
				} while (status == USBD_BUSY);
				finish = DWT->CYCCNT;// get the core cycle count and store it in finish variable
				///__enable_irq();
				HAL_Delay(100);		// 100ms delay
				totalmS = (finish - start);	// calculate the time it took in core cycles to send 140KB's
 
//				sprintf(result, " %d start  ", start);	// calculate transfer speed in bytes/second
//				status = CDC_Transmit_FS(result, sizeof(result));// send bytes/second string to PC via FS USB
//				HAL_Delay(500);
//				sprintf(result, " %d finish  ", finish);	// calculate transfer speed in bytes/second
//				status = CDC_Transmit_FS(result, sizeof(result));// send bytes/second string to PC via FS USB
//				HAL_Delay(500);
				// CalcTransSpeed function is in the SL-RAT Firmware library file, SLRAT_Firmware.c
				sprintf(result, " %d bytes/second  ", CalcTransSpeed(totalmS));	// calculate transfer speed in bytes/second
				status = CDC_Transmit_FS(result, sizeof(result));// send bytes/second string to PC via FS USB
				HAL_Delay(100);
				break;
			case 'B':// if 'B' command ( command to get the time from RTC and send it on the USB )
				RTC_Get(&hrtc, &sTime, &sDate, RTC_FORMAT_BCD);	// get the time and date from the RTC
				// format the date/time array for displaying time and date in the terminal program
				timedate[0] = (sDate.Month / 16) + 48;
				timedate[1] = (sDate.Month % 16) + 48;
				timedate[2] = '/';
				timedate[3] = (sDate.Date / 16) + 48;
				timedate[4] = (sDate.Date % 16) + 48;
				timedate[5] = '/';
				timedate[6] = '2';
				timedate[7] = '0';
				timedate[8] = (sDate.Year / 16) + 48;
				timedate[9] = (sDate.Year % 16) + 48;
				timedate[10] = ' ';
				timedate[11] = (sTime.Hours / 16) + 48;
				timedate[12] = (sTime.Hours % 16) + 48;
				timedate[13] = ':';
				timedate[14] = (sTime.Minutes / 16) + 48;
				timedate[15] = (sTime.Minutes % 16) + 48;
				timedate[16] = ':';
				timedate[17] = (sTime.Seconds / 16) + 48;
				timedate[18] = (sTime.Seconds % 16) + 48;
				timedate[19] = 32;
				status = CDC_Transmit_FS(timedate, sizeof(timedate));// send it to the host PC via USB
				HAL_Delay(1000);
				break;
			}
		}
	}
 

Ehill.16
Senior

I might add that I am not using the FreeRTOS.