2016-03-11 08:03 AM
Dear Community,
I am trying to use two peripherals (STM23F373) SDADC1 and DAC1_1 having the same DMA access channel: DMA2_Channel3 (STM32F37x reference page 164).
Due to a synch problem I want to use the DMA in normal mode thus I need to reset the DMA counter after each TC interrupt and unfortunately I can’t use the 12 bit ADC since it produces some strange spikes its conversion result (this topic is already addressed here but without solution). Is there a way to distinguish from which DMA memory (assigned to the SDADC or the DAC) the DMA_TC interrupt was fired ?2016-03-11 08:25 AM
Hi gerh.jo,
As stated in the reference manual: ''The hardware requests from the peripherals (TIMx, SDADCx, DAC and SPI) are simply logically ORed before entering the DMA2. This means that on one channel, only one request must be enabled at a time. ''.So you cannot configure DMA2_Channel3 for both SDADC and DAC at the same time.Why don't you use DMA1_Channel3 for DAC1_CH1?Then could you please share the link of the other discussion?-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2016-03-14 02:17 AM
Dear Mayla,
thank you very much for responding to my question. I actually tried your recommendation to use DMA1 for feeding the DAC(s) and DMA2 for reading the SDADC. However I noticed that DMA1 and DACs are not working together as expected. I was expecting to simply adapt my DAC/DMA initialization but the DMA_IRQ is not triggered but if I use the routine for initialization the DAC with DMA2_channel3 it works properly. Probably I’veoverlooked an important detail – I would be very happy, if someone could point me into the right direction (I attached my code below).
Regarding the topic on ADC – steps and spikes please have a look for this thread:
[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Step%20in%20ADC%20data&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=2253]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex%5Fmx%5Fstm32%2FStep%20in%20ADC%20data&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=2253
and also here:
/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=https%3a//my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/SD%20card%20write%20operation%20and%20spikes%20in%20analog%20ADC%20data&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=1074
void DAC12_Init() {
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
DAC_InitTypeDef DAC_InitStructure1;
DAC_InitTypeDef DAC_InitStructure2;
DMA_InitTypeDef DMA_InitStructure1;
DMA_InitTypeDef DMA_InitStructure2;
NVIC_InitTypeDef NVIC_InitStructure1; //DMA Interupt
NVIC_InitTypeDef NVIC_InitStructure2; //DMA Interupt
// CLOCK enable*************************************************************************
// DMA1 clock enable (to be used with DAC)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// DAC clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC1, ENABLE);
// Timer 2 CLOCK enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// GPIOA clock enable
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
//*****************Enable GPIOA (PA4,5 & 6) as DAC output
// Configure PA.04 (DAC_OUT1) as analog
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //DAC11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //DAC12
GPIO_Init(GPIOA, &GPIO_InitStructure);
//*****************Enable Timer 3 for itterating the DAC and DMA
// TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
// TIM_TimeBaseStructure.TIM_Period = SAMPLE_Interval;// 0x80;// 0x500; //0x80;// 0x80;// //define the periode (500 points so far
// TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
// TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
// TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
// TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
// TIM_Cmd(TIM3, ENABLE); //is OK
// TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
// DAC1 channel1 and channel2 Configuration
DAC_InitStructure1.DAC_Trigger = DAC_Trigger_T3_TRGO;// DAC_Trigger_T2_TRGO;//DAC_Trigger_None;// DAC_Trigger_Ext_IT9; //PIN!!!
DAC_InitStructure1.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure1.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
DAC_InitStructure1.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
DAC_InitStructure2.DAC_Trigger = DAC_Trigger_T3_TRGO;// DAC_Trigger_T2_TRGO;//DAC_Trigger_None;// DAC_Trigger_Ext_IT9; //PIN!!!
DAC_InitStructure2.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure2.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
DAC_InitStructure2.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
//DMA
DMA_DeInit(DMA1_Channel4);
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure1.DMA_MemoryBaseAddr = (uint32_t)&(VCOwaveOUT); //Array that contains the wave out data..
DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//DMA_MemoryDataSize_HalfWord; //
DMA_InitStructure1.DMA_PeripheralBaseAddr = (uint32_t)&DAC1->DHR12R1; // DAC->DHR12R1;// //DAC->DHR8R1; //the last digit indicates for the channel
DMA_InitStructure1.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//DMA_PeripheralDataSize_HalfWord; //
DMA_InitStructure1.DMA_BufferSize = BLOCK_SIZE;
DMA_InitStructure1.DMA_Mode = DMA_Mode_Normal;// Circular;DMA_Mode_Circular;
DMA_InitStructure1.DMA_Priority = DMA_Priority_High;
DMA_InitStructure1.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure1); //accordingly to STM32F37x ref page 162
DMA_InitStructure2.DMA_MemoryBaseAddr = (uint32_t)&(BASEwaveOUT); //Array that contains the wave out data..
DMA_InitStructure2.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure2.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//DMA_MemoryDataSize_HalfWord; //
DMA_InitStructure2.DMA_PeripheralBaseAddr = (uint32_t)&DAC1->DHR12R2; // DAC->DHR12R1;// //DAC->DHR8R1; //the last digit indicates for the channel
DMA_InitStructure2.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure2.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure2.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//DMA_PeripheralDataSize_HalfWord; //
DMA_InitStructure2.DMA_BufferSize = BLOCK_SIZE;
DMA_InitStructure2.DMA_Mode = DMA_Mode_Normal;// DMA_Mode_Circular;
DMA_InitStructure2.DMA_Priority = DMA_Priority_High;
DMA_InitStructure2.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure2);//accordingly to STM32F37x ref page 162
//Interrupts
//DMA_IT_TC: Transfer complete interrupt mask
//DMA_IT_HT: Half transfer interrupt mask
//DMA_IT_TE: Transfer error interrupt mask
// Enable DMA1 channel3 IRQ Channel
// Enable DMA1 channel4 IRQ Channel
// Enable DMA1 channel5 IRQ Channel
NVIC_InitStructure1.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure1);
NVIC_InitStructure2.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure2);
// NVIC_InitStructure3.NVIC_IRQChannel = DMA1_Channel5_IRQn;
// NVIC_InitStructure3.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure3.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure3.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure3);
// DMA CONFIG
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC , ENABLE);
DMA_Cmd(DMA1_Channel4, ENABLE);
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC , ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
//DAC INIT
DAC_Init(DAC1, DAC_Channel_1, &DAC_InitStructure1);
DAC_Init(DAC1, DAC_Channel_2, &DAC_InitStructure2);
//DAC_Init(DAC2, DAC_Channel_1, &DAC_InitStructure3);
//DAC ENABLE
DAC_Cmd(DAC1,DAC_Channel_1, ENABLE);
DAC_Cmd(DAC1,DAC_Channel_2, ENABLE);
// Enable DMA for DAC Channels
DAC_DMACmd(DAC1, DAC_Channel_1, ENABLE);
DAC_DMACmd(DAC1, DAC_Channel_2, ENABLE);
}
void DMA1_Channel4_IRQHandler() {
if(DMA_GetFlagStatus(DMA1_IT_TC4) != RESET) {
DMA_ClearITPendingBit(DMA1_IT_TC4);
DMA_Cmd(DMA1_Channel4, DISABLE);
DAC1ch1_isON = false;
if(DAC1ch1_ON) {
DAC1ch1_isON = true;
DMA1_Channel4->CNDTR = BLOCK_SIZE; // <--- transaction length
DMA_Cmd(DMA1_Channel4, ENABLE);
}
}
DMA_ClearITPendingBit(DMA1_IT_GL4);
}
void DMA1_Channel5_IRQHandler() {
if(DMA_GetFlagStatus(DMA1_IT_TC5) != RESET) {
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_Cmd(DMA1_Channel5, DISABLE);
DAC1ch2_isON = false;
if(DAC1ch2_ON) {
DAC1ch2_isON = true;
DMA1_Channel5->CNDTR = BLOCK_SIZE; // <--- transaction length
DMA_Cmd(DMA1_Channel5, ENABLE);
}
}
DMA_ClearITPendingBit(DMA1_IT_GL5);
}
*Edit I tried the DAC- DAM Channels DMA1_Channel3 -> DAC12 and DMA1_Channel4->DAC12 as well DMA1_Channel4->DAC11 and DAM1_Channel5-> DAC12 -- In all cases the IRQn routines where never called.
*EditII: In the meantime I've investigatedDAC to DMA connection in the STM32F373RB device - here are my results:
DMA2 Ch 1 2 3 4 5
DAC100 1 1 0
DAC20011 0
DMA1 Ch 1 2 3 4 5 6 7
DAC10 0 0 0 0 0 0
DAC20 0 0 0 0 0 0
Note: In contrast to the datasheet both the combinations DAC11 and DMA2ch4 + DAC12 and DMA2Ch3 are working well. Maybe ST want's to comment this finding