在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

全志R128基礎組件開發指南—SPI LCD顯示驅動

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

SPI LCD 顯示驅動

簡介

R128 平臺提供了 SPI DBI 的 SPI TFT 接口,具有如下特點:

  • 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

同時,提供了SPILCD驅動框架以供 SPI 屏幕使用。

模塊驅動

MENUCONFIG配置說明

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

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

另外可能需依賴的配置項有:

  • DRIVERS_SPI
  • DRIVERS_DBI
  • DRIVERS_PWM

源碼結構介紹

源碼結構及主要驅動文件如下:

spilcd/
├── lcd_fb/
│   ├── dev_lcd_fb.c                # spilcd driver 層
│   ├── disp_display.c
│   ├── disp_lcd.c
│   ├── lcd_fb_intf.c
│   └── panels/                        # lcd驅動相關
│       ├── kld2844b.c
│       ├── lcd_source.c
│       ├── panels.c
│       └── panels.h
└── soc/
    ├── disp_board_config.c            # 板級配置解析
    └── kld2844b_config.c            # 顯示私有方式的板級配置文件

模塊參數配置

當前板級顯示支持兩種配置方法,一是使用 sys_config.fex 的方式進行配置,二是在不支持sys_config.fex 情況下,可以通過顯示驅動私有的方式進行配置。下面分別對兩種方式進行說明。

使用 SYS_CONFIG.FEX 的方式進行配置

FreeRTOS系統路徑:board/芯片名/方案名/configs/sys_config.fex

