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.

Microphone access/debugging on tlv320 for am335x (beaglebone black)

Other Parts Discussed in Thread: TLV320AIC3104

I have design in which I've integrated a tlv320aic3104 into a beaglebone black cape for developing a pilot of our product. I have the DSP connected and can read and write the device over i2c but can't record audio. I've got a valid looking wave on the mic line (even if I didn't I should get noise) however when I instantiate my cape and try to do an arecord for that device with proper settings and a 10 second duration I always get an input/output error and my recording file is completely empty (44B audio stub file).

My DTS is as follows (I have other devices on this board but nothing crosses with the i2s for the tlv320):

/**
 * Copyright © 2015 AmbientBox, LLC. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/dts-v1/;
/plugin/;

/ {
	compatible = "ti,beaglebone-black";

	/* identification */
	part-number = "AMBIENTBOX";
	version = "00A0", "03";

	/* state the resources this cape uses */
  /* TODO: Add pins for xBee and wifi */
	exclusive-use =
		/* the pin header uses */
		"P9.31",	/* mcasp0: mcasp0_aclkx */
		"P9.29",	/* mcasp0: mcasp0_fsx */
		"P9.28",	/* mcasp0: mcasp0_axr2 */
		"P9.25",	/* mcasp0: mcasp0_ahclkx */
    "P9.11",  /* xbee UART_RXD */
    "P9.13",  /* xbee UART_TXD */
    "P8.33",  /* xbee UART_RTSN */
    "P8.35",  /* xbee UART_CTSN */
		/* the hardware ip uses */
		"gpio1_18", "gpio1_19",
    /* "gpio1_12",  green LED */
    /* "gpio0_26",  red LED */
    "gpio1_29", /* RGBC interval value */
    "gpio2_24", /* Temp/Humidity CS Value */
    "gpio2_25", /* VOC Prediction Value */
		"mcasp0",   /* DSP */
    "uart4"     /* Xbee */;

	fragment@0 {
		target = <&am33xx_pinmux>;
		__overlay__ {

			i2c2_pins: pinmux_i2c2_pins {
				pinctrl-single,pins = <
					0x150 0x72 	/*spi0_scl.i2c2_sda,SLEWCTRL_SLOW | INPUT_PULLUP |MODE2*/
					0x154 0x72	/*spi0_d0.i2c2_scl,SLEWCTRL_SLOW | INPUT_PULLUP | MODE2*/
				>;
			};

			ambientbox_pins: pinmux_ambientbox_pins {
				pinctrl-single,pins = <
					0x1ac 0x00      /* P9.25 mcasp0_ahclkx,             MODE0 | INPUT */
					0x19c 0x22      /* P9.28 mcasp0_ahclkr, */
					0x194 0x20      /* P9.29 mcasp0_fsx,         	      MODE0 | OUTPUT  */
					0x190 0x20      /* P9.31 mcasp0_aclkr.mcasp0_aclkx, MODE0 | OUTPUT_PULLDOWN */
					0x198 0x20
          0x070 0x20      /* P9_11 UART4_RXD */
          0x074 0x20      /* P9_13 UART4_TXD */
          0x0d4 0x20      /* P8_33 UART4_RTSN */
          0x0d0 0x20      /* P8_35 UART4_CTSN */
          0x030 0x07      /* P8_12 Green LED OUTPUT MODE7 */
          0x028 0x07      /* P8_14 Red LED OUTPUT MODE7 */
				>;
			};
		};
	};

	fragment@1 {
		target = <&i2c2>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			clock-frequency = <100000>;
			status = "okay";
			pinctrl-names = "default";
			pinctrl-0 = <&i2c2_pins>;


			tlv320aic3x: tlv320aic3x@18 {
				compatible = "ti,tlv320aic3x";
				reg = <0x18>;
				status = "okay";
			};
		};
	};

	fragment@2 {
		target = <&mcasp0>;
		__overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&ambientbox_pins>;

			status = "okay";

			op-mode = <0>;          /* MCASP_IIS_MODE */
			tdm-slots = <2>;
			num-serializer = <16>;
			serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
				2 0 1 0
				0 0 0 0
				0 0 0 0
				0 0 0 0
			>;
			tx-num-evt = <1>;
			rx-num-evt = <1>;
		};
	};

	fragment@3 {
		target = <&ocp>;
		__overlay__ {
			sound {
				compatible = "ti,da830-evm-audio";
				ti,model = "DA830 EVM";
				ti,audio-codec = <&tlv320aic3x>;
				ti,mcasp-controller = <&mcasp0>;
				ti,codec-clock-rate = <12000000>;
				ti,audio-routing =
					"Headphone Jack",       "HPLOUT",
					"Headphone Jack",       "HPROUT",
					"LINE1L",               "Line In",
					"LINE1R",               "Line In";
			};
		};

	};
};

I have hooked this up very similarly to the audio cape for the beaglebone black also HDMI is disabled so that it won't interfere.

You'll also notice I do not have, nor have any plans to have, audio out hooked up. Audio output is unnecessary for my needs. I've gone the route of this DSP given there was another design with it already so I hoped to shortcut development time. My ideal solution would be a DSP that could take two audio channels and create an FFT from that to send back to the MCU but so far that is wishful thinking. 

So my main question comes down to how do I get the tlv320 audio output working and/or how do I debug from here as everything appears to be working from an i2c perspective. 

Note I've tried programming the DSP based on the application note at http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=slaa403&fileType=pdf prior to enabling the cape with the same result (it does seem to take the programming based on i2c reads however).

