2014-05-03 09:56 AM
Hello, somehow i can't find way to do software trigger to start DMA transfer of memory array to dac.
Original idea is to fill data array with my wavefrom, and use software trigger to start DMA transfer. Original sample of dac code use timer to do that, but i want to make it software. Since i was unable to find any fuction call that could do that, i switched to event triger, connected that line to EXTI line 9, and use software interrupt to generate event ( or interrupt, have no idea, since only interupt is possible), same effect, no output, not even single shot ( even if dma buffer is circual) can some one tell me how can i initiate DMA transfer ? (also, if i have second dma transfer on different channel/stream, i can do that at the same time ? , since i use SPI to copy data to computer via FT232H in SPI mode, and i need at the same time to copy data from memory to 2 DACs separately ) code for DAC init looks like this :static void DAC_Ch1(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* DAC channel1 Configuration */
DAC_InitStructure.DAC_Trigger = DAC_Trigger_Software;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DMA_DeInit(DMA1_Stream5);
DMA_InitStructure.DMA_Channel = DMA_Channel_7;
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR8R1_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&aEscalator8bit;
DMA_InitStructure.DMA_BufferSize = 6;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
/* Enable DMA1_Stream5 */
DMA_Cmd(DMA1_Stream5, ENABLE);
/* Enable DAC Channel1 */
DAC_Cmd(DAC_Channel_1, ENABLE);
/* Enable DMA for DAC Channel1 */
DAC_DMACmd(DAC_Channel_1, ENABLE);
}
2014-05-03 11:39 PM
Which MCU are you using? For me, I am using STM32F429ZI, and according to datasheet, DMA request can only be generated when external interrtupt happens (not including software trigger).
2014-05-04 12:27 AM
For now test platfrom is STM32F429I, but later it will be STM32F415.
So that you are saying, i can't make it work the way i wanted to ? i think it should be possible to generate event via software, but how to do that on EXTI_Line9 ? ( i guess is not the same as interrupt)2014-05-04 01:02 AM
Seems like a pointless exercise, why wouldn't you just write the value from the array into the DAC, and be done? What possible benefit does DMA bring to this party?
2014-05-04 02:11 AM
i have 3 tasks that must be done in prallel.
1) Data logging to computer via SPI interface, also as bonus i get PID position values for system, right now i am pushing 6kHz cyclic speed from this loop, and processor is free from work 2) I have to read complex multichannel sensor with 18b adc, as well as performing multiplexing for singe ADC, and integrators resets also is handled by mcu . When i get data from adc, i have to calculate system parameters that will be logged to computer, and from that i am also get error signal for system X and Y coordinates. 3) from error signal as well as setpoint that i will get from computer i have to generate control pulses for piezo picomotors, problem is that picomotor will only generate single step with special waveform, it needs to get slow ramp voltage to 130V and extremely fast ramp-down to make step. relation ramp speed front will dictate where picomotor will turn. allso i have to perform this at two picomotors, so two data streams must be generated at the same time, good news i only need to send it, it's not very time critical, so that transfer will get lowest priority. So i only need to copy that waveform from memory to dac, and i will use DMA complete interrupt to calculate new pulse required to make my system stable, but i can't do that only by setting data software to DAC while at the same time i have to make data acquisition from sensor2014-05-04 04:23 AM
Ok, but still trying to get from ''Software Trigger'', to why won't DAC_SetChannel1Data() work, or that you have a fixed DMA buffer, clocked via a timer (to pace the waveform), and set the DMA in to a non-circular one shot fashion.
2014-05-04 05:19 AM
all i need is to be able to single arb waveform generation from software by using as less cpu time as possible.
So start DMA by Timer, and use dma compleate interrupt to stop it or/and restart for new data ?2014-05-04 05:59 AM
So, if you configure the DMA in Normal instead of Circular mode then it will stop automatically when the pattern buffer is exhausted. When you need a new pattern you reinitialize the DMA transfer.
You can leave the timer running, and you need the timer to keep the samples separated in the time domain properly.2014-05-04 07:51 PM
If you using STM32F429 Discovery board, then the uC should be STM32F429ZI, in its reference manual ''RM0090'' page 435, ''A DAC DMA request is generated when an external trigger (but not a software trigger) occurs while the DMAENx bit is set. The value of the DAC_DHRx register is then transferred into the DAC_DORx register.''