Skip to main content
Visitor II
July 29, 2020
Question

Making ADC with DMA working with µSD card (SDMMC1 + FATFS) on NUCLEO-H743ZI2

  • July 29, 2020
  • 3 replies
  • 1086 views

Hello,

I am working on a project in which I have to write data from my adc into a µSD card using SDMMC1 peripheral.

In my testing program to see the ADC1 behaviour with the DMA all work. My buffer stores the datas from my ADC using DMA and the callaback functions are used (HAL_ADC_ConvHalfCpltCallback() and HAL_ADC_ConvCpltCallback()).

In another testing program for SD card (using SDMMC1 and FATFS ) all work too. I can write textfiles on my sd card correctly.

However problems come when I want to write data from my ADC's buffer on the SD card. My callbacks fonction are never used in my program (the peripherals are configured like in my testing programs which work).

I saw on this post that ADC and DMA work correctly on D2 memory domain (https://community.st.com/s/question/0D50X00009XkXEH/stm32h7stm32h743-adc-with-dma?t=1596012726292), but SDMMC1 peripheral works in D1 domain and it can't access to D2 and D3 domain (it is in STM32H7 datasheet figure 4). The problem can be here but I don't know how to solve it.

I am using STM32CUBEIDE and STM32CUBEMX

Do you have an idea on the way to solve this matter ? You will find my project attached

Thanks for your help.

Mathieu

    This topic has been closed for replies.

    3 replies

    Graduate II
    July 29, 2020

    Might skim project later when at a computer.

    Polled mode SD​MMC should be agnostic to memory in use.

    You should not​ use SDMMC / FatFs operations in a callbacks. Callbacks occur under interrupt context and need to complete quickly and predictably. Manage large aligned buffers you can flush to card in a timely manner without making them the critical path for data collection.

    M.CHNAuthor
    Visitor II
    July 29, 2020

    Thank you for your answer Clive.

    I made the change for the callback function (I also changed the main() to adapt as in the code snippet). Now my callback function set a flag which indicate that I must write the data from the buffer to the sd card. The problem is that my buffer is never filled by the ADC. However it was filled when I was testing the ADC without SDMMC and FATFS on a testing program.

    /*main function */
    int main(void)
    {
     /*Init and f_mount part)*/
    	if(f_open(&SDFile, "wav1.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK){
    			//Error
    		printf("Error openning file\r\n");
    	}
    	else {
    		printf("File Openned Successfully!\r\n");
     
     
    		//Write to the text file
    		res = f_write(&SDFile, wtext, strlen((char *)wtext), (void *)&byteswritten);
    		if((byteswritten == 0) || (res != FR_OK))
    		{
    			printf("Failed to write file!\r\n");
    		}
    		else printf("File written successfully\r\n");
     
    		f_close(&SDFile);
    	}
    	HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
    	HAL_ADC_Start_DMA(&hadc1, (uint32_t*)rtext, BUFFER);
     
     /* USER CODE END 2 */
     
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
    	 if (flagToWrite) {
    		 	flagToWrite=0;
    		 	if(f_open(&SDFile, "wav1.TXT", FA_OPEN_APPEND | FA_WRITE) != FR_OK){
    		 		printf("Error opening file\r\n");
    		 	}
    		 	else {
     
    	 			printf("File Opened Successfully!\r\n");
    		 		for (int i = 0 ; i<BUFFER; i++){
    		 			sprintf(wtext2,"%hu\r\n",rtext[i]);
    					res = f_write(&SDFile, wtext2, strlen((char *)wtext2), (void *)&byteswritten);
    					if((byteswritten == 0) || (res != FR_OK)){
    						printf("Failed to write file!\r\n");
    					}
    					else printf("ok\r");
    				}
    	 			printf("\n");
    	 			f_close(&SDFile);
    		 	}
    	 }
     /* USER CODE END WHILE */
     
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }
     
    /* Callback functions */
     
    void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc){
    	HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 1);
    	flagToWrite = 1;
    	}
     
    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
    	HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 0);
    	flagToWrite = 1;
    }
     
    /* USER CODE END 4 */

    M.CHNAuthor
    Visitor II
    August 4, 2020

    I found the solution for this matter, It was my bad (wrong connection) and now it works properly. However does anyone know how to store the data stream from the ADC stream without loss on my µSD. I just modified my main to write the data into a .bin file to avoid sprintf() function, but I still loose data as you can see on the graph. 0693W000003C0c6QAC.jpg

    Do you have any advice to store these datas ?

    Best Regards

    Mathieu

    int main(void)
    {
     /* USER CODE BEGIN 1 */
     
     /* USER CODE END 1 */
     
     /* MCU Configuration--------------------------------------------------------*/
     
     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
     HAL_Init();
     
     /* USER CODE BEGIN Init */
     
     /* USER CODE END Init */
     
     /* Configure the system clock */
     SystemClock_Config();
     
     /* USER CODE BEGIN SysInit */
     
     /* USER CODE END SysInit */
     
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_DMA_Init();
     MX_USART3_UART_Init();
     MX_USB_OTG_FS_PCD_Init();
     MX_ADC1_Init();
     MX_TIM2_Init();
     MX_SDMMC1_SD_Init();
     MX_FATFS_Init();
     /* USER CODE BEGIN 2 */
     FATFS fs;
     FRESULT res ;
     res = f_mount(&fs, "0:", 1);
     if (res == FR_OK){
     	 HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, 1);
     	 /*res = f_open(&SDFile, "wav1.CSV", FA_CREATE_ALWAYS | FA_WRITE);
     	 if (res == FR_OK){
     		HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, 0);
     		res = f_write(&SDFile, wtext1, strlen((char *)wtext1), (void *)&byteswritten);
     		if((byteswritten == 0) || (res != FR_OK)){
     			HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 1);
     		}
     		else
     			HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, 1);
     		f_close(&SDFile);
     	 }*/
     
     }
     //HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
     
     if(f_open(&SDFile, "wav1.BIN", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK){ //ouvre un fichier en �criture, le cr�e s'il n'existe pas
     		 				//Error
     			 HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
     		 		}
     		 		else {
     		 			HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 1);
     		 			HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcBuffer, BUFFERLENGTH);
     		 		}
     /* USER CODE END 2 */
     
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
    	 if (flagToWrite){
    		 flagToWrite = 0;
    		 res = f_write(&SDFile, adcBuffer, strlen((char*)adcBuffer), (void *)&byteswritten);
    		 /*for (int i = 0 ; i<BUFFERLENGTH; i++){
    		 				sample = i+1+count*BUFFERLENGTH;
    		 				sprintf(time,"%e;",sample);
    		 				res = f_write(&SDFile, time, strlen((char*)time), (void *)&byteswritten);
    		 				if((byteswritten == 0) || (res != FR_OK)){
    		 					HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 1);
    		 				}
    		 				else {
    		 					HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
    		 				}
    			 sprintf(wtext2,"%hu\r\n",adcBuffer[i]);
    			 res = f_write(&SDFile, (uint8_t*)wtext2, strlen((char*)wtext2), (void *)&byteswritten);
    		 				if((byteswritten == 0) || (res != FR_OK)){
    		 					HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 1);
    		 				}
    		 				else {
    		 					HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
    		 				}
    		 }*/
    		 count++;
    		 if (count == 300){
    			 f_close(&SDFile);
    			 HAL_ADC_Stop_DMA(&hadc1);
    			 while(1){
    				 HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
    				 HAL_Delay(1000);
    			 }
    		 }
    	 }
     }
     /* USER CODE END WHILE */
     
     /* USER CODE BEGIN 3 */
     
     /* USER CODE END 3 */
    }