Author Topic: stm32 blue pill adc @ 1msps  (Read 1109 times)

0 Members and 1 Guest are viewing this topic.

Offline mercurialTopic starter

  • Contributor
  • Posts: 49
  • Country: gb
stm32 blue pill adc @ 1msps
« on: February 06, 2024, 07:55:01 pm »
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?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: stm32 blue pill adc @ 1msps
« Reply #1 on: February 06, 2024, 08:59:27 pm »
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.
Alex
 
The following users thanked this post: mercurial

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5913
  • Country: es
Re: stm32 blue pill adc @ 1msps
« Reply #2 on: February 06, 2024, 09:49:01 pm »
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.
« Last Edit: February 06, 2024, 09:53:53 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: mercurial

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: stm32 blue pill adc @ 1msps
« Reply #3 on: February 06, 2024, 10:12:23 pm »
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.
Alex
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5913
  • Country: es
Re: stm32 blue pill adc @ 1msps
« Reply #4 on: February 06, 2024, 10:18:32 pm »
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 devices :)

Still, 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.
« Last Edit: February 06, 2024, 10:25:01 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14488
  • Country: fr
Re: stm32 blue pill adc @ 1msps
« Reply #5 on: February 06, 2024, 10:42:04 pm »
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.

Yes, as long as there isn't any other USB device communicating concurrently on a shared hub, for instance. And said hub could be internal.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: stm32 blue pill adc @ 1msps
« Reply #6 on: February 06, 2024, 10:48:53 pm »
FWIW, a Teensy 4.0 can sustain 25 Mbytes/sec over USB Serial, because it supports USB 2.0 High Speed (480 Mbit/s).  (Here is 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 to Serial.write() in chunks of 32 to 1024 bytes, and only when Serial.availableForWrite() reports your chunk size or a larger value, like shown here.

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.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: stm32 blue pill adc @ 1msps
« Reply #7 on: February 06, 2024, 10:49:10 pm »
With HS hubs it is not an issue either. It may be even better, since FS traffic goes over HS to the hub.
Alex
 

Online iMo

  • Super Contributor
  • ***
  • Posts: 4791
  • Country: pm
  • It's important to try new things..
Re: stm32 blue pill adc @ 1msps
« Reply #8 on: February 06, 2024, 10:51:51 pm »
..Is it possible to get full 1msps with direct register manipulation, or any other method?

Stm32duino 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.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: stm32 blue pill adc @ 1msps
« Reply #9 on: February 06, 2024, 10:54:59 pm »
With HS hubs it is not an issue either. It may be even better, since FS traffic goes over HS to the hub.
To 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.
« Last Edit: February 06, 2024, 10:59:12 pm by Nominal Animal »
 

Online iMo

  • Super Contributor
  • ***
  • Posts: 4791
  • Country: pm
  • It's important to try new things..
Re: stm32 blue pill adc @ 1msps
« Reply #10 on: February 06, 2024, 11:04:25 pm »
..Is it possible to get full 1msps with direct register manipulation, or any other method?

Stm32duino 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.

https://www.stm32duino.com/viewtopic.php?t=138



 

Offline mercurialTopic starter

  • Contributor
  • Posts: 49
  • Country: gb
Re: stm32 blue pill adc @ 1msps
« Reply #11 on: February 07, 2024, 05:19:53 am »

https://www.stm32duino.com/viewtopic.php?t=138


Yes 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?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: stm32 blue pill adc @ 1msps
« Reply #12 on: February 07, 2024, 05:34:08 am »
You would need a Python script or something like this. Terminal software would be slow trying to render characters.
Alex
 

Online iMo

  • Super Contributor
  • ***
  • Posts: 4791
  • Country: pm
  • It's important to try new things..
Re: stm32 blue pill adc @ 1msps
« Reply #13 on: February 07, 2024, 07:58:59 am »
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"..
« Last Edit: February 07, 2024, 08:17:26 am by iMo »
 
The following users thanked this post: mercurial

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14488
  • Country: fr
Re: stm32 blue pill adc @ 1msps
« Reply #14 on: February 07, 2024, 08:51:03 am »
With HS hubs it is not an issue either. It may be even better, since FS traffic goes over HS to the hub.

It'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. ;D
 

Online pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3711
  • Country: nl
Re: stm32 blue pill adc @ 1msps
« Reply #15 on: February 07, 2024, 12:20:18 pm »
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.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf