0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

全志R128基礎(chǔ)組件開發(fā)指南—SPI LCD顯示驅(qū)動(dòng)

冬至子 ? 來源:丨budboool ? 作者:丨budboool ? 2023-10-25 17:49 ? 次閱讀

SPI LCD 顯示驅(qū)動(dòng)

簡(jiǎn)介

R128 平臺(tái)提供了 SPI DBI 的 SPI TFT 接口,具有如下特點(diǎn):

  • Supports DBI Type C 3 Line/4 Line Interface Mode
  • Supports 2 Data Lane Interface Mode
  • Supports data source from CPU or DMA
  • Supports RGB111/444/565/666/888 video format
  • Maximum resolution of RGB666 240 x 320@30Hz with single data lane
  • Maximum resolution of RGB888 240 x 320@60Hz or 320 x 480@30Hz with dual data lane
  • Supports tearing effect
  • Supports software flexible control video frame rate

同時(shí),提供了SPILCD驅(qū)動(dòng)框架以供 SPI 屏幕使用。

模塊驅(qū)動(dòng)

MENUCONFIG配置說明

SPILCD 模塊 menuconfig 的配置如下(以選擇kld2844b屏為例):

Drivers Options  --- >
    soc related device drivers  --- >
        SPILCD Devices  --- >
            [*] DISP Driver Support(spi_lcd)
            [*]   spilcd hal APIs test           //spilcd模塊測(cè)試用例
            LCD_FB panels select  --- >           //spilcd屏驅(qū)動(dòng)配置
                [*] LCD support kld2844B panel
                [ ] LCD support kld35512 panel
            Board select  --- >
                [ ] board kld2844b support       //板級(jí)顯示使用顯示驅(qū)動(dòng)私有方式的配置項(xiàng),而使用sys_config.fex方式不用配置

另外可能需依賴的配置項(xiàng)有:

  • DRIVERS_SPI
  • DRIVERS_DBI
  • DRIVERS_PWM

源碼結(jié)構(gòu)介紹

源碼結(jié)構(gòu)及主要驅(qū)動(dòng)文件如下:

spilcd/
├── lcd_fb/
│   ├── dev_lcd_fb.c                # spilcd driver 層
│   ├── disp_display.c
│   ├── disp_lcd.c
│   ├── lcd_fb_intf.c
│   └── panels/                        # lcd驅(qū)動(dòng)相關(guān)
│       ├── kld2844b.c
│       ├── lcd_source.c
│       ├── panels.c
│       └── panels.h
└── soc/
    ├── disp_board_config.c            # 板級(jí)配置解析
    └── kld2844b_config.c            # 顯示私有方式的板級(jí)配置文件

模塊參數(shù)配置

當(dāng)前板級(jí)顯示支持兩種配置方法,一是使用 sys_config.fex 的方式進(jìn)行配置,二是在不支持sys_config.fex 情況下,可以通過顯示驅(qū)動(dòng)私有的方式進(jìn)行配置。下面分別對(duì)兩種方式進(jìn)行說明。

使用 SYS_CONFIG.FEX 的方式進(jìn)行配置

FreeRTOS系統(tǒng)路徑:board/芯片名/方案名/configs/sys_config.fex

配置文件具體要看芯片方案所實(shí)際使用的,也可能使用的配置文件名稱為sys_config_xxx.fex(xx是存儲(chǔ)方案的標(biāo)識(shí),例如sys_config_nor.cfg、sys_config_nand.cfg)

具體配置舉例如下:

;----------------------------------------------------------------------------------
;lcd_fb0 configuration
;----------------------------------------------------------------------------------
[lcd_fb0]
lcd_used            = 1              ; 使用顯示屏
lcd_model_name      = "spilcd"       ; 模型:spilcd
lcd_driver_name     = "jlt35031c"    ; 屏幕驅(qū)動(dòng):jlt35031c
lcd_x               = 320            ; 屏幕寬分辨率
lcd_y               = 480            ; 屏幕高分辨率
lcd_width           = 49             ; 屏幕物理寬度
lcd_height          = 74             ; 屏幕物理高度
lcd_data_speed      = 60             ; SPI 驅(qū)動(dòng)頻率 60MHz
lcd_pwm_used        = 1              ; lcd使用pwm背光
lcd_pwm_ch          = 1              ; lcd使用pwm背光通道1
lcd_pwm_freq        = 5000           ; lcd使用pwm背光頻率5000Hz
lcd_pwm_pol         = 0              ; lcd使用pwm背光相位0
lcd_if              = 0              ; lcd使用spi接口,0-spi, 1-dbi
lcd_pixel_fmt       = 11             
lcd_dbi_fmt         = 2
lcd_dbi_clk_mode    = 1
lcd_dbi_te          = 1
fb_buffer_num       = 2
lcd_dbi_if          = 4
lcd_rgb_order       = 0
lcd_fps             = 60
lcd_spi_bus_num     = 1
lcd_frm             = 2
lcd_gamma_en        = 1
lcd_backlight       = 100

lcd_power_num       = 0
lcd_gpio_regu_num   = 0
lcd_bl_percent_num  = 0

lcd_spi_dc_pin      = port:PA19< 1 >< 0 >< 3 >< 0 > ; DC腳
;RESET Pin
lcd_gpio_0          = port:PA20< 1 >< 0 >< 2 >< 0 > ; 復(fù)位腳

lcd_driver_name

Lcd屏驅(qū)動(dòng)的名字(字符串),必須與屏驅(qū)動(dòng)中strcut __lcd_panel變量的name成員一致。

lcd_model_name

Lcd屏模型名字,非必須,可以用于同個(gè)屏驅(qū)動(dòng)中進(jìn)一步區(qū)分不同屏。

lcd_if

Lcd Interface

設(shè)置相應(yīng)值的對(duì)應(yīng)含義為:

0:spi接口
1:dbi接口

spi接口就是俗稱的4線模式,這是因?yàn)榘l(fā)送數(shù)據(jù)時(shí)需要額外借助DC線來區(qū)分命令和數(shù)據(jù),與sclk,cssda共四線。

spi-16932054745452.png

如果設(shè)置了dbi接口,那么還需要進(jìn)一步區(qū)分dbi接口,需要設(shè)置 lcd_dbi_if

lcd_dbi_if

Lcd dbi 接口設(shè)置。

這個(gè)參數(shù)只有在lcd_if=1時(shí)才有效。

設(shè)置相應(yīng)值的對(duì)應(yīng)含義為:

0:L3I1
1:L3I2
2:L4I1
3:L4I2
4:D2LI

所有模式在發(fā)送數(shù)據(jù)時(shí)每個(gè)周期的比特?cái)?shù)量根據(jù)不同像素格式不同而不同。

L3I1L3I2是三線模式(不需要DC腳),區(qū)別是讀時(shí)序,也就是是否需要額外腳來讀寄存器。讀寫時(shí)序圖如下:

L3I1-16932054745453.png

L3I_RD-16932054745464.png

L4I1L4I2是四線模式,與spi接口協(xié)議一樣,區(qū)別是DC腳的控制是否自動(dòng)化控制,另外I2和I1的區(qū)別是讀時(shí)序,也就是否需要額外腳來讀取寄存器。

spi-16932054745452 (1).png

spi_read-16932054745465.png

