cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F0 Discovery, double buffering

MMaj.1
Associate II

As the topic says i want to implement double buffer for my ADC on DMA interruption to save data on SD card.

I've done two buffors. I am saving data to two of them in sequence. If one gets to it's limits the other one is taking the data. To point the cell of my buffer, I am using iterator. The problem is my iterator doesn't reset despite of code that does that. Whole two buffors are filled with data in first loop, then iterator gets stuck. Here is code.

uint32_t measurementADC;
uint16_t buff1[256];
uint16_t buff2[256];
 
int buff_iterator = 0;
bool flag_active_buff = true;
bool flag_to_save = false;
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
	if(buff_iterator==255)
	{
		flag_active_buff = !flag_active_buff;
		flag_to_save = true;
		buff_iterator=0;
	}
	else
	{
		flag_to_save = false;
	}
	if(flag_active_buff == true)
	{
		save_to_buff(buff1, measurementADC);
	}
	else
	{
		save_to_buff(buff2, measurementADC);
	}
}
void save_to_buff(uint16_t table[], uint16_t value)
{
	table[buff_iterator] = value;
	buff_iterator++;
}
while (1)
  {
	  if(flag_to_save ==true)
	  {
		  if(flag_active_buff == true)
		  {
			  update_file(buff1);
		  }
		  else
		  {
			 update_file(buff2);
		  }
  	  }
  }

Any ideas what's wrong?

1 ACCEPTED SOLUTION

Accepted Solutions

Using the code from the link above, the first buffer half is accessed as &adc_buf[0], the second as &adc_buf[ADC_BUF_LEN/2]. Both lengths are ADC_BUF_LEN/2. I.e. you may write the data using f_write, see FATFS middleware.

Note, that the buffer holds is raw binary data, not ASCII, you may need conversion first.

Using FatFS has its own learning curve, you might want to start with some simple examples first.

View solution in original post

6 REPLIES 6
KnarfB
Principal III

For ADC + DMA I would expect double buffering in hardware (DMA), not software. Here is an example: https://www.digikey.de/de/maker/projects/getting-started-with-stm32-working-with-adc-and-dma/f5009db3a3ed4370acaf545a3370c30c

That is exacly what helps me. But now, there is a question. How can i acces those values? I need to save them on SD.

When HAL_ADC_ConvHalfCpltCallback is called, the first half of the global array contains valid values, when HAL_ADC_ConvCpltCallback is called, the second half is valid. A simple approach would be to use FatFS and write those values out to SD directly within the interrupt. The (half) buffer size should be a multiple of the block size (512 bytes). Timing is crucial, so you should experiment with different buffer sizes and measure the timing using a logic analyzer or such. A more evolved solution would use a queue which is filled from the Callbacks and emptied in the main loop, perharps using FreeRTOS.

Okay, I understood. So how can I acces those buffers, becouse I can't see custom ones in this example. Only variable like mine.

Using the code from the link above, the first buffer half is accessed as &adc_buf[0], the second as &adc_buf[ADC_BUF_LEN/2]. Both lengths are ADC_BUF_LEN/2. I.e. you may write the data using f_write, see FATFS middleware.

Note, that the buffer holds is raw binary data, not ASCII, you may need conversion first.

Using FatFS has its own learning curve, you might want to start with some simple examples first.

Okay, I implemented everything as you said. Now I am saving data with FATFS through SPI to my SD card.

Thank you very much for your help! 😊