AnsweredAssumed Answered

STM32F4 Audio Capture using FatFs SD

Question asked by afzal.uzair on Dec 16, 2014
I am facing problem in capturing and saving audio .wav file to SD card using DMA and SDIO interface. I am using STM32F4 discovery. The loopback works fine. I am using I2S sampling rate of 32k. Problem arrives when writing to SD. I am using buffer size of 1024 now which was initially 8192. I figured out after spending a week that FatFs library work only if i write 512 bytes  on SD.If i write more data like 8k buffer,it randomly skips huge chunks of data. Also i notices that it takes 20ms max to write 512 bytes(write cycle varies from 5ms to 20ms) on SD using SDIO which i think is horribly slow speed.I am now writing 1024 bytes by writing 512 bytes in ping pong method but data is skipping and audio is barely recognized.Note that i am writing to file in main while loop when DMA buffer is filled in ping pong method.I tried to write data in DMA ISR but it SDIO stuck during writes which i think is due to fast speed of incoming data so i moved to while loop.Can somebody tell me why cannot i write more than 512 bytes at once on SD and why is SDIO speed so slow.SD card is of good quality? Basic chunks of code is copied below. Thanks,

int16_t array_pong[512];

/* CODEC_I2S peripheral configuration for master TX */
SPI_I2S_DeInit(CODEC_I2S);
I2S_InitStructure.I2S_AudioFreq = 32000;
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;//extended;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
/* Initialize the I2S main channel for TX */
I2S_Init(CODEC_I2S, &I2S_InitStructure);


void DMA1_Stream3_IRQHandler(void)

     int16_t *src, *dst, sz;
     GPIO_ToggleBits(GPIOC, GPIO_Pin_1);
     total_time++;


     /* Transfer complete interrupt */
     if (DMA_GetFlagStatus(AUDIO_I2S_EXT_DMA_STREAM, AUDIO_I2S_EXT_DMA_FLAG_TC) != RESET)
     {
          /* Point to 2nd half of buffers */
          sz = szbuf/2;
          src = (int16_t *)(rxbuf) + sz;
          dst = (int16_t *)(txbuf) + sz;


          WaveCounter += sz;
          
          //I2S_RX_CallBack(src, dst, sz, 0);
  
          ping_complete = 1;
          
          /* Clear the Interrupt flag */
          DMA_ClearFlag(AUDIO_I2S_EXT_DMA_STREAM, AUDIO_I2S_EXT_DMA_FLAG_TC);
     }


     /* Half Transfer complete interrupt */
     if (DMA_GetFlagStatus(AUDIO_I2S_EXT_DMA_STREAM, AUDIO_I2S_EXT_DMA_FLAG_HT) != RESET)
     {
          /* Point to 1st half of buffers */
          sz = szbuf/2;
          src = (int16_t *)(rxbuf);
          dst = (int16_t *)(txbuf);
          WaveCounter += sz;
          
          //I2S_RX_CallBack(src, dst, sz, 1);
          pong_complete = 1;
          /* Clear the Interrupt flag */
          DMA_ClearFlag(AUDIO_I2S_EXT_DMA_STREAM, AUDIO_I2S_EXT_DMA_FLAG_HT);    
     }
}




while(1)
{
     if(total_time >= 2000)
     {
               I2S_Cmd(CODEC_I2S, DISABLE);
               I2S_Cmd(CODEC_I2S_EXT, DISABLE);
               break;
     }
     if(ping_complete == 1)
     {
          f_write (&file, (int16_t*)array_pong+256, 512, (void *)&bw);
          ping_complete =0;
     }
     if(pong_complete == 1)
     {
          f_write (&file,(int16_t *) array_pong, 512, (void *)&bw);
          pong_complete =0;
     }
     
          __nop;
          __nop;
          __nop;
          __nop;
          __nop;
          __nop;
     }

Outcomes