D2LI是兩data lane模式。發(fā)送命令部分時(shí)序與讀時(shí)序與L3I1一致,下圖是發(fā)送數(shù)據(jù)時(shí)的時(shí)序,不同像素格式時(shí)鐘周期數(shù)量不一樣。

D2LI-16932054745466.png

lcd_dbi_fmt

DBI接口像素格式。

0:RGB111
1:RGB444
2:RGB565
3:RGB666
4:RGB888

選擇的依據(jù)是接收端屏Driver IC的支持情況,請(qǐng)查看Driver IC手冊(cè)或詢問屏廠。

然后必須配合lcd_pixel_fmt的選擇,比如說選RGB565時(shí),lcd_pixel_fmt也要選565格式。

lcd_dbi_te

使能te觸發(fā)。

te即(Tearing effect),也就是撕裂的意思,由于讀寫不同導(dǎo)致撕裂現(xiàn)象,te腳的功能就是用于同步讀寫,te腳的頻率也就是屏的刷新率,所以te腳也可以看做vsync腳(垂直同步腳)

0: 禁止te
1: 下降沿觸發(fā)
2: 上升沿觸發(fā)

查看帶te腳的屏進(jìn)一步說明。

lcd_dbi_clk_mode

選擇dbi時(shí)鐘的行為模式。

0:自動(dòng)停止。有數(shù)據(jù)就有時(shí)鐘,沒發(fā)數(shù)據(jù)就沒有
1:一直保持。無論發(fā)不發(fā)數(shù)據(jù)都有時(shí)鐘

注意上面的選項(xiàng)關(guān)系屏兼容性。

lcd_rgb_order

輸入圖像數(shù)據(jù)rgb順序識(shí)別設(shè)置,僅當(dāng)lcd_if=1時(shí)有效。

0:RGB
1:RBG
2:GRB
3:GBR
4:BRG
5:BGR
6:G_1RBG_0
7:G_0RBG_1
8:G_1BRG_0
9:G_0BRG_1

非RGB565格式用0到5即可。

針對(duì)rgb565格式說明如下:

rgb565格式會(huì)遇到大小端問題,arm平臺(tái)和PC平臺(tái)存儲(chǔ)都是小端(little endian,低字節(jié)放在低地址,高字節(jié)放在高地址),但是許多spi屏都是默認(rèn)大端(Big Endian)。

也就是存儲(chǔ)的字節(jié)順序和發(fā)送的字節(jié)順序不對(duì)應(yīng)。

這個(gè)時(shí)候選擇6以下,DBI接口就會(huì)自動(dòng)將小端轉(zhuǎn)成大端。

如果遇到默認(rèn)是小端的spi屏,則需要選擇6以上,DBI接口會(huì)自動(dòng)用回小端方式。

6以上格式這樣解釋:

R是5比特,G是6比特,B是5比特,再把G拆成高3位(G_1)和低3位(G_0)
所以以下兩種順序:

rgb565-16932054745467.png

  1. R-G_1-G_0-B,大端。
  2. G_0-B-R-G_1,對(duì)應(yīng)上面的9,小端。

lcd_x

顯示屏的水平像素?cái)?shù)量,注意如果屏支持橫豎旋轉(zhuǎn),那么lcd_x和lcd_y也要對(duì)調(diào)。

lcd_y

顯示屏的行數(shù),注意如果屏支持橫豎旋轉(zhuǎn),那么lcd_x和lcd_y也要對(duì)調(diào)。

lcd_data_speed

用于設(shè)置spi/dbi接口時(shí)鐘的速率,單位MHz。

  1. 發(fā)送端(SOC)的最大限制是100MHz。
  2. 接收端(屏Driver IC)的限制,請(qǐng)查看對(duì)應(yīng)Driver IC手冊(cè)或者詢問屏廠支持。
  3. 超出以上限制都有可能導(dǎo)致顯示異常。

lcd_fps

設(shè)置屏的刷新率,單位Hz。當(dāng)lcd_dbi_te使能時(shí),這個(gè)值設(shè)置無效。

lcd_pwm_used

是否使用pwm。

此參數(shù)標(biāo)識(shí)是否使用pwm用以背光亮度的控制。

lcd_pwm_ch

Pwm channel used

此參數(shù)標(biāo)識(shí)使用的Pwm通道。

lcd_pwm_freq

Lcd backlight PWM Frequency

這個(gè)參數(shù)配置PWM信號(hào)的頻率,單位為Hz。

lcd_pwm_pol

Lcd backlight PWM Polarity

這個(gè)參數(shù)配置PWM信號(hào)的占空比的極性。設(shè)置相應(yīng)值對(duì)應(yīng)含義為:

0:active high
1:active low

lcd_pwm_max_limit

Lcd backlight PWM

最高限制,以亮度值表示。

比如150,則表示背光最高只能調(diào)到150,0~255范圍內(nèi)的亮度值將會(huì)被線性映射到0~150范圍內(nèi)。用于控制最高背光亮度,節(jié)省功耗。

lcd_backlight

默認(rèn)背光值,取值范圍0到255,值越大越亮。

lcd_bl_en

背光使能腳定義

lcd_spi_dc_pin

指定作為DC的管腳,用于spi接口時(shí)。

lcd_gpio_x

x表示數(shù)字。如果有多個(gè)gpio腳需要控制,則定義lcd_gpio_0,lcd_gpio_1等。

lcd_spi_bus_num

選擇spi總線id,只有spi1支持DBI協(xié)議,所以這里一般選擇1。

取值范圍:0到1。

lcd_pixel_fmt

選擇傳輸數(shù)據(jù)的像素格式。

可選值如下,當(dāng)你更換RGB分量順序的時(shí)候,也得相應(yīng)修改lcd_rgb_order,或者修改屏驅(qū)動(dòng)的rgb分量順序(一般是3Ah寄存器)。

DBI接口只支持RGB32和RGB16的情況。

SPI接口只支持RGB16的情況。

enum lcdfb_pixel_format {
            LCDFB_FORMAT_ARGB_8888 = 0x00,    // MSB  A-R-G-B  LSB
            LCDFB_FORMAT_ABGR_8888 = 0x01,
            LCDFB_FORMAT_RGBA_8888 = 0x02,
            LCDFB_FORMAT_BGRA_8888 = 0x03,
            LCDFB_FORMAT_XRGB_8888 = 0x04,
            LCDFB_FORMAT_XBGR_8888 = 0x05,
            LCDFB_FORMAT_RGBX_8888 = 0x06,
            LCDFB_FORMAT_BGRX_8888 = 0x07,
            LCDFB_FORMAT_RGB_888 = 0x08,
            LCDFB_FORMAT_BGR_888 = 0x09,
            LCDFB_FORMAT_RGB_565 = 0x0a,
            LCDFB_FORMAT_BGR_565 = 0x0b,
            LCDFB_FORMAT_ARGB_4444 = 0x0c,
            LCDFB_FORMAT_ABGR_4444 = 0x0d,
            LCDFB_FORMAT_RGBA_4444 = 0x0e,
            LCDFB_FORMAT_BGRA_4444 = 0x0f,
            LCDFB_FORMAT_ARGB_1555 = 0x10,
            LCDFB_FORMAT_ABGR_1555 = 0x11,
            LCDFB_FORMAT_RGBA_5551 = 0x12,
            LCDFB_FORMAT_BGRA_5551 = 0x13,
        };

fb_buffer_num

顯示framebuffer數(shù)量,為了平滑顯示,這里一般是2個(gè),為了省內(nèi)存也可以改成1。

