I am trying to make sense of DMA. So, if I understand correctly, I can have a predetermined memory space with an array of numbers and tell the MCU to just transfer that memory space to an DAC without actually reading any of it (during run time of course and the values in the array have to make sense too)? It is almost as if it is running in the background?
Exactly!
DMA goes on behind the CPU back, so once set up and activated it will do its thing, once or continuously, depending on the settings.
It can report various events to CPU via interrupt and flags in the DMA controller registers, e.g. end of transfer, errors etc.
Though the transfers happen without CPU intervention, there are always memory bandwidth considerations.
Also, I can make it uninterruptible from a timer (or I can manually tell it), so it will iterate through an array as it is directed?
I don't think "uninterruptible" is the right word (or I might have misunderstood what you mean).
DMA can be started by a SW command - usually a register write, by some HW conditions - e.g. the end of an ADC conversion and can usually be interrupted, again by writing a register.
A DMA transfer can involve a single memory location or several, and all the 4 combination of memory and peripherals as source and destination are usually supported (P->M, M->P - The DAC case, M->M, P->P).
Options for data size and increments, burst, FIFOs etc. are set up before initiating the transfer.
The flexibility of the DMA controllers varies from the very simple to the very sophisticated (e.g. with a Cypress PSoC 5 one can set up the destination of a DMA write inside the structure that define the next transfer, and automatically chain a number of them)
Is there any speed benefit (even if it is minuscule) to using DMA if the total array or message is only 2 or 3 bytes?
There are advantages, at least the CPU does not need to stop in its track and service an interrupt for transferring a couple of bytes, but as usual, it's casa by case decision.
Last, but not least, is there any good demo code? The stm code base (for the STM32F429ZI-Nucleo) shows you how to set up clearly....but it really does not show you how to actually start a transfer....or did I just completely miss it?
If I understood correctly you are looking at the DAC_GenerateWaveform_TriggerHW_Init in the STM32F429ZI Nucleo examples.
That code is not too bad, and does a good job of showing how to work with the LL; being the LL very close to the HW, the
reference manual is (to me) the best source of information.
Several parts combine to make the DMA transfer possible.
In the DMA setup function, one finds:
/*## Activation of DMA #####################################################*/
/* Enable the DMA transfer */
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);
This allows the DMA stream to start when ordered.
In the DAC setup functions, we have:
/* Enable DAC channel DMA request */
LL_DAC_EnableDMAReq(DAC1, LL_DAC_CHANNEL_1);
This tell the DAC to start a DMA request when it receives an HW trigger (but not a SW one, see the Reference Manual
).
The HW trigger is selected with:
DAC_InitStruct.TriggerSource = LL_DAC_TRIG_EXT_TIM6_TRGO;
passed to the LL init function, and the trigger out of the timer is set accordingly.
Of course, different type of transfers will have or need a different activation chain, the simplest being a memory to memory DMA: it will start immediately when the stream is enabled.