2019-09-05 01:54 PM
I want to use a periodic timer to trigger an ADC conversion (which uses DMA).
I have the periodic timer working OK on its own, and the ADC conversion with DMA working on its own... but when I try to put the two together it doesn't seem to trigger the conversion
ADC_HandleTypeDef hadcSensors;
DMA_HandleTypeDef hdma_adc1;
TIM_HandleTypeDef htim3;
TaskHandle_t pressureSensorTaskHandle;
TaskHandle_t adcSensorTaskHandle;
uint32_t ADC1ConvertedValues[2] = {0,0};
#define ADC_TIMER_PERIOD 4550
static void MX_DMA_Init(void);
void MX_TIM3_Init(void);
void PressureSensorTask(void *arg)
{
int timerValue = 0;
HAL_TIM_Base_Start(&htim3);
if ( HAL_ADC_Start_DMA(&hadcSensors, (uint32_t*)ADC1ConvertedValues, 2)!= HAL_OK)
Error_Handler(__LINE__, __FILE__);
while(true)
{
//Do something
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
print(PRINT_ALWAYS,"%u::%u::%u\r\n", ADC1ConvertedValues[0], ADC1ConvertedValues[1],__HAL_TIM_GET_COUNTER(&htim3));
}
/**
* @brief ADC1 Initialization Function
* @param None
* @retval None
*/
void MX_PressureSensor_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
BaseType_t createStatus = pdFAIL; // Init to fail to be safe
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */
hadcSensors.Instance = ADC1;
hadcSensors.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadcSensors.Init.Resolution = ADC_RESOLUTION_12B;
hadcSensors.Init.ScanConvMode = DISABLE;
hadcSensors.Init.ContinuousConvMode = DISABLE;
hadcSensors.Init.DiscontinuousConvMode = DISABLE;
hadcSensors.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadcSensors.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
hadcSensors.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadcSensors.Init.NbrOfConversion = 2;
hadcSensors.Init.DMAContinuousRequests = DISABLE;
hadcSensors.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadcSensors) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = PRESSURE_SENSOR_ADC_RANK;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadcSensors, &sConfig) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
sConfig.Channel = ADC_CHANNEL_14;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadcSensors, &sConfig) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
HAL_NVIC_SetPriority(ADC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
MX_DMA_Init();
MX_TIM3_Init();
createStatus = xTaskCreate(PressureSensorTask, "Pressure Sensor task", configMINIMAL_STACK_SIZE,(void*) NULL,1, &pressureSensorTaskHandle);
configASSERT(createStatus == pdPASS);
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM3_Init 1 */
__HAL_RCC_TIM3_CLK_ENABLE();
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 84000;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = ADC_TIMER_PERIOD;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4;
htim3.Init.RepetitionCounter = 0;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
HAL_NVIC_SetPriority(TIM3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
/* sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler(__LINE__, __FILE__);
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
/* DMA2_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
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_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA0-WKUP ------> ADC1_IN0
PA1 ------> ADC1_IN1
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA2_Stream0;
hdma_adc1.Init.Channel = DMA_CHANNEL_0;
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_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
2019-09-05 11:15 PM
Read out and check the TIM, ADC and DMA registers' content.
JW
2019-09-13 06:29 AM
Gave up on this... it was easier to use a normal sw trigger and trigger it from a periodic freertos task