模塊 SYS_CONFIG.FEX 配置案例

典型2 data lane配置

一些屏支持雙數(shù)據(jù)線傳輸以加快數(shù)據(jù)傳輸速度,此時(shí)需要走DBI協(xié)議,典型配置如下:

[lcd_fb0]
lcd_used          = 1
lcd_driver_name   = "kld2844b"
lcd_if            = 1
lcd_dbi_if        = 4
lcd_data_speed    = 60
lcd_spi_bus_num   = 1
lcd_x             = 320
lcd_y             = 240
lcd_pwm_used      = 1
lcd_pwm_ch        = 4
lcd_pwm_freq      = 5000
lcd_pwm_pol       = 0
lcd_pixel_fmt     = 0
lcd_dbi_fmt       = 3
lcd_rgb_order     = 0
fb_buffer_num     = 2
lcd_backlight     = 200
lcd_fps           = 60
lcd_dbi_te        = 0
lcd_bl_en         = port:PB04< 1 >< 0 >< default >< 1 >
lcd_gpio_0        = port:PB02< 1 >< 0 >< default >< 1 >
  1. 硬件連接上,第二根數(shù)據(jù)腳連接到原來1 data lane的DC腳,可以這樣理解:2數(shù)據(jù)線在傳輸數(shù)據(jù)時(shí)就自帶D/C(Data/Commend)信息了,所以原來的DC腳就可以空出來作為第二根數(shù)據(jù)線了。
  2. 屏驅(qū)動(dòng)上,需要使能2 data lane模式,具體寄存器查看對(duì)應(yīng)driverIC手冊(cè)或者詢問屏廠。
  3. 這里的針對(duì)對(duì)2 data lane的關(guān)鍵參數(shù)是lcd_if,lcd_dbi_if,lcd_dbi_fmt和lcd_spi_bus_num。
  4. lcd_x和lcd_y是屏分辨率。如果屏支持旋轉(zhuǎn)(橫豎旋轉(zhuǎn)),這里也需要對(duì)調(diào)。
  5. lcd_pwm開頭,lcd_backlight和lcd_bl_en)的是背光相關(guān)設(shè)置,如果有相關(guān)硬件連接的話。
  6. lcd_pixel_fmt和fb_buffer_num是顯示framebuffer的設(shè)置。
  7. lcd_gpio_開頭的是自定義gpio的設(shè)置(比如復(fù)位腳)。
  8. lcd_fps和lcd_dbi_te是刷新方式相關(guān)的設(shè)置。

原SPI接口屏配置

如果IC支持DBI接口,那么就沒有必要用SPI接口,DBI接口其協(xié)議能覆蓋所有情況。

一些IC不支持DBI,那么只能用spi接口(通過設(shè)置lcd_if),如果使用spi接口,它有一些限制。

  1. 不支持2 data lane。
  2. 必須指定DC腳。這是由于spi協(xié)議不會(huì)自動(dòng)控制DC腳來區(qū)分?jǐn)?shù)據(jù)命令,通過設(shè)置lcd_spi_dc_pin可以完成這個(gè)目的,這跟管腳不必用spi里面的腳。
  3. 只支持rgb565的像素格式。由于只有單data lane,速度過慢,rgb565以上格式都不現(xiàn)實(shí)。
    [lcd_fb0]
    lcd_used = 1
    lcd_driver_name = "kld2844b"
    lcd_if = 0
    lcd_data_speed = 60
    lcd_spi_bus_num = 1
    lcd_x = 320
    lcd_y = 240
    lcd_pwm_used = 1
    lcd_pwm_ch = 4
    lcd_pwm_freq = 5000
    lcd_pwm_pol = 0
    lcd_pixel_fmt = 10
    lcd_rgb_order = 0
    fb_buffer_num = 2
    lcd_backlight = 200
    lcd_fps = 60
    lcd_dbi_te = 0
    lcd_bl_en = port:PB04<1><0><1>
    lcd_gpio_0 = port:PB02<1><0><1>
    lcd_spi_dc_pin = port:PA19<1><0><3><1>

帶te腳的屏

te即(Tearing effect),也就是撕裂的意思,是由于讀寫不同步導(dǎo)致撕裂現(xiàn)象,te腳的功能就是用于同步讀寫,te腳的頻率也就是屏的刷新率,所以te腳也可以看做vsync腳(垂直同步腳)。

  1. 硬件設(shè)計(jì)階段,需要將屏的te腳連接到IC的DBI接口的te腳。
  2. 配置上接口使用dbi接口。
  3. 然后使能lcd_dbi_te。
  4. 屏驅(qū)動(dòng)使能te功能,寄存器一般是35h,詳情看屏對(duì)應(yīng)的driver IC手冊(cè)。
  5. 屏驅(qū)動(dòng)設(shè)置幀率,根據(jù)屏能接受的傳輸速度選擇合理的幀率(比如ST7789H2里面是通過c6h來設(shè)置te頻率)。
    [lcd_fb0]
    lcd_used = 1
    lcd_driver_name = "kld2844b"
    lcd_if = 1
    lcd_dbi_if = 4
    lcd_data_speed = 60
    lcd_spi_bus_num = 1
    lcd_x = 320
    lcd_y = 240
    lcd_pwm_used = 1
    lcd_pwm_ch = 4
    lcd_pwm_freq = 5000
    lcd_pwm_pol = 0
    lcd_pixel_fmt = 0
    lcd_dbi_fmt = 3
    lcd_rgb_order = 0
    fb_buffer_num = 2
    lcd_backlight = 200
    lcd_fps = 60
    lcd_dbi_te = 1
    lcd_bl_en = port:PB04<1><0><1>
    lcd_gpio_0 = port:PB02<1><0><1>

橫豎屏旋轉(zhuǎn)

  1. 平臺(tái)沒有硬件旋轉(zhuǎn)功能,軟件旋轉(zhuǎn)太慢而且耗費(fèi)CPU。
  2. 不少spi屏支持內(nèi)部旋轉(zhuǎn),需要在屏驅(qū)動(dòng)初始化的時(shí)候進(jìn)行設(shè)置,一般是36h寄存器。
    // 轉(zhuǎn)成橫屏
    sunxi_lcd_cmd_write(sel, 0x36);
    sunxi_lcd_para_write(sel, 0xa0);
  3. lcd_fb0的配置中需要將lcd_x和lcd_y的值對(duì)調(diào),此時(shí)軟件將屏視為橫屏。
  4. 屏內(nèi)部旋轉(zhuǎn)出圖效果可能會(huì)變差,建議選屏的時(shí)候直接選好方向。

幀率控制

屏的刷新率受限于多方面:

  1. SPI/DBI硬件傳輸速度,也就是時(shí)鐘腳的頻率。設(shè)置lcd_data_speed可以設(shè)置硬件傳輸速度,最大不超過100MHz。如果屏能正常接收,這個(gè)值自然是越大越好。
  2. 屏driver IC接收能力。Driver IC手冊(cè)中會(huì)提到屏的能接受的最大sclk周期。
  3. 使用2 data lane還是1 data lane,理論上2 data lane的速度會(huì)翻倍。見典型2 data lane配置。
  4. 像素格式。像素格式?jīng)Q定需要傳輸?shù)臄?shù)據(jù)量,顏色數(shù)量越小的像素格式,幀率越高,但是效果越差。
  5. 帶te腳的屏一節(jié)中我們知道,te相關(guān)設(shè)置直接影響到屏刷新率。
  6. 如果不支持te,可以通過設(shè)置lcd_fps來控制幀率,你需要根據(jù)第一點(diǎn)和第二點(diǎn)選擇一個(gè)合適的值。