配置文件具體要看芯片方案所實際使用的,也可能使用的配置文件名稱為sys_config_xxx.fex(xx是存儲方案的標識,例如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"    ; 屏幕驅動:jlt35031c
lcd_x               = 320            ; 屏幕寬分辨率
lcd_y               = 480            ; 屏幕高分辨率
lcd_width           = 49             ; 屏幕物理寬度
lcd_height          = 74             ; 屏幕物理高度
lcd_data_speed      = 60             ; SPI 驅動頻率 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 > ; 復位腳

lcd_driver_name

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

lcd_model_name

Lcd屏模型名字,非必須,可以用于同個屏驅動中進一步區分不同屏。

lcd_if

Lcd Interface

設置相應值的對應含義為:

0:spi接口
1:dbi接口

spi接口就是俗稱的4線模式,這是因為發送數據時需要額外借助DC線來區分命令和數據,與sclkcssda共四線。

spi-16932054745452.png

如果設置了dbi接口,那么還需要進一步區分dbi接口,需要設置 lcd_dbi_if

lcd_dbi_if

Lcd dbi 接口設置。

這個參數只有在lcd_if=1時才有效。

設置相應值的對應含義為:

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

所有模式在發送數據時每個周期的比特數量根據不同像素格式不同而不同。

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

L3I1-16932054745453.png

L3I_RD-16932054745464.png

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

spi-16932054745452 (1).png

spi_read-16932054745465.png

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

D2LI-16932054745466.png

lcd_dbi_fmt

DBI接口像素格式。

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

選擇的依據是接收端屏Driver IC的支持情況,請查看Driver IC手冊或詢問屏廠。

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

lcd_dbi_te

使能te觸發。

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

0: 禁止te
1: 下降沿觸發
2: 上升沿觸發

查看帶te腳的屏進一步說明。

lcd_dbi_clk_mode

選擇dbi時鐘的行為模式。

0:自動停止。有數據就有時鐘,沒發數據就沒有
1:一直保持。無論發不發數據都有時鐘

注意上面的選項關系屏兼容性。

lcd_rgb_order

輸入圖像數據rgb順序識別設置,僅當lcd_if=1時有效。

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即可。

針對rgb565格式說明如下:

rgb565格式會遇到大小端問題,arm平臺和PC平臺存儲都是小端(little endian,低字節放在低地址,高字節放在高地址),但是許多spi屏都是默認大端(Big Endian)。

也就是存儲的字節順序和發送的字節順序不對應。

這個時候選擇6以下,DBI接口就會自動將小端轉成大端。

如果遇到默認是小端的spi屏,則需要選擇6以上,DBI接口會自動用回小端方式。

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,對應上面的9,小端。

lcd_x

顯示屏的水平像素數量,注意如果屏支持橫豎旋轉,那么lcd_x和lcd_y也要對調。

lcd_y

顯示屏的行數,注意如果屏支持橫豎旋轉,那么lcd_x和lcd_y也要對調。

lcd_data_speed

用于設置spi/dbi接口時鐘的速率,單位MHz。

  1. 發送端(SOC)的最大限制是100MHz。
  2. 接收端(屏Driver IC)的限制,請查看對應Driver IC手冊或者詢問屏廠支持。
  3. 超出以上限制都有可能導致顯示異常。

lcd_fps

設置屏的刷新率,單位Hz。當lcd_dbi_te使能時,這個值設置無效。

lcd_pwm_used

是否使用pwm。

此參數標識是否使用pwm用以背光亮度的控制。

lcd_pwm_ch

Pwm channel used

此參數標識使用的Pwm通道。

lcd_pwm_freq

Lcd backlight PWM Frequency

這個參數配置PWM信號的頻率,單位為Hz。

lcd_pwm_pol

Lcd backlight PWM Polarity

這個參數配置PWM信號的占空比的極性。設置相應值對應含義為:

0:active high
1:active low

lcd_pwm_max_limit

Lcd backlight PWM

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

比如150,則表示背光最高只能調到150,0~255范圍內的亮度值將會被線性映射到0~150范圍內。用于控制最高背光亮度,節省功耗。

lcd_backlight

默認背光值,取值范圍0到255,值越大越亮。

lcd_bl_en

背光使能腳定義

lcd_spi_dc_pin

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

lcd_gpio_x

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

lcd_spi_bus_num

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

取值范圍:0到1。

lcd_pixel_fmt

選擇傳輸數據的像素格式。

可選值如下,當你更換RGB分量順序的時候,也得相應修改lcd_rgb_order,或者修改屏驅動的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數量,為了平滑顯示,這里一般是2個,為了省內存也可以改成1。

模塊 SYS_CONFIG.FEX 配置案例

典型2 data lane配置

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

[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. 硬件連接上,第二根數據腳連接到原來1 data lane的DC腳,可以這樣理解:2數據線在傳輸數據時就自帶D/C(Data/Commend)信息了,所以原來的DC腳就可以空出來作為第二根數據線了。
  2. 屏驅動上,需要使能2 data lane模式,具體寄存器查看對應driverIC手冊或者詢問屏廠。
  3. 這里的針對對2 data lane的關鍵參數是lcd_if,lcd_dbi_if,lcd_dbi_fmt和lcd_spi_bus_num。
  4. lcd_x和lcd_y是屏分辨率。如果屏支持旋轉(橫豎旋轉),這里也需要對調。
  5. lcd_pwm開頭,lcd_backlight和lcd_bl_en)的是背光相關設置,如果有相關硬件連接的話。
  6. lcd_pixel_fmt和fb_buffer_num是顯示framebuffer的設置。
  7. lcd_gpio_開頭的是自定義gpio的設置(比如復位腳)。
  8. lcd_fps和lcd_dbi_te是刷新方式相關的設置。

原SPI接口屏配置

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

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

  1. 不支持2 data lane。
  2. 必須指定DC腳。這是由于spi協議不會自動控制DC腳來區分數據命令,通過設置lcd_spi_dc_pin可以完成這個目的,這跟管腳不必用spi里面的腳。
  3. 只支持rgb565的像素格式。由于只有單data lane,速度過慢,rgb565以上格式都不現實。
    [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),也就是撕裂的意思,是由于讀寫不同步導致撕裂現象,te腳的功能就是用于同步讀寫,te腳的頻率也就是屏的刷新率,所以te腳也可以看做vsync腳(垂直同步腳)。

  1. 硬件設計階段,需要將屏的te腳連接到IC的DBI接口的te腳。
  2. 配置上接口使用dbi接口。
  3. 然后使能lcd_dbi_te。
  4. 屏驅動使能te功能,寄存器一般是35h,詳情看屏對應的driver IC手冊。
  5. 屏驅動設置幀率,根據屏能接受的傳輸速度選擇合理的幀率(比如ST7789H2里面是通過c6h來設置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>

橫豎屏旋轉

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

幀率控制

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

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

背光控制

  1. 硬件需要支持pwm背光電路。
  2. 驅動支持pwm背光調節,只需要配置好lcd_pwm開頭,lcd_backlight和lcd_bl_en等背光相關配置即可。

像素格式相關

  1. lcd_pixel_fmt,這個設置項用于設置fbdev的像素格式。
  2. lcd_dbi_fmt,這個用于設置DBI接口發送的像素格式。

SPI/DBI發送數據的時候沒有必要發送alpha通道,但是應用層卻有對應的alpha通道,比如ARGB8888格式。

這個時候硬件會自動幫我們處理好alpha通道,所以lcd_pixel_fmt選擇有alpha通道的格式時,lcd_dbi_fmt可以選rgb666或者rgb888,不用和它一樣。

電源配置

有多個電源的話,就用lcd_power1,lcd_power2......然后屏驅動里面調用sunxi_lcd_power_enable接口即可。

GPIO配置說明

lcd_bl_enlcd_spi_dc_pin以及lcd_gpio_x都是屬于GPIO屬性類型。

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

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

引腳說明:port: 端口 < 復用功能 >< 上下拉 >< 驅動能力 >< 輸出值 >

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

  • PA19:端口,表示GPIO管腳。PA表示PA組管腳,19表示第19根管腳;即PA19管腳。
  • <1>:復用功能,表示GPIO復用類型。1表示將PA19選擇為通用GPIO功能,0為輸入,1為輸出。
  • <0>:上下拉,表示內置電阻。使用0的話,表示內部電阻高阻態,如果是1則是內部電阻上拉,2就代表內部電阻下拉。其它數據無效。
  • <3>:表示驅動能力。1是默認等級,數字越大驅動能力越強,最大是3。
  • <1>:表示默認輸出電平值。0為低電平,1為高電平。

多個顯示

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

依賴驅動配置

spilcd模塊依賴spi,dbi,pwm等驅動。

使用顯示私有方式進行配置

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

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

該文件模仿 sys_config.fex來配置一些板級相關的資源,源文件中需要定義4個全局變量:g_lcd0_configg_lcd1_configg_lcd0_config_leng_lcd1_config_len,且變量名字固定,不能修改。

具體說明如下:

  1. g_lcd0_config:第一個屏的配置變量,struct property_t數據類型。
  2. g_lcd1_config:第二個屏的配置變量,struct property_t數據類型。
  3. g_lcd0_config_leng_lcd1_config_len是對應上面兩個數組變量的長度,照搬即可。

struct property_t數據類型,用于定義一個屬性的信息:

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

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

整型:

{
        .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一致。

編寫屏驅動

屏驅動源碼位置:

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

開關屏流程函數解析

開關屏的操作流程如下圖所示。

其中,LCD_open_flow和LCD_close_flow稱為開關屏流程函數,該函數利用LCD_OPEN_FUNC進行注冊回調函數,先注冊先執行,可以注冊多個,不限制數量。

lcd_flow.png

LCD_open_flow

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

原型:

static __s32 LCD_open_flow(__u32 sel)

函數常用內容為:

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;
}

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

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

LCD_open_flow 函數只會系統初始化的時候調用一次,執行每個 LCD_OPEN_FUNC 即是把對應的開屏步驟函數進行注冊, 并沒有立即執行該開屏步驟函數 。LCD_open_flow函數的內容必須統一用 LCD_OPEN_FUNC(sel, function, delay_time) 進行函數注冊的形式,確保正常注冊到開屏步驟中。

LCD_OPEN_FUNC的第二個參數是前后兩個步驟的延時長度,單位ms,注意這里的數值請按照屏手冊規定去填,亂填可能導致屏初始化異常或者開關屏時間過長,影響用戶體驗。

LCD_close_flow

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

原型:

static __s32 LCD_close_flow(__u32 sel)

函數常用內容為:

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,是關背光,關完背光在處理其它事情,不會影響用戶視覺。
  2. LCD_panel_exit,發送命令讓屏退出工作狀態。
  3. 關電復位,讓屏徹底關閉。

LCD_OPEN_FUNC

功能:注冊開屏步驟函數到開屏流程中,記住這里是注冊不是執行!

原型:

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

參數說明:

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

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

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

LCD_power_on

這是開屏流程中第一步,一般在這個函數使用sunxi_lcd_gpio_set_value進行GPIO控制,用sunxi_lcd_power_enable函數進行電源開關

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

LCD_panel_init

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

請向屏廠索要初始化寄存器代碼或者自行研究屏Driver IC手冊。

lcd_fb_black_screen

向屏傳輸全黑數據的接口,是必須的,否則打開背光后,呈現的將是雪花屏。

LCD_bl_open

這是背光使能,固定調用。

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

LCD_bl_close

這是關閉背光。固定調用下面兩個函數,分別是:

  1. sunxi_lcd_backlight_disable,lcd_bl_en關閉
  2. sunxi_lcd_pwm_disable, 關閉pwm。

LCD_power_off

這是關屏流程中最后一步,一般在這個函數使用sunxi_lcd_gpio_set_value進行GPIO控制,用sunxi_lcd_power_enable函數進行電源開關。

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

sunxi_lcd_delay_ms

函數:sunxi_lcd_delay_ms/sunxi_lcd_delay_us

功能:延時函數,分別是毫秒級別/微秒級別的延時。

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

sunxi_lcd_backlight_enable

函數:sunxi_lcd_backlight_enable/ sunxi_lcd_backlight_disable

功能:打開/關閉背光,操作的是lcd_bl_en

原型:

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

sunxi_lcd_pwm_enable

函數:sunxi_lcd_pwm_enable / sunxi_lcd_pwm_disable

功能:打開/關閉pwm控制器,打開時pwm將往外輸出pwm波形。對應的是lcd_pwm_ch所對應的那一路pwm。

原型:

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

sunxi_lcd_power_enable

函數:sunxi_lcd_power_enable / sunxi_lcd_power_disable

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

原型:

  • 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:對應于配置文件中的lcd_power。
  2. pwr_id = 1:對應于配置文件中的lcd_power1。
  3. pwr_id = 2:對應于配置文件中的lcd_power2。
  4. pwr_id = 3:對應于配置文件中的lcd_power3。

sunxi_lcd_cmd_write

函數:sunxi_lcd_cmd_write

功能:使用spi/dbi發送命令。

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

sunxi_lcd_para_write

函數:sunxi_lcd_para_write

功能:使用spi/dbi發送參數。

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

sunxi_lcd_gpio_set_value

函數:sunxi_lcd_gpio_set_value

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

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

參數說明:

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

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

sunxi_lcd_gpio_set_direction

函數:sunxi_lcd_gpio_set_direction

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

原型:

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

參數說明:

  • io_index = 0:對應于配置文件中的lcd_gpio_0。
  • io_index = 1:對應于配置文件中的lcd_gpio_1。
  • io_index = 2:對應于配置文件中的lcd_gpio_2。
  • io_index = 3:對應于配置文件中的lcd_gpio_3。
  • direction = 0:對應IO設置為輸入。
  • direction = 1:對應IO設置為輸出。

模塊測試用例

#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)

測試命令:

test_spilcd

測試結果:

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

FAQ

怎么判斷屏初始化成功

屏初始化成功,一般呈現的現象是雪花屏。因為屏驅動里面,在 LCD_open_flow 中添加了lcd_fb_black_screen的注冊,故正常情況下開機是有背光的黑屏畫面。

黑屏-無背光

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

送圖無顯示

排除步驟:

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

閃屏

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

畫面偏移

畫面隨著數據的發送偏移越來越大。

嘗試修改lcd_dbi_clk_mode

屏幕白屏

屏幕白屏,但是背光亮起

image-20231017113731873 (1).png

白屏是因為屏幕沒有初始化,需要檢查屏幕初始化序列或者初始化數據是否正確。

屏幕花屏

屏幕花屏,無法控制

image-20231017113841569 (1).png

花屏一般是因為屏幕初始化后沒有正確設置 addrwin,或者初始化序列錯誤。

LVGL 屏幕顏色不正確

出現反色,顏色異常

image-20231017113620580 (1).png

請配置 LVGL LV_COLOR_DEPTH 參數為 16,LV_COLOR_16_SWAP 為 1,這是由 SPI LCD 的特性決定的。

image-20231017113520621 (1).png

顯示反色

運行 test_spilcd ,屏幕顯示藍色。

這是由于屏幕啟動了 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 出現 DMA OVER SIZE

image-20231023101154351.png

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

image-20231023101317634.png

出現部分花屏

image-20231023103039467.png

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

總結

調試LCD顯示屏實際上就是調試發送端芯片(全志SOC)和接收端芯片(LCD屏上的driver IC)的一個過程:

  1. 添加屏驅動請看編寫屏驅動
  2. 仔細閱讀屏手冊以及driver IC手冊(有的話)。
  3. 仔細閱讀板級顯示配置參數詳解。
  4. 確保LCD所需要的各路電源管腳正常。

SPI LCD 顏色相關問題

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

DBI接口的全稱是 Display Bus Serial Interface ,在顯示屏數據手冊中,一般會說這是SPI接口,所以有人會誤認為SPI屏可以使用 normal spi 去直接驅動。

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

對于R128這類支持DBI接口的CPU,可以選擇不去了解SPI。如果需要用到SPI去驅動顯示屏,必須把顯示屏設置成小端。

RGB565和RGB666

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

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

image-20231016100553340.png
RGB666一個點的顏色由3字節組成,每個字節代表一個顏色,其中每個字節的低2位會無視,如下圖所示:

image-20231016100620890.png

SPI 接口

因為SPI接口的通訊效率不高,所以建議使用RGB565的顯示,以 jlt35031c 顯示屏為例,他的顯示驅動芯片ST7789,設置顯示格式的方式是往 3a 寄存器寫入0x55(RGB565)或者 0x66(RGB666),在 R128SDK 中,已經把 jlt35031c 的通訊格式寫死為 0x55lcd_pixel_fmt配置選項無效:

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

在例程中,輸入的數據是 0xff,0x00,0xff,0x00,對于SPI接口,是按字節發送。實際上,例程只需要每次發送2字節即可,因為前后發送的都是相同的ff 00,所以沒有看出問題。

根據對 565 的數據解析,我們拆分 ff 00 就可以得到紅色分量是 0b11111,也就是 31,綠色是0b111000,也就是 56,,藍色是 0.我們等效轉換成 RGB888,有:

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

在調色板輸入對應顏色,就可以得到黃色

image-20231016100913213.png

DBI 接口

因為 DBI 通訊效率較高,所以可以使用 RGB565 或者 RGB666,使用 DBI 接口,也就是 lcd_if 設置為1時,驅動會根據 lcd_pixel_fmt 配置寄存器,以 SDK 中的 kld2844b.c 為例,這顯示屏的顯示驅動也是 ST7789,但是不同的屏幕,廠家封裝時已經限制了通訊方式,所以即使是能使用 DBI 接口的驅動芯片的屏幕,或許也用不了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);
}

