Showing results for 
Search instead for 
Did you mean: 

How to read continuous data from an external ADC via the SPI interface with DMA?

Associate II

I am not sure how to read continuous data from an external ADC. The ADC has an SPI interface and a data ready pin.

Every time the data is ready, the data ready pin goes low and the data can be read. 

My goal is to read out the data via the DMA every time the data ready pin goes low.

Is this possible?

Unfortunately I have not found any examples.

I would be very grateful for any help.

David Littell
Senior III

Use the ADC's data ready pin transition low to create an interrupt. In the interrupt handler do the SPI DMA call.

Which STM32?

There may be ways to automate this without need for interrupt - in models with DMAMUX, using that; in models without, e.g. by generating SPI clocks/framing using cascaded timers triggered by the external signal. Just read the Reference Manual, and write many many small and simple experiments.


Senior III
  1. Two timers, one generates for CS, another (gated mode driven by CS event) - SPI clock.
  2. I2S, PCM mode. Provide higher frequency (PWM) clock to ADC that is synchronous to I2S frame rate, than you don't need to read DR pin.
  3. stm32H7 has NSSP - nice feature I discovered recently. Pity other stm32 uCPU product lines doesn't have.

Thank you very much for this advice. 

This helps in the beginning to increase the performance

Thank you very much for your advice.  

It would be really nice to do this without interrupts. 

I am using the STM32F303K8, so I have to use cascaded timers in this case.

Unfortunately I am not sure how to do this.

Is it possible to trigger the timer with the Data Ready pin and this calls the DMA request for the SPI interface?

> Is it possible to trigger the timer with the Data Ready pin and this calls the DMA request for the SPI interface?

Yes, that's an option too. Just set the given TIM channel to Input Capture and trigger DMA from it, transferring from memory to SPI's data register.

As I've said, read all related chapters in RM and experiment, while observing all the relevant pins using a logic analyzer.


I know it was a long time ago since you did answer this but how can the NSSP help us extract data from an external ADC via the SPI interface with DMA?

 The idea is to read external adc w/o GPIO interrupt, so sampling rate is not restricted by interrupt latency, 1usec or so on 480 MHz uCPU , or less than 1 MSPS.

Knowing number of  clock cycles for adc to complete conversion, it's not required to read DRDY. Especialy, when some ADC (AD798x etc) runs at 1.33 MSPS and doesn't have DRDY pin  at all.

1. Provide master clock from stm32H7 to adc, so adc running in sync.

2. Set up SPI-DMA in continuous mode, than adjusting NSSP delay time make SPI to run in sync with ADC conversion complete frequency.

  Changing prescaller of the SPI clock divider if NSSP delay time reach a limit.

Succsessfuly tested on stm32H743zi2 interfaced to MCP3562 & MAX11270, plan for ads127l11 and what ever comes after > 1MSPS 24-32 bits. 

Just to avoid any confusion: there is no mention of NSSP in the 'H7 RM.

NSSP in SPI of newer models other than 'H7 (e.g. the 'F3 as the OP uses) inserts a pulse on NSS with duration of exactly 1 SCK; and that is not very helpful here.

What I suspect @MasterT is referring to above, is the feature which inserts a delay between frames using the MIDI bitfield, which allows to fine-tune duration of one frame (or a sequence of frames) - in this case, adjusting it to the total sampling cycle of the ADC. A pulse simlar to NSSP can be optionally output to NSS (by setting SSOM bit, if the delay provided by MIDI is long enough), but that is not important for this purpose.