背光控制

  1. 硬件需要支持pwm背光電路。
  2. 驅(qū)動(dòng)支持pwm背光調(diào)節(jié),只需要配置好lcd_pwm開頭,lcd_backlight和lcd_bl_en等背光相關(guān)配置即可。

像素格式相關(guān)

  1. lcd_pixel_fmt,這個(gè)設(shè)置項(xiàng)用于設(shè)置fbdev的像素格式。
  2. lcd_dbi_fmt,這個(gè)用于設(shè)置DBI接口發(fā)送的像素格式。

SPI/DBI發(fā)送數(shù)據(jù)的時(shí)候沒有必要發(fā)送alpha通道,但是應(yīng)用層卻有對(duì)應(yīng)的alpha通道,比如ARGB8888格式。

這個(gè)時(shí)候硬件會(huì)自動(dòng)幫我們處理好alpha通道,所以lcd_pixel_fmt選擇有alpha通道的格式時(shí),lcd_dbi_fmt可以選rgb666或者rgb888,不用和它一樣。

電源配置

有多個(gè)電源的話,就用lcd_power1,lcd_power2......然后屏驅(qū)動(dòng)里面調(diào)用sunxi_lcd_power_enable接口即可。

GPIO配置說明

lcd_bl_en、lcd_spi_dc_pin以及lcd_gpio_x都是屬于GPIO屬性類型。

下面以lcd_spi_dc_pin為例,具體說明GPIO屬性的參數(shù)值含義:

lcd_spi_dc_pin   = port:PA19< 1 >< 0 >< 3 >< 1 >

引腳說明:port: 端口 < 復(fù)用功能 >< 上下拉 >< 驅(qū)動(dòng)能力 >< 輸出值 >

等式右邊的從左到右5個(gè)字段代表的具體含義如下:

  • PA19:端口,表示GPIO管腳。PA表示PA組管腳,19表示第19根管腳;即PA19管腳。
  • <1>:復(fù)用功能,表示GPIO復(fù)用類型。1表示將PA19選擇為通用GPIO功能,0為輸入,1為輸出。
  • <0>:上下拉,表示內(nèi)置電阻。使用0的話,表示內(nèi)部電阻高阻態(tài),如果是1則是內(nèi)部電阻上拉,2就代表內(nèi)部電阻下拉。其它數(shù)據(jù)無效。
  • <3>:表示驅(qū)動(dòng)能力。1是默認(rèn)等級(jí),數(shù)字越大驅(qū)動(dòng)能力越強(qiáng),最大是3。
  • <1>:表示默認(rèn)輸出電平值。0為低電平,1為高電平。

多個(gè)顯示

  1. 確定硬件有沒有多余的spi/dbi接口。
  2. 需要在sys_config.fex里面新增lcd_fb1,配置方式與lcd_fb0一樣(或者在顯示私有方式的板級(jí)配置文件里面新增g_lcd1_config,配置方式與g_lcd0_config一樣),其中lcd_spi_bus_num不能一樣。

依賴驅(qū)動(dòng)配置

spilcd模塊依賴spi,dbi,pwm等驅(qū)動(dòng)。

使用顯示私有方式進(jìn)行配置

路徑:rtos-hal/hal/source/spilcd/soc/

具體板級(jí)顯示配置文件可參考該路徑下的 kld2844b_config.c 配置文件。

該文件模仿 sys_config.fex來配置一些板級(jí)相關(guān)的資源,源文件中需要定義4個(gè)全局變量:g_lcd0_config、g_lcd1_config、g_lcd0_config_leng_lcd1_config_len,且變量名字固定,不能修改。

具體說明如下:

  1. g_lcd0_config:第一個(gè)屏的配置變量,struct property_t數(shù)據(jù)類型。
  2. g_lcd1_config:第二個(gè)屏的配置變量,struct property_t數(shù)據(jù)類型。
  3. g_lcd0_config_leng_lcd1_config_len是對(duì)應(yīng)上面兩個(gè)數(shù)組變量的長(zhǎng)度,照搬即可。

struct property_t數(shù)據(jù)類型,用于定義一個(gè)屬性的信息:

  1. 屬性名字。對(duì)應(yīng)其成員name,字符串。
  2. 屬性類型。對(duì)應(yīng)其成員type,看enum proerty_type的定義,共有整型,字符串,GPIO,專用pin和電源。
  3. 屬性值。根據(jù)上面的屬性類型來選擇union中成員來賦值。

對(duì)于上述常用的屬性類型舉例如下:

整型:

{
        .name = "lcd_used",
        .type = PROPERTY_INTGER,
        .v.value = 1,
    },

字符串:

{
        .name = "lcd_driver_name",
        .type = PROPERTY_STRING,
        .v.str = "kld2844b",
    },

GPIO:

{
        .name = "lcd_spi_dc_pin",
        .type = PROPERTY_GPIO,
        .v.gpio_list = {
            .gpio = GPIOA(19),
            .mul_sel = GPIO_DIRECTION_OUTPUT,
            .pull = 0,
            .drv_level = 3,
            .data = 1,
        },
    },

g_lcd0_config的含義與前述的使用sys_config.fex方式中的lcd_fb0一致。

編寫屏驅(qū)動(dòng)

屏驅(qū)動(dòng)源碼位置:

rtos-hal/hal/source/spilcd/lcd_fb/panels
  1. 在屏驅(qū)動(dòng)源碼位置下拷貝現(xiàn)有一個(gè)屏驅(qū)動(dòng),包括頭文件和源文件,然后將文件名改成有意義的名字,比如屏型號(hào)。
  2. 修改源文件中的strcut __lcd_panel變量的名字,以及這個(gè)變量成員name的名字,這個(gè)名字必須和 sys_config.fex[lcd_fb0](或板級(jí)配置文件中g_lcd0_config)的lcd_driver_name一致。
  3. 在屏驅(qū)動(dòng)目錄下修改panel.cpanel.h。在全局結(jié)構(gòu)體變量panel_array中新增剛才添加strcut __lcd_panel的變量指針。panel.h中新增strcut __lcd_panel的聲明。并用宏括起來。
  4. 修改rtos-hal/hal/source/spilcd/lcd_fb/panels/Kconfig,新增一個(gè)config,與第三點(diǎn)提到的宏對(duì)應(yīng)。
  5. 修改rtos-hal/hal/source/spilcd/lcd_fb/路徑下的Makefile文件。給lcd_fb-obj變量新增剛才加入的源文件對(duì)應(yīng).o
  6. 根據(jù)本手冊(cè)以及屏手冊(cè),Driver IC手冊(cè)修改sys_config.fex中的[lcd_fb0]節(jié)點(diǎn)(或顯示私有方式的板級(jí)配置文件中的g_lcd0_config配置變量)下面的屬性
  7. 實(shí)現(xiàn)屏源文件中的LCD_open_flow,LCD_close_flow,LCD_panel_init,LCD_power_on等函數(shù)

開關(guān)屏流程函數(shù)解析

開關(guān)屏的操作流程如下圖所示。

