2011-05-09 07:52:08     Delay of the block zero of tdm

Document created by Aaronwu Employee on Aug 26, 2013
Version 1Show Document
  • View in full screen mode

2011-05-09 07:52:08     Delay of the block zero of tdm

Karinne Silva (BRAZIL)

Message: 100514   

 

I'am using the BF537. We used the SPORT and DMA to transmitte and receive audio. The reception is OK, but we have an intermittent problem in the transmission:

The channel zero of tdm is delayed in relation to others and it generate noise.

Example:

Original Audio:

ff 00 ff 00 ff 00 56 00 56 00 56 00 56 00 da 00

e6 00 e4 00 c3 00 ff 00 cc 00 cd 00 c3 00 d3 00

ff d8 ff 57 1a 00 89 ff 27 fe 47 f9 b2 f9 3b fd

 

Transmitted Audio:

7f 7f ff 00 ff 00 56 00 56 00 56 00 56 00 da 00

ff 00 ff 57 1a 00 89 ff 27 fe 47 f9 b2 f9 3b fd

e6 00 0d fd 04 fd 3e fd 74 fe 12 fe 6f ff 2e ff

 

I've done several tests and the filling of the DMA buffer is correct.

The problem is always in channel zero of the tdm, independent of the number of pages in the DMA, the number of channels and the codec.

 

Has anyone experienced a similar problem? Can anyone help? I'm trying to solve this problem for 3 weeks.

 

Thanks

TranslateQuoteReplyEditDelete

 

 

2011-05-09 09:54:46     Re: Delay of the block zero of tdm

Mike Frysinger (UNITED STATES)

Message: 100515   

 

please fully describe your software and hardware stack.  what versions of things are you using ?  what SPORT/codec are you using ?

QuoteReplyEditDelete

 

 

2011-05-09 10:06:11     Re: Delay of the block zero of tdm

Karinne Silva (BRAZIL)

Message: 100516   

 

SPORT config:

 

struct sport_config config = {

        .mode = TDM_MODE,

        .channels = MAX_TDM_CHANNELS,

        .frame_delay = 1,

        .int_clk = 0,

        .serial_clk = 2048000,

        .fsync_clk = 8000,

        .tckfe = 0,

        //.fsync = 1,

        .data_format = 0, /*Normal, u-law or a-law */

        .word_len = 8,

        .blocksize = 8

};

 

 

        sport_set_multichannel(dev->regs, config->channels, 1, config->frame_delay);

        tcr1 |= (config->tckfe << 14);

        rcr1 |= (config->tckfe << 14);

 

 

 

DMA config:

 

        /* DMA channel 4 mapped to TX sport1 */

 

        bfin_write_DMA4_CONFIG(WDSIZE_16 | DI_EN | DI_SEL | DMA2D | FLOW_1);

        bfin_write_DMA4_START_ADDR(sport_channel->dma_tx_buf);

 

        bfin_write_DMA4_X_COUNT(MAX_TDM_CHANNELS * config->blocksize);

        bfin_write_DMA4_X_MODIFY(2);

 

        bfin_write_DMA4_Y_COUNT(MAX_DMA_PAGES);

        bfin_write_DMA4_Y_MODIFY(2);

 

 

 

Codecs: alaw, ulaw and linear. The problem occurs in all of them.

 

Fill Buffer:

 

    for(chan = 0; chan < LEG_VP_DVR_NUM_DEVS; chan++) {

        LegVpDvrAudioDataType *pAudio = gLegVpDvrInfo[chan].pAudio;

        if (pAudio->enabled) {

                if (pAudio->linear) {

                    for (block = 0; block < blocksize; block++) {

                        unsigned short value;

                        value = cbuffer_get(&pAudio->cbuf_out);

                        buftx[(block * MAX_TDM_CHANNELS) + pAudio->channel    ] = (value >> 8) & 0xff;

                        buftx[(block * MAX_TDM_CHANNELS) + pAudio->channel + 1] = value  & 0xff;

 

                    }

                } else {

                    for (block = 0; block < blocksize; block++) {

                        buftx[(block * MAX_TDM_CHANNELS) + pAudio->channel] = (unsigned short)(pAudio->cbuf_out.buf[block]);

                    }

                }

            pAudio->can_write = 1;

            wake_up_interruptible(&pAudio->outq);

        }

    }

 

 

 

I've 4 channels. The problem occurs in all of them.

 

I've 2 dma pages. The problem occurs in all of them and if I use only one the problem occurs too.

 

BF537 revision 0.3.

 

Do you need anything else?

TranslateQuoteReplyEditDelete

 

 

2011-05-09 10:07:08     Re: Delay of the block zero of tdm

Karinne Silva (BRAZIL)

Message: 100517   

 

even filling the buffer with a constant value (without audio), the problem occurs.

TranslateQuoteReplyEditDelete

 

 

2011-05-09 10:14:40     Re: Delay of the block zero of tdm

Mike Frysinger (UNITED STATES)

Message: 100518   

 

so you're using the bfin_sport driver rather than the normal ALSA stack.

 

you still havent said what version of software you're using ...

QuoteReplyEditDelete

 

 

2011-05-09 10:18:49     Re: Delay of the block zero of tdm

Karinne Silva (BRAZIL)

Message: 100519   

 

sorry,

 

We're using our own driver.

TranslateQuoteReplyEditDelete

 

 

2011-05-09 19:09:04     Re: Delay of the block zero of tdm

Mike Frysinger (UNITED STATES)

Message: 100525   

 