I did walk through  https://e2e.ti.com/support/arm/sitara_arm/f/791/p/345940/1229640 but it did not lead me to an answer.

Thank you for your help,

Paul

  • Hi Paul,

    Please post what Linux version you are using. I will forward this to the SW team.

  • Hi Biser, 

    Thanks for looking into this and getting it to the right team.

    I'm running Ubuntu 14.04 LTS (kernel 3.8.13-bone59). 

    I'm getting the following in the syslog/dmesg when I instantiate the device:

    [  140.049467] bone-capemgr bone_capemgr.9: slot #9: Applied #4 overlays.
    [  143.200111] tlv320aic3x-codec 1-0018: ASoC: Not enforcing symmetric_rates due to race
    [  143.355331] bone-capemgr bone_capemgr.9: part_number 'bspm_P8_7_f', version 'N/A'
    [  143.355433] bone-capemgr bone_capemgr.9: slot #10: generic override
    [  143.355457] bone-capemgr bone_capemgr.9: bone: Using override eeprom data at slot 10
    [  143.355483] bone-capemgr bone_capemgr.9: slot #10: 'Override Board Name,00A0,Override Manuf,bspm_P8_7_f'
    [  143.355622] bone-capemgr bone_capemgr.9: slot #10: Requesting part number/version based 'bspm_P8_7_f-00A0.dtbo
    [  143.355647] bone-capemgr bone_capemgr.9: slot #10: Requesting firmware 'bspm_P8_7_f-00A0.dtbo' for board-name 'Override Board Name', version '00A0'
    [  143.359707] bone-capemgr bone_capemgr.9: slot #10: dtbo 'bspm_P8_7_f-00A0.dtbo' loaded; converting to live tree
    [  143.360723] bone-capemgr bone_capemgr.9: slot #10: #2 overlays
    [  143.369796] bone-capemgr bone_capemgr.9: slot #10: Applied #2 overlays.
    [  194.318309] init: ambientbox main process (1236) terminated with status 143
    [  198.909523] init: ambientbox post-stop process (1761) terminated with status 1

    and the following when I run arecord -D hw:0 -d 10 -c 2 -r 44100 -f S16_LE test.wav (this is the tlv320 according to proc and arecord -l):

    [  214.641262] ALSA sound/core/pcm_lib.c:1910 capture write error (DMA or IRQ trouble?)

    The thing that has me more concerned that I've programmed the DSP incorrectly is that I'm getting nothing when I hook up a logic analyzer to the pins for the i2s signal.

    I'm also getting a little bit of an odd behavior on i2c. I've run the following to setup and make then echo the register based on the guide I mentioned previously. 

    var i2c = require('i2c-bus');
    var async = require('async');
    
    var DSP_ADDR = 0x18;
    
    var bus = i2c.openSync(1);
    
    function writeAndRespond(port, address, value, done) {
      bus.writeByte(port, address, value, function(error){
        if(error){
          return done(error);
        }
        bus.readByte(port, address, function(error, result){
          if(error){
            return done(error);
          }
          console.dir("0x" + (address).toString(16) + " is 0x" + result.toString(16));
          done();
        });
      });
    
    }
    
    async.series([
      function(cb){
        writeAndRespond(DSP_ADDR, 0x01, 0x08, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x13, 0x04, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x16, 0x04, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x04, 0x00, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x10, 0x08, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x07, 0x0a, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x25, 0xc0, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x2b, 0x00, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x2c, 0x00, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x52, 0x80, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x5c, 0x80, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x56, 0x09, cb);
      },
      function(cb){
        writeAndRespond(DSP_ADDR, 0x5d, 0x09, cb);
      }
    ], function(error){
      if(error){
        console.log('Got error ' + error.message);
      }
    });

    The result of running this gives the following, you'll notice some of the registers don't read the same value that was just set. Is this expected?

    root@arm:/home/ubuntu/bonebox# node test/dsp.js
    '0x1 is 0x0'
    '0x13 is 0x4'
    '0x16 is 0x4'
    '0x4 is 0x0'
    '0x10 is 0x8'
    '0x7 is 0xa'
    '0x25 is 0xc0'
    '0x2b is 0x0'
    '0x2c is 0x0'
    '0x52 is 0x80'
    '0x5c is 0x80'
    '0x56 is 0xb'
    '0x5d is 0xb'

    Thanks Again,

    Paul

     

  • Just wanted to update whomever might be interested in helping me, I think I've found root cause behind this problem. I'm not getting a clock signal on the mclk pin (see dts above). I'm digging into why now but if anything jumps out at you please let me know.

  • i'm stuck with the same identical problem. (I use stock Debian deployed with Beaglebone Black instead of Ubuntu but... whatever...)

    Plus... i can't read/write registers through I2C because "Device or resource busy" (i ran your dsp.js)

    I compiled the following DTS:

    did you find the solution?

    thank you

    Dave

  • I have not yet.

    Also you won't be able to run the i2c commands once you've loaded the device tree overlay as it takes that address out of general use. You can only run it before setting that cape up.
  • As an update I've now put an ASE 12Mhz oscillator on the board (with a jumper to disable if I get the am335x clock working). This is sending a clock signal to the DSP (verified via oscilloscope) however I'm still not getting audio out with this clock in. I am seeing what appears to be an audio wave from the MICS on pins 14 and 16 of the tlv320.

    Again any help with this problem would be appreciated.  any luck getting a software person from am335x to chime in?