AnsweredAssumed Answered

ADC with DMA with SW Trigger on L486 MCU

Question asked by Andy Pevy on Jun 9, 2017
Latest reply on Nov 2, 2017 by Evgeny Erlihman

I wish to use ADC1 to measure 6 channels and to have the results DMAd into memory.

 

I am using CubeMX V4.21 and I think that I have set the parameters up correctly

(See attached screen snip ADC_DMA_1 to 3.PNG)

 

This sequence is to be triggered by S/W to run once, terminate and then run again sometime later.

(This is in a loop for testing at the moment).

 

The DMA happens as I am seeing the ADC readings appear in the adc1_data array and I get the DMA half complete interrupt handler being called but not the end of sequence interrupt.

 

What am I doing wrong please.....

 

My code is :-

 


uint16_t adc1_data[6];

#define ADC1_BUFFER_SIZE_IN_BYTES 12

#define   ADC1_TEMP1_OFFSET                   0
#define  ADC1_TEMP2_OFFSET                    1
#define  ADC1_VBOOST_OFFSET                 2
#define  ADC1_VHLC_OFFSET                       3
#define  ADC1_INTERNAL_TEMP_OFFSET  4
#define  ADC1_VREF_OFFSET                       5

 

volatile bool adc1_active_flag;


void start_adc1(void)
{
   HAL_StatusTypeDef status;

   set_VDDA_PWR_EN(ANALOG_POWER_ON);
   set_nVMON_ENABLE(VMON_ENABLE_ON);
   set_nTEMP_SENSOR_PWR_EN(TEMP_SENSOR_POWER_ON);

   adc1_active_flag = TRUE;

   osDelay(2);

   status = HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
   if(HAL_OK != status)
   {
      // Blah
   }

   status = HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1_data, ADC1_BUFFER_SIZE_IN_BYTES);
   if(HAL_OK != status)
   {
      // Blah
   }
}

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
   static bool apapap;

   if(ADC1 == hadc->Instance)
   {
      // Voltage subsystem...
      apapap = TRUE; // <<< Gets here....
   }
   if(ADC2 == hadc->Instance)
   {
      // Blah
   }   

   if(ADC3 == hadc->Instance)
   {
      // Blah
   }
}


void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
   if(ADC1 == hadc->Instance)
   {
      if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS)) // << Never gets here...
      {
         // Voltage subsystem...
         adc1_active_flag = FALSE;
         set_nTEMP_SENSOR_PWR_EN(TEMP_SENSOR_POWER_OFF);
         set_nVMON_ENABLE(VMON_ENABLE_OFF);
      }
      if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC))
      {
         // Voltage subsystem...
         adc1_active_flag = FALSE;
         set_nTEMP_SENSOR_PWR_EN(TEMP_SENSOR_POWER_OFF);
         set_nVMON_ENABLE(VMON_ENABLE_OFF);
      }
   }
   if(ADC2 == hadc->Instance)
   {
      // Blah
   }
   if(ADC3 == hadc->Instance)
   {
      // Blah
   }
}


// freeRTOS task...
//
/* Infinite loop */
for(;;)
{
   if(MODE_BLAH == my_mode)
   {
   osDelay(1000);

   // We have been woken so do something...
   start_adc1();

   // Block until the scan has completed...
   // Better way would be to use a mutex block here... [AP]
   while(TRUE == read_adc1_active_flag())
   {
      ;
   }

   len = sprintf(adc1_test, "T1:%d\tT2%dVB:%d\tVHLC:%d\tMCU_Temp:%d\tVref:%d\n",
   adc1_data[ADC1_TEMP1_OFFSET],
   adc1_data[ADC1_TEMP2_OFFSET],
   adc1_data[ADC1_VBOOST_OFFSET],
   adc1_data[ADC1_VHLC_OFFSET],
   adc1_data[ADC1_INTERNAL_TEMP_OFFSET],
   adc1_data[ADC1_VREF_OFFSET]);

   // Trace the output...
   str_trace("ADC Vals:%s", adc1_test);

   }
}

Attachments

Outcomes