CS47L63 Config for Line IN to Headphone OUT

So I was experimenting with the Hardware Codec and I created a simple config which redirects the audio coming from the LINE IN mic to HEADPHONE OUT speakers.

Here's the configuration:

const uint32_t line_in_to_headphone[][2] = {
	/* 
	GPIO 9 -> SPI CS
	GPIO 10 -> SPI CLK
	GPIO 11 -> SPI MISO
	GPIO 12 -> SPI MOSI
	*/
	{ CS47L63_GPIO9_CTRL1, 0xE1000000 },
	{ CS47L63_GPIO10_CTRL1, 0xE1000000 },
	{ CS47L63_GPIO11_CTRL1, 0xE1000000 },
	{ CS47L63_GPIO12_CTRL1, 0xE1000000 },

	/* CLK Config */
	{ CS47L63_OUTPUT_SYS_CLK, 0x8000 },
	{ CS47L63_OUTPUT_DSP_CLK, 0x0010 },

	/* SYS CLK Enable */
	{ CS47L63_SYSTEM_CLOCK1, 0x0444 },

	/* Sample Rate -> 192KHz */
	{ CS47L63_SAMPLE_RATE1, 0x0005 },

	/* Disable unused sample rates */
	{ CS47L63_SAMPLE_RATE2, 0 },
	{ CS47L63_SAMPLE_RATE3, 0 },
	{ CS47L63_SAMPLE_RATE4, 0 },

	/* FLL Config */
	{ CS47L63_FLL1_CONTROL1, 0x0001 },
	{ CS47L63_FLL1_CONTROL2, 0x28600177 },
	{ CS47L63_FLL1_CONTROL3, 0x10000 },
	{ CS47L63_FLL1_CONTROL4, 0x23F05004 },

	/* Line In Setup */
	{ CS47L63_INPUT_CONTROL, 0x000C },
	{ CS47L63_INPUT_CONTROL3, 0x20000000 },
	{ CS47L63_IN2L_CONTROL1, 0x10000004 },
	{ CS47L63_IN2L_CONTROL2, 0xBC0080 },
	{ CS47L63_IN2R_CONTROL1, 0x10000004 },
	{ CS47L63_IN2R_CONTROL2, 0xBC0080 },

	/* High pass filter */
	{ CS47L63_INPUT_HPF_CONTROL, 0x0001 },

	/* Output enable */
	{ CS47L63_OUTPUT_ENABLE_1, 0x0002 },
	{ CS47L63_OUT1L_VOLUME_1, 0x00BC },
	{ CS47L63_OUT1L_INPUT1, 0x800012 },
	{ CS47L63_OUT1L_INPUT2, 0x800013 },

	/* Digital core sample rate */
	{ CS47L63_FX_SAMPLE_RATE, 0x0800 },
};

However, nothing works as intended. There's no audio being streamed out of speakers.

One of my engineers in the hardware domain suggested me to look into the TRACECLK config as the hardware codec runs on some internal clock source. Is it internally setup or do I need to set it up myself? Also are there any corrections in the config file?