其中,LCD_open_flow和LCD_close_flow稱為開關(guān)屏流程函數(shù),該函數(shù)利用LCD_OPEN_FUNC進(jìn)行注冊(cè)回調(diào)函數(shù),先注冊(cè)先執(zhí)行,可以注冊(cè)多個(gè),不限制數(shù)量。

lcd_flow.png

LCD_open_flow

功能:初始化開屏的步驟流程。

原型:

static __s32 LCD_open_flow(__u32 sel)

函數(shù)常用內(nèi)容為:

static __s32 LCD_open_flow(__u32 sel)
{
    LCD_OPEN_FUNC(sel, LCD_power_on,10);
    LCD_OPEN_FUNC(sel, LCD_panel_init, 50);
    LCD_OPEN_FUNC(sel, lcd_fb_black_screen, 100); 
    LCD_OPEN_FUNC(sel, LCD_bl_open, 0);
    return 0;
}

如上,初始化整個(gè)開屏的流程步驟為四個(gè):

  1. 打開LCD電源,再延遲10ms。
  2. 初始化屏,再延遲50ms;(不需要初始化的屏,可省掉此步驟)。
  3. 向屏發(fā)送全黑的數(shù)據(jù)。這一步驟是必須的,而且需要在開背光之前。
  4. 打開背光,再延遲0ms。

LCD_open_flow 函數(shù)只會(huì)系統(tǒng)初始化的時(shí)候調(diào)用一次,執(zhí)行每個(gè) LCD_OPEN_FUNC 即是把對(duì)應(yīng)的開屏步驟函數(shù)進(jìn)行注冊(cè), 并沒有立即執(zhí)行該開屏步驟函數(shù) 。LCD_open_flow函數(shù)的內(nèi)容必須統(tǒng)一用 LCD_OPEN_FUNC(sel, function, delay_time) 進(jìn)行函數(shù)注冊(cè)的形式,確保正常注冊(cè)到開屏步驟中。

LCD_OPEN_FUNC的第二個(gè)參數(shù)是前后兩個(gè)步驟的延時(shí)長(zhǎng)度,單位ms,注意這里的數(shù)值請(qǐng)按照屏手冊(cè)規(guī)定去填,亂填可能導(dǎo)致屏初始化異?;蛘唛_關(guān)屏?xí)r間過長(zhǎng),影響用戶體驗(yàn)。

LCD_close_flow

功能:初始化關(guān)屏的步驟流程。

原型:

static __s32 LCD_close_flow(__u32 sel)

函數(shù)常用內(nèi)容為:

static __s32 LCD_close_flow(__u32 sel)
{
    LCD_CLOSE_FUNC(sel, LCD_bl_close, 50);
    LCD_CLOSE_FUNC(sel, LCD_panel_exit, 10);
    LCD_CLOSE_FUNC(sel, LCD_power_off, 10);
    return 0;
}
  1. LCD_bl_close,是關(guān)背光,關(guān)完背光在處理其它事情,不會(huì)影響用戶視覺。
  2. LCD_panel_exit,發(fā)送命令讓屏退出工作狀態(tài)。
  3. 關(guān)電復(fù)位,讓屏徹底關(guān)閉。

LCD_OPEN_FUNC

功能:注冊(cè)開屏步驟函數(shù)到開屏流程中,記住這里是注冊(cè)不是執(zhí)行!

原型:

void LCD_OPEN_FUNC(__u32 sel, LCD_FUNC func, __u32 delay)

參數(shù)說明:

func是一個(gè)函數(shù)指針,其類型是:void (*LCD_FUNC) (__u32 sel),用戶自己定義的函數(shù)必須也要用統(tǒng)一的形式。比如:

void user_defined_func(__u32 sel)
{
    //do something
}

delay是執(zhí)行該步驟后,再延遲的時(shí)間,時(shí)間單位是毫秒。

LCD_power_on

這是開屏流程中第一步,一般在這個(gè)函數(shù)使用sunxi_lcd_gpio_set_value進(jìn)行GPIO控制,用sunxi_lcd_power_enable函數(shù)進(jìn)行電源開關(guān)。

參考屏手冊(cè)里面的上電時(shí)序(Power on sequence)。

LCD_panel_init

這是開屏流程第二步,一般使用sunxi_lcd_cmd_write和sunxi_lcd_para_write對(duì)屏寄存器進(jìn)行初始化。

請(qǐng)向屏廠索要初始化寄存器代碼或者自行研究屏Driver IC手冊(cè)。

lcd_fb_black_screen

向屏傳輸全黑數(shù)據(jù)的接口,是必須的,否則打開背光后,呈現(xiàn)的將是雪花屏。

LCD_bl_open

這是背光使能,固定調(diào)用。

  1. sunxi_lcd_backlight_enable, 打開lcd_bl_en腳。
  2. sunxi_lcd_pwm_enable, 使能pwm。

LCD_bl_close

這是關(guān)閉背光。固定調(diào)用下面兩個(gè)函數(shù),分別是:

  1. sunxi_lcd_backlight_disable,lcd_bl_en關(guān)閉
  2. sunxi_lcd_pwm_disable, 關(guān)閉pwm。

LCD_power_off

這是關(guān)屏流程中最后一步,一般在這個(gè)函數(shù)使用sunxi_lcd_gpio_set_value進(jìn)行GPIO控制,用sunxi_lcd_power_enable函數(shù)進(jìn)行電源開關(guān)。

參考屏手冊(cè)里面的下電時(shí)序(Power off sequence)。

sunxi_lcd_delay_ms

函數(shù):sunxi_lcd_delay_ms/sunxi_lcd_delay_us

功能:延時(shí)函數(shù),分別是毫秒級(jí)別/微秒級(jí)別的延時(shí)。

原型:s32 sunxi_lcd_delay_ms(u32 ms); / s32 sunxi_lcd_delay_us(u32 us);

sunxi_lcd_backlight_enable

函數(shù):sunxi_lcd_backlight_enable/ sunxi_lcd_backlight_disable

功能:打開/關(guān)閉背光,操作的是lcd_bl_en。

原型:

  • void sunxi_lcd_backlight_enable(u32 screen_id);
  • void sunxi_lcd_backlight_disable(u32 screen_id);

sunxi_lcd_pwm_enable

函數(shù):sunxi_lcd_pwm_enable / sunxi_lcd_pwm_disable

功能:打開/關(guān)閉pwm控制器,打開時(shí)pwm將往外輸出pwm波形。對(duì)應(yīng)的是lcd_pwm_ch所對(duì)應(yīng)的那一路pwm。

原型:

  • s32 sunxi_lcd_pwm_enable(u32 screen_id);
  • s32 sunxi_lcd_pwm_disable(u32 screen_id);

sunxi_lcd_power_enable

函數(shù):sunxi_lcd_power_enable / sunxi_lcd_power_disable

功能:打開/關(guān)閉Lcd電源,操作的是板級(jí)配置文件中的lcd_power/lcd_power1/lcd_power2。(pwr_id標(biāo)識(shí)電源索引)。

原型:

  • void sunxi_lcd_power_enable(u32 screen_id, u32 pwr_id);
  • void sunxi_lcd_power_disable(u32 screen_id, u32 pwr_id);
  1. pwr_id = 0:對(duì)應(yīng)于配置文件中的lcd_power。
  2. pwr_id = 1:對(duì)應(yīng)于配置文件中的lcd_power1。
  3. pwr_id = 2:對(duì)應(yīng)于配置文件中的lcd_power2。
  4. pwr_id = 3:對(duì)應(yīng)于配置文件中的lcd_power3。

