本文章為《STM32MP157 Linux系統移植開發篇》系列中的一篇,筆者使用的開發平台為華清遠見FS-MP1A開發闆(STM32MP157開發闆)。stm32mp157是ARM雙核,2個A7核,1個M4核,A7核上可以跑Linux作業系統,M4核上可以跑FreeRTOS、RT-Thread等實時作業系統,STM32MP157開發闆是以既可以學嵌入式linux,也可以學stm32單片機。
針對FS-MP1A開發闆,除了Linux系統移植篇外,還包括其他多系列教程,包括Cortex-A7開發篇、Cortex-M4開發篇、擴充闆驅動移植篇、Linux應用開發篇、FreeRTOS系統移植篇、Linux驅動開發篇、硬體設計篇、人工智能機器視覺篇、Qt應用程式設計篇、Qt綜合項目實戰篇等。歡迎關注,更多stm32mp157開發教程及視訊,可加技術交流Q群459754978,感謝關注。
關于FS-MP1A開發闆:
手機淘寶分享碼:複制本行文字打開手淘₤T4FPXn3YYJ2₤
連結:https://item.taobao.com/item.htm?id=622457259672
1.實驗原理
FS-MP1A使用的是CS42L51音頻晶片,SoC通過I2C和SAI與其進行資料互動,原理圖如下:

