Using SSC and PDC

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am working on a SSC Driver for I2S and am having trouble getting the PDC to work. I am only concerned with incoming data. I have allocated the buffer using DMA memory,

//allocate buffers
ssc->buffer = kmalloc(sizeof(char) * 1024, GFP_DMA); 

and configured the PDC registers PTCR, RPR, and RCR as follows:

pdc_ptcr =  (SSC_BF(CR_RXDIS, SSC_RXDIS_ZERO) |
	     SSC_BF(CR_RXEN, SSC_RXEN_YES) |
	     SSC_BF(CR_TXDIS, SSC_TXDIS_YES) | 
	     SSC_BF(CR_TXEN, SSC_TXEN_ZERO));

ssc_writel(ssc->regs, PDC_RPR, (u32)&i2s_devp[0]->buffer); 
ssc_writel(ssc->regs, PDC_RCR, 32);
ssc_writel(ssc->regs, PDC_PTCR, pdc_ptcr); 

I am trying to interrupt when the buffer is full, but am not sure on where to set up the interrupt. According to the documentation it appears the PDC flags the SSC Interrupt Register and triggers the SSC to interrupt but that isn't working. Or, am I just missing some clock setup for the PDC? Not sure what to do, and the other kernel drivers have their PDC code in so many places I can't seem to decode it.

Thanks for the help,
John

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is not the way to get a DMA buffer, you must have a hardware address for the memory, not an address provided by kmalloc.

IIRC the function you should look into are named dma_alloc_SOMETHING.

Hans-Christian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It appears to be dma_alloc_coherent()

So I now have the DMA Buffer allocated using

//allocate buffers
i2s_devp[i]->size = sizeof(int) * 1024; 
i2s_devp[i]->buffer = dma_alloc_coherent(NULL, i2s_devp[i]->size, &i2s_devp[i]->addr, GFP_KERNEL); 
...
ssc_writel(ssc->regs, PDC_RPR, (u32)&i2s_devp[i]->buffer); 
ssc_writel(ssc->regs, PDC_RCR, i2s_devp[i]->size);
ssc_writel(ssc->regs, PDC_PTCR, pdc_ptcr);

When I enable interrupts on SSC_RXBUFF or SSC_ENDRX, the entire system freezes. By having the interrupt flip a gpio port I am able to see that the interrupts are still being called when the system apparently freezes. They are being triggered every 32 bits that come through. Is it still suppose to trigger when the SSC_reg is full, or is the PDC suppose to trigger RXBUFF and ENDRX based on the new buffer and size? I'm sure there is something simple I am missing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seem to have gotten it working. Turns out that I needed to add the buffer in the interrupt to the Next Pointer Register.

ssc_writel(ssc->regs, PDC_RNPR, (u32)&i2s_devp[i]->buffer); 
ssc_writel(ssc->regs, PDC_RNCR, i2s_devp[i]->size); 

Thanks for your help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I am trying to do something similar using SSC as an I2S driver.  Would you be able to post some of your code? I am having issues with my configuration.
Thank you 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Jay12701" has not been here since 2009. I suggest that you don't hold your breath waiting for a reply.

 

Ross McKenzie ValuSoft Melbourne Australia