2025-04-06 8:04 AM
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.
2025-04-06 8:11 AM
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