SAI2管腳對應關系:
I2C5管腳對應關系:
晶片複位管腳對應關系:
原理圖網絡編号 | 對應管腳 | 管腳功能 | 管腳功能碼 |
SAI2_MCLKA | PE0 | SAI2_MCLK_A | AF10 |
SAI2_SDB | PF11 | SDA2_SD_B | AF10 |
SAI2_SCKA | PI5 | SAI2_SCK_A | AF10 |
SAI_SDA | PI6 | SAI2_SD_A | AF10 |
SAI2_FSA | PI7 | SAI2_FS_A | AF10 |
AUDIO_RST | PC0 | IO | ANALOG |
I2C5_SDA | PA11 | I2C5_SDA | AF4 |
I2C5_SCL | PA12 | I2C5_SDA | AF4 |
- SAI2裝置樹節點
參考文檔:
Documentation/devicetree/bindings/sound/st,stm32-sai.txt
核心中ST對STM32MP15x系列晶片的裝置樹資源了做了定義,可參見:
sai2: [email protected] {
compatible = "st,stm32h7-sai";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x4400b000 0x400>;
reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
resets = <&rcc SAI2_R>;
status = "disabled";
sai2a: [email protected] {
#sound-dai-cells = <0>;
compatible = "st,stm32-sai-sub-a";
reg = <0x4 0x1c>;
clocks = <&rcc SAI2_K>;
clock-names = "sai_ck";
dmas = <&dmamux1 89 0x400 0x01>;
status = "disabled";
};
sai2b: [email protected] {
#sound-dai-cells = <0>;
compatible = "st,stm32-sai-sub-b";
reg = <0x24 0x1c>;
clocks = <&rcc SAI2_K>;
clock-names = "sai_ck";
dmas = <&dmamux1 90 0x400 0x01>;
status = "disabled";
};
};
上述代碼隻對SAI2做了基本的初始化,并沒有針對不同的硬體設計做适配,是以需結合硬體補全裝置樹節點資訊。
參考stm32mp15xx-dkx.dtsi對于SAI2裝置節點的描述,增加SAI2内容如下:
&sai2 {
clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
clock-names = "pclk", "x8k", "x11k";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
status = "okay";
sai2a: [email protected] {
#clock-cells = <0>;
dma-names = "tx";
clocks = <&rcc SAI2_K>;
clock-names = "sai_ck";
status = "okay";
sai2a_port: port {
sai2a_endpoint: endpoint {
remote-endpoint = <&cs42l51_tx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
};
};
sai2b: [email protected] {
dma-names = "rx";
st,sync = <&sai2a 2>;
clocks = <&rcc SAI2_K>, <&sai2a>;
clock-names = "sai_ck", "MCLK";
status = "okay";
sai2b_port: port {
sai2b_endpoint: endpoint {
remote-endpoint = <&cs42l51_rx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
};
};
};
由于stm32mp15-pinctrl.dtsi中對于SAI2管腳的定義與FS-MP1A實際使用管腳一緻,是以無需修改。
- CS42L51裝置樹節點
由于前文中已經增加過I2C5的節點資訊,本節就不再重複,在原有I2C5節點添加CS42L51内容即可。
參考文檔:
Documentation/devicetree/bindings/sound/cs42l51.txt
參考stm32mp15xx-dkx.dtsi對于codec晶片裝置節點的描述,增加内容如下:
cs42l51: [email protected] {
compatible = "cirrus,cs42l51";
reg = <0x4a>;
#sound-dai-cells = <0>;
VL-supply = <&v3v3>;
VD-supply = <&v1v8_audio>;
VA-supply = <&v1v8_audio>;
VAHP-supply = <&v1v8_audio>;
reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;
clocks = <&sai2a>;
clock-names = "MCLK";
status = "okay";
cs42l51_port: port {
#address-cells = <1>;
#size-cells = <0>;
cs42l51_tx_endpoint: [email protected] {
reg = <0>;
remote-endpoint = <&sai2a_endpoint>;
frame-master;
bitclock-master;
};
cs42l51_rx_endpoint: [email protected] {
reg = <1>;
remote-endpoint = <&sai2b_endpoint>;
frame-master;
bitclock-master;
};
};
};
- 1.8V電源裝置節點
前文已經說過如何添加電源節點,本節不再重複,在根節點添加&v1v8_audio節點,内容如下:
v1v8_audio: regulator-v1v8_audio {
compatible = "regulator-fixed";
regulator-name = "v1v8_audio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
- SOC聲霸卡驅動節點
核心中包含audio-graph-card驅動,驅動将聲霸卡各個部分關聯起來,驅動正常工作需添加對應裝置樹節點。
參考文檔:
Documentation/devicetree/bindings/sound/audio-graph-card.txt
在根節點寫下添加sound節點:
sound {
compatible = "audio-graph-card";
label = "STM32MP1-FSMP1A";
routing =
"Playback" , "MCLK",
"Capture" , "MCLK",
"MICL" , "Mic Bias";
dais = <&sai2a_port &sai2b_port>;
status = "okay";
};
2.實驗平台
華清遠見開發環境,FS-MP1A平台;
3.實驗目的
熟悉基于Linux作業系統下的音頻裝置驅動移植配置過程。
4.實驗步驟
- 導入交叉編譯工具鍊
[email protected]:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
- 添加SAI2節點
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi檔案,在檔案末尾添加如下内容:
&sai2 {
clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
clock-names = "pclk", "x8k", "x11k";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
status = "okay";
sai2a: [email protected] {
#clock-cells = <0>;
dma-names = "tx";
clocks = <&rcc SAI2_K>;
clock-names = "sai_ck";
status = "okay";
sai2a_port: port {
sai2a_endpoint: endpoint {
remote-endpoint = <&cs42l51_tx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
};
};
sai2b: [email protected] {
dma-names = "rx";
st,sync = <&sai2a 2>;
clocks = <&rcc SAI2_K>, <&sai2a>;
clock-names = "sai_ck", "MCLK";
status = "okay";
sai2b_port: port {
sai2b_endpoint: endpoint {
remote-endpoint = <&cs42l51_rx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
};
};
};
- 添加CS42L51節點
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi檔案,在I2C5節點中添加如下内容:
cs42l51: [email protected] {
compatible = "cirrus,cs42l51";
reg = <0x4a>;
#sound-dai-cells = <0>;
VL-supply = <&v3v3>;
VD-supply = <&v1v8_audio>;
VA-supply = <&v1v8_audio>;
VAHP-supply = <&v1v8_audio>;
reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;
clocks = <&sai2a>;
clock-names = "MCLK";
status = "okay";
cs42l51_port: port {
#address-cells = <1>;
#size-cells = <0>;
cs42l51_tx_endpoint: [email protected] {
reg = <0>;
remote-endpoint = <&sai2a_endpoint>;
frame-master;
bitclock-master;
};
cs42l51_rx_endpoint: [email protected] {
reg = <1>;
remote-endpoint = <&sai2b_endpoint>;
frame-master;
bitclock-master;
};
};
};
- 添加v1v8_audio電源節點
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi檔案,在根節點中添加如下内容:
v1v8_audio: regulator-v1v8_audio {
compatible = "regulator-fixed";
regulator-name = "v1v8_audio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
- 添加Sound節點
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi檔案,在根節點中添加如下内容:
sound {
compatible = "audio-graph-card";
label = "STM32MP1-FSMP1A";
routing =
"Playback" , "MCLK",
"Capture" , "MCLK",
"MICL" , "Mic Bias";
dais = <&sai2a_port &sai2b_port>;
status = "okay";
};
- 配置核心
由于核心源碼預設配置以及支援CS42L51,本節列出主要選項,如下:
[email protected]:$ make menuconfig
Device Drivers --->
<*> Sound card support --->
<*> Advanced Linux Sound Architecture --->
<*> ALSA for SoC audio support --->
STMicroelectronics STM32 SOC audio support --->
<*> STM32 SAI interface (Serial Audio Interface) support
CODEC drivers --->
<*> Cirrus Logic CS42L51 CODEC (I2C)
<*> ASoC Audio Graph sound card support
- 編譯核心及裝置樹
[email protected]:$ make -j4 uImage dtbs LOADADDR=0xC2000040
- 重新開機測試
将編譯好的裝置樹和核心鏡像拷貝到/tftpboot目錄下,通過tftp引導核心,啟動後啟動資訊中出現如下内容:
插上耳機,終端輸入錄音指令:
[email protected]:# arecord -D record_codec -f S16_LE -d 10 test.wav
終端輸入播放指令:
[email protected]:# aplay test.wav
注意:由于3.5mm的4段式耳機接口還分為兩種,一種是美标版(CTIA),也稱為“蘋果标準”,同時小米、魅族也是使用這種标準;另外一種是國标版(OMTP),也稱為“諾基亞标準”,現在絕大多數諾基亞和大多數國産手機都是使用這種标準。FS-MP1A使用的是國标版,是以部分耳機并不能正常實作錄播功能。
硬體平台:華清遠見FS-MP1A開發闆(STM32MP157)
部分開發教程下載下傳:加QQ群459754978,群檔案裡有。
部分視訊課程收看:華清遠見研發中心的個人空間_哔哩哔哩_Bilibili
淘寶購買連結:https://item.taobao.com/item.htm?id=622457259672
手機淘寶分享碼:複制本行文字打開手淘₤T4FPXn3YYJ2₤