sunxi_lcd_cmd_write

函數(shù):sunxi_lcd_cmd_write

功能:使用spi/dbi發(fā)送命令。

原型:s32 sunxi_lcd_cmd_write(u32 screen_id, u8 cmd);

sunxi_lcd_para_write

函數(shù):sunxi_lcd_para_write

功能:使用spi/dbi發(fā)送參數(shù)。

原型:s32 sunxi_lcd_para_write(u32 screen_id, u8 para);

sunxi_lcd_gpio_set_value

函數(shù):sunxi_lcd_gpio_set_value

功能:LCD_GPIO PIN腳上輸出高電平或低電平。

原型:s32 sunxi_lcd_gpio_set_value(u32 screen_id, u32 io_index, u32 value);

參數(shù)說明:

  • io_index = 0:對(duì)應(yīng)于配置文件中的lcd_gpio_0。
  • io_index = 1:對(duì)應(yīng)于配置文件中的lcd_gpio_1。
  • io_index = 2:對(duì)應(yīng)于配置文件中的lcd_gpio_2。
  • io_index = 3:對(duì)應(yīng)于配置文件中的lcd_gpio_3。
  • value = 0:對(duì)應(yīng)IO輸出低電平。
  • Value = 1:對(duì)應(yīng)IO輸出高電平。

只用于該GPIO定義為輸出的情形。

sunxi_lcd_gpio_set_direction

函數(shù):sunxi_lcd_gpio_set_direction

功能:設(shè)置LCD_GPIO PIN腳為輸入或輸出模式。

原型:

s32 sunxi_lcd_gpio_set_direction(u32 screen_id, u32 io_index, u32 direction);

參數(shù)說明:

  • io_index = 0:對(duì)應(yīng)于配置文件中的lcd_gpio_0。
  • io_index = 1:對(duì)應(yīng)于配置文件中的lcd_gpio_1。
  • io_index = 2:對(duì)應(yīng)于配置文件中的lcd_gpio_2。
  • io_index = 3:對(duì)應(yīng)于配置文件中的lcd_gpio_3。
  • direction = 0:對(duì)應(yīng)IO設(shè)置為輸入。
  • direction = 1:對(duì)應(yīng)IO設(shè)置為輸出。

模塊測(cè)試用例

#include < stdio.h >
#include < stdlib.h >
#include < stdint.h >
#include < string.h >
#include < unistd.h >

#include < hal_cache.h >
#include < hal_mem.h >
#include < hal_log.h >
#include < hal_cmd.h >
#include < hal_lcd_fb.h >

static uint32_t width;
static uint32_t height;
static long int screensize = 0;
static char *fbsmem_start = 0;

static void lcdfb_fb_init(uint32_t yoffset, struct fb_info *p_info)
{
    p_info- >screen_base = fbsmem_start;
    p_info- >var.xres = width;
    p_info- >var.yres = height;
    p_info- >var.xoffset = 0;
    p_info- >var.yoffset = yoffset;
}

int show_rgb(unsigned int sel)
{
    int i = 0, ret = -1;
    struct fb_info fb_info;
    int bpp = 4;
    unsigned char color[4] = {0xff,0x0,0xff,0x0};

    width = bsp_disp_get_screen_width(sel);
    height = bsp_disp_get_screen_height(sel);

    screensize = width * bpp * height;
    fbsmem_start = hal_malloc_coherent(screensize);

    hal_log_info("width = %d, height = %d, screensize = %d, fbsmem_start = %xn",
            width, height, screensize, fbsmem_start);

    memset(fbsmem_start, 0, screensize);
    for (i = 0; i < screensize / bpp; ++i) {
        memcpy(fbsmem_start+i*bpp, color, bpp);
    }

    memset(&fb_info, 0, sizeof(struct fb_info));
    lcdfb_fb_init(0, &fb_info);
    hal_dcache_clean((unsigned long)fbsmem_start, screensize);
    bsp_disp_lcd_set_layer(sel, &fb_info);

    hal_free_coherent(fbsmem_start);
    return ret;
}

static int cmd_test_spilcd(int argc, char **argv)
{
    uint8_t ret;

    hal_log_info("Run spilcd hal layer test casen");

    ret = show_rgb(0);

    hal_log_info("spilcd test finishn");

    return ret;
}

FINSH_FUNCTION_EXPORT_CMD(cmd_test_spilcd, test_spilcd, spilcd hal APIs tests)

測(cè)試命令:

test_spilcd

測(cè)試結(jié)果:

1.如果LCD是ARGB8888像素格式輸入,執(zhí)行命令后會(huì)顯示一幀紫色畫面。
2.如果LCD是RGB565像素格式輸入,執(zhí)行命令后會(huì)顯示一幀藍(lán)色畫面(SPI 協(xié)議是黃色畫面(沒有RB Swap))

FAQ

怎么判斷屏初始化成功

屏初始化成功,一般呈現(xiàn)的現(xiàn)象是雪花屏。因?yàn)槠硫?qū)動(dòng)里面,在 LCD_open_flow 中添加了lcd_fb_black_screen的注冊(cè),故正常情況下開機(jī)是有背光的黑屏畫面。

黑屏-無背光

一般是電源或者pwm相關(guān)配置沒有配置好。參考lcd_pwm開頭的相關(guān)配置。

送圖無顯示

排除步驟:

  1. 首先執(zhí)行spilcd模塊測(cè)試命令test_spilcd,如果能正常顯示顏色畫面,說明顯示通路正常,只是應(yīng)用未能正確配置送圖接口。如果執(zhí)行測(cè)試用例無法正常顯示顏色畫面,接著下面步驟。
  2. 屏驅(qū)動(dòng)里面,在LCD_open_flow中刪除lcd_fb_black_screen的注冊(cè),啟動(dòng)后,如果屏初始化成功應(yīng)該是花屏狀態(tài)(大部分屏如此)。
  3. 如果屏沒有初始化成功,請(qǐng)檢查屏電源,復(fù)位腳狀態(tài)。
  4. 如果屏初始化成功,但是發(fā)數(shù)據(jù)時(shí)又沒法顯示,那么需要檢查是不是幀率過快,查看幀率控制
  5. 如果電源復(fù)位腳正常,請(qǐng)檢查配置,lcd_dbi_if, lcd_dbi_fmt是否正確,屏是否支持, 如果支持,在屏驅(qū)動(dòng)里面是否有對(duì)應(yīng)上。
  6. 嘗試修改lcd_dbi_clk_mode。

閃屏

非常有可能是速度跑太快,參考幀率控制一小節(jié)。

畫面偏移

畫面隨著數(shù)據(jù)的發(fā)送偏移越來越大。

嘗試修改lcd_dbi_clk_mode

屏幕白屏

屏幕白屏,但是背光亮起

image-20231017113731873 (1).png

白屏是因?yàn)槠聊粵]有初始化,需要檢查屏幕初始化序列或者初始化數(shù)據(jù)是否正確。

屏幕花屏

屏幕花屏,無法控制

image-20231017113841569 (1).png

花屏一般是因?yàn)槠聊怀跏蓟鬀]有正確設(shè)置 addrwin,或者初始化序列錯(cuò)誤。

LVGL 屏幕顏色不正確

出現(xiàn)反色,顏色異常

image-20231017113620580 (1).png

