cancel
Showing results for 
Search instead for 
Did you mean: 

Writing Blocks of ADC DMA Conversions to SD Card on the STM32F7 Discovery Board (ADC + Timer + DMA + SDMMC)

ConfusedContrarian
Associate III

I'm trying to write blocks of ADC Conversions using DMA from the STM32F46 Dsicovery board and I'm having issues writing to the SD card when HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) is called.

I'm running a 500KHz timer to trigger my ADC and I calculate I'll need roughly 21333 samples to fill a 32KB buffer. Based on benchmarking my SD card for random writes, I estimate this will take around 20ms. My ADC buffer will require about 42.66ms to fill up so I have some time to play with before the next set of conversions are ready.

But for some reason I'm unable to write to the SD card at all. My Main code is shown below:

#define BUFFER_LENGTH 21333
int main(void)
{
 
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SDMMC1_SD_Init();
  MX_FATFS_Init();
  MX_ADC3_Init();
  MX_TIM1_Init();
	
	/* Start Timer */
	if (HAL_TIM_Base_Start_IT(&htim1) != HAL_OK)
       {
         Error_Handler();
       }
	 /* Start ADC */
	if(HAL_ADC_Start_DMA(&hadc3, (uint32_t*)&adc_values, BUFFER_LENGTH) != HAL_OK)
	{
		Error_Handler();
	}
 
  while (1)
  {
			
  }
 
}

And the Conversion Complete Callback goes something like:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{	
	if(hadc->Instance == ADC3)
	{
              // This doesn't work
		if(f_mount(&myFatFS, SDPath, 1) == FR_OK)
		{
			char myFileName[] = "DMA.txt";
			if(f_open(&myFile, myFileName, FA_WRITE | FA_CREATE_ALWAYS) == FR_OK)
			{
				 res = f_write(&myFile, (uint8_t *)adc_values, BUFFER_LENGTH * 2, &myBytes);								
				 f_close(&myFile);	
				HAL_GPIO_WritePin(GPIOI, GPIO_PIN_1, GPIO_PIN_SET);	// Set LED once compete			
				 
			}
		}		
	}
			
}

This doesn't work and the file is not created nor is the SD Card mounted. What would be the best way to solve this issue. There are also a few things I'm unclear about on this as well and would appreciate if I could get some answers

  • In situations when you need to constantly write to SD cards, Does closing the file unmount the card? Would it be better to mount card once in initailazation and simply just keep writing?
  • The same question applies to f_open. What penalties could be incurred on the lifespan of the Card by continuously opening to write 32KB Data. Is it advisable to mount and open card in a main function and just perform an f_write and f_close when done?

1 REPLY 1

Callbacks are called under interrupt context, you should buffer the data and leave, not doing anything that will block.

Personally, if you're not doing multi-threaded stuff, put the writing in the main() loop, do f_open/f_close once, and f_write a holding buffer when you accumulate enough data. The balance of buffer sizes will depend on expected through-put. The ADC can operate on a smaller buffer that it ping-pongs between, and fills a larger buffer, or can do it in-place with a larger buffer say 32K or 64K, flagging a flush of the inactive upper/lower half to a secondary task.

>>What penalties could be incurred on the lifespan of the card..

Likely to be significant, the cards are typically juggling a pool of 128KB erase blocks, as the cards get fuller the availability will drop, and while the wear is spread around this open-write-close methodology will be detrimental. Caching and lazy writing can diminish these issues significantly, but does increase complexity. Pick your battles.

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