USB Bulk reads at 60ksps
Posted: Thu Apr 09, 2026 5:40 am
I'm using ESP-IDF V5.5.2 on a Seeed Studio Xiao ESP32S3 running at 160MHz with 8MB of octal PSRAM running at 40MHz.
What I am trying to do is to read 60ksps from a USB device using the USB Host software.
I have set up a freeRTOS task for the USB Host software and within that I set up 4 consecutive bulk transfers (each ultimately calling usb_host_transfer_submit()) with a callback to handle the results.
The way the USB device is set up with this arrangement I get 131,136 bytes from each transfer which means the callback is being called about every 2ms.
Also within the callback is another call to usb_host_transfer_submit() so the series of transfers should keep going.
All is (seemingly) working well as long as I do nothing in the callback (other than restart the next transfer).
But what I want to do is to trigger another task to process the bytes just received (and ultimately send them via a WiFI UDP transfer but I'm not there yet). I've tried using a freeRTOS queue or a semaphore but the 10ms task switching means that I always need to overwrite the USB buffer before the other task has even started.
I've therefore tried using task notifications but with the same (apparent) issue.
BTW, the USB task is pinned to one core and the 'processing' task is pinned to the other so they can work in parallel.
I've also noticed that, even if I create all the USB transfers and THEN submit them, the callback occurs for the first few before the later transfers are even submitted for the first time - and this really messes things up unless I have only one or 2 transfers.
Therefore my questions are:
1) Am I taking the wrong approach? - If so then what is the 'correct' way to have an app read 60ksps from a USB device and have the data processed
2) If my approach is correct, then what is 'correct' way of handling the issues I've outlined above
Susan
What I am trying to do is to read 60ksps from a USB device using the USB Host software.
I have set up a freeRTOS task for the USB Host software and within that I set up 4 consecutive bulk transfers (each ultimately calling usb_host_transfer_submit()) with a callback to handle the results.
The way the USB device is set up with this arrangement I get 131,136 bytes from each transfer which means the callback is being called about every 2ms.
Also within the callback is another call to usb_host_transfer_submit() so the series of transfers should keep going.
All is (seemingly) working well as long as I do nothing in the callback (other than restart the next transfer).
But what I want to do is to trigger another task to process the bytes just received (and ultimately send them via a WiFI UDP transfer but I'm not there yet). I've tried using a freeRTOS queue or a semaphore but the 10ms task switching means that I always need to overwrite the USB buffer before the other task has even started.
I've therefore tried using task notifications but with the same (apparent) issue.
BTW, the USB task is pinned to one core and the 'processing' task is pinned to the other so they can work in parallel.
I've also noticed that, even if I create all the USB transfers and THEN submit them, the callback occurs for the first few before the later transfers are even submitted for the first time - and this really messes things up unless I have only one or 2 transfers.
Therefore my questions are:
1) Am I taking the wrong approach? - If so then what is the 'correct' way to have an app read 60ksps from a USB device and have the data processed
2) If my approach is correct, then what is 'correct' way of handling the issues I've outlined above
Susan