cancel
Showing results for 
Search instead for 
Did you mean: 

How to configure the SAI as slave on the I2S bus

bimorqt
Associate III

Hello everyone,

I am trying to replicate this approach to integrate STM32MP1 with an external audio codec.

0693W00000Sw5BHQAZ.pngThe issue I am facing is that the sub-block SAI-A is generating the bitclock (SCK), while I need it to receive it from the external audio codec. I am sniffing the I2S bus and whenever the audio is played, I can see the SCK being generated by SAI-A.

Could you please provide details on how to set the SAI in slave mode, so that the SCK is not generated?

Thanks in advance!

2 REPLIES 2
PatrickF
ST Employee

Hi @bimorqt​ 

I'm not expert, but according to wiki, it seems 'bitclock-master;' is required in the codec device Tree.

https://wiki.st.com/stm32mpu/wiki/SAI_device_tree_configuration#Sharing_the_codec_interface_between_two_SAIs

Could you share your Device Tree ?

Some posts which might help in this area:

https://community.st.com/s/question/0D53W00000HKwSZSA1

https://community.st.com/s/question/0D53W00001SeXRGSA3

Regards,

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
bimorqt
Associate III

Hello @PatrickF​ 

thank you for the quick response. I tried to replicate the devicetree provided here. Here are the most salient parts related to audio of my devicetree:

sound {
	compatible = "audio-graph-card";
	label = "AUDIO;
	routing =
			"HP_OUT", "Digital Input Mux",
			"LINE_OUT", "Digital Input Mux",
			"AIFOUT", "Capture Mux";
	dais = <&sai2a_port &sai2b_port>;
	status = "okay";
};
 
&i2c1{
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c1_pins_mx>;
	pinctrl-1 = <&i2c1_sleep_pins_mx>;
	status = "okay";
 
	/* USER CODE BEGIN i2c1 */
	#address-cells = <1>;
	#size-cells = <0>;
	i2c-scl-rising-time-ns = <100>;
	i2c-scl-falling-time-ns = <7>;
	/delete-property/dmas;
	/delete-property/dma-names;
 
	sgtl5000: codec@0a {                                                   
		compatible = "fsl,sgtl5000";                                   
		reg = <0x0a>;
		#sound-dai-cells = <0>;                                      
		clocks = <&sai2a>;  /* The codec is a consumer of SAI2A master clock */
		clock-names = "MCLK";
		VDDA-supply = <&v3v3>;                                  
		VDDIO-supply = <&v1v8>;      
 
		sgtl5000_port: port {
			#address-cells = <1>;
			#size-cells = <0>;
			sgtl5000_tx_endpoint: endpoint@0 {
				reg = <0>;
				remote-endpoint = <&sai2a_endpoint>;
				frame-master; // if I comment these two lines, the audio playback works
				bitclock-master;
			};
 
			sgtl5000_rx_endpoint: endpoint@1 {
				reg = <1>;
				remote-endpoint = <&sai2b_endpoint>;
				frame-master;  // if I comment these two lines, the audio playback works
				bitclock-master;
			};
		};
	};
 
	/* USER CODE END i2c1 */
};
 
&sai2{
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&sai2a_pins_mx>, <&sai2b_pins_mx>;
	pinctrl-1 = <&sai2a_sleep_pins_mx>, <&sai2b_sleep_pins_mx>;
	status = "okay";
 
	/* USER CODE BEGIN sai2 */
	clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
	clock-names = "pclk", "x8k", "x11k";
	/* USER CODE END sai2 */
 
	sai2a:audio-controller@4400b004{	// Playback DAI
		status = "okay";
 
		/* USER CODE BEGIN sai2a */
		compatible = "st,stm32-sai-sub-a";
		#clock-cells = <0>;
		dma-names = "tx";
		clocks = <&rcc SAI2_K>;
		clock-names = "sai_ck";
 
		sai2a_port: port {	
			sai2a_endpoint: endpoint {
				format = "i2s";
				remote-endpoint = <&sgtl5000_tx_endpoint>;
				mclk-fs = <256>;
			};
		};
		/* USER CODE END sai2a */
	};
 
	sai2b:audio-controller@4400b024{	// Capture DAI
		status = "okay";
 
		/* USER CODE BEGIN sai2b */
		compatible = "st,stm32-sai-sub-b";
		dma-names = "rx";
		st,sync = <&sai2a 2>;
		clocks = <&rcc SAI2_K>, <&sai2a>;
		clock-names = "sai_ck", "MCLK";
 
		sai2b_port: port {
			sai2b_endpoint: endpoint {
				remote-endpoint = <&sgtl5000_rx_endpoint>;
				format = "i2s";
				mclk-fs = <256>;
			};
		};
		/* USER CODE END sai2b */
	};
};

If I leave lines 40-41 uncommented, both the SAI-A and the codec generate SCK and audio playback does not work. If I leave lines 40-41 commented and lines 48-49 uncommented, the audio playback is heavily disturbed by a high-frequency noise (the source media file is basically unhearable). A working solution for audio playback is to comment lines 40-41 and 48-49, but in these conditions the audio capture does not work, because SCK is not present on the I2S bus.