1

I have a STM32F417IG microcontroller an external 16bit-DAC (TI DAC81404) that is supposed to generate a Signal with a sampling rate of 32kHz. The communication via SPI should not involve any CPU resources. That is why I want to use a timer triggered DMA to shift the data with a rate of 32kHz to the SPI data register in order to send the data to the DAC.

Information about the DAC Whenever the DAC receives a channel address and the new corresponding 16bit value the DAC will renew its output voltage to the new received value. This is achieved by:

  1. Pulling the CS/NSS/SYNC – pin to low
  2. Sending the 24bit/3 byte long message and
  3. Pulling the CS back to a high state The first 8bit of the message are containing among other information the information where the output voltage should be applied. The next and concurrently the last 16bit are containing the new value.

Information about STM32 Unfortunately the microcontroller of ST are having a hardware problem with the NSS-pin. Starting the communication via SPI the NSS-pin is pulled low. Now the pin is low as long as SPI is enabled (. (reference manual page 877). That is sadly not the right way for communicate with device that are in need of a rise of the NSS after each message. A “solution” would be to toggle the NSS-pin manually as suggested in the manual (When a master is communicating with SPI slaves which need to be de-selected between transmissions, the NSS pin must be configured as GPIO or another GPIO must be used and toggled by software.)

Problem If DMA is used the ordinary way the CPU is only used when starting the process. By toggling the NSS twice every 1/32000 s this leads to corresponding CPU interactions. My question is whether I missed something in order to achieve a communication without CPU.

If not my goal is now to reduce the CPU processing time to a minimum. My pIan is to trigger DMA with a timer. So every 1/32k seconds the data register of SPI is filled with the 24bit data for the DAC. The NSS could be toggled by a timer interrupt. I have problems achieving it because I do not know how to link the timer with the DMA of the SPI using HAL-functions. Can anyone help me?

1
  • I don't think you missed anything. Most stm32's don't seem to have that feature; which is insane really. The thing you're looking for will mention "NSSP" (NSS pulse mode). You might be interested in a STM32L432KC, which has both a NSSP and a built-in DAC. Of course, you possibly won't need NSSP if you just use the built-in DAC. Commented Apr 30, 2022 at 7:33

1 Answer 1

3

This is a tricky one. It might be difficult to avoid having one interrupt per sample with this combination of DAC and microcontroller.

However, one approach I would look at is to have the CS signal created as a timer output-compare (like PWM). You can use multiple channels of the same timer or link multiple timers to create a delay between the CS output and the DMA trigger. You should allow some room for jitter, because depending on what else is happening the DMA might not respond instantly. This won't hurt your DAC output signal though, because it only outputs the value on the rising edge of chip select (called SYNC in the DAC datasheet) which will still be from your first timer.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you. Sounds like a promising approach. I will try.
what really annoys me that the STM32 MCUS (I have worked with so far) dont toggle the NSS line before and after the transmission, but pull it low once and stay there "forever", if you choose to select "Hardware NSS" in combination with "SPI Master". It shoud IMHO behave like the RS485-DE Pin in the newer G-Series, where the DE-Pin for the Transceiver is toggled automatically without any code needed ...
To release nSS high you have to clear the enable bit. Clearing it automatically would make the peripheral incompatible with any slave that requires it to stay low. A good solution would be a data count register after which it is cleared, as in some of the later I2C peripherals.
Sorry for necroposting but I don't think that this approach will work. What OP needs is 1 sample per timer tick, this means that DMA should be clocked at 32 kHz, but DMA simply follows SPI on F4.
I was suggesting to have a timer trigger the DMA, not the SPI peripheral. As far as the SPI peripheral is concerned it is being used in polling mode.
Thanks for the response. So this would mean that the DMA buffer should be just with the size of 1 sample/command, right? Because if it carries more then 1 sample, e.g. full sine wave (say 256 commands) it will trigger DMA per 32 kHz, but the DMA will burst out (per tick) the full sine with the much faster SPI clock? I am facing a similar issue here: community.st.com/t5/stm32-mcus-embedded-software/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.