RE: Configuring McBSP as part of Audio driver for OMAP3530

New design:

XRDY Interrupt is enabled.

I configure the Threshold value to 1Kbytes. Transmit buffer size is 5Kbytes.

The decoded audio samples(16 bit) will be written to Data transmit register one by one in a for loop.

After writing the each sample I read the XRDY bit of MCBSPLP_SPCR2_REG(serial port control register 2).

If not possible to write Rendering task shall wait on a semaphore.

Assumption: XRDY bit is zero because there is no free space in transmit buffer. When the free locations

in the transmit buffer goes above threshold value McBSP interrupts the CPU and in the interrupt handler

I shall release the semaphore for which the rendering task was waiting. Semaphore is used for

signaling here.

Soren, can you please check the new design. Am i missing anything?

Hi Rahanesh,

I just went quickly through you question and I can’t see any obvious problems. As stated previously it has been some time since I have done any McBSP coding myself, but I think your approach as such is correct. It might be you mis a single bit here and there, but the general structure is correct – Just go for it J

I however have two comments:

  1. Take care, there are two different XRDY bits – One in MCBSPLP_SPCR2_REG and one in MCBSPLP_IRQSTATUS_REG. I guess you already found this, but thought to mention it to be 100% sureJ

  2. Dependent on the number of other tasks you need to run on the A8 core you might want a DMA channel to fill the McBSP buffer instead of having the A8 doing it? In this case you should program the McBSP to signal a DMA request “instead of”/”in addition to” an interrupt when it’s running low on data. This approach is better at ensuring the McBSP not under-running in case of “heavy system activity”/”disabled interrupts”/etc on the A8 core. Although 5KB might sound as a huge buffer it will for a 48KHz stereo signal only contain data for ~25ms J

Best regards – Good luck

Søren

Hi Rahanesh,

In the spec i see both software trigger DMA and a Hardware trigger DMA. Which is most suited here?

You need the HW triggered version in order for the McBSP module to trigger a DMA transfer when it needs more data. I’m not completely sure, but I think a SW triggered transfer might be able to overflow the McBSP FIFO since nothing is controlling the “speed” of the DMA transfer.

As part of understanding the DMA i have written a code for data transfer from one place to another in RAM . it works fine and i get interrupt

on completion of each frame. This one is a software triggered DMA. And i use only a single channel for the transfer.

Now for audio:

I have changed the start address of DMA to be the decoded buffer address. End address to be the address of Transmit register

of McBSP2(MCBSPLP_DXR_REG).

DATA TYPE = 16 bit.

Addressing mode for source address is increment mode. and for destination is constant mode.

Size of one frame is 1K.

Once i get the decoded samples from the codec library in the decode buffer(Size is 1K) i

enable the DMA channel by setting the EN bit in CCR register. And i get interrupt after the transfer completion of 1K.

Everything seems correct to me, although I would increase the DMA transfer size (to i.e. 10KB) in order to get a lower interrupt load. Not that important though, and this of cause assumes you can live with the bigger delay this causes for decoding of the initial larger frame?

– Great work J

Assumption: During the transfer of 1K by the DMA. Processor will continue with further decoding.

The ARM core will be free continuing to run code while the DMA operates in parallel. What it actually does depend on your program, which I don’t know, but it can certainly decode the next data while the DMA is sending the current – That would be my approach J

Codec Library does not wait for the End of Frame interrupt. Will the 1K buffer be overwritten by the codec library?

I don’t know codec library, so I unfortunately can’t help you here. I would recommend using some kind of double buffering approach putting data in one buffer while transferring the other as stated above.

Current scenario: I experiance a break while audio hearing. What might be the problem?

Anything regarding the configuration?

Seems like the McBSP is under running sometimes – Most likely you are throwing away/overwriting data due to a full FIFO because nothing controls the DMA transfer. Try to change to HW controlled transfers, controlled by the McBSP DMA request signal. I can’t remember if you need to tell a threshold for the DMA request as you did for programming the interrupt from the McBSP in the beginning. Furthermore make sure you are running double buffered and decoding the next data, while transferring the current.

or Is it required to enable more than one channel?

One channel is correct. In case you want to record (RX) as well you need another channel for this.

You approach is totally correct – Just missing the last fine tuning – Good luck

Søren

"or Is it required to enable more than one channel?

One channel is correct. In case you want to record (RX) as well you need another channel for this."

The only thing I tried to say is, that in case you want to do McBSP traffic both ways (both for speaker and microphone) you need to use two DMA channels. One transferring data for input and another for the output … I hope it was clear this time?

Best regards

Søren