2013-07-29 08:54 AM
Hello,
I have a problem to work the DMA2 with ADC1 on STM32F205 chip. Problem is the interrupt routineDMA2_Stream0_IRQHandler is never executed despite of configuration is performed. The flag TCIF0 is however raised. I worked 2 days on this problem without to find where is the problem. Thanks for your help. Configuration is the following:void
DV_ADC_Init(
void
)
{
T_U8 Rank;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable ADC1, GPIOA/B/C and DMA2 clocks **********************************/
RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = 0;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = NUMBER_OF_ADC_CHANNEL;
ADC_Init(ADC1, &ADC_InitStructure);
/* Enable ADC interrupt in NVIC ********************************************/
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Set regular channel config **********************************************/
for
(Rank=0; Rank<(NUMBER_OF_ADC_CHANNEL); Rank++)
{
if
(REGULAR == LS_DV_ADC_ChannelMap[Rank].Cfg.u8ChannelType)
{
/* Regular channel configuration */
ADC_RegularChannelConfig(ADC1,
(T_U32)LS_DV_ADC_ChannelMap[Rank].Cfg.u8ChannelId,
Rank + 1,
(T_U32)LS_DV_ADC_ChannelMap[Rank].Cfg.u8SampleTime);
}
else
{
/* Injected channel configuration */
}
}
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Power on the ADC module / Shall be the last operation because rewrite this
register will cause a start of conversion ********************************/
ADC_Cmd(ADC1, ENABLE);
/* Activates DMA transfert *************************************************/
ADC_DMACmd(ADC1, ENABLE);
/* Configure the DMA2 Stream0 *********************************************/
DMA_Config();
}
void
DMA_Config(
void
)
{
DMA_InitTypeDef DMA_InitStructure;
__IO uint32_t Timeout = TIMEOUT_MAX;
T_U32 Llu_u32SizeOfTransfer = (T_U32)NUMBER_OF_ADC_CHANNEL;
/* Reset DMA Stream registers (for debug purpose) */
DMA_DeInit(DMA2_Stream0);
/* Check if the DMA Stream is disabled before enabling it.
Note that this step is useful when the same Stream is used multiple times:
enabled, then disabled then re-enabled... In this case, the DMA Stream disable
will be effective only at the end of the ongoing data transfer and it will
not be possible to re-configure it before making sure that the Enable bit
has been cleared by hardware. If the Stream is used only once, this step might
be bypassed. */
while
(DMA_GetCmdStatus(DMA2_Stream0) != DISABLE)
{
}
/* Configure DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Gua_DMA_RawValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = (uint32_t)Llu_u32SizeOfTransfer;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
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_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
/* DMA Stream enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
/* Check if the DMA Stream has been effectively enabled.
The DMA Stream Enable bit is cleared immediately by hardware if there is an
error in the configuration parameters and the transfer is no started (ie. when
wrong FIFO threshold is configured ...) */
Timeout = TIMEOUT_MAX;
while
((DMA_GetCmdStatus(DMA2_Stream0) != ENABLE) && (Timeout-- > 0))
{
}
/* Check if a timeout condition occurred */
if
(Timeout == 0)
{
/* Manage the error: to simplify the code enter an infinite loop */
while
(1)
{
}
}
}
void
DMA2_Stream0_IRQHandler(
void
)
{
if
(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0))
{
DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
DV_ADC_DMA_EndOfTransfer();
//--> Perform the data treatment of ADC result.
}
}
int
main(
void
)
{
DV_ADC_Init();
while
(1);
//Other tasks is performed but not presented.
}
#stm32f205 #adc-dma #adc-dma #interrupt
2013-07-29 08:59 AM
/* Enable ADC interrupt in NVIC ********************************************/
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
Yeah, that's the ADC (EOC) interrupt, you want to be configuring the DMA interrupt.
/* Enable the DMA Stream IRQ Channel */
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
2013-07-30 01:43 AM
Thanks you so much for you answer.
I thought thatDMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
was sufficient to initialize the interrupt for DMA, but not.Your help was very usefull :)CG