cancel
Showing results for 
Search instead for 
Did you mean: 

stm32 f107 i2s and sd card via dma

Amal
Associate III
void DMA1_Channel5_IRQHandler()
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC5))
	{
		transfer_complete_flag=1;
   DMA_ClearFlag(DMA1_FLAG_TC5);
		
  }
	if(DMA_GetFlagStatus(DMA1_FLAG_HT5))
	{
	ht_c=1;
   DMA_ClearFlag(DMA1_FLAG_HT5);
  }
}
 
 
int counter=0;
int sd_ok=0;
int main()
{
int loop=0;
 
 
  GPIO_INIT();
  USART1_INIT();
  SPI_INIT();
  Debug_Port(" uart ready debugging..... \r\n");
  I2S_GPIO_Config(); 
  I2S_Config(); 
  DMA_setup();
	
  if(f_mount(&FatFs, "", 1) == FR_OK) 
  {
	Debug_Port("SD card Mounted SuccessFully!!!\r\n");
	if(f_open(&fil,"m_16.wav", FA_OPEN_EXISTING | FA_READ) == FR_OK)  
	{
            f_read(&fil,&music_buffer,100,&bw);
	   WaveFileStatus=WavePlayer_WaveParsing(&wavelen);
//		if (WaveFileStatus == Valid_WAVE_File)  /* the .WAV file is valid */
//	          {
	           /* Set WaveDataLenght to the Speech wave length */
	            WaveDataLength = WAVE_Format.DataSize;
//		  }
	//f_close(&fil); // close the file
            Debug_Port("file read complete\r\n"); // print the output at Debug Window
		}
	      f_lseek(&fil, WaveCounter);
  	      f_read (&fil,music_buffer,2000,&bw);
         				
  		DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)&music_buffer;
		DMA_InitStructure.DMA_BufferSize =2000;
		DMA_Init(DMA1_Channel5, &DMA_InitStructure);
		DMA_Cmd(DMA1_Channel5, ENABLE);
 
switch_flag=0;				
while(dummy_flag==1)
{
if(ht_c==1)
{
ht_c=0;	
f_read (&fil,music_buffer,1000,&bw);	
}
if(transfer_complete_flag==1)
{
transfer_complete_flag=0;
f_read (&fil,music_buffer_2,1000,&bw);
	for(loop=1000;loop<2000;loop++)
	{
		music_buffer[loop]=music_buffer_2[loop];
	}
}
}
} 
	else
	{
	Debug_Port("SD card Not Mounted\r\n");
	}
 
 while(1)
 {
 }
 }

i have interfaced sd card (FATFS) and i2s and also enabled dma to play wave files.i have to play large wave files >5mb how will i do that ? i am able play small files correctly <50 kb files correctly?please help

4 REPLIES 4
berendi
Principal

Review the DMA functional description / DMA channels chapter in the reference manual.

Read the first chunk of the file into memory, fill up the memory buffer. Start DMA in circular mode for playback, and watch the HTIF and TCIF flags in the DMA interrupt status register (ISR).

If the HTIF bit for the channel is set, then I2S has finished playing the first half of the buffer, and it's playing samples from the second half. You can read more data into the first half of the buffer.

If the TCIF bit is set, I2S has finished playing the second half of the buffer, and it's playing from the first half. Read more data into the second half.

hi thank you for your response ,i did like your suggestion can you please look into my code and suggest e a better way

void DMA1_Channel5_IRQHandler()
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC5))
	{
		transfer_complete_flag=1;
   DMA_ClearFlag(DMA1_FLAG_TC5);
		
  }
	if(DMA_GetFlagStatus(DMA1_FLAG_HT5))
	{
	ht_c=1;
   DMA_ClearFlag(DMA1_FLAG_HT5);
  }
}
 
 
int counter=0;
int sd_ok=0;
int main()
{
int loop=0;
 
 
  GPIO_INIT();
  USART1_INIT();
  SPI_INIT();
  Debug_Port(" uart ready debugging..... \r\n");
  I2S_GPIO_Config(); 
  I2S_Config(); 
  DMA_setup();
	
  if(f_mount(&FatFs, "", 1) == FR_OK) 
  {
	Debug_Port("SD card Mounted SuccessFully!!!\r\n");
	if(f_open(&fil,"m_16.wav", FA_OPEN_EXISTING | FA_READ) == FR_OK)  
	{
            f_read(&fil,&music_buffer,100,&bw);
	   WaveFileStatus=WavePlayer_WaveParsing(&wavelen);
//		if (WaveFileStatus == Valid_WAVE_File)  /* the .WAV file is valid */
//	          {
	           /* Set WaveDataLenght to the Speech wave length */
	            WaveDataLength = WAVE_Format.DataSize;
//		  }
	//f_close(&fil); // close the file
            Debug_Port("file read complete\r\n"); // print the output at Debug Window
		}
	      f_lseek(&fil, WaveCounter);
  	      f_read (&fil,music_buffer,2000,&bw);
         				
  		DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)&music_buffer;
		DMA_InitStructure.DMA_BufferSize =2000;
		DMA_Init(DMA1_Channel5, &DMA_InitStructure);
		DMA_Cmd(DMA1_Channel5, ENABLE);
 
switch_flag=0;				
while(dummy_flag==1)
{
if(ht_c==1)
{
ht_c=0;	
f_read (&fil,music_buffer,1000,&bw);	
}
if(transfer_complete_flag==1)
{
transfer_complete_flag=0;
f_read (&fil,music_buffer_2,1000,&bw);
	for(loop=1000;loop<2000;loop++)
	{
		music_buffer[loop]=music_buffer_2[loop];
	}
}
}
} 
	else
	{
	Debug_Port("SD card Not Mounted\r\n");
	}
 
 while(1)
 {
 }
 }

Normally people would have the buffer in two halves and then have the content alternately read into each half of the buffer in a ping-pong type mode. You should read directly into the inactive half of the buffer rather than copy it back to the front of the buffer, that makes no sense.

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

hi thank you for your response.can you please give me a sample code as i am beginner