2021-06-20 07:09 AM
Folks,
We are using STM32G030C6T6 (48 pin LQFP) chip on our motor control board. We need to convert 6 analog values every 50 uS or so.
Here is what we do. We have setup the TIM3 to fire at 50uS. That is working fine, we are pulsing a port in the ISR and are able to see it on the scope OK. The timer3 kicks off the ADC conversion (sequence of conversions in scan mode). Then we are using the DMA to transfer the values to memory and use it in the ISR.
In a previous version of the board we were using the 32 pin LQFP. The whole thing described above was working fine. In the new rev of the board we are using the 48 pin LQFP. We have reassigned our ports and taken care of the changes. The big difference from the previous version to this version as far as the ADC is concerned is that we have to supply the VREF voltage which we are doing and we have verified it. DMA is happening but we are getting wrong values. The voltage on two of the pins is .3 V, so we expect around 500 (in decimal) as the converted value. We are always getting 0x7FF. Sometimes we see 0xFFFF. What are we missing ? Appreciate any pointers.
Thanks.
-Bhaktha
A few details to help debug the issue.
The processor is running at 64 MHz
We copy the values from the memory buffer to our"variables" as show below, in the callback function.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if ( HAL_ADC_Stop_DMA(&hadc1) != HAL_OK )
Error_Handler();
HAL_GPIO_WritePin(ADC2Pin_GPIO_Port, ADC2Pin_Pin, 1);
Var0 = adcData[0];
Var1 = adcData[1];
Var2 = adcData[2];
Var3 = adcData[3];
Var4 = adcData[4];
Var5 = adcData[5];
if ( HAL_ADC_Start_DMA(&hadc1, (uint32_t *) adcData, ADC_BUF_SIZE) != HAL_OK )
Error_Handler();
}
The following inits are done at the beginning in main.
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
Here are the ADC, Timer and DMA init functions.
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 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 6;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_TRGO;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
static 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};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 64;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 70;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* 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_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);
}
2021-06-21 06:04 PM
Follow up information. We tried a few other things. Giving know voltages thru on a specified pin, what we found was that the last 8 bits of the read value is always 0xFF. The most significant 4 bits do change according to the voltage in a non linear fashion to the applied voltage. We also tried polling instead of DMA, we get the same results.
Appreciate any pointers.
Thanks.
-Bhaktha