Using DMA ADC in combination with normal ADC?
Posted: Wed Jul 22, 2020 4:20 am
Hello there,
I'm looking a way to use DMA ADC and normal ADC combined, the DMA ADC is used to measuring current and voltage of power supply (continous), while the normal ADC used to measure temperature of transistor (probably like once per second), when i read the ADC value of temperature, the DMA goes messed up. Is there a way to do that?
I have separated the DMA ADC channel with the ADC that is used for temperature reading, the DMA is ADC1 whilst the temperature is ADC2.
If i call readTherm(int channel) function somewhere on the program, the DMA buffer goes mad (random big number like 12412812951) and also i did'nt get my temperature reading either (also some random big number).
Here is my whole DMA, ADC and some HAL GPIO settings :
I have tried to change the PinMap setting on "variants//Generic_F103Cx", like this :
but no luck
My board is BluePill and i use STM32Core
{UPDATE} : the DMA actually crashes on HAL_ADC_Start(&hadc2); as well.
HAL_ADCEx_Calibration_Start(&hadc2) too.
I'm looking a way to use DMA ADC and normal ADC combined, the DMA ADC is used to measuring current and voltage of power supply (continous), while the normal ADC used to measure temperature of transistor (probably like once per second), when i read the ADC value of temperature, the DMA goes messed up. Is there a way to do that?
I have separated the DMA ADC channel with the ADC that is used for temperature reading, the DMA is ADC1 whilst the temperature is ADC2.
If i call readTherm(int channel) function somewhere on the program, the DMA buffer goes mad (random big number like 12412812951) and also i did'nt get my temperature reading either (also some random big number).
Here is my whole DMA, ADC and some HAL GPIO settings :
Code: Select all
extern "C" void DMA1_Channel1_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_adc1);
}
extern "C" void HAL_ADC_MspInit(ADC_HandleTypeDef* hadcx)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hadcx->Instance==ADC2){
__HAL_RCC_ADC2_CLK_ENABLE();
}
if(hadcx->Instance==ADC1)
{
__HAL_RCC_ADC1_CLK_ENABLE();
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_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hadcx,DMA_Handle,hdma_adc1);
}
}
extern "C" void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadcx)
{
if(hadcx->Instance==ADC1)
{
__HAL_RCC_ADC1_CLK_DISABLE();
HAL_DMA_DeInit(hadcx->DMA_Handle);
}
if(hadcx->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_DISABLE();
HAL_DMA_DeInit(hadcx->DMA_Handle);
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
/*Configure GPIO pin : PB10 */
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_10|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_8|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
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);
}
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
ADC_ChannelConfTypeDef sConfig2 = {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 = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 4;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
hadc2.Instance = ADC2;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = DISABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
sConfig2.Channel = ADC_CHANNEL_6;
sConfig2.Rank = ADC_REGULAR_RANK_1;
sConfig2.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig2) != HAL_OK){
Error_Handler();
}
sConfig2.Channel = ADC_CHANNEL_7;
sConfig2.Rank = ADC_REGULAR_RANK_2;
sConfig2.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig2) != HAL_OK){
Error_Handler();
}
/*
sConfig2.Channel = ADC_CHANNEL_8;
sConfig2.Rank = ADC_REGULAR_RANK_3;
sConfig2.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig2) != HAL_OK){
Error_Handler();
}
*/
//////////////////////////////////////////////////////////////////
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_2;
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_3;
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = ADC_REGULAR_RANK_4;
sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK){
Error_Handler();
}
//if (HAL_ADCEx_Calibration_Start(&hadc2) != HAL_OK){
// Error_Handler();
//}
}
int readTherm(int channel){
ADC_ChannelConfTypeDef adcChannel = {0};
switch(channel){
case 0:
//adcChannel.Channel = ADC_CHANNEL_8;
break;
case 1:
adcChannel.Channel = ADC_CHANNEL_6;
break;
case 2:
adcChannel.Channel = ADC_CHANNEL_7;
break;
}
adcChannel.Rank = 1;
adcChannel.SamplingTime = ADC_SAMPLETIME_55CYCLES_5; //or any other value available.
if(HAL_ADC_ConfigChannel(&hadc2, &adcChannel) != HAL_OK){
Error_Handler();
}
HAL_ADC_Start(&hadc2);
if (HAL_ADC_PollForConversion(&hadc2, 10) == HAL_OK){
return HAL_ADC_GetValue(&hadc2);
}
}
int raw_ch1Voltage;
int raw_ch2Voltage;
int raw_ch1Current;
int raw_ch2Current;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
if(AdcHandle->Instance==ADC1){
raw_ch1Voltage = (dmaAdcBuffer[0]+dmaAdcBuffer[4]+dmaAdcBuffer[8])/3;
raw_ch2Voltage = (dmaAdcBuffer[2]+dmaAdcBuffer[6]+dmaAdcBuffer[10])/3;
raw_ch1Current = (dmaAdcBuffer[3]+dmaAdcBuffer[7]+dmaAdcBuffer[11])/3;
raw_ch2Current = (dmaAdcBuffer[1]+dmaAdcBuffer[5]+dmaAdcBuffer[9])/3;
// Add value from DMA buffer to running average (for smooth performance).
ch1Voltage.reading(raw_ch1Voltage);
ch2Current.reading(raw_ch2Current);
ch2Voltage.reading(raw_ch2Voltage);
ch1Current.reading(raw_ch1Current);
}
}
void initializeHAL(){
HAL_Init();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
HAL_ADC_Start(&hadc1);
HAL_ADC_Start(&hadc2);
HAL_ADC_Start_DMA(&hadc1, dmaAdcBuffer, 12);
}
I have tried to change the PinMap setting on "variants//Generic_F103Cx", like this :
Code: Select all
#ifdef HAL_ADC_MODULE_ENABLED
WEAK const PinMap PinMap_ADC[] = {
{PA_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0
// {PA_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0
{PA_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1
// {PA_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1
{PA_2, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2
// {PA_2, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2
{PA_3, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3
// {PA_3, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3
{PA_4, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4
// {PA_4, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4
{PA_5, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5
// {PA_5, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5
//{PA_6, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6
{PA_6, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6
//{PA_7, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7
{PA_7, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7
{PB_0, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8
// {PB_0, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8
//{PB_1, ADC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9
{PB_1, ADC2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9
{NC, NP, 0}
};
#endif
My board is BluePill and i use STM32Core
{UPDATE} : the DMA actually crashes on HAL_ADC_Start(&hadc2); as well.
HAL_ADCEx_Calibration_Start(&hadc2) too.