請(qǐng)配置 LVGL LV_COLOR_DEPTH 參數(shù)為 16,LV_COLOR_16_SWAP 為 1,這是由 SPI LCD 的特性決定的。

image-20231017113520621 (1).png

顯示反色

運(yùn)行 test_spilcd ,屏幕顯示藍(lán)色。

這是由于屏幕啟動(dòng)了 RB SWAP,一般是 0x36 寄存器修改

正常顯示

sunxi_lcd_cmd_write(sel, 0X36);
sunxi_lcd_para_write(sel, 0x00);

反色顯示

sunxi_lcd_cmd_write(sel, 0X36);
sunxi_lcd_para_write(sel, 0x08);

LVGL 出現(xiàn) DMA OVER SIZE

image-20231023101154351.png

這是由于 LVGL 配置的 LV_COLOR_DEPTH 為 32,但是 SPI 屏配置為16位。請(qǐng)修改 lv_conf.h

image-20231023101317634.png

出現(xiàn)部分花屏

image-20231023103039467.png

  • 檢查 address 函數(shù)是否正確
  • 檢查 sys_config.fex 屏幕配置分辨率是否正確

總結(jié)

調(diào)試LCD顯示屏實(shí)際上就是調(diào)試發(fā)送端芯片(全志SOC)和接收端芯片(LCD屏上的driver IC)的一個(gè)過程:

  1. 添加屏驅(qū)動(dòng)請(qǐng)看編寫屏驅(qū)動(dòng)
  2. 仔細(xì)閱讀屏手冊(cè)以及driver IC手冊(cè)(有的話)。
  3. 仔細(xì)閱讀板級(jí)顯示配置參數(shù)詳解。
  4. 確保LCD所需要的各路電源管腳正常。

SPI LCD 顏色相關(guān)問題

首先,得先確定顯示屏使用的是SPI接口,還是DBI接口,不同的接口,輸入數(shù)據(jù)的解析方式是不一樣的。

DBI接口的全稱是 Display Bus Serial Interface ,在顯示屏數(shù)據(jù)手冊(cè)中,一般會(huì)說這是SPI接口,所以有人會(huì)誤認(rèn)為SPI屏可以使用 normal spi 去直接驅(qū)動(dòng)。

閱讀lcd_dbi_if部分的介紹可以知道,在3線模式時(shí),發(fā)送命令前有1位A0用于指示當(dāng)前發(fā)送的是數(shù)據(jù),還是命令。而命令后面接著的數(shù)據(jù)就沒有這個(gè)A0位了,代表SPI需要在9位和8位之間來回切換,而在讀數(shù)據(jù)時(shí),更是需要延時(shí) dummy clock 才能讀數(shù)據(jù),normal spi 都很難,甚至無法實(shí)現(xiàn)。所以 normal spi 只能模擬4 線的DBI的寫操作。

對(duì)于R128這類支持DBI接口的CPU,可以選擇不去了解SPI。如果需要用到SPI去驅(qū)動(dòng)顯示屏,必須把顯示屏設(shè)置成小端。

RGB565和RGB666

SPI顯示屏一般支持RGB444,RGB565和RGB666,RGB444使用的比較少,所以只討論RGB565和RGB666.

RGB565代表一個(gè)點(diǎn)的顏色由2字節(jié)組成,也就是R(紅色)用5位表示,G(綠色)用6位表示,B(藍(lán)色)用5位表示,如下圖所示:

image-20231016100553340.png
RGB666一個(gè)點(diǎn)的顏色由3字節(jié)組成,每個(gè)字節(jié)代表一個(gè)顏色,其中每個(gè)字節(jié)的低2位會(huì)無視,如下圖所示:

image-20231016100620890.png

SPI 接口

因?yàn)镾PI接口的通訊效率不高,所以建議使用RGB565的顯示,以 jlt35031c 顯示屏為例,他的顯示驅(qū)動(dòng)芯片ST7789,設(shè)置顯示格式的方式是往 3a 寄存器寫入0x55(RGB565)或者 0x66(RGB666),在 R128SDK 中,已經(jīng)把 jlt35031c 的通訊格式寫死為 0x55,lcd_pixel_fmt配置選項(xiàng)無效:

sunxi_lcd_cmd_write(sel, 0x3a);
sunxi_lcd_para_write(sel, 0x55);

在例程中,輸入的數(shù)據(jù)是 0xff,0x00,0xff,0x00,對(duì)于SPI接口,是按字節(jié)發(fā)送。實(shí)際上,例程只需要每次發(fā)送2字節(jié)即可,因?yàn)榍昂蟀l(fā)送的都是相同的ff 00,所以沒有看出問題。

根據(jù)對(duì) 565 的數(shù)據(jù)解析,我們拆分 ff 00 就可以得到紅色分量是 0b11111,也就是 31,綠色是0b111000,也就是 56,,藍(lán)色是 0.我們等效轉(zhuǎn)換成 RGB888,有:

R = 31/31*255 = 255
G = 56/63*255 = 226

在調(diào)色板輸入對(duì)應(yīng)顏色,就可以得到黃色

image-20231016100913213.png

DBI 接口

因?yàn)?DBI 通訊效率較高,所以可以使用 RGB565 或者 RGB666,使用 DBI 接口,也就是 lcd_if 設(shè)置為1時(shí),驅(qū)動(dòng)會(huì)根據(jù) lcd_pixel_fmt 配置寄存器,以 SDK 中的 kld2844b.c 為例,這顯示屏的顯示驅(qū)動(dòng)也是 ST7789,但是不同的屏幕,廠家封裝時(shí)已經(jīng)限制了通訊方式,所以即使是能使用 DBI 接口的驅(qū)動(dòng)芯片的屏幕,或許也用不了DBI。

sunxi_lcd_cmd_write(sel, 0x3A); /* Interface Pixel Format */
/* 55----RGB565;66---RGB666 */
if (info[sel].lcd_pixel_fmt == LCDFB_FORMAT_RGB_565 ||
    info[sel].lcd_pixel_fmt == LCDFB_FORMAT_BGR_565) {
    sunxi_lcd_para_write(sel, 0x55);
    if (info[sel].lcd_pixel_fmt == LCDFB_FORMAT_RGB_565)
        rotate &= 0xf7;
    else
        rotate |= 0x08;
} else if (info[sel].lcd_pixel_fmt < LCDFB_FORMAT_RGB_888) {
    sunxi_lcd_para_write(sel, 0x66);
    if (info[sel].lcd_pixel_fmt == LCDFB_FORMAT_BGRA_8888 ||
        info[sel].lcd_pixel_fmt == LCDFB_FORMAT_BGRX_8888 ||
        info[sel].lcd_pixel_fmt == LCDFB_FORMAT_ABGR_8888 ||
        info[sel].lcd_pixel_fmt == LCDFB_FORMAT_XBGR_8888) {
        rotate |= 0x08;
    }
} else {
    sunxi_lcd_para_write(sel, 0x66);
}

對(duì)于 DBI 格式,不再是以字節(jié)的形式去解析,而是以字的方式去解析,為了統(tǒng)一,軟件已經(jīng)規(guī)定了,RGB565 格式時(shí),字大小是2字節(jié),也就是16位,而 RGB666 格式時(shí),字大小是4字節(jié),也就是32位。

