I am trying to make a project with the STM32F746ZG Nucleo board using the DMA to make a transfer of 16-bit values to a DAC connected to the MCU by SPI. I am using the STM32CubeMX to generate the init code and also the HAL Cube libraries to develop the code.
You can see the idea in the attached image,
I have configured the Request channel for DMA using the TIM7 peripheral so I can request in Stream2 (this is specified un the user manual). But I need now to configure the memory location and from where to read the data and also the SPI3 memory direction so I can send it to the DAC device.
The problem es that I can't find the code configuring this in the code generated by the STM32CubeMX and there is no example of this kind of application in the STM32CubeHAL examples so I am stucked.
Has anyone made a similar application tell me how to configure correctly the DMA to make a transision from MemToPeripheral?
Best Answer
I would like to share my related code here. The program runs on an STM32F746 Nucleo Board. It uses timer 1 to trigger DMA2 stream 5 causing fixed length transmission of data via SPI 1 to an external ADC without interrupts on the transmission side. My solution is not a generic solution to transmit variable length of SPI data. It allows to transmit up to 16 bits via SPI only. The program configures SPI to be ready to transmit and receive data. Then the DMA controller simply moves data to the SPI data register. In my DMA configuration the SPI peripheral has no change to control or synchronize the DMA stream. That's why sending more data than the 16 bits causes an overflow in the SPI peripheral. In this case DMA moves data faster than SPI transmission! As an result you detect an overrun flag in the SPI status register and indeterministic data transmission on the bus.
I used the HAL with Cube to generate the code. Later some modifications on registers are necessary to adapt the Cube peripheral configuration. To simplify and shorten my code for this post I removed most of the HAL dependency.
Edit:
ST support helped me to find a solution using the HAL functions.
Note 1: Also this solution uses the hardware generated NSS chip select. Be aware this solution might cause a little jitter caused by some processor cycles delay before DMA starts. It it also possible to use a capture compare channel of timer 1 to generate chip select signal in HW completely without jitter. For me some cycles jitter is fine.
Note 2: Also this solution does not provide any synchronization between SPI and Timer. If SPI bus is to slow to transfer data in time you end up in a mess.
Note 3: This code also contains the DMA configuration for the SPI reception side. This was not part of my first code posted above.
I tried to copy only relevant functions here. So this it is not a copy & paste solution.