you dont seem to be programming the DMA correctly.  you cannot enable things until all other fields have been properly initialized.  please consult the DMA chapter of the HRM.

QuoteReplyEditDelete

 

 

2011-05-10 07:17:37     Re: Delay of the block zero of tdm

Karinne Silva (BRAZIL)

Message: 100539   

 

The DMA and SPORT are enabled after the configuration:

 

-----------------------------------------------------------------------------------------------------------------------------------

 

if ((dev->regs->tcr1 & TSPEN) || (dev->regs->rcr1 & RSPEN))

        return -EBUSY;

 

    /* Configure DMA */

    if (dma_configure(dev->sport_num, config) < 0)

        return -EINVAL;

 

    if (config->mode == TDM_MODE) {

        if (config->channels & 0x7 || config->channels > 32)

            return -EINVAL;

 

        sport_set_multichannel(dev->regs, config->channels, 1, config->frame_delay);

        tcr1 |= (config->tckfe << 14);

        rcr1 |= (config->tckfe << 14);

 

    }

 

(...)

 

        u_long sclk = get_sclk();

 

        if (config->serial_clk < 0 || config->serial_clk > sclk / 2)

            return -EINVAL;

        clkdiv = sclk / (2 * config->serial_clk) - 1;

        fsdiv = config->serial_clk / config->fsync_clk - 1;

 

        tcr1 |= (ITFS);

        rcr1 |= (IRFS);

 

(...)

 

    tcr1 |= (config->data_format << 2); /* Bit TDTYPE */

    rcr1 |= (config->data_format << 2); /* Bit TDTYPE */

        tcr2 |= config->word_len - 1;

        rcr2 |= config->word_len - 1;

 

(...)

 

    dev->regs->rcr1 = rcr1;

    dev->regs->rcr2 = rcr2;

    dev->regs->rclkdiv = clkdiv;

    dev->regs->rfsdiv = fsdiv;

    dev->regs->tcr1 = tcr1;

    dev->regs->tcr2 = tcr2;

    dev->regs->tclkdiv = clkdiv;

    dev->regs->tfsdiv = fsdiv;

 

    SSYNC();

 

    sport_channels[dev->sport_num]->data_readable = 1;

    sport_channels[dev->sport_num]->data_writable = 1;

 

    sport_channels[dev->sport_num]->running = 1;

 

    /* Enable DMA and SPORT */

    dma_enable(dev->sport_num);

    sport_enable(dev->sport_num);

 

(...)

 

-------------------------------------------------------------------------------------------------------------------------

 

Do you have any more idea?

TranslateQuoteReplyEditDelete

 

 

2011-05-10 11:00:49     Re: Delay of the block zero of tdm

Mike Frysinger (UNITED STATES)

Message: 100544   

 

so you're using the bfin_sport driver we wrote ?  the code you quoted originally appear nowhere in our driver.

QuoteReplyEditDelete

 

 

2011-05-10 13:50:10     Re: Delay of the block zero of tdm

Karinne Silva (BRAZIL)

Message: 100549   

 

No. We are using a driver that we write here, in Brazil.

 

I add a delay in:

 

-------------------------------------------------------------------------------------------------------------------------------

 

static void le89010_audio_write(unsigned long data)

{

    int block, chan;

    unsigned short *buftx;

    int page, blocksize;

    struct sport_dev *dev = sport_devices;

    struct _sport_channel_s *sport_channel = sport_channels[dev->sport_num];

 

/*--------------------------------------------------------------------------------------------------------------------*/

    /*delay para sincronizacao do DMA/SPORT*/

    udelay(100);

/*--------------------------------------------------------------------------------------------------------------------*/

    page = sport_channel->usr_tx_page;

 

    blocksize = dev->config.blocksize;

 

    buftx = (unsigned short *)(sport_channel->dma_tx_buf + (MAX_TDM_CHANNELS*blocksize*page));

    memset(buftx, 0x7f, (MAX_TDM_CHANNELS*blocksize*2));

 

    for(chan = 0; chan < LEG_VP_DVR_NUM_DEVS; chan++) {

        LegVpDvrAudioDataType *pAudio = gLegVpDvrInfo[chan].pAudio;

        if (pAudio->enabled) {

                if (pAudio->linear) {

                    for (block = 0; block < blocksize; block++) {

                        unsigned short value;

 

                        value = cbuffer_get(&pAudio->cbuf_out);

                        buftx[(block * MAX_TDM_CHANNELS) + pAudio->channel    ] = (value >> 8) & 0xff;

                        buftx[(block * MAX_TDM_CHANNELS) + pAudio->channel + 1] = value  & 0xff;

                    }

                } else {

                    for (block = 0; block < blocksize; block++) {

                        buftx[(block * MAX_TDM_CHANNELS) + pAudio->channel] = (unsigned short)(cbuffer_get(&pAudio->cbuf_out));

                    }

                }

            pAudio->can_write = 1;

            wake_up_interruptible(&pAudio->outq);

        }

    }

 

    flush_dcache_range((unsigned long)buftx, (unsigned long)buftx + (MAX_TDM_CHANNELS * blocksize * 2));

}

 

----------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

Util now this resolve the problem. I'm not sure why exactaly.

TranslateQuoteReplyEditDelete

 

 

2011-05-10 23:48:04     Re: Delay of the block zero of tdm

Mike Frysinger (UNITED STATES)

Message: 100558   

 

you keep posting different code snippets.  the last one you posted is absolutely taken straight from the bfin_sport driver that ADI wrote.

 

the very first snippet you posted certainly is programming DMA channels incorrectly.

Attachments

    Outcomes