對(duì)于 RGB565 格式,同樣是設(shè)置為 0xff,0x00。因?yàn)槠聊皇谴蠖耍酒鎯?chǔ)方式是小端,所以芯片的 DBI 模塊,會(huì)自動(dòng)把數(shù)據(jù)從新排列,也就是實(shí)際上 DBI 發(fā)送數(shù)據(jù)時(shí),會(huì)先發(fā)送0x00,再發(fā)送0xff,也就是紅色分量為0,綠色分量為 0b000111,也就是7,藍(lán)色分量是 0x11111,也就是31,我們同樣轉(zhuǎn)換成RGB888

G = 7/63*255 = 28
B= 31/31*255 = 255

在調(diào)色板上輸入,可以得到藍(lán)色。

image-20231016101233907.png

如果是 RGB666,雖然占用的是3個(gè)字節(jié),但是沒有CPU是3字節(jié)對(duì)齊的,所以需要一次性輸入4字節(jié),然后 DBI 硬件模塊,會(huì)自動(dòng)舍棄1個(gè)字節(jié),軟件同意舍棄了最后一個(gè)字節(jié)。

依舊以例程為例,例程輸入了 0xff,0x00,0xff,0x00,為了方便說明,標(biāo)準(zhǔn)為 0xff(1),0x00(1),0xff(2),0x00(2),其中 0x00(2)會(huì)被舍棄掉,然后發(fā)送順序是0xff(2),0x00(1),0xff(1),也就是 0xff(2) 是紅色分量,0xff(1) 是藍(lán)色分量,混合可以得到紫色。

image-20231016101308346.png

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120363
  • 觸發(fā)器

    關(guān)注

    14

    文章

    2000

    瀏覽量

    61155
  • SPI接口
    +關(guān)注

    關(guān)注

    0

    文章

    258

    瀏覽量

    34382
  • LCD顯示
    +關(guān)注

    關(guān)注

    0

    文章

    132

    瀏覽量

    18364
  • 顯示驅(qū)動(dòng)
    +關(guān)注

    關(guān)注

    1

    文章

    66

    瀏覽量

    14991
  • R128
    +關(guān)注

    關(guān)注

    0

    文章

    41

    瀏覽量

    105
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    R128應(yīng)用開發(fā)案例—適配SPI驅(qū)動(dòng)ST7789V2.4寸LCD

    R128 平臺(tái)提供了 SPI DBI 的 SPI TFT 接口,具有如下特點(diǎn)
    的頭像 發(fā)表于 11-02 16:44 ?1011次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>應(yīng)用<b class='flag-5'>開發(fā)</b>案例—適配<b class='flag-5'>SPI</b><b class='flag-5'>驅(qū)動(dòng)</b>ST7789V2.4寸<b class='flag-5'>LCD</b>

    R128內(nèi)存泄漏調(diào)試案例分享

    硬件:R128 軟件:FreeRTOS + rtplayer\_test(Cedarx)+ AudioSystem
    的頭像 發(fā)表于 11-20 17:27 ?1028次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>內(nèi)存泄漏調(diào)試案例分享

    縱享絲滑!R128+LVGL驅(qū)動(dòng)多尺寸RGB LCD屏幕流暢運(yùn)行

    新晉點(diǎn)屏神器,R128!各種屏幕都能點(diǎn)!高刷、大屏、寬色域......通常來講,顯示器的配置越高,越能給使用者帶來優(yōu)于其它一般配置顯示器的體驗(yàn)。但就某些特殊的使用場(chǎng)景來講,選擇配置合適的顯示
    發(fā)表于 12-22 09:52

    R128硬件設(shè)計(jì)指南

    。添加按鍵時(shí)保證按鍵按下后,ADC網(wǎng)絡(luò)電壓范圍為 0~1.08V,最小間隔大于 200mV。 LCD電路接口R128 支持一路 RGB屏接口和一路 SPI屏接口。其中 RGB屏接口可支持并行
    發(fā)表于 01-04 09:23

    R128 SDK架構(gòu)與目錄結(jié)構(gòu)

    HSPSRAM 以及 16M NORFLASH。本文檔作為 R128 FreeRTOS SDK 開發(fā)指南,旨在幫助軟件開發(fā)工程師、技術(shù)支持工程師快速上手,熟悉 R128 FreeRT
    發(fā)表于 01-05 10:05

    R128 Devkit開發(fā)板原理圖模塊介紹及使用說明

    :CH341SER.EXE 購買鏈接 百問科技淘寶店 - R128 DevKit 原理圖模塊介紹R128 模組R128 模組使用 SMT
    發(fā)表于 01-17 09:45

    R128基礎(chǔ)組件開發(fā)——顯示與屏幕驅(qū)動(dòng)

    RTOS 提供了一套完整的屏幕驅(qū)動(dòng),支持 RGB, i8080, SPI, DBI 格式的屏幕。 (1)RGB 接口 RGB接口在平臺(tái)又稱HV接口(Horizontal同步和Ver
    發(fā)表于 01-31 14:20

    R128基礎(chǔ)組件開發(fā)——顯示與屏幕驅(qū)動(dòng)

    )可以自己輸出內(nèi)置的一些 patten,比如說彩條,灰階圖,棋盤圖等。當(dāng)接口輸出這些內(nèi)置 patten 的時(shí)候,如果這時(shí)候顯示就異常,這說明了: LCD驅(qū)動(dòng)或者配置有問題 LCD
    發(fā)表于 01-31 14:25

    使用R128將LVGL運(yùn)行在SPI TFT GUI上

    載入方案選擇 r128s2_module_c906 $ source envsetup.sh $ lunch_rtos 1 配置 SPI LCD 驅(qū)動(dòng)
    發(fā)表于 10-23 13:56

    R128應(yīng)用開發(fā)案例——SPI 驅(qū)動(dòng) TFT LCD

    SPI 驅(qū)動(dòng) TFT LCDR128 平臺(tái)提供了 SPI DBI 的 SPI TFT 接口
    發(fā)表于 10-23 14:29

    R128基礎(chǔ)組件開發(fā)指南——SPI LCD 顯示驅(qū)動(dòng)

    SPI LCD 顯示驅(qū)動(dòng) 簡(jiǎn)介 R128 平臺(tái)提供了 SPI DBI 的
    發(fā)表于 10-25 14:36

    R128應(yīng)用開發(fā)案例——SPI驅(qū)動(dòng)ST7789V1.3寸LCD

    SPI驅(qū)動(dòng)ST7789V1.3寸LCD R128 平臺(tái)提供了 SPI DBI 的 SPI TFT
    發(fā)表于 11-06 10:16

    A64開發(fā)LCD開發(fā)指南

    A64開發(fā)LCD開發(fā)指南,驅(qū)動(dòng)開發(fā)指南
    發(fā)表于 06-21 17:02 ?0次下載

    R128適配ST7789v LCD

    R128 平臺(tái)提供了 SPI DBI 的 SPI TFT 接口,具有如下特點(diǎn)
    的頭像 發(fā)表于 10-23 11:26 ?989次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>適配ST7789v <b class='flag-5'>LCD</b>

    DshanMCU-R128s2 R128 EVT 開發(fā)套件

    針對(duì) R128 模組,百問科技推出了 R128 EVT 開發(fā)套件作為快速開發(fā)評(píng)估工具。
    的頭像 發(fā)表于 12-22 15:16 ?783次閱讀
    DshanMCU-<b class='flag-5'>R128</b>s2 <b class='flag-5'>R128</b> EVT <b class='flag-5'>開發(fā)</b>套件