STMCU小助手
发布时间:2022-9-30 16:02
|
1.实验原理 前文介绍过LTDC的内容,本节只需为LTDC添加一个面板即可。内核中包含一个通用的面板驱动,驱动之包含大量各种各样的面板。 . ?. |0 i) \& ~, j: ^ 1.驱动修改 驱动路径为:drivers/gpu/drm/panel/panel-simple.c! W% [# b% G0 {7 J \0 X/ \1 S 0 T+ @% l( O, `* b& r5 T 移植时可以在驱动中支持新的面板的内容,也可以找到一个与自己面板相仿的内容进行修改,本节即使用在原有面板修改的方法。如本节参考面板名称为zj070na-01p,对于一个面板最关键的内容在驱动通过drm_display_mode的结构体描述,zj070na-01p的描述如下:
这个结构体主要用来描述面板的时序相关信息,时序框图如下:
hdisplay:有效显示区水平像素数量,对应Active Width 2 p# E2 X2 q; ~ H hsync_start:水平同步开始,对应hdispay + HFP- j! Z- C. _& ]$ W% v* z" e3 T @+ N( N3 Y3 [. B% ~8 [3 d7 o! E hsync_end:水平同步结束,对应hdisplay + HFP + HSYNC width(HPW) 6 c" a4 w4 b: |5 f6 N htotal:水平总像素,对应hdisplay + HFP + HSYNC width + HBP vdisplay:垂直显示像素,对应Active Height ( f4 ^" u1 ?+ i! _ vsync_start:垂直同步开始,对应vdispay + VFP( g( W7 Q. v: r+ p 1 u# [6 C( H" C4 }, p& i! t. c vsync_end:垂直像素结束,对应vdisplay + VFP + VSYNC width(VPW) ! W' c/ c5 {$ ?5 a vtotal:垂直总像素,对应vdisplay + VFP + VSYNC width + VBP6 ^# T. w0 h( G ]- u) ] vrefresh:刷新率8 e/ T2 f/ {' k. d& j7 D ! F( [/ S, {: g/ L4 @, X7 _ 面板芯片手册中关于时序的描述如下:
* n6 p& R1 L7 r6 L4 P: Z& c 表中可以确认HBP=140、HPW=20、HFP=160、VBP=20、VPW=3、VFP=12,修改面板信息如下: static const struct drm_display_mode innolux_zj070na_01p_mode = {2 I7 |# S8 r8 u$ ? .clock = 51501,( g% U2 {6 f* F7 F( d& [7 k .hdisplay = 1024, & O- A) L% B' x! b3 z6 ^; I, s7 Z& T .hsync_start = 1024 + 160,) I: O1 w7 H9 V/ ]5 U: g0 b o' i1 }; o$ z) v6 d5 ] .hsync_end = 1024 + 160 + 20, .htotal = 1024 + 160 + 20 + 140,. B. M F; V+ @7 h .vdisplay = 600,) `0 k' H {& Y) s+ ? ; I" ?: d" T" Y% C3 u .vsync_start = 600 + 12,4 r- V+ I( k2 X! a! L .vsync_end = 600 + 12 + 3, .vtotal = 600 + 12 + 3 + 12, .vrefresh = 60,- {" N4 u' y2 b+ Z9 O9 E }; 5 d3 m; g( P' j7 n7 t$ [ 2.设备树修改 增加ltdc输出端口: 1 I1 u8 G, f7 I+ h# d2 \% n% k <dc { ' d4 O" A$ r5 q2 h% y status = "okay"; 7 x4 k# c' D% u4 K3 a' |+ ^ port { * N1 H- u7 d8 b- d( h! i #address-cells = <1>;' N) D& z" k; m; k. W & G; U$ D5 n- a8 `5 u& M& x, E' x& i #size-cells = <0>;" ^$ {1 u5 l! b) L$ S ltdc_ep1_out: endpoint@1 { reg = <1>;/ Z: j4 `- {5 P+ E& |' b1 I+ _ remote-endpoint = <&panel_in_rgb>; }; 6 `+ r5 k2 d2 j5 b9 L8 o) l };0 H+ v6 V8 K( Q& X4 ?$ ^0 n2 e };- n$ ]; W8 T* m0 W: C# r 3.增加面板节点: panel: panel-rgb { ; s; V2 W) C- P6 @& V% a compatible = "innolux,zj070na-01p"; pinctrl-names = "default", "sleep";+ p& [# i: v+ L) j: m7 |; i a5 w4 _+ B - q# g( I; `$ }3 y backlight = <&panel_backlight>; 9 f' S S6 y; H status = "okay"; 3 Q3 |: P6 D8 v1 j6 ]$ T% t1 v5 W port { panel_in_rgb: endpoint {6 x: r+ \" d! r0 H, p' p remote-endpoint = <<dc_ep1_out>; }; }; }; 3 }7 `. O* a7 V- h) O% W 4.PWM设备节点 9 _8 Y* z( _% f0 e2 S 内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见: arch/arm/boot/dts/stm32mp151.dtsi stm32mp151中timers2定义如下: # X$ u) z. J3 C& u; k( S7 q timers2: timer@40000000 { #address-cells = <1>; 6 s. c+ c/ Q1 k: l0 } #size-cells = <0>;7 v3 V3 c, R$ F( I% m$ W% I compatible = "st,stm32-timers";$ ?0 m9 |5 @$ l reg = <0x40000000 0x400>; 8 u D! g9 ^$ P! G* f- ~/ a clocks = <&rcc TIM2_K>;9 j; S1 i& t% n* T) e" V * s& W4 Z, X) r6 b; }8 | clock-names = "int";' b7 Z& Y! t2 b' e, }! K / x& r4 K% Z8 N* n3 X dmas = <&dmamux1 18 0x400 0x80000001>, <&dmamux1 19 0x400 0x80000001>,' [+ P3 q: I6 a/ k6 h; c: W <&dmamux1 20 0x400 0x80000001>, <&dmamux1 21 0x400 0x80000001>, * S. o0 z3 T8 N <&dmamux1 22 0x400 0x80000001>;, p8 q z$ N5 E, W: Z" p ^ % W9 s5 ]" Y+ `1 k dma-names = "ch1", "ch2", "ch3", "ch4", "up";) N* ~( H0 v2 T( y0 \ status = "disabled"; c" T- l" P) C3 U$ ^+ [. U5 a # W, p6 H6 x7 G) C% T. N pwm { compatible = "st,stm32-pwm"; ) p* m& B) M! ?# e- n1 h #pwm-cells = <3>; }, \* o0 A: j/ u) c status = "disabled"; };- i8 b- g$ @, Y1 [3 o timer@1 { 6 U* V5 ?) f" @( R! q compatible = "st,stm32h7-timer-trigger"; reg = <1>; status = "disabled"; }; counter {2 W6 H/ w; E+ y5 S8 e6 E compatible = "st,stm32-timer-counter";* h: a' p# w7 m# O, c, D& i status = "disabled";$ S9 [1 H6 D) R& N7 c : f3 q% M4 W, T8 O6 a+ V% @5 v8 l }; }; 上述代码只对timers5做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。6 a5 w c% g0 O% n( _3 ?* h9 P 参考文档或stm32mp15xx-dkx.dtsi对于i2c设备节点的描述,增加timers内容如下:5 q( L/ \4 A" L" d {( Z 4 c" L) w' H4 N &timers2 {3 u" j% z" a$ m7 H( z y2 | 2 Q* \7 R0 Z; B: M7 h8 [ /* spare dmas for other usage */5 C& K9 J+ B8 x /delete-property/dmas;+ u, \5 v8 \' g& K7 p ! l0 P+ y1 V% z( D! v3 e( | /delete-property/dma-names;$ @7 K" Y* x5 A% l , }0 T4 E$ ?( R* _2 U" D- [ w status = "okay";! X5 V6 _5 F& I! m! ]3 | $ o& n+ o1 Z7 f3 @ pwm2: pwm { 7 I5 k( K& a) V4 Y! f5 {6 h pinctrl-0 = <&pwm2_pins_b>; m5 w& X3 N5 e/ J pinctrl-1 = <&pwm2_sleep_pins_b>;- L, B9 S \; E+ e , l! B8 g9 o2 \" ]( n pinctrl-names = "default", "sleep"; #pwm-cells = <2>;( l2 U6 ]! ?# `& k3 S) z P( d, o/ R+ A; x/ ~; M status = "okay"; " W9 Q* a; t; p& q };0 l' d9 @' p+ [$ x4 Z0 O+ ? X ) }1 V6 T9 R1 h3 T* I I- F timer@2 {5 q3 \4 X. q3 v F( z6 w% j; X status = "disabled"; ; Y- N& z( k5 X };2 I5 N9 \5 J& U) R" \ }; stm32mp15-pinctrl.dtsi对于pwm2的描述与FS-MP1A所使用管脚不一致,所以无法直接使用,需参考其增加如下内容:6 `: K: v/ L0 [8 V! n' r pwm2_pins_b: pwm2-0 { pins { pinmux = <STM32_PINMUX('A', 5, AF1)>; /* TIM2_CH1 */1 k$ V5 G+ [& D- j9 ^8 K/ k bias-pull-down; 4 o# X9 C7 p7 W drive-push-pull; slew-rate = <0>;5 z' H6 a: H6 A };4 [, p/ g/ h( J' a+ Z };# y' n; \$ w/ A$ D7 L3 \- f . ]% @, f- [/ u pwm2_sleep_pins_b: pwm1-sleep-0 { pins { ' T- j4 R1 L. h2 e pinmux = <STM32_PINMUX('A', 5, ANALOG)>; /* TIM2_CH1 */$ |4 s! m0 P2 a }; / I" p8 I2 Q( Y& z$ C }; / E% a/ z, o2 V5 y9 Q 5.背光设备节点 FS-MP1A背光可以通过GPIO驱动也可通过PWM2的通道1驱动,可以对比参考文档或内核中其他设备树关于背光的定义。! V8 e, D: G2 A8 v) ^. X+ _' R GPIO驱动背光节点内容如下:' q; N1 g1 q: ]0 E panel_backlight: panel-backlight {! m; t7 I/ |' } compatible = "gpio-backlight"; gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; " D& ^' H+ |% G default-on; ; B# c: G: s! ~7 g) b8 U Y) t status = "okay"; };; F& S9 }& W" _3 g PWM驱动背光节点内容如下: - X, [" @1 {2 ` panel_backlight: panel-backlight { compatible = "pwm-backlight"; # G- O& h& Y( S. c- C( I pwms = <&pwm2 0 5000000>;* D5 h1 P$ }, R: P7 w# k brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; status = "okay";% Z$ p. G/ [/ q3 E7 Q( f };* @$ r7 K2 K) h( c8 I8 A # N8 x& k/ w# H# H5 w1 | 2.实验目的5 ?- |! L) ?8 w# Y1 q$ s) W 熟悉基于Linux操作系统下的摄像头设备驱动移植配置过程。0 h0 S9 P( n. @' j 3.实验平台" ?2 `/ [% Z7 U9 ?" y 华清远见开发环境,FS-MP1A平台; 4.实验步骤 1.导入交叉编译工具链 linux@ubuntu source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi+ K: D! u* g+ j) Z C 2.增加设备树文件 由于RGB LCD并非FS-MP1A必须配置,本节增加一个设备树文件,对应增加了屏幕的设备。. U% S6 f; l2 ~6 F* j4 V& k * g$ D* h9 T5 _ 在内核的arch/arm/boot/dts目录下新建文件stm32mp157a-fsmp1a-rgb070.dts文件并添加如下内容: #include "stm32mp157a-fsmp1a.dts"5 Q |% k$ H# S / { model = "HQYJ STM32MP157 FSMP1A RGB Discovery Board";' [2 }# U3 m2 G* ^ compatible = "st,stm32mp157a-dk1", "st,stm32mp157";4 E+ T1 G- l( ]' _, J1 n }; 由于增加了新的设备树文件需修改arch/arm/boot/dts/Makefile,在文件中增加新的条目,红色字体部分为增加内容 dtb-$(CONFIG_ARCH_STM32) += \) R6 U( j) J. h, I: n) \& `$ A ….. stm32mp157a-dk1.dtb \# R# k; h; y* Y8 D. l' ]$ X 8 s: K& L2 D2 o( E h stm32mp157a-fsmp1a.dtb \ 3 D1 ?7 v9 g! E; ?' s) P stm32mp157a-fsmp1a-mipi050.dtb \' X( _" |1 p ~ stm32mp157a-fsmp1a-rgb070.dtb \6 T l9 d+ U1 M stm32mp157d-dk1.dtb \0 F" \7 ?* t; O" d : b5 W" h4 \% b 添加pwm2内容( K7 e- J D f7 z* N 修改stm32mp15xx-fsmp1x.dtsi,在stm32mp15xx-fsmp1x.dtsi文件末尾添加如下内容: ( A6 K' Z( {' ~2 q) e &timers2 {; w: k) K4 @& ~# V4 H5 |3 n j /* spare dmas for other usage */! V, ~6 I. K. d3 E ( C9 _7 B3 j: ^% m /delete-property/dmas;+ h8 _$ k" U9 S; }! ^6 U 0 Z- o* {. D" }8 [ /delete-property/dma-names; # L3 p2 Q: R7 |$ F. m$ {5 c5 D' g status = "okay"; pwm2: pwm {" L+ S3 v, q1 w5 c& d0 {" ^+ f pinctrl-0 = <&pwm2_pins_b>; F; L' l' G# g, Y- F& [ pinctrl-1 = <&pwm2_sleep_pins_b>;, b/ A: L8 F1 B! b2 ]/ h5 g* l3 e' X pinctrl-names = "default", "sleep"; e( ~- d' B; K0 }! A2 e* u" U #pwm-cells = <2>;, w! s" H5 a9 _/ K 8 q2 f' p1 R5 \. F$ U status = "okay"; }; 1 m2 ^1 v/ A; R+ i' m9 x: f timer@2 { 2 A; @0 O* H8 G1 H0 t status = "disabled";- I* k; k$ C, L q* i) C9 P / z" F* {% q' j a };2 V; l3 J1 f4 h u$ h7 _2 W }; ; K" a, Z" ?+ K1 y &pinctrl {9 T" \# ^' D5 P) o. I6 c 5 d: [ h& a3 I$ ?& q& L* \, }9 g pwm2_pins_b: pwm2-0 { / i. c# S& K. m( q9 j4 M1 z( n pins { 9 h, ?% C/ h; g! d pinmux = <STM32_PINMUX('A', 5, AF1)>; /* TIM2_CH1 */ 7 b: G! A- t. K6 z$ p6 _) @. M bias-pull-down;# C- m9 ~. K% N1 T4 A+ n + X/ A1 }9 o, l4 h* W# b$ \ drive-push-pull;2 Q3 ^3 ^3 z. C0 G/ v3 s( j1 F3 y 6 F/ ?& N( Z" Z: W- s9 W1 ]* ? slew-rate = <0>;: q7 w! M1 K8 c1 }3 E$ d7 l ) F# V4 H; H _0 ]4 n7 a% F }; };4 @0 f: B. j6 ` pwm2_sleep_pins_b: pwm1-sleep-0 { D) z! V; t4 h9 H5 ]. W8 q pins { 3 ~7 o7 h4 }# [( p6 ^ pinmux = <STM32_PINMUX('A', 5, ANALOG)>; /* TIM2_CH1 */ ; ]+ ~9 y& O- e4 E A }; a, g D% b' e9 G* c) H };; n2 q+ E5 O. i% T8 M5 D1 Y7 P };/ S0 F6 X; l5 k 2 C! e! r/ a# E. P6 B9 v 3.添加背光内容/ D: }% x0 r' C5 I. L. B8 I 修改stm32mp15xx-fsmp1x.dtsi,在根节点中添加如下内容:8 ?0 S0 z( N! u( J( N; o( Q 8 E4 l6 }* O s5 R) L panel_backlight: panel-backlight {1 g. z) `: w' f% D 3 ?! n9 M# ]& M- g compatible = "pwm-backlight"; pwms = <&pwm2 0 5000000>;6 b; u4 o+ G7 l. H( i$ k b$ m' w brightness-levels = <0 4 8 16 32 64 128 255>; 8 s* ^; `: M. N8 r' f6 ? default-brightness-level = <6>;# E+ N. g5 u! p E% G2 X V2 \ i status = "okay"; , P, s3 f+ d, v$ V5 |* a };6 V! A. t/ Y9 K4 W3 G & e& d! G5 k7 z" m) k( S 4.添加ltdc端口 修改文件arm/arm/boot/dts/stm32mp157a-fsmp1a-rgb070.dts,在文件末尾添加如下内容:2 z) }" e% }8 u C2 x1 d Q" C3 j <dc {/ W8 ^2 T; v/ F. _# u% E status = "okay"; port {" B8 g* \; G4 Z/ t #address-cells = <1>;: J" i4 d( J; Z, S 1 @4 A2 _7 u P9 X4 f* i6 h) e #size-cells = <0>; ltdc_ep1_out: endpoint@1 { $ i$ p) x9 c8 X: f* Y reg = <1>; : ?) b+ M' a& O& r, {+ U remote-endpoint = <&panel_in_rgb>; };0 j/ w/ r: N) Q' e2 z # V% k Z& T H5 u& z }; n6 o2 s' u6 s3 D; V0 b + }' \$ g+ F4 u( M }; 5.添加面板信息 修改文件arm/arm/boot/dts/stm32mp157a-fsmp1a-rgb070.dts,在根节点中添加如下内容:& l# R- r. q. I) } 9 k9 ^( p; o9 M4 T9 r, q panel: panel-rgb { compatible = "innolux,zj070na-01p"; 1 m4 G: l6 F/ e pinctrl-names = "default", "sleep";- i! \" h9 O: q; J# y. C- X $ ^4 X, X- m$ Y; { backlight = <&panel_backlight>;! f# ^5 e& c5 M+ l# r V ! r% t p( F# m4 F9 v6 c- L5 A status = "okay"; - k$ |' z# J; k2 H port { 1 P: [. k" s4 J panel_in_rgb: endpoint { remote-endpoint = <<dc_ep1_out>;1 S5 Z9 h# ]( R/ m( i5 y }; 3 m! T. B q# Q+ Q& z& S# J };8 D4 |2 |, v2 e: ]3 h/ {& r 0 R2 F! V# V5 `/ V; {7 Q }; . _0 U. U9 t% m' x 修改面板驱动,修改面板时序参数, L/ [! h5 ~ F$ M 修改文件drivers/gpu/drm/panel/panel-simple.c,修改zj070na-01p面板信息,对照面板芯片手册修改原有内容,红色字体部分为修改内容: static const struct drm_display_mode innolux_zj070na_01p_mode = { .clock = 51501, ; S: t. E! q0 T% y+ G! b: M. N .hdisplay = 1024,$ U N. N. w; b* w, W 1 b* Z0 x9 A6 y0 T: I! f .hsync_start = 1024 + 160, + G$ p& K; W8 u: U .hsync_end = 1024 + 160 + 20,7 J8 a) f. |0 {3 H6 h 8 ], s" `! Q' a" G0 P0 @- G$ ]' W .htotal = 1024 + 160 + 20 + 140,: y7 b3 ^( b4 U4 y8 S .vdisplay = 600,: `& @; G% Y' n, I9 H p .vsync_start = 600 + 12,2 W, W o- v) N6 t7 a0 e .vsync_end = 600 + 12 + 3, ! Y8 S2 W9 @: w+ ^# p1 Y .vtotal = 600 + 12 + 3 + 12, 5 w7 d% w$ l( v( @ .vrefresh = 60,* u, d. R$ p. w8 s7 o $ \' M: ?0 T" M7 |8 }$ {* q }; ! A2 X$ ?) Z5 b7 y" ^+ _ 6.配置内核3 C2 n% `" c& l4 R6 t0 o6 } H1 M 由于内核默认支持通用面板驱动,本节列出主要选项,如下1 `2 f( ?& o7 l) I) P# u% h4 ? ( k1 B: w8 u0 G% H& c linux@ubuntu make menuconfigDevice Drivers ---> B- k( {6 H3 D8 a2 C $ N* u; S+ k- j/ {5 b! _1 H Graphics support --->( u5 G* s2 U6 F, e4 q. F ) ?+ }+ X. S0 a: N& s7 g <*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) ---> <*> DRM Support for STMicroelectronics SoC Series& Q U5 }( h9 i: z Display Panels ---> <*> support for simple panels* g& X9 a0 w6 r. n1 a Backlight & LCD device support --->) g# D8 H4 l- k) _# |7 M0 | <*> Generic PWM based Backlight Driver 7 v& C7 W) M1 `: i 7.增加启动项7 M7 s& E8 \ Z; r" X% E7 s 在虚拟机/tftpboot /tftpboot/pxelinux.cfg/01-00-80-e1-42-60-17末尾添加: m- e: p) K2 w; [ LABEL stm32mp157a-fsmp1a-mipi KERNEL /uImage+ t& A# p9 n% d& K8 J FDT /stm32mp157a-fsmp1a-rgb070.dtb APPEND root=/dev/mmcblk1p4 rootwait rw console=ttySTM0,115200 8.编译内核及设备树 linux@ubuntu make -j4 uImage dtbs LOADADDR=0xC2000040/ B$ ]5 b) p5 e0 m 9.重启测试: q' ^5 O7 U& d/ g8 T: p 安装上7寸LCD面板,将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,启动后可正常显示,如果屏幕显示不正可适当调节面板参数。' }5 E3 f3 \+ Q( f, P( E0 J2 `
- _8 v0 T: |3 b+ k; i ————————————————7 y- T# v1 ~' s3 K4 W& Q3 O5 c 版权声明:华清远见IT开放实验室 |
STM32MP157双A核Linux + 自研RTOS双系统镜像免费下载
扩展STM32微处理器,实现高性价比、低功耗和灵活性能
STM32MP1 自举程序编程:USB DFU/USART 协议全解析
兔哥心中的ST中文论坛
我心中的ST中文论坛
STM32 开发者指南:ST.com 全新 MCU 产品阵容视觉布局深度解析
深度拆解 STM32MP1 Boot 链路
STM32串口自动识别波特率的原理
STM32MP135 MP157 MP257 CoreMark移植&&跑分对比&&多核心负载不均衡问题排查与解决
STM32--STM32 微控制器详解
微信公众号
手机版