cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f429 ADC+DMA problem

DPech.2432
Associate II

Hi there

I am using stm32f429 dc / ac inverter.

There was a measurement problem. Without any frequency, the ADC shuts off via the ADC or DMA2st0. Turns off once every 3 weeks. Therefore, I cannot investigate this problem on my own.

I use ADC in triple mode with DMA timer start. What is the reason?

Also use USART1 + DMA2st5 + DMA2st7 modbusRTU. After an ADC error, USART1 also stops working. So I think there are problems with DMA2.

Any thoughts?

/* ADC1 init function */
void MX_ADC1_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	// RCC
	__HAL_RCC_ADC1_CLK_ENABLE();
	__HAL_RCC_DMA2_CLK_ENABLE();
	
	//NVIC
	HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); // 0 - головне , 15 - другор�?дне
  HAL_NVIC_EnableIRQ(ADC_IRQn);
	HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
	
  
  //GPIO
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 
                          |GPIO_PIN_4|GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  // DMA2_ST0  triple mode. comon register 
	
	DMA2_Stream0->NDTR = SIZEBUF_ADC123 * CHANELS_ADC123 / 2; // DMA 32bit
	DMA2_Stream0->PAR = (uint32_t )&ADC->CDR;
	DMA2_Stream0->M0AR =(uint32_t )&adc123_value[0];
	DMA2_Stream0->M1AR =(uint32_t )&adc123_value[SIZEBUF_ADC123];
	DMA2_Stream0->FCR = 0;
	
	DMA2_Stream0->CR = DMA_SxCR_MSIZE_1| // Memory data size 01: half-word (16-bit) | 10: Word (32-bit)
										 DMA_SxCR_PSIZE_1| // Peripheral data size 01: Half-word (16-bit) | 10: Word (32-bit)
										 DMA_SxCR_MINC| 	 // MINC: Memory increment mode
										 DMA_SxCR_DBM |// Double buffer mode
										 DMA_SxCR_CIRC|//
										 DMA_SxCR_TEIE| //Transfer error interrupt enable
										 DMA_SxCR_DMEIE;// Direct mode error interrupt enable
											
 
	//COMON ADC interval triple mode DMA mode 2
	ADC123_COMMON->CCR =  ADC_CCR_ADCPRE_0; // 01: PCLK2 divided by 4;
	ADC123_COMMON->CCR |= ADC_TRIPLEMODE_INTERL;
  ADC123_COMMON->CCR |= ADC_DMAACCESSMODE_2;
	ADC123_COMMON->CCR |= ADC_CCR_DDS;
  ADC123_COMMON->CCR |= ADC_TWOSAMPLINGDELAY_5CYCLES;
  //ADC triger tim 4 ch4
	ADC1->CR1 = ADC_CR1_OVRIE | // Overrun interrupt enable
							ADC_CR1_AWDEN| //Analog watchdog enable on regular channels
							ADC_CR1_SCAN| //Scan mode
							ADC_CR1_AWDIE; //Analog watchdog interrupt enable
							
	ADC1->CR2 = ADC_CR2_EOCS| //End of conversion selection
							ADC_CR2_EXTEN_0 | //01: Trigger detection on the rising edge
							ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_0 ;	//1001: Timer 4 CC4 event
							//ADC_CR2_DDS| //DMA disable selection (for single ADC mode)
							//ADC_CR2_DMA| //Direct memory access mode (for single ADC mode)
							//ADC_CR2_CONT; //Continuous conversion
							
							
	ADC1->HTR = 0xfff;//ADC watchdog higher threshold register
	ADC1->LTR = 0; //ADC watchdog lower threshold register
	
	
	// 9 pcs
	ADC1->SQR1 =  ADC_SQR1_L_3; // [3:0]: Regular channel sequence length +1
	ADC1->SQR3 = 	ADC_SQR3_RK(8,  1) |
								ADC_SQR3_RK(9,  2) |
								ADC_SQR3_RK(10,  3) |
								ADC_SQR3_RK(11, 4) |
								ADC_SQR3_RK(13, 5) |
								ADC_SQR3_RK(15, 6);
	ADC1->SQR2 = 	ADC_SQR2_RK(12, 7) |
								ADC_SQR2_RK(5,  8) |
								ADC_SQR2_RK(14, 9);
 
								
	DMA2_Stream0->CR |= DMA_SxCR_EN;							
	ADC1->CR2 |=		ADC_CR2_ADON;// A/D Converter ON / OFFA
 
 
}
/* ADC2 init function */
void MX_ADC2_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	// RCC
	__HAL_RCC_ADC2_CLK_ENABLE();
	__HAL_RCC_DMA2_CLK_ENABLE();
	
	//NVIC
	HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); // 0 - головне , 15 - другор�?дне
  HAL_NVIC_EnableIRQ(ADC_IRQn);
	//HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
  //HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
	
  
  //GPIO
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 
                          |GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  // DMA2_ST0  
	//DMA2_Stream2->NDTR = SIZEBUF_ADC2 * CHANELS_ADC2;
	//DMA2_Stream2->PAR = (uint32_t )&ADC2->DR;
	//DMA2_Stream2->M0AR =(uint32_t )&adc2_value[0];
	//DMA2_Stream2->M1AR =(uint32_t )&adc2_value[SIZEBUF_ADC2];
	//DMA2_Stream2->FCR = 0;
	
	//DMA2_Stream2->CR = DMA_SxCR_CHSEL_0 |// 001: channel 1 selected
	//									 DMA_SxCR_MSIZE_0| // Memory data size 01: half-word (16-bit)
	//									 DMA_SxCR_PSIZE_0| // Peripheral data size 01: Half-word (16-bit)
	//									 DMA_SxCR_MINC| 	 // MINC: Memory increment mode
	//									 DMA_SxCR_DBM |// Double buffer mode
	//									 DMA_SxCR_CIRC|//
	//									 DMA_SxCR_TEIE| //Transfer error interrupt enable
	//									 DMA_SxCR_DMEIE;// Direct mode error interrupt enable
											
 
	//COMON ADC
	//ADC123_COMMON->CCR = ADC_CCR_ADCPRE_0; // 01: PCLK2 divided by 4;
  //ADC
	ADC2->CR1 = ADC_CR1_OVRIE | // Overrun interrupt enable
							ADC_CR1_AWDEN| //Analog watchdog enable on regular channels
							ADC_CR1_SCAN| //Scan mode
							ADC_CR1_AWDIE; //Analog watchdog interrupt enable
							
	ADC2->CR2 = ADC_CR2_EOCS;//| //End of conversion selection
							//ADC_CR2_DDS| //DMA disable selection (for single ADC mode)
							//ADC_CR2_DMA| //Direct memory access mode (for single ADC mode)
							//ADC_CR2_CONT; //Continuous conversion
							
							
	//ADC watchdog higher threshold register 2.65V; 3V - 4095 ->  2.65 - 3620
	ADC2->HTR = 3620;
	//ADC watchdog lower threshold register 0.65V; 3V - 4095 ->  0.65 - 887
	ADC2->LTR = 887;
	
	
	// 9 pcs
	ADC2->SQR1 =  ADC_SQR1_L_3 ; // [3:0]: Regular channel sequence length
	
	ADC2->SQR3 = 	ADC_SQR3_RK(0, 1) |
								ADC_SQR3_RK(1, 2) |
								ADC_SQR3_RK(2, 3) |
								ADC_SQR3_RK(3, 4) |
								ADC_SQR3_RK(4, 5) |
								ADC_SQR3_RK(4, 6);
	ADC2->SQR2 = 	ADC_SQR2_RK(4, 7) |
								ADC_SQR2_RK(4, 8) |
								ADC_SQR2_RK(4, 9);
								
	
	
								
								
	//DMA2_Stream2->CR |= DMA_SxCR_EN;							
	ADC2->CR2 |=		ADC_CR2_ADON;// A/D Converter ON / OFFA
	
	
	
}
/* ADC3 init function */
void MX_ADC3_Init(void)
{
	
	
	GPIO_InitTypeDef GPIO_InitStruct;
	
	// RCC
	__HAL_RCC_ADC3_CLK_ENABLE();
	__HAL_RCC_DMA2_CLK_ENABLE();
	
	//NVIC
	HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); // 0 - головне , 15 - другор�?дне
  HAL_NVIC_EnableIRQ(ADC_IRQn);
	//HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
  //HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
	
  
  //GPIO
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9 
                        |GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
  // DMA2_ST1  
	//DMA2_Stream1->NDTR = SIZEBUF_ADC3 * CHANELS_ADC3;
	//DMA2_Stream1->PAR = (uint32_t )&ADC3->DR;
	//DMA2_Stream1->M0AR =(uint32_t )&adc3_value[0];
	//DMA2_Stream1->M1AR =(uint32_t )&adc3_value[SIZEBUF_ADC3];
	//DMA2_Stream1->FCR = 0;
	
	//DMA2_Stream1->CR = DMA_SxCR_CHSEL_1 |// 010: channel 2 selected
	//									 DMA_SxCR_MSIZE_0| // Memory data size 01: half-word (16-bit)
	//									 DMA_SxCR_PSIZE_0| // Peripheral data size 01: Half-word (16-bit)
	//									 DMA_SxCR_MINC| 	 // MINC: Memory increment mode
	//									 DMA_SxCR_DBM |// Double buffer mode
	//									 DMA_SxCR_CIRC|//
	//									 DMA_SxCR_TEIE| //Transfer error interrupt enable
	//									 DMA_SxCR_DMEIE;// Direct mode error interrupt enable
											
 
	//COMON ADC
	//ADC123_COMMON->CCR = ADC_CCR_ADCPRE_0; // 01: PCLK2 divided by 4;
  //ADC
	ADC3->CR1 = ADC_CR1_OVRIE | // Overrun interrupt enable
							ADC_CR1_AWDEN| //Analog watchdog enable on regular channels
							ADC_CR1_SCAN| //Scan mode
							ADC_CR1_AWDIE; //Analog watchdog interrupt enable
							
	ADC3->CR2 = ADC_CR2_EOCS;//| //End of conversion selection
							//ADC_CR2_DDS| //DMA disable selection (for single ADC mode)
							//ADC_CR2_DMA| //Direct memory access mode (for single ADC mode)
							//ADC_CR2_CONT; //Continuous conversion
							
							
	//ADC watchdog higher threshold register 
	ADC3->HTR = 0xfff;
	//ADC watchdog lower threshold register 
	ADC3->LTR = 0;
	
	
	// 9 pcs
	ADC3->SQR1 =  ADC_SQR1_L_3 ; // [3:0]: Regular channel sequence length
	
	ADC3->SQR3 = 	ADC_SQR3_RK(4, 1) |
								ADC_SQR3_RK(5, 2) |
								ADC_SQR3_RK(6, 3) |
								ADC_SQR3_RK(7, 4) |
								ADC_SQR3_RK(8, 5) |
								ADC_SQR3_RK(8, 6);
	ADC3->SQR2 = 	ADC_SQR2_RK(8, 7) |
								ADC_SQR2_RK(8, 8) |
								ADC_SQR2_RK(8, 9);
	
 
	
	
								
								
	//DMA2_Stream1->CR |= DMA_SxCR_EN;							
	ADC3->CR2 |=		ADC_CR2_ADON;// A/D Converter ON / OFFA
}

3 REPLIES 3
TDK
Guru

DMA shuts off if there are errors such as underflow/overflow. Might be that. You can attach a debugger after it happens to investigate without resetting the chip.

If you feel a post has answered your question, please click "Accept as Solution".
DPech.2432
Associate II

do not quite understand how to connect to the chip without overloading.

I'm interested in all the potential reasons for a DMA failure.

if DMA in circulates mode, how can overflow occur?

experimented with DMA BURST and DMA FIFO modes, errors always occur. sometimes more often, sometimes less often.

Perhaps there is some proven reliable configuration?

i can't afford to sit over the device for a month with a debugger.

TDK
Guru

> if DMA in circulates mode, how can overflow occur?

The DMA has limited bandwidth. If a DMA request triggers before the previous one is served, this will stop the DMA. Using the DMA FIFO will mitigate this, or setting the ADC DMA stream to higher priority than the others.

Seems like your ADC conversions could be at a pretty high rate which could be taxing on the DMA, especially if it's being used by other peripherals, e.g. USART1.

> i can't afford to sit over the device for a month with a debugger.

You can attach to an already-running chip. For example, one which has already crashed, to examine. You don't need to sit there for a month waiting for it to fail.

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