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.

TLV320ADC5140: No activity on the PDM signals after device initialisation

Part Number: TLV320ADC5140

I have a custom PCB with a TLV320ADC5140, hooked up to an ESP-WROOM-32UE module.

Having followed the I2C initialisation example from the datasheet (the 8-channel PDM microphone one), the device seems to be up and running. I've since customised the initialisation code to only set up the first 4 channels rather than 8 and I've changed the ASI_FORMAT to output in I2S format.

However, when I query the DEV_STS0 register (0x76), the received byte indicates that all of the channels are powered down. I also see no activity on the PDMCLK signals and nor do I see any data coming from the microphones. I'm confused because the channels are definitely enabled because I write 0xF0 to the IN_CH_EN register which enables channels 1-4.

Is there anything which would not be indicated in the datasheet example which I'm missing?

The device is taken out of shutdown once the 3.3V rail has stabilised and then a short delay of 10ms occurs before initialistion. Just for clarity.

Thanks!

Schematic for the TLV320ADC5140:

  • Hi Kevin,

    From the datasheet:

    After configuring all other registers for the target application and system settings, configure the input and output channel enable registers, P0_R115 (IN_CH_EN) and P0_R116 (ASI_OUT_CH_EN), respectively. Lastly, configure the device power-up register, P0_R117 (PWR_CFG). All the programmable coefficient values must be written before powering up the respective channel. In active mode, the power-up and power-down status of various blocks is monitored by reading the read-only device status bits located in the P0_R117 (DEV_STS0) and P0_R118 (DEV_STS1) registers.

    Can you confirm that your output register is configured as well as that you are writing to the power up register (P0_R117) to turn on the device?

    Thank you,
    Jeff McPherson

  • Hi Jeff,

    Thanks for your response.

    I can confirm that the ASI_OUT_CH_EN is set to enable the first 4 channels and that also the PWR_CFG register is written with both the ADC_PDZ and PLL_PDZ bits set to 1 to enable both the ADC and PLL.

    Kind regards,
    Kevin

  • Hi Kevin,

    Thanks for the confirmation. Can you share with me your edited script? I'd like to confirm that it works on an EVM.

    Thank you,
    Jeff McPherson

  • Hi Jeff,

    Sure thing. Below is the initialistion sequence I'm using (sadly, its using the Arduino platform at the moment):

    /* STEP 2.a - release SHDNZ */
    digitalWrite(AUD_SHDN, HIGH);
    
    /* STEP 2.b - wait for at least 1ms for intialisation */
    delay(10);
    
    /* STEP 3.a - wake up device */
    Wire.beginTransmission(0x4C);
    Wire.write(SLEEP_CFG);
    /* AREG_SELECT = 1, SLEEP_ENZ = 1 */
    Wire.write(AREG_SELECT_MASK | SLEEP_ENZ_MASK);
    Wire.endTransmission();
    
    /* STEP 3.b - wait for wakeup */
    delay(50);
    
    /* STEP 3.d - configure channels for PDM */
    Wire.beginTransmission(0x4C);
    Wire.write(CH1_CFG0);
    /* CH1_INSRC = 10 */
    Wire.write(CH_INSRC(2));
    Wire.endTransmission();
    
    delay(10);
    
    /* STEP 3.d continued - configure channels */
    Wire.beginTransmission(0x4C);
    Wire.write(CH2_CFG0);
    /* CH2_INSRC = 10 */
    Wire.write(CH_INSRC(2));
    Wire.endTransmission();
    
    delay(10);
    
    /* STEP 3.e - configure PDMCLK output */
    Wire.beginTransmission(0x4C);
    Wire.write(GPO_CFG0);
    /* GPO1_CFG = 0100, GPO1_DRV = 001 */
    Wire.write(GPO_CFG(4) | GPO_DRV(1));
    Wire.endTransmission();
    
    delay(10);
    
    /* STEP 3.e continued - configure PDMCLK output */
    Wire.beginTransmission(0x4C);
    Wire.write(GPO_CFG1);
    /* GPO2_CFG = 0100, GPO2_DRV = 001 */
    Wire.write(GPO_CFG(4) | GPO_DRV(1));
    Wire.endTransmission();
    
    delay(10);
    
    /* STEP 3.f - configure PDMIN inputs */
    Wire.beginTransmission(0x4C);
    Wire.write(GPI_CFG0);
    /* GPI1_CFG = 0100, GPI2_CFG = 101 */
    Wire.write(GPI_CFG_1(4) | GPI_CFG_2(5));
    Wire.endTransmission();
    
    delay(10);
    
    /* STEP 3.g - enable 4 input channels */
    Wire.beginTransmission(0x4C);
    Wire.write(IN_CH_EN);
    /* IN_CH1_EN = 1, IN_CH2_EN = 1, IN_CH3_EN = 1, IN_CH4_EN = 1 */
    Wire.write(IN_CH1_EN_MASK | IN_CH2_EN_MASK | IN_CH3_EN_MASK | IN_CH4_EN_MASK);
    Wire.endTransmission();
    
    delay(100);
    
    /* STEP 3.h - enable ASI output channels */
    Wire.beginTransmission(0x4C);
    Wire.write(ASI_OUT_CH_EN);
    Wire.write(ASI_OUT_CH1_EN_MASK | ASI_OUT_CH2_EN_MASK | ASI_OUT_CH3_EN_MASK | ASI_OUT_CH4_EN_MASK);
    Wire.endTransmission();
    
    delay(10);
    
    /* set the ASI_FORMAT to I2S */
    Wire.beginTransmission(0x4C);
    Wire.write(ASI_CFG0);
    /* ASI_FORMAT = 1, ASI_WLEN = 3 */
    Wire.write(0x70);
    Wire.endTransmission();
    
    delay(10);
    
    /* STEP 3.i - power up ADC and PLL */
    Wire.beginTransmission(0x4C);
    Wire.write(PWR_CFG);
    /* ADC_PDZ = 1, PLL_PDZ = 1 */
    Wire.write(ADC_PDZ_MASK | PLL_PDZ_MASK);
    Wire.endTransmission();
    
    delay(10);

    I then perform a read-back of all registers up to and including I2C_CKSUM using the following code:

    /* read back the registers for validation */
    Wire.beginTransmission(0x4C);
    Wire.write(0);
    Wire.endTransmission();
    
    for (int i = 0; i < 0x7F; i++) {
      /* try and ready a byte */
      Wire.requestFrom(0x4C, 1);
      uint8_t value = Wire.read();
    
      Serial.printf("0x%02X: ", i);
      Serial.print(value);
    
      if (value) {
        Serial.print(" (0b");
        Serial.print(((value & 0xF0) >> 4), BIN);
        Serial.print(" ");
        Serial.print((value & 0x0F), BIN);
        Serial.println(")");
      } else {
        Serial.println();
      }
    }

    And the following shows the register values:

    0x00: 0
    0x01: 0
    0x02: 129 (0b1000 1)
    0x03: 0
    0x04: 0
    0x05: 5 (0b0 101)
    0x06: 0
    0x07: 112 (0b111 0)
    0x08: 0
    0x09: 0
    0x0A: 0
    0x0B: 0
    0x0C: 1 (0b0 1)
    0x0D: 2 (0b0 10)
    0x0E: 3 (0b0 11)
    0x0F: 4 (0b0 100)
    0x10: 5 (0b0 101)
    0x11: 6 (0b0 110)
    0x12: 7 (0b0 111)
    0x13: 2 (0b0 10)
    0x14: 72 (0b100 1000)
    0x15: 255 (0b1111 1111)
    0x16: 16 (0b1 0)
    0x17: 16 (0b1 0)
    0x18: 4 (0b0 100)
    0x19: 32 (0b10 0)
    0x1A: 2 (0b0 10)
    0x1B: 8 (0b0 1000)
    0x1C: 0
    0x1D: 0
    0x1E: 2 (0b0 10)
    0x1F: 64 (0b100 0)
    0x20: 0
    0x21: 34 (0b10 10)
    0x22: 65 (0b100 1)
    0x23: 65 (0b100 1)
    0x24: 0
    0x25: 0
    0x26: 0
    0x27: 0
    0x28: 0
    0x29: 0
    0x2A: 0
    0x2B: 69 (0b100 101)
    0x2C: 0
    0x2D: 0
    0x2E: 0
    0x2F: 0
    0x30: 0
    0x31: 0
    0x32: 0
    0x33: 255 (0b1111 1111)
    0x34: 0
    0x35: 0
    0x36: 128 (0b1000 0)
    0x37: 0
    0x38: 128 (0b1000 0)
    0x39: 0
    0x3A: 0
    0x3B: 0
    0x3C: 64 (0b100 0)
    0x3D: 0
    0x3E: 201 (0b1100 1001)
    0x3F: 128 (0b1000 0)
    0x40: 0
    0x41: 64 (0b100 0)
    0x42: 0
    0x43: 201 (0b1100 1001)
    0x44: 128 (0b1000 0)
    0x45: 0
    0x46: 0
    0x47: 0
    0x48: 201 (0b1100 1001)
    0x49: 128 (0b1000 0)
    0x4A: 0
    0x4B: 0
    0x4C: 0
    0x4D: 201 (0b1100 1001)
    0x4E: 128 (0b1000 0)
    0x4F: 0
    0x50: 0
    0x51: 0
    0x52: 201 (0b1100 1001)
    0x53: 128 (0b1000 0)
    0x54: 0
    0x55: 0
    0x56: 0
    0x57: 201 (0b1100 1001)
    0x58: 128 (0b1000 0)
    0x59: 0
    0x5A: 0
    0x5B: 0
    0x5C: 201 (0b1100 1001)
    0x5D: 128 (0b1000 0)
    0x5E: 0
    0x5F: 0
    0x60: 0
    0x61: 201 (0b1100 1001)
    0x62: 128 (0b1000 0)
    0x63: 0
    0x64: 0
    0x65: 0
    0x66: 0
    0x67: 0
    0x68: 0
    0x69: 0
    0x6A: 0
    0x6B: 1 (0b0 1)
    0x6C: 64 (0b100 0)
    0x6D: 123 (0b111 1011)
    0x6E: 0
    0x6F: 0
    0x70: 231 (0b1110 111)
    0x71: 0
    0x72: 0
    0x73: 240 (0b1111 0)
    0x74: 240 (0b1111 0)
    0x75: 64 (0b100 0)
    0x76: 0
    0x77: 192 (0b1100 0)
    0x78: 0
    0x79: 0
    0x7A: 255 (0b1111 1111)
    0x7B: 0
    0x7C: 255 (0b1111 1111)
    0x7D: 140 (0b1000 1100)
    0x7E: 200 (0b1100 1000)

    Nothing seems untoward with the initialisation, except the fact that the channels are all showing as powered down.

  • Hi Kevin,

    From Register 0x15 it seems the device is reporting that there is a clock error. I converted your code into an I2C script (see below, I also added CH3 and 4 since those were missing) and ran it on an EVM with no issues. Can you confirm that all clocks being delivered to the device are clean and the correct frequencies?

    w 98 01 01 #software reset
    w 98 02 81 #wake up from shutdown
    d 50
    w 98 3c 40 #CH1 Config as PDM
    w 98 41 40 #CH2 Config as PDM
    w 98 46 40 #CH3 Config as PDM
    w 98 4b 40 #CH4 Config as PDM
    w 98 22 41 #GPO Config0
    w 98 23 41 #GPO Config1
    w 98 2b 45 #Set GPI1/2 for PDM1&2/3&4
    w 98 73 f0 #Enable input CH1-4
    w 98 74 f0 #Enable output CH1-4
    w 98 07 70 #Set I2S Format
    w 98 75 60 #Power Up

    Best regards,
    Jeff McPherson

  • Hi Jeff,

    This may well be where my lack of understanding comes in to play.

    When you refer to “all clocks”, do you mean clocks from the master, ie my ESP32 I2S bus?

    I had assumed that the PDM interfaces would be up and running irrespective of the ASI/I2S bus.

    Kevin

  • Ok, some progress...

    I've configured the I2S bus using some default values and register 0x15 is now reporting a value of 4, which indicates that the detected sample rate is 44.1 or 48kHz and a BCLK to FSYNC ratio of 16. Register 0x76 is now reporting 0xF0 so the 4 channels are now enabled.

    However, I'm still not seeing any activity on the PDM signals to either sets of microphone and the data reported back from the I2S driver is all zero. The PDMCLK lines are sat at about 0.7V and the PDMDAT lines are sat at about 0.1V. There are no shorts on the board, just zero activity.

    Here is a full register dump following I2S initialisation:

    0x00: 0
    0x01: 0
    0x02: 129 (0b1000 1)
    0x03: 0
    0x04: 0
    0x05: 5 (0b0 101)
    0x06: 0
    0x07: 112 (0b111 0)
    0x08: 0
    0x09: 0
    0x0A: 0
    0x0B: 0
    0x0C: 1 (0b0 1)
    0x0D: 2 (0b0 10)
    0x0E: 3 (0b0 11)
    0x0F: 4 (0b0 100)
    0x10: 5 (0b0 101)
    0x11: 6 (0b0 110)
    0x12: 7 (0b0 111)
    0x13: 2 (0b0 10)
    0x14: 72 (0b100 1000)
    0x15: 4 (0b0 100)
    0x16: 16 (0b1 0)
    0x17: 16 (0b1 0)
    0x18: 4 (0b0 100)
    0x19: 32 (0b10 0)
    0x1A: 2 (0b0 10)
    0x1B: 8 (0b0 1000)
    0x1C: 0
    0x1D: 0
    0x1E: 2 (0b0 10)
    0x1F: 64 (0b100 0)
    0x20: 0
    0x21: 34 (0b10 10)
    0x22: 65 (0b100 1)
    0x23: 65 (0b100 1)
    0x24: 0
    0x25: 0
    0x26: 0
    0x27: 0
    0x28: 0
    0x29: 0
    0x2A: 0
    0x2B: 69 (0b100 101)
    0x2C: 0
    0x2D: 0
    0x2E: 0
    0x2F: 0
    0x30: 0
    0x31: 0
    0x32: 0
    0x33: 255 (0b1111 1111)
    0x34: 0
    0x35: 0
    0x36: 128 (0b1000 0)
    0x37: 0
    0x38: 0
    0x39: 0
    0x3A: 0
    0x3B: 0
    0x3C: 64 (0b100 0)
    0x3D: 0
    0x3E: 201 (0b1100 1001)
    0x3F: 128 (0b1000 0)
    0x40: 0
    0x41: 64 (0b100 0)
    0x42: 0
    0x43: 201 (0b1100 1001)
    0x44: 128 (0b1000 0)
    0x45: 0
    0x46: 0
    0x47: 0
    0x48: 201 (0b1100 1001)
    0x49: 128 (0b1000 0)
    0x4A: 0
    0x4B: 0
    0x4C: 0
    0x4D: 201 (0b1100 1001)
    0x4E: 128 (0b1000 0)
    0x4F: 0
    0x50: 0
    0x51: 0
    0x52: 201 (0b1100 1001)
    0x53: 128 (0b1000 0)
    0x54: 0
    0x55: 0
    0x56: 0
    0x57: 201 (0b1100 1001)
    0x58: 128 (0b1000 0)
    0x59: 0
    0x5A: 0
    0x5B: 0
    0x5C: 201 (0b1100 1001)
    0x5D: 128 (0b1000 0)
    0x5E: 0
    0x5F: 0
    0x60: 0
    0x61: 201 (0b1100 1001)
    0x62: 128 (0b1000 0)
    0x63: 0
    0x64: 0
    0x65: 0
    0x66: 0
    0x67: 0
    0x68: 0
    0x69: 0
    0x6A: 0
    0x6B: 1 (0b0 1)
    0x6C: 64 (0b100 0)
    0x6D: 123 (0b111 1011)
    0x6E: 0
    0x6F: 0
    0x70: 231 (0b1110 111)
    0x71: 0
    0x72: 0
    0x73: 240 (0b1111 0)
    0x74: 240 (0b1111 0)
    0x75: 64 (0b100 0)
    0x76: 240 (0b1111 0)
    0x77: 224 (0b1110 0)
    0x78: 0
    0x79: 0
    0x7A: 255 (0b1111 1111)
    0x7B: 0
    0x7C: 255 (0b1111 1111)
    0x7D: 140 (0b1000 1100)
    0x7E: 200 (0b1100 1000)
    

  • Hi Kevin,

    To clarify, you're not getting a PDM Clock output from GPO1 or 2? What are the exact frequencies of MCLK, BCLK, and FSYNC?

    Thanks,
    Jeff McPherson

  • Hi Jeff,

    I'm getting no PDM clock on either GPO1 or GPO2 - both pins are exhibiting the exact same behaviour.

    Your question about the exact frequencies is a good one. I'm actually not sure as I don't believe the code I'm using to configure the I2S peripheral allows me to specify these frequencies - it seems to be somehow taken care of behind the scenes. Again, apologies for my ignorance in this as its my first time in bringing up an I2S device.

    I doubt it's helpful but the I2S initialisation code I'm using is as follows:

    /* do we need to change these values? */
    #define SAMPLE_BUFFER_SIZE 512
    #define SAMPLE_RATE 8000
    
    #define I2S_MIC_CHANNEL I2S_CHANNEL_FMT_RIGHT_LEFT
    
    #define I2S_MIC_SERIAL_CLOCK GPIO_NUM_21
    #define I2S_MIC_LEFT_RIGHT_CLOCK GPIO_NUM_25
    #define I2S_MIC_SERIAL_DATA GPIO_NUM_27
    
    i2s_config_t i2s_config = {
        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
        .sample_rate = SAMPLE_RATE,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
        .channel_format = I2S_MIC_CHANNEL,
        .communication_format = I2S_COMM_FORMAT_I2S,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 4,
        .dma_buf_len = 1024,
        .use_apll = false,
        .tx_desc_auto_clear = false,
        .fixed_mclk = 0
    };
    
    i2s_pin_config_t i2s_mic_pins = {
        .bck_io_num = I2S_MIC_SERIAL_CLOCK,
        .ws_io_num = I2S_MIC_LEFT_RIGHT_CLOCK,
        .data_out_num = I2S_PIN_NO_CHANGE,
        .data_in_num = I2S_MIC_SERIAL_DATA
    };
    
    // in the main function...
    
    /* set up the I2S bus */
    i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM_0, &i2s_mic_pins);

    I don't have access to an oscilloscope until next week so I can verify what the exact frequences are at present using that.

    Thanks again for all your help with this. It is greatly appreciated.

    Kind regards
    Kevin

  • Hi Kevin,

    No worries. Once you get frequency measurements for MCLK, BCLK, FSYNC, let me know.

    Best regards,
    Jeff McPherson

  • Hi Jeff,

    The frequency of FSYNC is 8kHz and for BCLK is 500kHz. Still nothing on the PDMCLK for each channel.

    Kind regards,
    Kevin 

  • Updated.

    I've changed the sample rate to 44100 and I now get an FSYNC of 44.1kHz and a BCLK of about 2.8MHz - which would appear to be correct, according to table 7 "supported FSYNC and BLCK frequencies" in the datasheet. Still nothing on the PDMCLK lines though.

    I've also set the GPIO1 config register (0x21) to output PDMCLK (0x40) however I also see nothing on the GPIO1 pin itself. Something is obviously not configured correctly however having trawled through the datasheet, I'm at a loss to understand what.

  • SUCCESS!!!

    There was actually a mistake in my definition of the PLL_PDZ_MASK which I was setting in the PWR_CFG register. The PLL was never being enabled. It is now and I can see a PDMCLK and I'm receiving data from the microphones. I checked the read-back of register 0x75 and only the ADC_PDZ bit was set.

    Thanks for all your help Jeff.

    Kind regards,
    Kevin