cancel
Showing results for 
Search instead for 
Did you mean: 

Full Speed (FS) USB communication with STM32F407VG Discovery Board

d_n_s
Associate

I'm trying to test out Full Speed USB Communication with the STM32F407 DISCOVERY board.

I'm sending 1 MB of data to the serial port of the computer and receiving them and saving the data using a python script. The speed I'm getting is close to 350 kB/s (~0.34 MB/s), but USB FS theoretical speed is 1.2 MB/s. Is there a way to increase the speed or am I doing something wrong to get such a lower speed?

In the clock configuration, HCLK is 168 MHz (max) and PLLQ is set to 7, giving a 48 MHz USB clock.
This is the function I'm using to send the data.

void send_very_large_data()
{
uint8_t chunk[64]; // 64-byte chunk (USB FS max packet size)
memset(chunk, 'A', sizeof(chunk)); // Fill with 'A' for testing

uint32_t totalSize = 1 * 1024 * 1024; // 1MB for testing (change as needed)
uint32_t sentBytes = 0;

// Loop to send data in 64-byte chunks
while (sentBytes < totalSize)
{
// Wait for USB to be ready for the next transmission
while (CDC_Transmit_FS(chunk, sizeof(chunk)) == USBD_BUSY);

sentBytes += sizeof(chunk);
}
}

I have attached pictures of the changed configuration from Cube MX.

1 REPLY 1
d_n_s
Associate

This is the Python script I'm using to receive the data from the USB port and calculate the speed.

import serial
import time

PORT = "/dev/ttyACM16" 
BAUD_RATE = 115200 # Required by PySerial but ignored for USB CDC
OUTPUT_FILE = "received_data.txt"

def receive_data():
try:
with serial.Serial(PORT, BAUD_RATE, timeout=1) as ser, open(OUTPUT_FILE, "wb") as file:
print(f"Listening on {PORT} ...")

received_bytes = 0
start_time = time.time() # Start timing before first read

while True:
data = ser.read(512) # Read USB FS max packet size (64 bytes)

if data:
file.write(data)
file.flush()
received_bytes += len(data)
print(f"Received {len(data)} bytes, Total: {received_bytes} bytes")
else:
# No data received (timeout), exit the loop
if received_bytes > 0:
print("No more data received, exiting...")
break

end_time = time.time() # End timing after the transmission
elapsed_time = end_time - start_time
print(f"Transmission Completed. Total bytes received: {received_bytes}")
print(f"Time elapsed: {elapsed_time:.2f} seconds")
print(f"Measured Speed: {received_bytes / elapsed_time:.2f} B/s")

except serial.SerialException as e:
print(f"Error: {e}")

if __name__ == "__main__":
receive_data()


These are the speeds I got.

First attempt: 358936.70 B/s

Second attempt: 359011.95 B/s

Third attempt: 359060.76 B/s

Fourth attempt: 363372.03 B/s

Fifth attempt: 358888.39 B/s