cancel
Showing results for 
Search instead for 
Did you mean: 

Store ADC's data stream without losses

M.CHN
Associate III

Hello,

I am working on a project in which I have to store the data from my ADC (in continuous mode with DMA) on a SD card (with FATFS and SDMMC1) without losses. I try to use a ping pong buffer but when I want to change the bufferinwhich the ADC store values I have to stop my adc and restart it with the good buffer in parameter. Thus I lose a lots of data because of that.

Do you have a better solution to this matter ?

I also use my SD card in 1 bit mode because when I want to use it in 4 bits mode I have the RXOverrun flag. Fatfs is not configure to work with DMA because I don't know how to do it.

***EDIT 1***

I tryed to use a pointer in second parameter of HAL_ADC_Start_DMA() but it never write in the second buffer enven if my pointer is set at the 2nd buffer's adress.

Thank you for your help.

Best regards

Mathieu

Here is my main function

res= f_mount(&fs, "0:", 1);
  if (res == FR_OK){
	  HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
  }
  res = f_open(&SDFile, "test.bin", FA_CREATE_ALWAYS|FA_WRITE);
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)raw, LENGTH);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  int i = 0, time = 0;
  while (1)
  {
	  if (flag1){ // this flag is set in Adc convcplt callback
		if (!time) {
			HAL_ADC_Stop_DMA(&hadc1);
			HAL_ADC_Start_DMA(&hadc1, (uint32_t*)baw, LENGTH);
			res = f_write(&SDFile, raw, sizeof(raw),(void * ) &wr);
			time = 1;
		}
		else {
			HAL_ADC_Stop_DMA(&hadc1);
			HAL_ADC_Start_DMA(&hadc1, (uint32_t * )raw, LENGTH);
			res = f_write(&SDFile, baw, sizeof(baw),(void * ) &wr);
			time = 0;
		}
		  i++;
		  flag1=0;
	  }
	  if (i ==3){
		  //res = f_write(&SDFile, raw, sizeof(raw), &wr);
		  f_close(&SDFile);
		  while(1){
			  HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
			  HAL_Delay (500);
		  }
	  }
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

15 REPLIES 15

Needs to be large enough, and some multiple of sectors to write efficiently. Say 8192 bytes or 32768 as it flushes the inactive portion of the buffer.

Hard deadline is the time the ADC takes to fill the active half of the buffer.

Should get the SDMMC implementation working properly first, and 4-bit, and speed benchmarked.

Where using DMA to fill from ADC, and using polled writes from memory for SDMMC, need to watch cache coherency​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
M.CHN
Associate III

Ok, thanks four your help, I will try with these buffer sizes. However, I don't understand why I have the RXOVERRUN flag when I mount the card in 4 bits mode. I saw things about the parameter clock divider, or setting SDMMC1 pin with pull-up but nothing change when I try (SDMMC1 clock is set to 48MHz on cubeMX).

I am using a nucleo-h743zi2 board. Do you have any idea for this matter ( or maybe I must open another post for this)?

When your sampling speed is bigger as write , buffer size change dont will help. Your ADC speed must be lower as file write...when you maximize it

gregstm
Senior III

My suggestions-

Use circular buffer with HT and TC interrupts that is never stopped.

Use no calls, write only to registers, especially in interrupt handlers.

Use the GPIO BSRR register to set/reset IO pins to provide efficient accurate timing info within the interrupt routines eg. set a pin at start of routine and reset at end of routine

M.CHN
Associate III

I agree but the problem is that wen I try to maximize my file write speed I have error. I had "better" results when I set my SDMMC clock to 48 MHz with a divider of 10 ( if I understood well the datasheet I should have sdmmc clk near to 2,4 MHz which is very low). The card is mounted but nothing in writen and my code is stuck in f_close().

I continue looking for solution but the post I see don't help a lot :|

However I tryed my project's system (even with the losses of data) and It worked. The datas that I store from the adc were perfectly studyable.

Thanks for your help on this all😁

M.CHN
Associate III

I finally succeded in using my SD card in 4 bit mode. I was still loosing some datas but when I set my buffer length to 32768 as @Community member​ told me to do all work perfectly.

Thank you all for your help. 😀