stm32 blue pill adc @ 1msps - Page 1
Forum section: electronics / general

author: mercurial
author_rank: Regular Contributor
timestamp: February 06, 2024, 07:55:01 pm
content: I'm trying to stream adc data (single channel) from stm32 blue pill board to a pc.Since adc data is 12bit per sample it turns out to be around 2MB/sec for 1msps.I'm not sure USB cdc of the blue pill can handle that.But with packing 2 12 bit samples into 3 bytes I can get it down to 1.5MB/sec.The stm32 blue pill is programmed with the Stm32duino core.As per reports on various forums i found that the max speed with analogRead() is around 143ksps (~7us per sample)But that maybe only the adc conversion time and there would be additional overhead in sending the data over usb cdc.Is it possible to get full 1msps with direct register manipulation, or any other method?

author: ataradov
author_rank: Super Contributor
timestamp: February 06, 2024, 08:59:27 pm
content: 1.5 MB/sec is the raw USB FS bandwidth. With the protocol overflow, the maximum theoretical transfer rate is 1.216 MB/sec. Whether you can achieve that in practice depends on the CDC implementation and OS CDC drivers. Using raw bulk endpoints, it is possible to get that speed easily.

author: DavidAlfa
author_rank: Super Contributor
timestamp: February 06, 2024, 09:49:01 pm
content: For that speed you'll need continuous conversion mode with DMA.IIRC fastest USB FS speed can be achieved in isochronous mode, 1K x 1Kbyte packets per second, so 1MB/s.You should fill a memory buffer, send it through USB while filling a second one and so on (double buffer mode).1MB is ~700K 12-bit samples, so that's your best possible throughput.The ADC will output the 12-bit conversion into a 16-bit word, right or left justified, any data packing would need CPU intervention, it might be doable @ 72MHz, at 1K packets/s you have 72K CPU instructions to process 1K buffer.You might achieve the 1Msamples/s by implementing RLE (Run-length encoding) to compress the ADC data, but this will more cpu power and definitely neeed good programming to be as fast and efficient as possible.

author: ataradov
author_rank: Super Contributor
timestamp: February 06, 2024, 10:12:23 pm
content: Fastest USB FS data rate is 1.216 MB/sec with bulk transfers. Technically bulk does not have guaranteed bandwidth, but in practice all modern OSes are capable of fully saturating the link.It is likely simple delta compression would be sufficient. Analog data is not likely to swing rapidly.

author: DavidAlfa
author_rank: Super Contributor
timestamp: February 06, 2024, 10:18:32 pm
content: Edit: Indeed, bulk mode will use all the possible BW. I read a not-so-correct PDF and I don't work in developing USB devicesStill, bulk mode will trigger USB interrupts every 64 bytes... that's 42us at 12Mbit/s? Not very cpu-friendly?isochronous might not be as fast, but allows much larger packets and lower cpu load.Not sure if the stm32F103 allows 1K packet size, though.

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 06, 2024, 10:42:04 pm
content: Quote from: ataradov on February 06, 2024, 10:12:23 pmYes, as long as there isn't any other USB device communicating concurrently on a shared hub, for instance. And said hub could be internal.

author: Nominal Animal
author_rank: Super Contributor
timestamp: February 06, 2024, 10:48:53 pm
content: FWIW, aTeensy 4.0can sustain 25 Mbytes/sec over USB Serial, because it supports USB 2.0 High Speed (480 Mbit/s). (Hereis how you can verify it for yourself. It is not a synthetic benchmark, but a PRNG generator generating a pseudorandom sequence that passes all BigCrush tests (32 high bits of Xorshift64; "more random" than even Mersenne Twister), with a program on the computer receiving the output and verifying it matches a locally duplicated sequence, using a seed value the program running on the computer supplies. It does all that at a sustained data rate of 25 Mbytes/sec or more, even on my ye olde Core i5-7200U laptop.)In other words, if you use DMA to obtain the ADC data, with a Teensy 4.x using bog-standard USB Serial you can sustain 25 Msps with 8-bit, 12 Msps with 16-bit, 8 Msps with 24-bit, or 6 Msps with 32-bit samples, and you only need toSerial.write()in chunks of 32 to 1024 bytes, and only whenSerial.availableForWrite()reports your chunk size or a larger value, like shownhere.There are some very cheap RISC-V -cored microcontrollers with high-speed USB 2.0 support, too, but I personally haven't verified what kind of performance one can get using something like the above test. I'm keeping my eye on CH32V307 and its extended family, though.

author: ataradov
author_rank: Super Contributor
timestamp: February 06, 2024, 10:49:10 pm
content: With HS hubs it is not an issue either. It may be even better, since FS traffic goes over HS to the hub.

