1
\$\begingroup\$

for some reason my DMA only seems to update ADC values once. I've set it up so that the callback function simply raises a flag everytime the DMA converts the ADCs, this flag only seems to go off once. I tried going through the example and I cannot pinpoint what I'm doing wrong. Hopefully someone can help.

void SysTimer(void) {
  ..
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1|RCC_PERIPHCLK_USB|RCC_PERIPHCLK_ADC;
  PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
  PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
}

void MX_ADC_Init(void) {
  ADC_ChannelConfTypeDef sConfig;

  //If I try to De-Init here first, I get an error

  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.OversamplingMode = DISABLE;
  if ( HAL_ADC_Init(&hadc1) != HAL_OK ) {
    errHandle(2);
  }

  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if ( HAL_ADC_ConfigChannel(&hadc1, &sConfig) ) {
    errHandle(3);
  }
}

void MX_DMA_Init(void) {
  __HAL_RCC_DMA1_CLK_ENABLE();
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {  
  adc_detect = 1;
}

ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;

int main(void) {
  MX_ADC_Init();
  MX_DMA_Init();

  uint32_t adc[32];
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc, 32);

  while (1) {
    if ( adc_detect ) {
      adc_detect = 0;
    }


  HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
  HAL_Delay(500);
  }
}

Edit (Solution): You need to init DMA before ADC because the HAL_ADC_Init file calls the HAL_ADC_MspInit, which configures your DMA. As such, you need to initialize your DMA channels before that.

\$\endgroup\$
  • \$\begingroup\$ So I figured it out. I need to init DMA before I init ADC. \$\endgroup\$ – Momo Mar 29 at 23:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.