CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

dspic audio dac + DMA

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

dspic audio dac + DMA
PostPosted: Fri Apr 05, 2024 3:43 pm     Reply with quote

Hello,
I have setup the dspic33fj64gp802 audio dac to work with continuous ping pong DMA playing wav from SD card.


Code:

#bank_dma
    int16 AudioBufferA[256];
#bank_dma
    int16 AudioBufferB[256];

setup_dma(0, DMA_OUT_DACL, DMA_WORD);

 dma_start(0, DMA_PING_PONG,AudioBufferA,AudioBufferB,255);
DAC1LDAT=0;



and then there is the code for filling the 2 buffers.

The problem is the the DMA feeds the DAC with data all the time and the file plays very fast.
I have to use "while(ldac_full);" to wait for the DAC buffer to empty but then what is the meaning of using DMA?
When I use "while(ldac_full);" the file plays ok but with glitches on each data refill.

What is the proper way to sync the DMA to the wav sampling frequency?

Thanks for any ideas!
_________________
George.
temtronic



Joined: 01 Jul 2010
Posts: 9121
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Apr 05, 2024 4:27 pm     Reply with quote

off the top of head, never having used DMAed PIC or WAV files....
I'd think you'd read the wav file, extract the speed (44.1 KHz ? ) and somehow use that to control the speed of the DAC output ?
I bet there's 15 different 'wav formats' NOT just the 44.1 speed, heck it has to be 30+ years old now !!!
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Fri Apr 05, 2024 5:09 pm     Reply with quote

When I use the DAC without DMA I just wait for the buffer to empty then fill in some bytes and it is working good.
I just want to test the DMA to free my CPU but I can not see how to "sync" the DMA with the DAC. It keeps sending data.
I thought that since the clock divider in the DAC1CON register is set, the DAC knows how often to ask for data as it is done when "manual feeding data" when the buffer in not full.
_________________
George.
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Sun Apr 07, 2024 5:21 am     Reply with quote

The DAC has 4 word deep FiFo.
My DMA buffer is 256 16bit words because each sector read from the SD card is 512 bytes.

Is the DMA supposed to feed the DAC from this buffer 4 words at the time until the buffer is empty and then generate an interrupt?

I really cannot understand how to sync the DMA with the DAC.
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19238

View user's profile Send private message

PostPosted: Mon Apr 08, 2024 2:21 am     Reply with quote

First have you read 70211B.pdf, This is the family reference manual for
the DAC?.
Now the DMA can be programmed to send data when the DAC FIFO is
less than full or empty. Either should work the same. The speed of output
is setup in the DAC, by the DAC clock rate, which should be 256* the
specified rate in the .wav file. So 11.2896MHz for a 44.1KHz wav.
It sounds as if you may have the DAC setup with a faster clock than is
required for the specific wav file, and this is only showing when the data
is being automatically loaded by the DMA,
georpo



Joined: 18 Nov 2008
Posts: 278
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Mon Apr 08, 2024 3:20 am     Reply with quote

yes I have read the 70211B.pdf

I have to tell you that I have an audio device playing wav files from SD for many years now. The DAC clock rate is set for 22050 and I just wait for the buffer to empty and fill with data untill it is full like this:


Code:


//------------------- play 1 sector --------------------------
    for (count=1;count<=256;++count){      
     low_byte=spi_read(0xFF);      //read low byte from SD
     high_byte=spi_read(0xFF);      //read high byte from SD   
     audio=make16(high_byte,low_byte);

     while(rdac_full);   
     DAC1RDAT = audio;
     }      

//--------------------- end of 1 sector ----------------------


The code above uses continuous read command from SD card with SPI and I feed the DAC with data when it asks for.

So yes I know that since I set the DAC clock rate, it asks for data when it wants to.


Now I am using Brush Electronics FAT filesystem and I have to read the whole sector of 512 bytes, create 256 words and feed the DAC.

This delay is causing glitches of course and I am trying to use DMA in continuous ping mode mode with 2 buffers. Read from SD and fill one buffer while the other is feeding the DAC

I thought that since the DAC clock rate is set, when there is data in the DMA buffer (256 words each buffer) then the DAC will use this data and then create an interrupt. Or the DMA will create an interrupt?

I have tried both but no luck.

Now I have this as a test:

Code:

          result = f_read(&fsrc, Buffer, 512, &br);
   
     p=0;
     for (count=0;count<256;++count){       
      low_byte=Buffer[p];
      high_byte=Buffer[p+1];
      p+=2;
      AudioBufferA[count]=make16(high_byte,low_byte);
      while(!DAC1LIF);
      DAC1LIF=0;
          }


          result = f_read(&fsrc, Buffer, 512, &br);
   
     p=0;
     for (count=0;count<256;++count){       
      low_byte=Buffer[p];
      high_byte=Buffer[p+1];
      p+=2;
      AudioBufferB[count]=make16(high_byte,low_byte);
      while(!DAC1LIF);
      DAC1LIF=0;
          }



It is working with glitches on each f_read but I do not like it either way because I am waiting for the DAC interrupt within the loop.
If I remove the
Code:

      while(!DAC1LIF);
      DAC1LIF=0;

then the files plays fast.


If I need to use the DAC interrupts for every 4 words then there is no point in using DMA. The point is to fill with 256 words and do nothing else until this is finished.

I think that I should fill the buffers with data, then sit there do NOTHING and wait for interrupt (DMA or DAC?) and just refill the buffers.

Sorry for the long post and thanks for any ideas.
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19238

View user's profile Send private message

PostPosted: Mon Apr 08, 2024 8:58 am     Reply with quote

Good.
I suggest you try changing the configuration of the DAC interrupt. You
don't show how this is configured (for buffer empty, or buffer has space),
so whichever you have, try the other.

I notice in the family reference manual, it specifically says that you would
use two dma channels to handle both buffers. I think your configuration
will result in it running at double speed.

Post your configuration for the DAC. I think to work as you are, you need to
disable the right channel DAC, and interrupt. I think what is happening
is you are getting an interrupt from both channels, so the first word of
data gets fed to the left channel, then the second word to the right. Result
double the output rate from the buffers, and double the frequency on
the output.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group