STMCU小助手
发布时间:2022-9-30 15:28
|
1.实验原理/ q4 o* G! @. w' @ FS-MP1A使用的是CS42L51音频芯片,SoC通过I2C和SAI与其进行数据交互,原理图如下:5 R2 ?" U, ~, L: S1 \ ! Y8 n6 c2 H, r
6 l) C! p4 F0 `6 d8 K3 |$ ~; o u SAI2管脚对应关系:
& u. g. ~/ N. F2 h
I2C5管脚对应关系: $ u4 S! O6 `) I! n. F' B8 i
; Y( c$ B2 T6 r8 Z" }) i 芯片复位管脚对应关系:' B( q8 S5 ^ w/ \" i0 D $ k- W ~- H8 ^
) U: d- O& L/ b 1.SAI2设备树节点6 v W# j+ K9 i6 Q* ^0 y u8 b D' Y3 U . r. ^) h3 b" y& f$ p 内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见:( H9 x# |7 ?; f. |7 i5 x5 x7 t sai2: sai@4400b000 {4 l" ~) E. T/ H1 p3 w; _, j# C9 x compatible = "st,stm32h7-sai";* u" d" |$ g+ X! `: T % N; `+ P' @7 y6 r- U: [& C #address-cells = <1>; #size-cells = <1>;, v2 y/ \! I0 e/ h2 k1 \ 5 M% M' Y' e" H2 ]' k! C+ M1 w ranges = <0 0x4400b000 0x400>;! W+ f; |! n! @; a( A, J 3 o" x& F, ~, {; l- l2 V# V reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>; interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; resets = <&rcc SAI2_R>;& V0 ]% i- J# u# x3 N4 A: @. {/ ^: Y$ M ) o# c' ? \8 o$ n+ Q: D# V# Y status = "disabled"; sai2a: audio-controller@4400b004 {. d: u$ `* \3 N; ~$ T; K' Y, `/ d4 Q #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a";7 m' ?3 l0 d6 I reg = <0x4 0x1c>;/ R5 u w) q! i# v# @ clocks = <&rcc SAI2_K>;; X5 p, R6 y0 h( ~- t1 B $ v% z0 @8 ?9 T7 z) ?. | clock-names = "sai_ck"; ( F# H: Q- b- m* X+ b dmas = <&dmamux1 89 0x400 0x01>; 9 v# R1 q: {( q6 N status = "disabled";, P6 z" [! S4 t% ~0 Q . f; N: k+ J2 h$ W' C5 j1 S% A };: A# |7 [% I. A( }4 ]3 S. u sai2b: audio-controller@4400b024 {+ X, H) e+ t7 g( A% g #sound-dai-cells = <0>;9 P" Y% _5 W/ t: w* U % s- X9 X+ v: L7 \4 R compatible = "st,stm32-sai-sub-b"; reg = <0x24 0x1c>;" ~. G1 T( [+ P; h2 } / Y: {* o) g& S8 l O! Q clocks = <&rcc SAI2_K>; j) r$ K B0 |4 p, f ; J8 J A9 P% v) U$ G6 j! u: ^% F) S clock-names = "sai_ck"; % A2 n5 M8 U) s; H2 m0 u2 V' j dmas = <&dmamux1 90 0x400 0x01>;' O$ b0 F. e, a9 V status = "disabled"; };1 @8 r. e7 {% v5 J* `. i; C & g I' O8 i: e }; ; d( x; }1 |2 g Z O9 M 上述代码只对SAI2做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。 O; s4 s$ d9 y. y* A! i% U 2 G# i- J' Q. e1 e% [: ] 参考stm32mp15xx-dkx.dtsi对于SAI2设备节点的描述,增加SAI2内容如下: &sai2 { clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; * K2 _" A: x# K. R0 A clock-names = "pclk", "x8k", "x11k"; pinctrl-names = "default", "sleep";1 d( _- [3 T/ R0 G - J, k" h$ p. n$ X8 B9 W& C' S+ s7 _- R5 d pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;0 a. Y3 J. r) h+ T8 ] pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;& L1 K3 a' `1 Q status = "okay"; : x% o( L3 M/ u3 S8 Y' B sai2a: audio-controller@4400b004 {9 }" s8 ]. e- ^ #clock-cells = <0>; - `2 X( l7 B& Q$ @5 q& m. z dma-names = "tx"; clocks = <&rcc SAI2_K>; clock-names = "sai_ck";2 h: s/ V$ H! p3 {# W% k C ) f ~& X& E" f& h status = "okay";4 N2 ?3 i6 }: F- T sai2a_port: port {: W8 b2 D2 {8 O4 D+ P9 P8 y* o sai2a_endpoint: endpoint {6 a+ z, T5 H1 V( a 8 T/ _/ K! u. h remote-endpoint = <&cs42l51_tx_endpoint>; % W& y" z/ b8 ? format = "i2s"; , H3 ?0 W0 _" L2 N mclk-fs = <256>;& C' r5 [4 Z& M4 T3 r dai-tdm-slot-num = <2>;* y" x. I+ `. B2 l. R dai-tdm-slot-width = <32>; ) @/ b) M' r- G };$ l% U# }5 f3 e) V3 K. v3 c };) q* j" u/ U+ f$ h# w- M2 W }; sai2b: audio-controller@4400b024 { dma-names = "rx";: T' V: n: [( \' _4 r3 C 9 y1 F# f" s2 Z2 R; _ st,sync = <&sai2a 2>; clocks = <&rcc SAI2_K>, <&sai2a>;% d. w }) S9 G X- O: y + m; D, {9 X5 J clock-names = "sai_ck", "MCLK";0 J& g% w: P: I* n) x status = "okay";; w) X7 ]9 }! w- r/ X sai2b_port: port { 4 u5 T" Q/ ~8 o& S2 X$ L sai2b_endpoint: endpoint {! k+ [$ E3 T0 w remote-endpoint = <&cs42l51_rx_endpoint>; ; U8 l6 m% i' a format = "i2s";! \. d, L& v% f mclk-fs = <256>; dai-tdm-slot-num = <2>; / q- v4 Y3 ~# y, c8 P* z4 y- | dai-tdm-slot-width = <32>;: ]. l# `$ ^" j* Z9 Q5 d z$ a3 x$ x2 z# M };) h& Y7 T e* a% `9 x }; ( p9 I! i* r) _+ | };# Y @: r! H& A; k3 {5 ?) v 2 |( n% V# a& _, G };& [# p/ K6 j% h% s. Q. F M* x) b 由于stm32mp15-pinctrl.dtsi中对于SAI2管脚的定义与FS-MP1A实际使用管脚一致,所以无需修改。 2.CS42L51设备树节点7 J- M/ F1 J4 T- l& |% Z, p0 l 由于前文中已经增加过I2C5的节点信息,本节就不再重复,在原有I2C5节点添加CS42L51内容即可。 7 f5 i$ r" a' n; e 参考stm32mp15xx-dkx.dtsi对于codec芯片设备节点的描述,增加内容如下:' @1 x1 k. d- ~9 n3 l ! j) X, T) x2 A0 k4 n cs42l51: cs42l51@4a { & o) K, ^4 }2 C0 ~7 Q# c" ^ compatible = "cirrus,cs42l51";8 e3 {7 x$ O+ j- I+ ~( M 7 K5 L, @! ?+ A8 p7 [* b reg = <0x4a>; #sound-dai-cells = <0>; % K D2 \4 {7 M9 o VL-supply = <&v3v3>; VD-supply = <&v1v8_audio>;. D/ u9 U0 [/ u + p u3 M; p& Y6 E# I/ j. q VA-supply = <&v1v8_audio>;- P4 X; _" ]6 ` VAHP-supply = <&v1v8_audio>; reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;5 _6 `2 P2 {+ M, C clocks = <&sai2a>; clock-names = "MCLK";. r! F7 R' w( A- y$ v % l; P6 s. Y0 y3 @, ^ status = "okay";' Z) p$ X* ], o9 L- f' I0 c cs42l51_port: port { / S: o9 ^+ H8 _( [8 b #address-cells = <1>; #size-cells = <0>;8 R4 Q1 d! ^ h6 Q# Z" g4 X ) _7 B1 [/ T/ I* m% ?9 C$ f cs42l51_tx_endpoint: endpoint@0 {6 L" \- B) L: r! F2 _/ R/ {- N! y reg = <0>; remote-endpoint = <&sai2a_endpoint>; 2 J d9 `3 g( c/ s4 A frame-master;$ r8 c0 e# c$ T4 ~9 X bitclock-master;; k2 W8 n2 \ ^, H0 P) l 6 F4 k) E) B: j8 O7 |5 C. s };' [3 T) k5 R; b) p' v: {7 V& n 4 l) ]0 ^/ {3 _* F+ O. _ cs42l51_rx_endpoint: endpoint@1 {' `# {9 w/ G# W7 h1 ]1 p % l$ v8 D8 z0 h reg = <1>;' x3 @% p8 ^! p! Z ) E* H# W9 {+ l6 q" t+ R remote-endpoint = <&sai2b_endpoint>;) d9 p7 t$ J& p5 T& `) n1 ~ 6 C! q1 A, H J! m+ { frame-master;/ C1 o8 q% }7 Q* {5 @% j+ d0 U( P bitclock-master; };0 a) Q+ {5 W# e F/ n( M1 e4 Y, B }; # N: B2 d- f0 c6 ~/ |5 M- ]- V+ r) J };) ~2 y9 R7 r+ `6 p: ?0 t9 x" d, K & z6 Z# l' j( ^ 3.1.8V电源设备节点 前文已经说过如何添加电源节点,本节不再重复,在根节点添加&v1v8_audio节点,内容如下:4 w l) o9 L7 K G 6 R' [# a+ c. P& s, g1 n v1v8_audio: regulator-v1v8_audio { 0 r3 c5 E( n& e u compatible = "regulator-fixed";7 n1 r$ w- u. A ( Z* z: `& K1 A) s/ t: ]0 ] regulator-name = "v1v8_audio"; ! P+ O0 G5 w" t' l& _7 I; H regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; 5 Q p- g( ]6 r# N( |4 K regulator-always-on; regulator-boot-on; Q" x1 `5 A# G" z( F }; 4.SOC声卡驱动节点" G j& X2 O7 B" Z" e 内核中包含audio-graph-card驱动,驱动将声卡各个部分关联起来,驱动正常工作需添加对应设备树节点。 在根节点写下添加sound节点: q; l( v( g+ n6 H3 D j3 u sound { - z' j) W a9 Q compatible = "audio-graph-card";' D& Z3 W7 N9 v# `( c' g , h( Z* I6 F3 d L label = "STM32MP1-FSMP1A"; % L) K; x, B$ s2 x$ G0 X routing =0 u3 n$ J) P) t " V" n5 V8 y" I " layback" , "MCLK",* f# g# R) \6 H! b; x. P* U8 n* M4 v "Capture" , "MCLK", "MICL" , "Mic Bias";. `9 W8 e$ |# b6 i; h , U" Q; g; O- [, |% ?! _5 ~ dais = <&sai2a_port &sai2b_port>;$ E4 h. e9 ^/ B4 W8 K: `4 P 3 ?) G+ b( l7 q. V+ O# X, I1 _ status = "okay";+ c0 p/ p! X$ L& q 4 t; B; S) Z) w5 s) r% N }; 2.实验平台- ~" l% v" p9 F2 E) m C6 O8 n) M 华清远见开发环境,FS-MP1A平台;% u* @, s1 P( ^ 3.实验目的 熟悉基于Linux操作系统下的音频设备驱动移植配置过程。 5 Y+ W; e& i* B3 Q" s! Y' g0 M* _ 4.实验步骤" K/ i! F/ M2 [ l' U; N 1.导入交叉编译工具链4 n4 C) Q3 v7 ] ] linux@ubuntu source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi0 s4 t3 ` s. w4 `2 B 2.添加SAI2节点 修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在文件末尾添加如下内容:4 F/ k& v: E% O2 e0 E &sai2 { : @; W$ e! S5 U: @! X3 @' N clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;% x4 m D9 S# p; B clock-names = "pclk", "x8k", "x11k"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;" G+ S0 e8 j1 w2 {' D 3 l' t( E2 L* j7 c3 L/ T( J% W+ b pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>; status = "okay"; sai2a: audio-controller@4400b004 { 8 _4 m w/ W( f# |- l$ b, k- T #clock-cells = <0>;$ b; r; {$ L; l7 W& I9 g % m; ~* R+ ?2 }/ H6 u3 A dma-names = "tx"; clocks = <&rcc SAI2_K>;4 `' E( H+ J2 H g6 j. Z0 \9 L. ~ + a. l, i6 m# C* A/ g clock-names = "sai_ck";; Z" O! f5 `! \9 e) j( K. c status = "okay"; , f6 m2 ~' I2 W$ h8 l* j$ q9 Q sai2a_port: port {5 l( D+ Y, t% U6 f/ i sai2a_endpoint: endpoint {) u D% M7 a' m: V8 V" h! Q# I remote-endpoint = <&cs42l51_tx_endpoint>; format = "i2s"; mclk-fs = <256>; dai-tdm-slot-num = <2>;2 V) X Y: {- A3 I; W5 Z " x) t/ I# N- V5 N0 w7 P# j. H dai-tdm-slot-width = <32>;7 s* p( _; s# x% h- c2 r1 B };: g1 C m: W$ n+ N }; % V1 l- w2 _( B& ~* n ~1 X }; # N1 e8 U/ x# x6 S, r& p0 C$ U sai2b: audio-controller@4400b024 { dma-names = "rx"; st,sync = <&sai2a 2>; clocks = <&rcc SAI2_K>, <&sai2a>; / {* s( g2 X( z clock-names = "sai_ck", "MCLK";* ]+ J. @/ }1 L0 O5 B status = "okay";1 @5 E0 F; p) s1 n2 f1 m, A 0 r; F4 x5 h( V8 O5 E5 |+ Q sai2b_port: port { sai2b_endpoint: endpoint {; L D, d6 M$ N; `( H7 m* E, U d 2 @ u+ B" m7 } remote-endpoint = <&cs42l51_rx_endpoint>;/ r9 q" x1 w% \$ U7 W9 _! i2 \ $ q0 C, c% U8 c format = "i2s"; * ?8 h8 W9 L j/ b* F) N( {! U mclk-fs = <256>; . |3 U1 H$ U; ~. V/ [ dai-tdm-slot-num = <2>; : k: T. a' ]3 U7 F8 C3 F, C dai-tdm-slot-width = <32>; }; ( I$ D C1 x$ C( ] }; }; 9 N8 `7 R, m: A$ P; o }; 3.添加CS42L51节点 修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在I2C5节点中添加如下内容: # R2 J7 V W# ?, W# i: Y cs42l51: cs42l51@4a {! j9 P0 w$ M! ?" a7 P" ] compatible = "cirrus,cs42l51";$ h7 M* |3 E% f4 P/ w9 y9 Y reg = <0x4a>; #sound-dai-cells = <0>; VL-supply = <&v3v3>;( ?3 }, l4 u/ D7 {6 v) e" | & ^4 D9 X! P! Z: X VD-supply = <&v1v8_audio>;$ W l" X2 k3 c8 o/ u1 r* Q VA-supply = <&v1v8_audio>; VAHP-supply = <&v1v8_audio>;0 A% c& J$ ]% I& W+ r: M# k 9 n+ u* i! ?1 A9 c2 F/ p reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;9 N' C" G! `9 s6 I2 r$ g ' h. w5 ~% P- Y! Z$ T clocks = <&sai2a>;/ @4 j3 p& U$ P$ n5 _4 O clock-names = "MCLK"; " N1 h; h! o/ J' A4 ~ status = "okay"; * U& u) M9 B; N" m% z# R9 w cs42l51_port: port { - U: Z, Y D' \1 J* y+ W$ K #address-cells = <1>; #size-cells = <0>; cs42l51_tx_endpoint: endpoint@0 { 7 C% A K7 d5 K$ @. \ reg = <0>;5 s/ m1 M- R+ B; r7 q& h 8 U8 {+ i; `6 J0 { remote-endpoint = <&sai2a_endpoint>;( g% [% S# ?2 y, c frame-master;9 J& [' a& l0 c; h) y2 g( k bitclock-master;/ s$ b& ^4 U' \' j- o 2 I& s& w+ ~- U }; * H& U6 Y+ ]& H r; g cs42l51_rx_endpoint: endpoint@1 {% g- j, u8 Z+ y* Q 4 z" b! v4 \& B' l: C5 ]1 z! l reg = <1>;8 A) a/ K7 p0 h: y- Z remote-endpoint = <&sai2b_endpoint>; 3 G9 T: J) i! P( L8 d, ` frame-master;4 l7 D/ _0 }# u+ x bitclock-master; f# s- ]3 Z; Z% G. I }; }; }; 4.添加v1v8_audio电源节点 修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在根节点中添加如下内容:$ D, J9 Z9 K. X, t9 _ ~$ ]) ~7 o* { v1v8_audio: regulator-v1v8_audio { compatible = "regulator-fixed";1 D p( \$ I( k% V% s+ z + z( i* ~/ F( a6 V regulator-name = "v1v8_audio";1 ~" R l. M2 M! j regulator-min-microvolt = <1800000>; . m' Y* n: Z/ Q+ |/ p6 G regulator-max-microvolt = <1800000>; j1 s. O2 s) V+ { regulator-always-on;, a: F: R4 Z- S3 p- _ 7 b0 j3 v$ o# S3 h regulator-boot-on; }; 5.添加Sound节点0 P: ]. S/ J! O 修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在根节点中添加如下内容:8 |' O# e6 }2 |, n( Y) \ : ]; i9 {2 d2 {5 j6 ^* N; D, U7 T sound {6 I1 j- X; |3 P8 v- }6 r* U5 m0 N ( I8 I" C% L$ B8 A9 l7 ^* e compatible = "audio-graph-card";# v( G& U: t- L% S label = "STM32MP1-FSMP1A"; routing =- G, n L$ ~% O) U " layback" , "MCLK",6 P2 J$ C! f0 |7 l8 v) X "Capture" , "MCLK", "MICL" , "Mic Bias"; dais = <&sai2a_port &sai2b_port>;7 }, t7 z% L7 r3 q! V1 U/ c status = "okay"; ( n: F! T0 G- V- ^* Z7 h0 b3 r };0 |: V& o( a. W+ V: q g $ K/ o8 ?/ H! l5 G 6.配置内核9 j a7 z7 g. r 由于内核源码默认配置以及支持CS42L51,本节列出主要选项,如下:: [5 _3 K3 f. d) f* I5 {6 K ' a5 M0 _1 n# y6 u linux@ubuntu make menuconfig+ S1 P# m2 a% ^% V/ m; W8 w5 S& H: _- z2 `0 e$ [ Device Drivers ---># W9 d1 M/ s# d# Z8 M7 p4 u' c+ b <*> Sound card support --->3 t1 X* `8 z/ X# F/ D" A/ E <*> Advanced Linux Sound Architecture --->" b' e! i- t5 G4 Z + ?8 o' a; c* @3 q# |3 m+ W( j <*> ALSA for SoC audio support --->$ l6 n, [7 N3 D. n6 i* k 1 W9 S9 n3 K. Y' U STMicroelectronics STM32 SOC audio support ---> 5 ^$ E5 `& E3 | <*> STM32 SAI interface (Serial Audio Interface) support; z! n+ U. \. _3 X CODEC drivers --->; `6 R5 l: i3 s+ R" h0 j6 a5 y % H2 b. f e1 U3 M3 x <*> Cirrus Logic CS42L51 CODEC (I2C) * n& d& Z i9 q$ P <*> ASoC Audio Graph sound card support 7.编译内核及设备树 linux@ubuntu make -j4 uImage dtbs LOADADDR=0xC2000040* V5 r) |6 E3 k1 o 8.重启测试 将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,启动后启动信息中出现如下内容: 8 K# O0 v' d$ V
插上耳机,终端输入录音命令:8 E# Q8 o6 j* y0 p% b/ Z 3 _5 |2 R) [6 d! K1 M6 V root@fsmp1a:# arecord -D record_codec -f S16_LE -d 10 test.wav0 I: D h/ x* ^0 j( f. H 终端输入播放命令:9 p l8 s, I2 ?; B% h root@fsmp1a:# aplay test.wav / r: E& o6 C. s ————————————————& Y+ p. ?( G, u' o 版权声明:华清远见IT开放实验室 }% J, F, ~( @4 {2 m# |; a . s- y" ~6 G3 \; | |
STM32MP157双A核Linux + 自研RTOS双系统镜像免费下载
扩展STM32微处理器,实现高性价比、低功耗和灵活性能
STM32MP1 自举程序编程:USB DFU/USART 协议全解析
兔哥心中的ST中文论坛
我心中的ST中文论坛
STM32 开发者指南:ST.com 全新 MCU 产品阵容视觉布局深度解析
深度拆解 STM32MP1 Boot 链路
STM32串口自动识别波特率的原理
STM32MP135 MP157 MP257 CoreMark移植&&跑分对比&&多核心负载不均衡问题排查与解决
STM32--STM32 微控制器详解
微信公众号
手机版