cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with interupts STM32F410RB

Bogdan
Senior

Hello,

i have configured timer1 to trigger via CC1  an  adc + dma.

For the DMA i have  placed the TC irq routine and placed a gpio toggle to follow with a logic analyzer like shown below

 

void DMA2_Stream0_IRQHandler(void){

 if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET)
 {
	  GPIO_ResetBits(gpio_led_port,gpio_led2);
	  GPIO_SetBits(gpio_led_port,gpio_led2);
	  GPIO_ResetBits(gpio_led_port,gpio_led2);

 	 DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
  }
}

And this is my nvic setup

 

 SysTick_Config(SystemCoreClock / 1000);
	 NVIC_InitTypeDef NVIC_InitStructure;
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);


	 NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure);


	 NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure);

 

My problem is the DMA TC IRQ never triggeres,     the timer1 cc1 output works...

 

The systick irq routine works

 

The thing is that i have tried to port the same code,  to a stm32F407VG device, and there everything works as expected...

 

I remember that on the F410 devices i always have trouble running irq's, and i am not sure if this is related to the startup file.

 

Any advices on what to check?

 

 

 

4 REPLIES 4
TDK
Super User

NVIC_PriorityGroup_0 has 0 bits available for preemption, doesn't it?

Perhaps show the code where you use DMA. You could also look at the DMA registers after the DMA is started and when the TC interrupt fails to happen.

If you feel a post has answered your question, please click "Accept as Solution".
Saket_Om
ST Employee

Hello @Bogdan 

To facilitate debugging, begin with a basic ADC conversion using DMA. If this functions correctly, you can then incorporate the TIM trigger.

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.
Saket_Om
waclawek.jan
Super User

Read out and check/post content of TIM, ADC and DMA registers.

JW

Bogdan
Senior

Hello,

this is the adc dma function content

 

void adc1_dma_config(void)
{
	ADC_InitTypeDef ADC_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	DMA_InitTypeDef       DMA_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;
	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2| GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
	GPIO_Init(GPIOC, &GPIO_InitStructure);


	DMA_Cmd(DMA2_Stream0, DISABLE);
	DMA_DeInit(DMA2_Stream0);

	DMA_InitStructure.DMA_Channel = DMA_Channel_0;
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCval[0];
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // get from ADC1 periph and store to memory in ADCval[x]
	DMA_InitStructure.DMA_BufferSize = TOTAL_ADC_CHANNELS_FOR_DMA; // 8 memory locations
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // enable to increment from  ADCval[0] to... ADCval[2]
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // read ADC DR register continously and update the buffer values
	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_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); // enable transfer complete interupt
	DMA_Init(DMA2_Stream0, &DMA_InitStructure);

	


	// ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
	 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
	 //ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
	// ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
	 ADC_CommonInit(&ADC_CommonInitStructure);

	 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	 ADC_InitStructure.ADC_ScanConvMode = ENABLE; // multi channel
	 ADC_InitStructure.ADC_ContinuousConvMode =  DISABLE; //
	 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; // trigger by timer1 CC1
	 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
	 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	 ADC_InitStructure.ADC_NbrOfConversion = 3; // 
	 ADC_Init(ADC1, &ADC_InitStructure);


	 ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_CURRENT_W, 1, ADC_SampleTime_28Cycles);
	 ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_CURRENT_V, 2, ADC_SampleTime_28Cycles );
	 ADC_RegularChannelConfig(ADC1, ADC_CHANNEL_CURRENT_U, 3, ADC_SampleTime_28Cycles );

	 ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

	 ADC_Cmd(ADC1, ENABLE);
	 ADC_DMACmd(ADC1, ENABLE);
	 DMA_Cmd(DMA2_Stream0, ENABLE);


}

 

This is the timer setup

 

void timer1_config(void){

	    GPIO_InitTypeDef  GPIO_InitStructure;
	    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	    TIM_OCInitTypeDef  TIM_OCInitStructure;
	    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_9|GPIO_Pin_8;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;
		GPIO_Init(GPIOA, &GPIO_InitStructure);

	    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;
		GPIO_Init(GPIOB, &GPIO_InitStructure);



	    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
		GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_TIM1);
		GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_TIM1);

		GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_TIM1);
		GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_TIM1);
		GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_TIM1);

		TIM_DeInit(TIM1);
		TIM_InternalClockConfig(TIM1);

		  TIM_TimeBaseStructure.TIM_Prescaler = TIMER1_Prescaler_value;
		  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
		  TIM_TimeBaseStructure.TIM_Period = TIMER1_AutoReload_value; //arr
		  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
		  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
		  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

		  	  /* Channel 1 Configuration in PWM mode */
		  	  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
		  	  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
		  	  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
		  	  TIM_OCInitStructure.TIM_Pulse = TIM1_DEFAULT_PWM_DUTYCYCLE;
		  	  TIM_OCInitStructure.TIM_OCPolarity =  TIM_OCPolarity_High;
		  	  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
		  	  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
		  	  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

		  	
		  	  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
		 	  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
		 	  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
		  	  TIM_BDTRInitStructure.TIM_DeadTime = 200;
		  	  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
		  	  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
		  	  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
		  	  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);


		     	TIM_OC1Init(TIM1, &TIM_OCInitStructure);

		    	/* Select the Master Slave Mode */
		    	TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);

		    	 TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);//

		    	 TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC1Ref);


		  	  TIM_Cmd(TIM1, ENABLE);
		  	  /* Main Output Enable */
		  	  TIM_CtrlPWMOutputs(TIM1, ENABLE);

}

 

 

And this is the main code

 

int main(void){
	 
	 SystemInit();
	 SysTick_Config(SystemCoreClock / 1000);
	 NVIC_InitTypeDef NVIC_InitStructure;
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);


	 NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure);
        
         NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure);


	 RCC_ClocksTypeDef clocks;
	 RCC_GetClocksFreq(&clocks);
	 init_rcc_leds_clocks();

	 timer1_config();
	 adc1_dma_config();
while(1)
{
}
}


void DMA2_Stream0_IRQHandler(void){

 if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET)
 {
	  GPIO_ResetBits(gpio_led_port,gpio_led2);
	  GPIO_SetBits(gpio_led_port,gpio_led2);
	  GPIO_SetBits(gpio_led_port,gpio_led2);
	  GPIO_ResetBits(gpio_led_port,gpio_led2);

	 DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
  }
}

void SysTick_Handler(void)
{
	GPIO_SetBits(gpio_led_port,gpio_led1);
	GPIO_ResetBits(gpio_led_port,gpio_led1);

}

 

i have done a little debuging last night and i noticed if i use optimization level to none -O0 the  DMA IRQ does not run. The systick irq runs

But if set optimization level to -O3   the DMA TC IRQ runs

 

Bogdan_0-1756183439360.png

 

And i have another question, ADC EOC IRQ can run in the same time when using ADC DMA TC IRQ ?