Parents
  • Update: I have updated the config to use the internal oscillator, but that doesn't seem to be working too. Here's the new config

    const uint32_t line_in_to_headphone[][2] = {
    	/* 
    	GPIO 9 -> SPI CS
    	GPIO 10 -> SPI CLK
    	GPIO 11 -> SPI MISO
    	GPIO 12 -> SPI MOSI
    	*/
    	{ CS47L63_GPIO9_CTRL1, 0xE1000000 },
    	{ CS47L63_GPIO10_CTRL1, 0xE1000000 },
    	{ CS47L63_GPIO11_CTRL1, 0xE1000000 },
    	{ CS47L63_GPIO12_CTRL1, 0xE1000000 },
    
    	/* CLK Config */
    	{ CS47L63_OUTPUT_SYS_CLK, 0x8000 },
    	{ CS47L63_OUTPUT_DSP_CLK, 0x0010 },
    
    	/* SYS CLK Enable */
    	// { CS47L63_SYSTEM_CLOCK1, 0x0442 },
    	{ CS47L63_SYSTEM_CLOCK1, 0x0444 },
    	{ CS47L63_RCO_CTRL1, 0x00000001 },  /* EN=1 */
    
    	/* Sample Rate -> 192KHz */
    	{ CS47L63_SAMPLE_RATE1, 0x0005 },
    
    	/* Disable unused sample rates */
    	{ CS47L63_SAMPLE_RATE2, 0 },
    	{ CS47L63_SAMPLE_RATE3, 0 },
    	{ CS47L63_SAMPLE_RATE4, 0 },
    
    	/* FLL Config */
    	// { CS47L63_FLL1_CONTROL1, 0x0001 },
    	{ CS47L63_FLL1_CONTROL1, 0x0007 },
    	// { CS47L63_FLL1_CONTROL2, 0x28602177 },
    	{ CS47L63_FLL1_CONTROL2,     0x88202004 },  /* REFCLK_SRC=RCO */
    	{ CS47L63_FLL1_CONTROL3, 0x10000 },
    	{ CS47L63_FLL1_CONTROL4, 0x23F05004 },
    
    	/* Line In Setup */
    	{ CS47L63_INPUT_CONTROL, 0x000C },
    	{ CS47L63_INPUT_CONTROL3, 0x20000000 },
    	{ CS47L63_IN2L_CONTROL1, 0x10000004 },
    	{ CS47L63_IN2L_CONTROL2, 0xB00080 },
    	{ CS47L63_IN2R_CONTROL1, 0x10000004 },
    	{ CS47L63_IN2R_CONTROL2, 0xB00080 },
    
    	/* High pass filter */
    	{ CS47L63_INPUT_HPF_CONTROL, 0x0001 },
    
    	/* Output enable */
    	{ CS47L63_OUTPUT_ENABLE_1, 0x0002 },
    	{ CS47L63_OUT1L_VOLUME_1, 0x00B0 },
    	{ CS47L63_OUT1L_INPUT1, 0x800012 },
    	{ CS47L63_OUT1L_INPUT2, 0x800013 },
    
    	/* Digital core sample rate */
    	{ CS47L63_FX_SAMPLE_RATE, 0x0800 },
    };

  • You don't need to update the SDK. You don't need the nrf5340_audio app at all. You need to read the CS47L63 datasheet.

    Not only is much of your attempt misguided, your order of operations is incorrect. Configure first, enable last, especially clocks.

    Here's the minimum stand-alone config needed to route line-in to headphone out:

    static const uint32_t cs47l63_cfg[][2] =
    {
    	/* Configure clocks to use internal oscillator */
    	{ CS47L63_RCO_CTRL1,            0x00000001 },   /* EN=1 */
    	{ CS47L63_FLL1_CONTROL4,        0x21F05001 },   /* defaults */
    	{ CS47L63_FLL1_CONTROL3,        0x00010000 },   /* LAMBDA=1 */
    	{ CS47L63_FLL1_CONTROL2,        0x88202004 },   /* REFCLK_SRC=RCO */
    	{ CS47L63_FLL1_CONTROL1,        0x00000003 },   /* EN=1, HOLD=1 */
    	{ CS47L63_SYSTEM_CLOCK1,        0x00000444 },   /* EN=1 */
    
    	/* Configure IN2 as single-ended analog line-in */
    	{ CS47L63_INPUT2_CONTROL1,      0x00050020 },   /* MODE=analog */
    	{ CS47L63_IN2L_CONTROL1,        0x10000000 },   /* SRC=IN2LP */
    	{ CS47L63_IN2R_CONTROL1,        0x10000000 },   /* SRC=IN2RP */
    	{ CS47L63_INPUT_CONTROL,        0x0000000C },   /* IN2_EN=1 */
    
    	/* Set IN2 volume */
    	{ CS47L63_IN2L_CONTROL2,        0x00800080 },   /* VOL=0dB, MUTE=0 */
    	{ CS47L63_IN2R_CONTROL2,        0x00800080 },   /* VOL=0dB, MUTE=0 */
    	{ CS47L63_INPUT_CONTROL3,       0x20000000 },   /* VU=1 */
    
    	/* Configure output to play IN2 */
    	{ CS47L63_OUT1L_INPUT1,         0x00800012 },   /* SRC=IN2L */
    	{ CS47L63_OUT1L_INPUT2,         0x00800013 },   /* SRC=IN2R */
    	{ CS47L63_OUT1L_VOLUME_1,       0x00000280 },   /* MUTE=0, VU=1 */
    	{ CS47L63_OUTPUT_ENABLE_1,      0x00000002 },   /* EN=1 */
    };
    

  • That didn't work either for some reason. I tried increasing the volume too but that just increases the white noise thats coming out of the speaker.

  • Yes, I was hesitant to touch this thread because actually solving the problem requires introducing yet another deficiency in Nordic's CS47L63 implementation.

    There is a deeply buried file in Nordic's downstream Cirrus Logic HAL named /modules/hal/cirrus-logic/cs47l63/generated/cs47l63_syscfg_regs.c

    This file is supposed to store the default system configuration written at power-on after applying necessary firmware patches, but unfortunately the settings contained therein are so horribly wrong that they even ruin later attempts to properly configure the clocks (namely FLL1).

    Replacing this file with the correct base configuration is the appropriate strategy, but be aware that if you edit this file (and you should), you'll be making in-tree changes that will be lost during an SDK upgrade, unless you create a workspace application which you can freely modify however you desire.

    Having said that, if you change just one byte in this file you'll have much more success when trying to create your own configurations. The data is in address/value pairs, and the 5th pair is your target.

    On line 33, change "0x1c00, 0x0006" to "0x1c00, 0x0000"

    Then try a pristine build and see if it works.

  • Ok great, that worked! I'm pretty sure it would have been a nightmare for me to come up with that solution myself. Its a humble request to the Nordic's development team to please fix this issue in the upcoming SDK updates.

     With that being said,  Thanks a lot !!

Reply Children
Related