What is a good way to restarting ADC-DMA with different buffer?
Hello. I am new to using STM32 MCUs and this forum has helped me a lot in getting familiar fast. I am using using NUCLEO-F756ZG board. I have tried ADC with DMA and timer trigger and it all works fine. Now, I am trying to switch timer period dynamically along with changing DMA buffer. So, after some digging on the internet, this is what I came up with.
void Restart_DMA(uint32_t ARR_val, uint32_t* new_address, uint32_t new_len)
{
//Disable ADC
hadc1.Instance->CR2 &= ~ADC_CR2_ADON;
//Disable DMA
hdma_adc1.Instance->CR &= ~DMA_SxCR_EN;
while(!(hdma_adc1.Instance->CR & DMA_SxCR_EN));
//Clear DMA flags
DMA2->LIFCR = DMA_FLAG_TCIF0_4;
//Switch timer period
htim5.Instance->CR1 &= ~(TIM_CR1_CEN);
htim5.Instance->ARR = ARR_val;
htim5.Instance->CNT = 0;
htim5.Init.Period = ARR_val;
//Set new buffer and length
hdma_adc1.Instance->CR &= ~DMA_SxCR_DBM;
hdma_adc1.Instance->NDTR = new_len;
hdma_adc1.Instance->M0AR = (uint32_t)new_address;
//Enable DMA
hdma_adc1.Instance->CR |= DMA_SxCR_EN;
//Enable ADC
hadc1.Instance->CR2 |= ADC_CR2_ADON;
//Enable Timer
htim5.Instance->CR1|=(TIM_CR1_CEN);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
if(buff_flag == 1)
{
buff_flag = 2;
Restart_DMA(7, &adc_vals2[0], 5000);
}
else
{
buff_flag = 1;
Restart_DMA(3, &adc_vals1[0], 10000);
}
}The rest is just boilerplate codes from CubeMX. The main function just initializes everything and starts the DMA stream for the first time. Since I need to switch buffer length, buffer address and sampling frequency, circular DMA is not a solution. Is this a good way to do it?
Note: This is for an application of measuring response signals of electrical system for a long time (5mintues~). It doesn't make sense to keep up 1 Msps sample rate for such a long time, 100 samples/s is enough. But the signal usually changes rapidly or has noise in the transient state. So, for a few microseconds at the beginning, I need 1 Msps sample rate. Afterwards, as the signal stabilizes, the sampling rate is gradually reduced. In the actual application, there will be 10 or so separate buffers, each to be filled with different sampling rate. I am trying to keep the transition as fast as possible.