author: iMo
author_rank: Super Contributor
timestamp: February 06, 2024, 10:51:51 pm
content: Quote from: mercurial on February 06, 2024, 07:55:01 pmStm32duino sources are open, have a look at the ADC how it is done. The limit is given by the input impedance and S/H capacitors, imho.One method is overclocking, I ran the genuine chips at 128MHz clock in that "stm32duino" era.

author: Nominal Animal
author_rank: Super Contributor
timestamp: February 06, 2024, 10:54:59 pm
content: Quote from: ataradov on February 06, 2024, 10:49:10 pmTo clarify: as high-speed traffic between hub and computer; as full-speed between Blue Pill and hub. Which indeed means other full-speed devices won't affect the Blue Pill transfer rate much, just a little bit of latency jitter. When using USB 3 or later ports, including USB-C ports, the USB 2 side is handled by a dedicated USB 2 transceiver, so that basically applies to all USB ports you see in practice. (The only exception is the really early USB 1.1 ports.)Mice and keyboards on the same (internal) hub pose no problems, but USB Audio devices and USB 2 memory sticks and card adapters could affect the full speed transfers, being high-speed USB 2 devices.In practice, over USB Serial, 1 Mbyte/sec is what I can typically expect to sustain over full speed on 32-bit ARM Cortex-Ms, and even on an 8-bit AVRs like ATmega32u4 or AT90USB1286.

author: iMo
author_rank: Super Contributor
timestamp: February 06, 2024, 11:04:25 pm
content: Quote from: iMo on February 06, 2024, 10:51:51 pmhttps://www.stm32duino.com/viewtopic.php?t=138

author: mercurial
author_rank: Regular Contributor
timestamp: February 07, 2024, 05:19:53 am
content: Quote from: iMo on February 06, 2024, 11:04:25 pmYes I had read that post or achieving 5Mbps on a Blue Pill (official sample rate as per datasheet is 1msps).I shifted from Stm32Duino to Cube32Ide to achieve the desired rate of 1Msps.First I tried with simple 32 sample acquisition in a loop and send a packet over CDC (64 bytes), but the PC doesn't seem to cope up with that.My terminal software on the PC could where I was capturing was hanging up.Are there any terminal software that can cope up with saving data to disk arriving at high rates closes to 1MB/s?

author: ataradov
author_rank: Super Contributor
timestamp: February 07, 2024, 05:34:08 am
content: You would need a Python script or something like this. Terminal software would be slow trying to render characters.

author: iMo
author_rank: Super Contributor
timestamp: February 07, 2024, 07:58:59 am
content: You would need to implement buffers (fifo queues or similar) to cope with that on both mcu and pc. Like the ADC pushes data into a fifo_mcu buffer via dma (a producer) and usb_mcu subsystem (the consumer) collects and sends that to pc, and the usb_pc (the producer) receives that and passes that via a fifo_pc to your pc_app (the consumer).PS: the usb_mcu must be faster in emptying the fifo_mcu than the ADC fills it, and the pc_app must be faster with emptying the fifo_pc than the usb_pc fills it (otherwise you will get fifo overflow). The fifos will solve the "async" way the usb is handling the packets, while the ADC data stream has to be "continuous"..

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 07, 2024, 08:51:03 am
content: Quote from: ataradov on February 06, 2024, 10:49:10 pmIt's not, unless the hub is shared with other devices that are themselves in HS mode, and could hog the bandwidth. So, that's the kind of thing that is indeed what is called not guaranteed. It'll be fine in many cases, until it's not.But that shouldn't be much of a concern unless the OP was meaning to design a product - I doubt that's the case, I don't see anyone designing a commercial product around a STM32 blue pill board. Who knows though.For personal projects in which you have full control over your system, that's not really an issue indeed. At worst you plug your device to a different port, and off you go. When you have to answer hundreds of customers the same though, that's a bit less fun.

author: pcprogrammer
author_rank: Super Contributor
timestamp: February 07, 2024, 12:20:18 pm
content: In the STM32F103 you can use double buffering in the USB peripheral. Isochronous mode buffers can be 232 bytes. (The PMA buffer)I have done this with an ADS8321 100KSa/s 16bit ADC. Had to write my own driver on Linux to handle the data.Don't know if with a CDC driver this can be done with bulk end points. I tried it with a CH340 implementation, but the host did not allocate the bandwidth for it. That is why I switched over to isochronous with my own driver.Draw back is that you need to load your driver every time you start your computer and want to use the device.I attached the STM32 part of the USB setup. It is bare metal.