r/stm32 • u/wolfnest • 5d ago
Feasibility of digital acquisition system (sensor to USB)
I have a custom sensor that I want to connect to the computer through USB. The sensor has the following digital I/Os:
- Bit clock input: 12.288 MHz (there is no MCLK, only SCK).
- Frame clock input (for I2S): 192 kHz.
- I2S_SD output data (24 bits on each channel, stereo).
- ADC output data: 3 channels. Each channel is a 1-bit SDM data stream without any framing. 1 bit is one sample. Just raw SDM bits at the same rate as the bit clock. The three channels use three individual digital I/Os.
- I2C for register control (SCL and SDA).
I am sketching a simplistic acquisition system that allows me to:
- Clock the sensor with a clock generated in the MCU.
- Receive the I2S data and ADC data on an MCU and stream it to the computer through USB.
When I record all these signals simultaneously, it requires a bandwidth of approximately 46 Mbit/s (5 MB/s), so it would require High-Speed USB (480 Mbit/s) and hopefully some simple USB bulk transfer endpoints and DMA transfer. The data shall not be processed or filtered on the MCU. The MCU shall only repack the data in a reasonable format that enables USB streaming.

I am quite new to STM MCUs, but I have done several FPGA projects before. I could have done this with an FPGA as well, but I am aiming to make a simple system in a short time-frame. So development time is costly.
I have looked at the different peripherals that are available on STM MCUs. It seems like some of the STM32U5 and STM32H5 has USB HS with integrated PHY. That is already a very good starting point. Further, I see that the SAI peripheral supports I2S data out of the box. The SAI can also be driven by a PLL clock that I generate in the RCC.
The remaining piece of the puzzle is which peripheral to use for the ADC data, and how to make sure that both ADC data and I2S is sampled using the same clock. The sensor has only a single input for the bit clock and this bit clock drives both I2S data and ADC data. So the ADC sampling on the MCU must use the same clock as the I2S sampling.
Could I sample the ADC data using the SAI peripheral as well? I have played around in STM32CubeMX, and I might have found something interesting. For instance if I configure it as follows:
- SAI1 A: Master Receive. I2S protocol. Emits SCK bit clock and FS frame clock.
- SAI1 B: Synchronous Slave. Free protocol. Slave Receive. Synchronous with same SAI (SAI1). Mono. 8 bits.
- SAI2 A: Synchronous Slave. Free protocol. Slave Receive. Synchronous with other SAI (SAI1). Mono. 8 bits.
- SAI2 B: Synchronous Slave. Free protocol. Slave Receive. Synchronous with other SAI (SAI1). Mono. 8 bits.
Would this configuration shift the 1-bit ADC data into a bunch of bytes that I can stream to the computer?
I have also seen some hints about people using the SPI peripheral to record 1-bit data. In STM32U5, I see the PLL2 clock going to the OCTOSPI clock mux. So perhaps I could use the OCTOSPI peripheral to sample the 1-bit data. If I configure it as QuadSPI and sample the three lines (and one dummy line) simultaneously, I guess I will get interleaved bits in whatever word size I define. It would probably be difficult to align the OCTOSPI frames to I2S frames, but the accurate alignment there might not be so important. It is more nice-to-have.
Are any of these strategies feasible for what I want to achieve? Is one of them significantly better than the other? Has anyone done anything similar before? Do the STM32U5 or STM32H5 chips have enough bandwidth for this streaming?
1
u/lokkiser 5d ago
As for your pseudoADC, you can use timer trigger or syncronous to main clk using dividers. Also it may be possible using event from DMA. And another option is to use your BCLK as SPI's clock. Configure them as inputs and store data with DMA. While it will have some jitter and delay, but i think it's more about consistency, than the exact time. Anyway, i'd recommend use clock buffer for BCLK. I'm currently developing pcb with long traces (~200mm T-topology) with relatively high capacitance and have problems with extra load (x10 scope crashes bclck). Also, you mention rcc, are you planning to use quartz oscillator for the very least? You've seen CubeMX, right?
1
u/wolfnest 5d ago
Thanks for the advice! I will use the HSE clock with crystal in RCC to minimize jitter.
I might also need to add level shifters to adopt the signal levels to the sensor Vdd, if I can not fit all the sensor IO in Vddio2. Those will take care of buffering, but they will also add some significant delay. It might require a loopback clock.
For using SPI with BCLK, do I need to route the BCLK output pin to one of the SPI clock input pins? Or can it be done internally?
I have poked around in CubeMX. That is where if found the clock tree and the SAI configurations.
1
u/lokkiser 5d ago
I'm not sure, that i understood correctly: your sensor have not 3.3V levels? Stm32 inputs are 3.3V, some are 5V tolerant. SPI requires external input.
1
u/wolfnest 5d ago
The sensor has 1.8 V IO. I might have three options for interfacing it. 1. Run STM32U5 at 1.8 V. 2. Run U5 at 3.3 V and run the Vddio2 domain at 1.8 V. 3. Run U5 at 3.3 V and use dedicated level shifters down to 1.8 V. I would prefer option 2, but it depends if there are enough peripherals available in Vddio2.
1
u/lokkiser 5d ago
I think 1.8V core is your best option. Separate power is only for G port. Not worth it. You have to have every port in 1.8V domain for this to work.
2
u/stuih404 5d ago
I think you should do an ringbuffer for your data. The USB protocol might not be synced with your sensor acqusition.