STM32 DMA and DAC help with the LL library - Page 1
Forum section: electronics / general

author: Gibson486
author_rank: Frequent Contributor
timestamp: October 31, 2018, 09:38:15 pm
content: 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?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?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?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?

author: newbrain
author_rank: Super Contributor
timestamp: October 31, 2018, 11:37:35 pm
content: Quote from: Gibson486 on October 31, 2018, 09:38:15 pmExactly!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.Quote from: Gibson486 on October 31, 2018, 09:38:15 pmI 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)Quote from: Gibson486 on October 31, 2018, 09:38:15 pmThere 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.Quote from: Gibson486 on October 31, 2018, 09:38:15 pmIf 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, thereference manualis (to me) the best source of information.Several parts combine to make the DMA transfer possible.In the DMA setup function, one finds:Code:/*## 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:Code:/* 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:Code: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.

author: Gibson486
author_rank: Frequent Contributor
timestamp: November 01, 2018, 02:23:46 pm
content: I see, it is all HW triggered in the demo code, that is why I could not find it.So, for SW triggering, is that what the LL_DAC_TrigSWConversion() function is for in the DAC api and the DAC demo code?

author: newbrain
author_rank: Super Contributor
timestamp: November 01, 2018, 03:01:46 pm
content: Quote from: Gibson486 on November 01, 2018, 02:23:46 pmFor SW triggering of theDAC, yes, that function is (as most of the LL lib ones) only a thin veneer on setting the right bit in the DAC_SWTRIGR register:Code:__STATIC_INLINE void LL_DAC_TrigSWConversion(DAC_TypeDef *DACx, uint32_t DAC_Channel){SET_BIT(DACx->SWTRIGR,(DAC_Channel & DAC_SWTR_CHX_MASK));}Setting that bit will immediately transfer the DHR (data holding) register to the DOR and start the conversion.Note that a SW trigger willnotstart a DMA transfer even if the DMAENx bit is set, DMA can be started only by HW triggers (chap. 14.3.7 in the RM).

author: Gibson486
author_rank: Frequent Contributor
timestamp: November 01, 2018, 05:01:02 pm
content: Thanks.kind of confused on what the software trigger is for then. You can update the DAC just by updating the register with the function LL_DAC_ConvertData12RightAligned() or something similar. I noticed that in the demo code for the DAC_GenerateConstantSignal_TriggerSW project, they update the DAC, then do a SW trigger, but it seems rather redundant.To clarify...what i am trying to do is speed up processing time. I have bunch of processes that I need done in a certain amount of time, so I am trying to make sure any event is as fast as possible. One solution was to use DMA on the DAC, but seeing as how I cannot software trigger the solution does not seem real. It looks like you need to have an event controlled by a timer, which is not what I want since the event will not be time based (at least for now). I want the event to be controlled by whenever I hit a certain piece of code (for now).

author: newbrain
author_rank: Super Contributor
timestamp: November 01, 2018, 05:28:40 pm
content: Quote from: Gibson486 on November 01, 2018, 05:01:02 pmYou are welcome!Quote from: Gibson486 on November 01, 2018, 05:01:02 pmLL_DAC_ConvertData12RightAligned() and its siblings willnotstart a DAC conversion.They just provide thenewdata to be converted, writing it in the appropriately aligned DHR (data holding register).The DAC's output will not change when writing in the DHR.The conversion is started only when a trigger is received, be it SW (LL_DAC_TrigSWConversion()) or HW.This buffering is very useful in general (you can preload the data) and fundamental if one wants to synchronize the two channels of the DAC.All this is explained quite clearly in the reference manual, the LL functions are more or less a one to one match to the registers.

author: Gibson486
author_rank: Frequent Contributor
timestamp: November 01, 2018, 05:41:57 pm
content: Quote from: newbrain on November 01, 2018, 05:28:40 pmOh....I see...I am guessing that if I choose no trigger in cubemx, then it just triggers it somewhere in there code.