對于 DBI 格式,不再是以字節的形式去解析,而是以字的方式去解析,為了統一,軟件已經規定了,RGB565 格式時,字大小是2字節,也就是16位,而 RGB666 格式時,字大小是4字節,也就是32位。

對于 RGB565 格式,同樣是設置為 0xff,0x00。因為屏幕是大端,而芯片存儲方式是小端,所以芯片的 DBI 模塊,會自動把數據從新排列,也就是實際上 DBI 發送數據時,會先發送0x00,再發送0xff,也就是紅色分量為0,綠色分量為 0b000111,也就是7,藍色分量是 0x11111,也就是31,我們同樣轉換成RGB888

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

在調色板上輸入,可以得到藍色。

image-20231016101233907.png

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

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

image-20231016101308346.png

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5359

    瀏覽量

    120793
  • 觸發器
    +關注

    關注

    14

    文章

    2000

    瀏覽量

    61255
  • SPI接口
    +關注

    關注

    0

    文章

    259

    瀏覽量

    34451
  • LCD顯示
    +關注

    關注

    0

    文章

    132

    瀏覽量

    18390
  • 顯示驅動
    +關注

    關注

    1

    文章

    66

    瀏覽量

    15012
  • R128
    +關注

    關注

    0

    文章

    41

    瀏覽量

    110
