2020-04-22 07:57 AM
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
}
2020-04-22 08:45 AM
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.
2020-04-22 10:13 PM
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.
2020-04-23 06:06 AM
> 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.