Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TLV320ADC3140: I2S configuration not working

Part Number: TLV320ADC3140

I'm having the damnedest time trying to get a TLV320ADC3140 to transmit I2S on a prototype I was given.

I initially tried to make it a slave but the interrupts never cleared once I powered things up, and while things were running I got no data over SDOUT, and while ASI_STS showed 0x44 most of the time, it often showed 0xf4.

Initially I was using the internal clock (samd21g18) to run a BCLK at 3.07Mhz, and 64 FS ratio, but the clocks didn't seem good enough, and got ASI_STS showing 0x44, with a lot of 0xf4, and 0x40. So I managed to hack together an XIN using a 12Mhz clock signal from another board with a 12Mhz crystal, and output 3.00Mhz BCLK and 64 FS ratio. That looked better, but I still got the occasional ASI_STS 0xf4.

Now, I'm attempting to run run the 12Mhz clock straight to GPIO1, for the master clock. If I remove the clock, I get a FS square at 7.62khz, and BCLK square at 488.1khz (using the scope's counter), equal time HI and LOW. If I add the clock (11.9997Mhz). Still no SDOUT, but FS only stays LOW for 6us for every ~94us period, and what's really goofy is that it almost looks like I'm getting data on BCLK. Meanwhile the interrupts are all over the place, as are ASI_STATUS. For a while, I thought I might have my header pins mislabeled, but I traced things back to pin 22 on the chip, and

Now, I have every reason to think this prototype is a problem in general, for all I know, there's a short on one of the ADC pins. I've ordered the 3140 dev board, and am hoping that that helps eliminate some of the issues I'm seeing. But I'm just not sure if I'm just doing something stupid in the configuration.

I'd appreciate any clues, or help.

    gpio_set_pin_level(ADC_RESET, false);
    delay_ms(300); //wait for ADC to hardware shutdown
    gpio_set_pin_level(ADC_RESET, true);
    delay_ms(50);

    ADCwrite[0] = 0x02;
    ADCwrite[1] = 0x81;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //wake up
    delay_ms(20);

    ADCwrite[0] = 0x07;
    ADCwrite[1] = 0x70;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //ASI_CFG0 i2s, 32 bits, default fsync_pol, default bclk_pol, default tx_edge, tx_fill 0s

    ADCwrite[0] = 0x13;
    ADCwrite[1] = 0x80;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //MST_CFG0, master mode, 48k, mclk 12Mhz

    ADCwrite[0] = 0x14;
    ADCwrite[1] = 0x44;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //MST_CFG1, 48k, 64 fs_bclk_ratio

    ADCwrite[0] = 0x16;
    ADCwrite[1] = 0x88;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //CLK_CFG, MCLK audio root sourse, MCLK freq specified, MCLK to FS ratio 256

    ADCwrite[0] = 0x21;
    ADCwrite[1] = 0xa0;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //GPIO_CFG0, GPIO as MCLK input

    ADCwrite[0] = 0x73;
    ADCwrite[1] = 0xc0;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //input channels 1, 2

    ADCwrite[0] = 0x74;
    ADCwrite[1] = 0xc0;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //output channels 1, 2
    printf("written: %d\n", written_count);

    ADCwrite[0] = 0x36; //interrupt register
    ADCread[0] = 0xff;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 1);
    read_count = io_read(I2C_0_io, (uint8_t *)ADCread, 1);
    printf("read: %d\n", read_count);
    printf("interrupt: %x\n", ADCread[0]);

    ADCwrite[0] = 0x36; //interrupt register
    ADCread[0] = 0xff;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 1);
    read_count = io_read(I2C_0_io, (uint8_t *)ADCread, 1);
    printf("read: %d\n", read_count);
    printf("interrupt: %x\n", ADCread[0]);
    ADCwrite[0] = 0x15; //ASI_STS
    ADCread[0] = 0x00;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 1);
    read_count = io_read(I2C_0_io, (uint8_t *)ADCread, 1);
    printf("\nread: %d\n", read_count);
    printf("ASI_STS: %x\n", ADCread[0]);

    ADCwrite[0] = 0x75;
    ADCwrite[1] = 0xe0;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //power up adc, micbias, pll


 

  • Miles,

    Given the changing value in ASI_STS and interrupts generated. there might be an issue with polarity or frame sync edges. Seems the device is not receiving enough clocks to shift out the data. Refer to Section 8.3.1.2.2. for the timing diagrams and the impact of TX_OFFSET and BCLK_POL. Since you are setting the ADC for 32-bit data, you will need at least 64 BCLKs per frame sync. Have you looked at increasing the BCLK to FSYNC ratio? 

    I am attaching an app note that has not yet reached the web that describe how to configure the device for master mode.

    best regards,

      Pedro

  • Miles,

    After some testing, I do not see in your code that ASI_CH2 register is being set. By default, the CH2 is routed to I2S left slot 1 since it defaults to TDM mode. This needs to change to right slot-0 by setting register 0x0C to 0x20:

    ADCwrite[0] = 0x0C;
    ADCwrite[1] = 0x20;
    written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //ASI_CH2 routed to right slot 0
    In this way, CH1 is assigned to left slot-0 and CH2 is assigned to right slot-0. Otherwise, it is expecting more clocks to send four data slots per I2S frame. 

    best regards,

      Pedro

  • Thanks so much for this document! I've been struggling just to get a good bclk and fs out of this prototype for over a week. This document gave me the most simple thing to try. So I ignored all the I2S stuff for now. Turns out I have something very wrong with the prototype I was given. I can only get a solid 12.2877Mhz BCLK and 47.9987khz FS based on an external 12Mhz clock. Of course,  it only stabilizes when I have both my logic analyzer and analog probe connected... I'm still investigating, but there's a good chance one or more of the capacitors are too small (I already found resistors elsewhere that were smaller than specified), or there's a bad solder joint.

    For anyone curious, this was the basic code that (eventually) gave me a good BCLK and FS based on an external 12Mhz clock.

        ADCwrite[0] = 0x02;
        ADCwrite[1] = 0x81;
        written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //wake up
        delay_ms(20);
    
        ADCwrite[0] = 0x13;
        ADCwrite[1] = 0x80;
        written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //MST_CFG0, master mode, 48k, mclk 12Mhz
    
        ADCwrite[0] = 0x14;
        ADCwrite[1] = 0x48;
        written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //MST_CFG1, 48k, 256 fs_bclk_ratio
    
        ADCwrite[0] = 0x21;
        ADCwrite[1] = 0xa0;
        written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //GPIO_CFG0, GPIO as MCLK input
    
        ADCwrite[0] = 0x73;
        ADCwrite[1] = 0xc0;
        written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //input channels 1,2
    
        ADCwrite[0] = 0x74;
        ADCwrite[1] = 0xc0;
        written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //output channels 1,2
    
        ADCwrite[0] = 0x75;
        ADCwrite[1] = 0xe0;
        written_count = io_write(I2C_0_io, (uint8_t *)ADCwrite, 2); //power up adc, micbias, pll
    

  • I changed the previous link to the App Note that it is now on the external site.

    Configuring and Operating TLV320ADCx140 as Audio Bus Master