cancel
Showing results for 
Search instead for 
Did you mean: 

SPI DMA request triggered by Timer-compare

FredS
Senior

Hallo everyone,

As engineer who started to explore the world of MCU's years after my retirement, I regularly encounter problems that puzzle me for some time. However, since I'm stuck for several days now, I decided to ask for assistance by this forum.

For my project, I selected a high-performance MCU, (STM32H723VGT6) mounted on a WeAct test-board, because of its price and atractive form-factor.
I want to digitize the analoge output of a linear CCD by an ADC with SPI interface. This ADC (ADS8319) needs a rising edge to start a conversion and >1.6us later it expects a serie of 16 Clock pulses to export its data. I have read an attractive solution for such challenge at the 'StackExchange' site, that sends dummy uint16 data to a SPI with DMA, triggered by a Timer.
A SPI in Full-Duplex mode, will produce 16 Clock-pulses to transmit an U16 word. The Timer must produce PWM pulses with the wanted frequency for the CCD readout. The rising edge of the pulse will trigger the ADC conversion, while the falling edge triggers the DMA transfer of a dummy uint16 to SPI, that produces the Clock-pulses needed by the ADC to export its data. The ADC's uint16 data is sent to the SPI MISO pin, to let it be transferred to the global data-array by another DMA action. The scheme below shows the timing:

Scheme_Readout_CCD_w_SPI_ADC.png

Unfortunately, the organization of DMA on my MCU (BDMA, DMA with Mux, MDMA) is different from the STM32F746 on the 'StackExchange' forum, meaning the shown code snippets cannot be copied.

I configured SPI2 as Master in Full-Duplex mode with HW NSS signal handling, set 16bit frame-size, the baudrate and MSB-first. Despite many changes and different approaches, I have not been able to make SPI2 produce Clock-pulses, while the task looks quite simple: define and start a DMA action which, triggered by a Timer-compare event, writes a uint16 value to the SPI2 TXDR register.

 

 

I sincerely hope I made myself clear and that some readers are willing to think with me about how to crack this problem. Thank you in advance,

Fred Schimmel

 

 

 

 

 

 

 

 

25 REPLIES 25

As said at the end of that article, SPI in newer STM32 (where "newer" is relative) do have NSS framing mode. I don't know if it does or does not fit @FredS usage, I haven't had a look at  the ADC's DS - some ADCs have tricky timing, others less so.

However, the 'H7 SPI is a beast which is very different from other STM32 SPIs. Maybe it has more master-mode NSS options, I don't know.

JW

Good day Barry,

Thank you for your understanding and best wishes.

And what's more important: informing me (and all other readers) about the real behavior of the HW SPI NSS signal prevents me from struggling with an incomplete picture of the reality.

I hope to report some success after some time,

many greetings,

Fred Schimmel

 

    Hallo Jan,

After stating that 8us were more than enough to handle the interrupt you made a reservation "provided you don't use other lengthy interrupt (e.g. USB) with the same or higher priority".

Just that was the case: I also added code to export the collected data as a stream of hex values in ASCII by means of USB_OTG_FS, which is a big piece of code and probably will consume a lot of CPU cycles.

Anyway, thank you for pointing out that the simple ISR alone would fit in the available time on a 84MHz clocked MCU.

Have a nice day,

Fred Schimmel

I checked. STM32G4 has a useless NSS (tied to peripheral enable/disable instead of transfer start/end).

But STM32H72x/3x and STM32H7Bx have a usable NSS (can be tied to transfer start/end).

 

 

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.

Fred,

> Just that was the case: I also added code to export the collected data as a stream of hex values in ASCII by means of USB_OTG_FS which is a big piece of code and probably will consume a lot of CPU cycles.

In that case, you should just have set the timer's interrupt's priority to higher than USB interrupt's priority (confusingly, that means numerically lower, but that's just ARM's thinking for you).

JW

 

    Hallo Jan,

Thank you once more for your guidance and patience.

All the best for you,

      Fred Schimmel