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:器件初始化后、PDM 信号上无活动

Guru**** 2382630 points
Other Parts Discussed in Thread: TLV320ADC5140
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1250260/tlv320adc5140-no-activity-on-the-pdm-signals-after-device-initialisation

器件型号:TLV320ADC5140

我有一个带 TLV320ADC5140的定制 PCB、连接到 ESP-WROOM-32UE 模块。

按照数据表中的 I2C 初始化示例(8通道 PDM 麦克风示例)、器件似乎正常运行。 此后、我自定义了初始化代码、仅设置前4个通道、而不是8个通道、并且我已将 ASI_FORMAT 更改为以 I2S 格式输出。

但是、当我查询 DEV_STS0寄存器(0x76)时、接收到的字节表示所有通道都已断电。 我也看不到 PDMCLK 信号有任何活动、也看不到来自麦克风的任何数据。 我感到困惑的是、因为我将0xF0写入启用通道1-4的 IN_CH_EN 寄存器。

是否有我遗漏的数据表示例中未指明的任何内容?

3.3V 电源轨稳定后、该器件将退出关断模式、然后在启动前出现10ms 的短暂延迟。 只是为了说明清楚。

谢谢!

TLV320ADC5140的原理图:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Kevin:

    在数据表中:

    为目标应用和系统设置配置所有其他寄存器后、分别配置输入和输出通道启用寄存器 P0_R115 (IN_CH_EN)和 P0_R116 (ASI_OUT_CH_EN)。 最后、配置器件上电寄存器 P0_R117 (PWR_CFG)。 必须在相应通道上电之前写入所有可编程系数值。 在活动模式下、通过读取位于 P0_R117 (DEV_STS0)和 P0_R118 (DEV_STS1)寄存器中的只读器件状态位、监视各种模块的上电和断电状态。

    您是否能够确认您的输出寄存器已配置并且您正在写入加电寄存器(P0_R117)来开启器件?

    谢谢!
    J·麦克弗森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jeff:

    感谢您的答复。

    我可以确认、ASI_OUT_CH_EN 设置为启用前4个通道、并且还写入 PWR_CFG 寄存器且 ADC_PDZ 和 PLL_PDZ 位均设置为1、以启用 ADC 和 PLL。

    此致、
    凯文

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Kevin:

    感谢您的确认。 您能与我分享您编辑过的脚本吗? 我想确认一下、它适用于 EVM。

    谢谢!
    J·麦克弗森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jeff:

    好的。 下面是我正在使用的初始化顺序(可悲的是,它正在使用 Arduino 平台在此刻):

    /* 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);

    然后、我使用以下代码对所有寄存器执行回读、包括 I2C_CKSUM:

    /* 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();
      }
    }

    和下面显示了寄存器值:

    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)

    除了所有通道都显示为已断电这一事实外、初始化似乎没有什么不妥。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Kevin:

    从寄存器0x15、器件似乎在报告存在时钟错误。 我将您的代码转换为 I2C 脚本(请参阅下文、因为这些脚本缺失、我还添加了 CH3和4)、并在 EVM 上运行它、没有任何问题。 您能否确认发送到器件的所有时钟都是干净的、频率正确?

    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

    此致、
    J·麦克弗森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jeff:

    这很可能是我缺乏理解的原因。

    当您提到"所有时钟"时、您是指来自主站的时钟、即我的 ESP32 I2S 总线吗?

    我假定 PDM 接口将正常运行、与 ASI/I2S 总线无关。

    凯文

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    还不错,有些进步……

    我已使用一些默认值配置了 I2S 总线、寄存器0x15现在报告的值为4、这表示检测到的采样率为44.1或48kHz、BCLK 与 FSYNC 之比为16。 寄存器0x76现在报告0xF0、因此4个通道现在被启用。

    但是、我仍然看不到两组麦克风的 PDM 信号有任何活动、并且从 I2S 驱动程序报告的数据全部为零。 PDMCLK 线路的 SAT 处于大约0.7V、PDMDAT 线路的 SAT 处于大约0.1V。 电路板上没有短路、只有零活动。

    以下是 I2S 初始化后的完整寄存器转储:

    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)
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Kevin:

    为了澄清一点、您将无法从 GPO1或2获得 PDM 时钟输出。 MCLK、BCLK 和 FSYNC 的确切频率是多少?

    谢谢。
    J·麦克弗森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jeff:

    我在 GPO1或 GPO2上都没有看到 PDM 时钟-两个引脚都表现出完全相同的行为。

    您对确切频率的问题是一个好问题。 实际上我不确定、因为我不相信我用于配置 I2S 外设的代码允许我指定这些频率-背后似乎在某种程度上进行了处理。 在此、抱歉、我是第一次开发 I2S 器件、因为我对此一无所知。

    我怀疑它是否有帮助、但我正在使用的 I2S 初始化代码如下所示:

    /* 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);

    我直到下周才能接触到示波器、因此我可以使用它验证目前的确切频率是多少。

    再次感谢您对此提供的所有帮助。 非常感谢。

    此致
    凯文

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Kevin:

    不用担心。 获得 MCLK、BCLK 和 FSYNC 的频率测量值后、请告诉我。

    此致、
    J·麦克弗森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jeff:

    FSYNC 的频率为8kHz、 BCLK 的频率为500kHz。 对于每个通道、PDMCLK 上仍然没有任何内容。

    此致、
    凯文  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    更新了。

    我已经将采样率更改为44100、现在我得到的 FSYNC 为44.1kHz、BCLK 约为2.8MHz -根据数据表中的表7"支持的 FSYNC 和 BLCK 频率"、这似乎是正确的。 PDMCLK 线路上仍然什么也没有。

    我还将 GPIO1配置寄存器(0x21)设置为输出 PDMCLK (0x40)、但是我在 GPIO1引脚本身上也看不到任何内容。 某个项目显然配置不正确、但是在浏览数据表后、我很难理解其中的内容。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    成功!!!

    实际上、我  在 PWR_CFG 寄存器中设置的 PLL_PDZ_MASK 的定义存在错误。 PLL 从未被启用。 现在可以看到 PDMCLK、并且我正在从麦克风接收数据。 我检查了寄存器0x75的回读、仅设置了 ADC_PDZ 位。

    感谢 Jeff 的所有帮助。

    此致、
    凯文