收藏 人收藏

    評論

    相關推薦

    R128應用開發案例—適配SPI驅動ST7789V2.4寸LCD

    R128 平臺提供了 SPI DBI 的 SPI TFT 接口,具有如下特點
    的頭像 發表于 11-02 16:44 ?1070次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>應用<b class='flag-5'>開發</b>案例—適配<b class='flag-5'>SPI</b><b class='flag-5'>驅動</b>ST7789V2.4寸<b class='flag-5'>LCD</b>

    R128內存泄漏調試案例分享

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

    縱享絲滑!R128+LVGL驅動多尺寸RGB LCD屏幕流暢運行

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

    R128硬件設計指南

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

    R128 SDK架構與目錄結構

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

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

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

    R128基礎組件開發——顯示與屏幕驅動

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

    R128基礎組件開發——顯示與屏幕驅動

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

    使用R128將LVGL運行在SPI TFT GUI上

    載入方案選擇 r128s2_module_c906 $ source envsetup.sh $ lunch_rtos 1 配置 SPI LCD 驅動
    發表于 10-23 13:56

    R128應用開發案例——SPI 驅動 TFT LCD

    SPI 驅動 TFT LCDR128 平臺提供了 SPI DBI 的 SPI TFT 接口
    發表于 10-23 14:29

    R128基礎組件開發指南——SPI LCD 顯示驅動

    SPI LCD 顯示驅動 簡介 R128 平臺提供了 SPI DBI 的
    發表于 10-25 14:36

    R128應用開發案例——SPI驅動ST7789V1.3寸LCD

    SPI驅動ST7789V1.3寸LCD R128 平臺提供了 SPI DBI 的 SPI TFT
    發表于 11-06 10:16

    A64開發LCD開發指南

    A64開發LCD開發指南驅動開發指南
    發表于 06-21 17:02 ?0次下載

    R128適配ST7789v LCD

    R128 平臺提供了 SPI DBI 的 SPI TFT 接口,具有如下特點
    的頭像 發表于 10-23 11:26 ?1018次閱讀
    <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 開發套件

    針對 R128 模組,百問科技推出了 R128 EVT 開發套件作為快速開發評估工具。
    的頭像 發表于 12-22 15:16 ?817次閱讀
    DshanMCU-<b class='flag-5'>R128</b>s2 <b class='flag-5'>R128</b> EVT <b class='flag-5'>開發</b>套件
    主站蜘蛛池模板: 男女免费网站| 国产小片| 在线免费色视频| 成年大片免费播放视频人| youjizz国产| 一级黄视频| 天天操天天干天搞天天射| 日本免费黄色录像| 国产精品午夜剧场| 天天干中文字幕| 人人爱天天做夜夜爽| www.夜夜操.com| 久久久久久久久久久观看| 国产重口老太和小伙乱视频| 午夜影院黄| 欧美成人亚洲欧美成人| 亚洲三级小视频| 日本中文字幕在线播放| 亚洲第一毛片| 床上激情四射| 亚洲高清一区二区三区| 好深好爽视频| 涩久久| 久久观看视频| 黄色三级网站免费| 成人a级特黄毛片| 天堂在线视频| 神马影院午夜dy888| 免费免播放器在线视频观看| 特黄特色大片免费播放路01| 在线视频三区| 99热免费| 日韩美女拍拍免费视频网站| 狠狠色噜噜狠狠狠狠| 黄 色美 女人| 夜夜操天天爽| 凹厕所xxxxbbbb偷拍视频| 久久水蜜桃网| 日本黄色录像视频| 明日花在线观看| 4虎成人|