cancel
Showing results for 
Search instead for 
Did you mean: 

Why does the DMA gets out of sync when doing a sequence of regular AD conversions on stm32f103C8TX? This only happens with DMA_NORMAL.

Jwork.1
Associate II

It works with DMA_CIRCULAR (but I do not want or need continuous DMA transfers.)

You see by the terminal output below that reading 2 analog inputs works OK. However, after a while (< 1 minute) the 2 analog values are exchanged now. Apparently the DMA gets confused, but how and why I cannot understand.

Here is the code, all initialization was generated by STM32CubeMX, v5.5.0. (Had to omit part due to website restrictions on size of message.) NUM_AN_INPUTS=2

 ********** console output (about 30 seconds after swi upload / reset) ************

1959 0

1956 0

1957 0

1954 0

1955 0

1957 0

1955 0

1955 0

1954 0

1957 0

1959 0

0 1952

0 1953

3 1952

0 1952

0 1952

0 1953

0 1952

0 1953

 ********** usage of ADC in my code ************

volatile bool    adc_done = false;       

volatile uint16_t adc_buf[NUM_AN_INPUTS];   

while(1) {

adc_done = false;

     HAL_ADC_Start_DMA(&hadc1, (uint32_t*) adc_buf, NUM_AN_INPUTS);

while(!adc_done) {HAL_Delay(1);}   

 sprintf(message, "%d %d\n", adc_buf[0], adc_buf[1]);

 serial.USBwrite(message);

 HAL_Delay(100);

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *) {

 adc_done=true;

}

 STMCubeMX Generated code and ADC calibration:

 ************ main.c: **************

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();

 MX_DMA_Init();

 MX_ADC1_Init();

 MX_USB_DEVICE_Init();

 MX_USART3_UART_Init();

 MX_USART1_UART_Init();

 /* USER CODE BEGIN 2 */

  /* Run the ADC calibration */ 

 if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)

 {

   /* Calibration Error */

   Error_Handler();

 }

 Init functions generated by STM32CubeMX

/**

 * @brief ADC1 Initialization Function

 * @param None

 * @retval None

 */

static void MX_ADC1_Init(void)

{

 /* USER CODE BEGIN ADC1_Init 0 */

 /* USER CODE END ADC1_Init 0 */

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC1_Init 1 */

 /* USER CODE END ADC1_Init 1 */

 /** Common config

 */

 hadc1.Instance = ADC1;

 hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.NbrOfConversion = 2;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

   Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_8;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

   Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_9;

 sConfig.Rank = ADC_REGULAR_RANK_2;

 sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

   Error_Handler();

 }

 /* USER CODE BEGIN ADC1_Init 2 */

 /* USER CODE END ADC1_Init 2 */

}

/**

 * Enable DMA controller clock

 */

static void MX_DMA_Init(void)

{

 /* DMA controller clock enable */

 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */

 /* DMA1_Channel1_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}

 STMCubeMX Generated code:

 ************ main.c: **************

 void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 if(hadc->Instance==ADC1)

 {

 /* USER CODE BEGIN ADC1_MspInit 0 */

 /* USER CODE END ADC1_MspInit 0 */

   /* Peripheral clock enable */

   __HAL_RCC_ADC1_CLK_ENABLE();

   __HAL_RCC_GPIOB_CLK_ENABLE();

   /**ADC1 GPIO Configuration   

   PB0    ------> ADC1_IN8

   PB1    ------> ADC1_IN9

   */

   GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;

   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

   /* ADC1 DMA Init */

   /* ADC1 Init */

   hdma_adc1.Instance = DMA1_Channel1;

   hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;

   hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;

   hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

   hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

   hdma_adc1.Init.Mode = DMA_NORMAL;

   hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;

   if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)

   {

     Error_Handler();

   }

   __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);

   /* ADC1 interrupt Init */

   HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);

   HAL_NVIC_EnableIRQ(ADC1_2_IRQn);

 /* USER CODE BEGIN ADC1_MspInit 1 */

 /* USER CODE END ADC1_MspInit 1 */

 }

}

 STMCubeMX Generated code:

 ************ stm32f1xx_hal_msp.c: **************

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 if(hadc->Instance==ADC1)

 {

 /* USER CODE BEGIN ADC1_MspInit 0 */

 /* USER CODE END ADC1_MspInit 0 */

   /* Peripheral clock enable */

   __HAL_RCC_ADC1_CLK_ENABLE();

   __HAL_RCC_GPIOB_CLK_ENABLE();

   /**ADC1 GPIO Configuration   

   PB0    ------> ADC1_IN8

   PB1    ------> ADC1_IN9

   */

   GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;

   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

   /* ADC1 DMA Init */

   /* ADC1 Init */

   hdma_adc1.Instance = DMA1_Channel1;

   hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;

   hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;

   hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

   hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

   hdma_adc1.Init.Mode = DMA_NORMAL;

   hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;

   if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)

   {

     Error_Handler();

   }

   __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);

   /* ADC1 interrupt Init */

   HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);

   HAL_NVIC_EnableIRQ(ADC1_2_IRQn);

 /* USER CODE BEGIN ADC1_MspInit 1 */

 /* USER CODE END ADC1_MspInit 1 */

 }

}

11 REPLIES 11
Not sure if the picture of the clock configuration will get scrubbed, so:
AHB clock =  Is that the same as HCLOCK? I know that Hclock= Sysclock/1
= 72Mhz
APB1 (peripheral) clock = 36 Mhz, APB1 timer clock = 72Mhz
APB2 (peripheral) clock = 72 Mhz, APB2 timer clock = 72Mhz
ADC clock = 12 MHz
This time the ADC1 SR register is different after "ADC and DMA out of sync"
2696 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2703 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2694 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2700 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2695 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2693 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2697 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2698 9
ADC1: SR=00000010, DR=00000009. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2696 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2693 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2697 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2697 0
ADC1: SR=00000010, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2696 10
ADC1: SR=00000010, DR=0000000A. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
2695 1
ADC1: SR=00000012, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
0 2694
ADC1: SR=00000012, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
0 2692
ADC1: SR=00000012, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
0 2693
ADC1: SR=00000012, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
0 2693
ADC1: SR=00000012, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
0 2692
ADC1: SR=00000012, DR=00000000. DMA1: CNDTR=00000000, CPAR=4001244C,
CMAR=20001994
0 2694
On 2020-02-16 14:40, ST Community wrote:
Jwork.1
Associate II

This is the complete clock configuration